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.stateTypeId,
|
||||||
this.extra = const {},
|
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 ───────────────────────────────────────────────────────
|
// ── 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<NymeaThingClass> _thingClasses = [];
|
||||||
List<FavoriteWidget> _favoriteWidgets = [];
|
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 ──────────────────────────────────────────────────────────────────
|
// ── Getters ──────────────────────────────────────────────────────────────────
|
||||||
bool get connected => _connected;
|
bool get connected => _connected;
|
||||||
bool get isConnected => _connected; // alias pour les screens
|
bool get isConnected => _connected; // alias pour les screens
|
||||||
@ -1185,12 +1215,14 @@ class NymeaService extends ChangeNotifier {
|
|||||||
if (!_favoriteWidgets.any((f) => f.id == widget.id)) {
|
if (!_favoriteWidgets.any((f) => f.id == widget.id)) {
|
||||||
_favoriteWidgets.add(widget);
|
_favoriteWidgets.add(widget);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
_saveFavorites();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeFavorite(String id) {
|
void removeFavorite(String id) {
|
||||||
_favoriteWidgets.removeWhere((f) => f.id == id);
|
_favoriteWidgets.removeWhere((f) => f.id == id);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
_saveFavorites();
|
||||||
}
|
}
|
||||||
|
|
||||||
void reorderFavorites(int oldIndex, int newIndex) {
|
void reorderFavorites(int oldIndex, int newIndex) {
|
||||||
@ -1198,6 +1230,7 @@ class NymeaService extends ChangeNotifier {
|
|||||||
final item = _favoriteWidgets.removeAt(oldIndex);
|
final item = _favoriteWidgets.removeAt(oldIndex);
|
||||||
_favoriteWidgets.insert(newIndex, item);
|
_favoriteWidgets.insert(newIndex, item);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
_saveFavorites();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ═══════════════════════════════════════════════════════════════════════════
|
// ═══════════════════════════════════════════════════════════════════════════
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user