Files
pluriwave/lib/modelos/alarma_musical.dart
T
FreeTLab fb808ebb60
Build & Deploy Pluriwave / Análisis de código (push) Successful in 14s
Build & Deploy Pluriwave / Build APK + AAB release (push) Successful in 2m45s
feat(alarm): add musical alarm foundation
2026-05-21 23:47:06 +02:00

220 lines
6.3 KiB
Dart

import 'emisora.dart';
enum TipoProgramacionAlarma { unica, diaria, diasSemana }
enum SonidoInternoAlarma { amanecer, campanaSuave, pulsoDigital }
class AlarmaMusical {
const AlarmaMusical({
required this.id,
required this.nombre,
required this.hora,
required this.minuto,
required this.tipoProgramacion,
required this.diasSemana,
this.emisora,
this.emisoraFallback,
this.activa = true,
this.sonarEnVacaciones = true,
this.snoozeMinutos = 5,
this.volumen = 0.85,
this.sonidoInterno = SonidoInternoAlarma.amanecer,
this.proximaEjecucion,
this.creadaEn,
this.actualizadaEn,
});
final String id;
final String nombre;
final bool activa;
final int hora;
final int minuto;
final TipoProgramacionAlarma tipoProgramacion;
final List<int> diasSemana;
final Emisora? emisora;
final Emisora? emisoraFallback;
final bool sonarEnVacaciones;
final int snoozeMinutos;
final double volumen;
final SonidoInternoAlarma sonidoInterno;
final DateTime? proximaEjecucion;
final DateTime? creadaEn;
final DateTime? actualizadaEn;
AlarmaMusical copyWith({
String? id,
String? nombre,
bool? activa,
int? hora,
int? minuto,
TipoProgramacionAlarma? tipoProgramacion,
List<int>? diasSemana,
Emisora? emisora,
Emisora? emisoraFallback,
bool? sonarEnVacaciones,
int? snoozeMinutos,
double? volumen,
SonidoInternoAlarma? sonidoInterno,
DateTime? proximaEjecucion,
DateTime? creadaEn,
DateTime? actualizadaEn,
}) {
return AlarmaMusical(
id: id ?? this.id,
nombre: nombre ?? this.nombre,
activa: activa ?? this.activa,
hora: hora ?? this.hora,
minuto: minuto ?? this.minuto,
tipoProgramacion: tipoProgramacion ?? this.tipoProgramacion,
diasSemana: diasSemana ?? this.diasSemana,
emisora: emisora ?? this.emisora,
emisoraFallback: emisoraFallback ?? this.emisoraFallback,
sonarEnVacaciones: sonarEnVacaciones ?? this.sonarEnVacaciones,
snoozeMinutos: snoozeMinutos ?? this.snoozeMinutos,
volumen: volumen ?? this.volumen,
sonidoInterno: sonidoInterno ?? this.sonidoInterno,
proximaEjecucion: proximaEjecucion ?? this.proximaEjecucion,
creadaEn: creadaEn ?? this.creadaEn,
actualizadaEn: actualizadaEn ?? this.actualizadaEn,
);
}
Map<String, dynamic> toJson() => {
'id': id,
'nombre': nombre,
'activa': activa,
'hora': hora,
'minuto': minuto,
'tipoProgramacion': tipoProgramacion.name,
'diasSemana': diasSemana,
'emisora': emisora?.toMap(),
'emisoraFallback': emisoraFallback?.toMap(),
'sonarEnVacaciones': sonarEnVacaciones,
'snoozeMinutos': snoozeMinutos,
'volumen': volumen,
'sonidoInterno': sonidoInterno.name,
'proximaEjecucion': proximaEjecucion?.toIso8601String(),
'creadaEn': creadaEn?.toIso8601String(),
'actualizadaEn': actualizadaEn?.toIso8601String(),
};
factory AlarmaMusical.fromJson(Map<String, dynamic> json) {
return AlarmaMusical(
id: json['id'] as String,
nombre: json['nombre'] as String? ?? 'Alarma musical',
activa: json['activa'] as bool? ?? true,
hora: json['hora'] as int? ?? 7,
minuto: json['minuto'] as int? ?? 0,
tipoProgramacion: _enumFromName(
TipoProgramacionAlarma.values,
json['tipoProgramacion'] as String?,
TipoProgramacionAlarma.unica,
),
diasSemana:
(json['diasSemana'] as List? ?? const [])
.whereType<int>()
.where((d) => d >= DateTime.monday && d <= DateTime.sunday)
.toList(),
emisora: _emisoraFromJson(json['emisora']),
emisoraFallback: _emisoraFromJson(json['emisoraFallback']),
sonarEnVacaciones: json['sonarEnVacaciones'] as bool? ?? true,
snoozeMinutos: json['snoozeMinutos'] as int? ?? 5,
volumen: (json['volumen'] as num?)?.toDouble() ?? 0.85,
sonidoInterno: _enumFromName(
SonidoInternoAlarma.values,
json['sonidoInterno'] as String?,
SonidoInternoAlarma.amanecer,
),
proximaEjecucion: _dateFromJson(json['proximaEjecucion']),
creadaEn: _dateFromJson(json['creadaEn']),
actualizadaEn: _dateFromJson(json['actualizadaEn']),
);
}
static Emisora? _emisoraFromJson(Object? raw) {
if (raw is! Map) return null;
return Emisora.fromMap(Map<String, dynamic>.from(raw));
}
static DateTime? _dateFromJson(Object? raw) =>
raw is String ? DateTime.tryParse(raw) : null;
static T _enumFromName<T extends Enum>(
List<T> values,
String? name,
T fallback,
) {
for (final value in values) {
if (value.name == name) return value;
}
return fallback;
}
}
class RangoVacaciones {
const RangoVacaciones({
required this.id,
required this.nombre,
required this.inicio,
required this.fin,
this.activo = true,
});
final String id;
final String nombre;
final DateTime inicio;
final DateTime fin;
final bool activo;
bool contiene(DateTime fecha) {
final dia = DateTime(fecha.year, fecha.month, fecha.day);
final desde = DateTime(inicio.year, inicio.month, inicio.day);
final hasta = DateTime(fin.year, fin.month, fin.day);
return activo && !dia.isBefore(desde) && !dia.isAfter(hasta);
}
Map<String, dynamic> toJson() => {
'id': id,
'nombre': nombre,
'inicio': inicio.toIso8601String(),
'fin': fin.toIso8601String(),
'activo': activo,
};
factory RangoVacaciones.fromJson(Map<String, dynamic> json) {
return RangoVacaciones(
id: json['id'] as String,
nombre: json['nombre'] as String? ?? 'Vacaciones',
inicio: DateTime.parse(json['inicio'] as String),
fin: DateTime.parse(json['fin'] as String),
activo: json['activo'] as bool? ?? true,
);
}
}
class ExcepcionAlarma {
const ExcepcionAlarma({
required this.alarmaId,
required this.ejecucion,
required this.tipo,
});
final String alarmaId;
final DateTime ejecucion;
final String tipo;
Map<String, dynamic> toJson() => {
'alarmaId': alarmaId,
'ejecucion': ejecucion.toIso8601String(),
'tipo': tipo,
};
factory ExcepcionAlarma.fromJson(Map<String, dynamic> json) {
return ExcepcionAlarma(
alarmaId: json['alarmaId'] as String,
ejecucion: DateTime.parse(json['ejecucion'] as String),
tipo: json['tipo'] as String? ?? 'skipNext',
);
}
}