Files
ignis_app/lib/models/ignis_scene.dart
2026-04-23 20:44:51 +07:00

140 lines
3.8 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
class IgnisScene {
final String id;
final String displayName;
const IgnisScene({required this.id, required this.displayName});
static IgnisScene fromApi(Object? value, {String? fallbackId}) {
if (value is Map) {
final map = Map<String, dynamic>.from(value);
final id =
_stringValue(map, const ['id', 'scene', 'scene_id', 'value']) ??
fallbackId;
if (id == null || id.isEmpty) {
throw const FormatException('scene не содержит id');
}
final explicitName = _stringValue(map, const [
'name',
'label',
'display_name',
'title',
]);
return IgnisScene(
id: id,
displayName: explicitName ?? displayNameFor(id),
);
}
final id = value?.toString() ?? fallbackId;
if (id == null || id.isEmpty) {
throw const FormatException('scene должен быть объектом или id');
}
return IgnisScene(id: id, displayName: displayNameFor(id));
}
static List<IgnisScene> listFromApi(Object? data) {
final values = _collectionValues(data, const ['data', 'scenes']);
return values.map((value) {
if (value.entryKey == null) {
return IgnisScene.fromApi(value.value);
}
if (value.value is String || value.value is num) {
final name = value.value.toString();
return IgnisScene(
id: value.entryKey!,
displayName: _looksLikeTechnicalId(name)
? displayNameFor(name)
: name,
);
}
return IgnisScene.fromApi(value.value, fallbackId: value.entryKey);
}).toList();
}
static String displayNameFor(String id) {
final normalized = id.trim();
final knownName = _wizSceneNames[normalized];
if (knownName != null) return knownName;
return 'Сцена $normalized';
}
}
const Map<String, String> _wizSceneNames = {
'1': 'Океан',
'2': 'Романтика',
'3': 'Закат',
'4': 'Вечеринка',
'5': 'Камин',
'6': 'Уют',
'7': 'Лес',
'8': 'Пастель',
'9': 'Пробуждение',
'10': 'Сон',
'11': 'Тёплый белый',
'12': 'Дневной свет',
'13': 'Холодный белый',
'14': 'Ночник',
'15': 'Фокус',
'16': 'Расслабление',
'17': 'Настоящие цвета',
'18': 'ТВ',
'19': 'Рост растений',
'20': 'Весна',
'21': 'Лето',
'22': 'Осень',
'23': 'Погружение',
'24': 'Джунгли',
'25': 'Мохито',
'26': 'Клуб',
'27': 'Рождество',
'28': 'Хэллоуин',
'29': 'Свеча',
'30': 'Золотистый белый',
'31': 'Пульс',
'32': 'Стимпанк',
};
String? _stringValue(Map<String, dynamic> map, List<String> keys) {
for (final key in keys) {
final value = map[key];
if (value != null && value.toString().isNotEmpty) {
return value.toString();
}
}
return null;
}
bool _looksLikeTechnicalId(String value) => int.tryParse(value.trim()) != null;
List<_CollectionValue> _collectionValues(Object? data, List<String> wrappers) {
if (data is List) {
return data.map((value) => _CollectionValue(value)).toList();
}
if (data is Map) {
final map = Map<String, dynamic>.from(data);
for (final wrapper in wrappers) {
final value = map[wrapper];
if (value is List) {
return value.map((item) => _CollectionValue(item)).toList();
}
}
return map.entries
.map((entry) => _CollectionValue(entry.value, entryKey: entry.key))
.toList();
}
throw const FormatException('ожидался список или объект');
}
class _CollectionValue {
final Object? value;
final String? entryKey;
const _CollectionValue(this.value, {this.entryKey});
}