feat: favoris — persistance SharedPreferences + restyle EtmTokens
Persistance (FavoriteWidget) - FavoriteWidget.fromJson / toJson ajoutés dans nymea_models.dart - NymeaService : constructeur appelle _loadFavorites() au démarrage - _saveFavorites() appelé après addFavorite / removeFavorite / reorderFavorites - Clé SharedPreferences : 'etm_favorites_v1' - Résistance aux données corrompues (try/catch sur fromJson) Restyle (favorites_screen.dart) - AppTheme → EtmTokens sur toutes les couleurs et typographies - Valeurs en IBM Plex Mono (size 36 pour les grandes métriques) - Cartes avec EtmTokens.cardShadow + border radius 22 - _EmptyState : bouton vert + étoile + message - _AddSheet : DraggableScrollableSheet restyled, sans emoji, items visuellement distingués (ajouté vs disponible) - ReorderableDelayedDragStartListener pour le drag discret - Simulation auto-démarrée si non connecté (comme Dashboard/Things) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d0a475a5d9
commit
80500e21e6
@ -281,6 +281,26 @@ class FavoriteWidget {
|
||||
this.stateTypeId,
|
||||
this.extra = const {},
|
||||
});
|
||||
|
||||
factory FavoriteWidget.fromJson(Map<String, dynamic> j) => FavoriteWidget(
|
||||
id: j['id'] as String,
|
||||
type: FavoriteType.values.firstWhere(
|
||||
(t) => t.name == j['type'],
|
||||
orElse: () => FavoriteType.pvPower),
|
||||
title: j['title'] as String,
|
||||
thingId: j['thingId'] as String?,
|
||||
stateTypeId: j['stateTypeId'] as String?,
|
||||
extra: Map<String, dynamic>.from(j['extra'] as Map? ?? {}),
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
'type': type.name,
|
||||
'title': title,
|
||||
if (thingId != null) 'thingId': thingId,
|
||||
if (stateTypeId != null) 'stateTypeId': stateTypeId,
|
||||
if (extra.isNotEmpty) 'extra': extra,
|
||||
};
|
||||
}
|
||||
|
||||
// ── Historique d'un état ───────────────────────────────────────────────────────
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -75,6 +75,36 @@ class NymeaService extends ChangeNotifier {
|
||||
List<NymeaThingClass> _thingClasses = [];
|
||||
List<FavoriteWidget> _favoriteWidgets = [];
|
||||
|
||||
static const _favKey = 'etm_favorites_v1';
|
||||
|
||||
NymeaService() {
|
||||
_loadFavorites();
|
||||
}
|
||||
|
||||
Future<void> _loadFavorites() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final raw = prefs.getString(_favKey);
|
||||
if (raw != null) {
|
||||
try {
|
||||
final list = jsonDecode(raw) as List;
|
||||
_favoriteWidgets = list
|
||||
.map((e) => FavoriteWidget.fromJson(e as Map<String, dynamic>))
|
||||
.toList();
|
||||
notifyListeners();
|
||||
} catch (_) {
|
||||
// Données corrompues — on repart de zéro
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _saveFavorites() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString(
|
||||
_favKey,
|
||||
jsonEncode(_favoriteWidgets.map((f) => f.toJson()).toList()),
|
||||
);
|
||||
}
|
||||
|
||||
// ── Getters ──────────────────────────────────────────────────────────────────
|
||||
bool get connected => _connected;
|
||||
bool get isConnected => _connected; // alias pour les screens
|
||||
@ -1185,12 +1215,14 @@ class NymeaService extends ChangeNotifier {
|
||||
if (!_favoriteWidgets.any((f) => f.id == widget.id)) {
|
||||
_favoriteWidgets.add(widget);
|
||||
notifyListeners();
|
||||
_saveFavorites();
|
||||
}
|
||||
}
|
||||
|
||||
void removeFavorite(String id) {
|
||||
_favoriteWidgets.removeWhere((f) => f.id == id);
|
||||
notifyListeners();
|
||||
_saveFavorites();
|
||||
}
|
||||
|
||||
void reorderFavorites(int oldIndex, int newIndex) {
|
||||
@ -1198,6 +1230,7 @@ class NymeaService extends ChangeNotifier {
|
||||
final item = _favoriteWidgets.removeAt(oldIndex);
|
||||
_favoriteWidgets.insert(newIndex, item);
|
||||
notifyListeners();
|
||||
_saveFavorites();
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user