new favourites feature
This commit is contained in:
@@ -1,21 +1,55 @@
|
||||
/// App preferences beyond theme (Look ahead horizon, etc.).
|
||||
/// App preferences beyond theme (Look ahead, Overview favourites, Home widgets).
|
||||
library;
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import '../models/home_filter_widget.dart';
|
||||
import '../models/overview_favourite.dart';
|
||||
import '../services/storage_service.dart';
|
||||
|
||||
class PreferencesController extends ChangeNotifier {
|
||||
PreferencesController(this._storage) {
|
||||
_lookAheadMaxYears = _storage.lookAheadMaxYears;
|
||||
_overviewFavourites = _storage.loadOverviewFavourites();
|
||||
_homeFilterWidgets = _storage.loadHomeFilterWidgets();
|
||||
}
|
||||
|
||||
final StorageService _storage;
|
||||
late int _lookAheadMaxYears;
|
||||
late List<OverviewFavourite> _overviewFavourites;
|
||||
late List<HomeFilterWidget> _homeFilterWidgets;
|
||||
|
||||
/// Fired after favourites are persisted (for cloud push debounce).
|
||||
VoidCallback? onFavouritesPersisted;
|
||||
|
||||
/// Fired after Home widgets are persisted (for cloud push debounce).
|
||||
VoidCallback? onHomeWidgetsPersisted;
|
||||
|
||||
/// Years ahead Look ahead can navigate (1–30, default 5).
|
||||
int get lookAheadMaxYears => _lookAheadMaxYears;
|
||||
|
||||
List<OverviewFavourite> get overviewFavourites =>
|
||||
List.unmodifiable(_overviewFavourites);
|
||||
|
||||
List<OverviewFavourite> get displayedOverviewFavourites => [
|
||||
for (final fav in _overviewFavourites)
|
||||
if (fav.display) fav,
|
||||
];
|
||||
|
||||
bool get hasDisplayedOverviewFavourites =>
|
||||
_overviewFavourites.any((f) => f.display);
|
||||
|
||||
List<HomeFilterWidget> get homeFilterWidgets =>
|
||||
List.unmodifiable(_homeFilterWidgets);
|
||||
|
||||
List<HomeFilterWidget> get displayedHomeFilterWidgets => [
|
||||
for (final w in _homeFilterWidgets)
|
||||
if (w.display) w,
|
||||
];
|
||||
|
||||
bool get hasDisplayedHomeFilterWidgets =>
|
||||
_homeFilterWidgets.any((w) => w.display);
|
||||
|
||||
Future<void> setLookAheadMaxYears(int years) async {
|
||||
final next = years.clamp(1, 30);
|
||||
if (next == _lookAheadMaxYears) return;
|
||||
@@ -23,4 +57,118 @@ class PreferencesController extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
await _storage.setLookAheadMaxYears(next);
|
||||
}
|
||||
|
||||
Future<void> addOverviewFavourite(OverviewFavourite favourite) async {
|
||||
_overviewFavourites = [..._overviewFavourites, favourite];
|
||||
notifyListeners();
|
||||
await _persistFavourites();
|
||||
}
|
||||
|
||||
Future<void> updateOverviewFavourite(OverviewFavourite favourite) async {
|
||||
final index = _overviewFavourites.indexWhere((f) => f.id == favourite.id);
|
||||
if (index < 0) return;
|
||||
final next = [..._overviewFavourites];
|
||||
next[index] = favourite;
|
||||
_overviewFavourites = next;
|
||||
notifyListeners();
|
||||
await _persistFavourites();
|
||||
}
|
||||
|
||||
Future<void> removeOverviewFavourite(String id) async {
|
||||
final next = [
|
||||
for (final fav in _overviewFavourites)
|
||||
if (fav.id != id) fav,
|
||||
];
|
||||
if (next.length == _overviewFavourites.length) return;
|
||||
_overviewFavourites = next;
|
||||
notifyListeners();
|
||||
await _persistFavourites();
|
||||
}
|
||||
|
||||
Future<void> setOverviewFavouriteDisplay(String id, bool display) async {
|
||||
final index = _overviewFavourites.indexWhere((f) => f.id == id);
|
||||
if (index < 0) return;
|
||||
final current = _overviewFavourites[index];
|
||||
if (current.display == display) return;
|
||||
await updateOverviewFavourite(current.copyWith(display: display));
|
||||
}
|
||||
|
||||
Future<void> replaceOverviewFavourites(
|
||||
List<OverviewFavourite> favourites, {
|
||||
bool notify = true,
|
||||
bool schedulePush = false,
|
||||
}) async {
|
||||
_overviewFavourites = List.of(favourites);
|
||||
if (notify) notifyListeners();
|
||||
await _storage.saveOverviewFavourites(_overviewFavourites);
|
||||
if (schedulePush) onFavouritesPersisted?.call();
|
||||
}
|
||||
|
||||
Future<void> addHomeFilterWidget(HomeFilterWidget widget) async {
|
||||
final order = _homeFilterWidgets.isEmpty
|
||||
? 0
|
||||
: _homeFilterWidgets
|
||||
.map((w) => w.sortOrder)
|
||||
.reduce((a, b) => a > b ? a : b) +
|
||||
1;
|
||||
_homeFilterWidgets = [
|
||||
..._homeFilterWidgets,
|
||||
widget.copyWith(sortOrder: widget.sortOrder == 0 ? order : widget.sortOrder),
|
||||
];
|
||||
notifyListeners();
|
||||
await _persistHomeWidgets();
|
||||
}
|
||||
|
||||
Future<void> updateHomeFilterWidget(HomeFilterWidget widget) async {
|
||||
final index = _homeFilterWidgets.indexWhere((w) => w.id == widget.id);
|
||||
if (index < 0) return;
|
||||
final next = [..._homeFilterWidgets];
|
||||
next[index] = widget;
|
||||
next.sort((a, b) => a.sortOrder.compareTo(b.sortOrder));
|
||||
_homeFilterWidgets = next;
|
||||
notifyListeners();
|
||||
await _persistHomeWidgets();
|
||||
}
|
||||
|
||||
Future<void> removeHomeFilterWidget(String id) async {
|
||||
final next = [
|
||||
for (final w in _homeFilterWidgets)
|
||||
if (w.id != id) w,
|
||||
];
|
||||
if (next.length == _homeFilterWidgets.length) return;
|
||||
_homeFilterWidgets = next;
|
||||
notifyListeners();
|
||||
await _persistHomeWidgets();
|
||||
}
|
||||
|
||||
Future<void> setHomeFilterWidgetDisplay(String id, bool display) async {
|
||||
final index = _homeFilterWidgets.indexWhere((w) => w.id == id);
|
||||
if (index < 0) return;
|
||||
final current = _homeFilterWidgets[index];
|
||||
if (current.display == display) return;
|
||||
await updateHomeFilterWidget(current.copyWith(display: display));
|
||||
}
|
||||
|
||||
Future<void> replaceHomeFilterWidgets(
|
||||
List<HomeFilterWidget> widgets, {
|
||||
bool notify = true,
|
||||
bool schedulePush = false,
|
||||
}) async {
|
||||
final next = List.of(widgets)
|
||||
..sort((a, b) => a.sortOrder.compareTo(b.sortOrder));
|
||||
_homeFilterWidgets = next;
|
||||
if (notify) notifyListeners();
|
||||
await _storage.saveHomeFilterWidgets(_homeFilterWidgets);
|
||||
if (schedulePush) onHomeWidgetsPersisted?.call();
|
||||
}
|
||||
|
||||
Future<void> _persistFavourites() async {
|
||||
await _storage.saveOverviewFavourites(_overviewFavourites);
|
||||
onFavouritesPersisted?.call();
|
||||
}
|
||||
|
||||
Future<void> _persistHomeWidgets() async {
|
||||
await _storage.saveHomeFilterWidgets(_homeFilterWidgets);
|
||||
onHomeWidgetsPersisted?.call();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user