diff --git a/lib/school/ywb/index.dart b/lib/school/ywb/index.dart index 8e3b6110e..417eedcde 100644 --- a/lib/school/ywb/index.dart +++ b/lib/school/ywb/index.dart @@ -1,6 +1,7 @@ import 'dart:math'; import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:sit/design/widgets/app.dart'; import 'package:sit/school/ywb/entity/application.dart'; @@ -12,36 +13,21 @@ import 'widgets/application.dart'; const _applicationLength = 2; -class YwbAppCard extends StatefulWidget { +class YwbAppCard extends ConsumerStatefulWidget { const YwbAppCard({super.key}); @override - State createState() => _YwbAppCardState(); + ConsumerState createState() => _YwbAppCardState(); } -class _YwbAppCardState extends State { - final $running = YwbInit.applicationStorage.listenApplicationListOf(YwbApplicationType.running); - @override - void initState() { - super.initState(); - $running.addListener(refresh); - } - - @override - void dispose() { - $running.removeListener(refresh); - super.dispose(); - } - - void refresh() { - setState(() {}); - } - +class _YwbAppCardState extends ConsumerState { @override Widget build(BuildContext context) { + final storage = YwbInit.applicationStorage; + final running = ref.watch(storage.$applicationFamily(YwbApplicationType.running)); return AppCard( title: i18n.title.text(), - view: buildRunningCard(), + view: running == null ? null : buildRunningCard(running), leftActions: [ FilledButton.icon( onPressed: () { @@ -61,9 +47,7 @@ class _YwbAppCardState extends State { ); } - Widget buildRunningCard() { - final running = YwbInit.applicationStorage.getApplicationListOf(YwbApplicationType.running); - if (running == null) return const SizedBox(); + Widget buildRunningCard(List running) { final applications = running.sublist(0, min(_applicationLength, running.length)); return applications .map((e) => YwbApplicationTile(e).inCard( diff --git a/lib/school/ywb/init.dart b/lib/school/ywb/init.dart index 45d82ee67..58039f7de 100644 --- a/lib/school/ywb/init.dart +++ b/lib/school/ywb/init.dart @@ -17,6 +17,6 @@ class YwbInit { serviceService = Dev.demoMode ? const DemoYwbServiceService() : const YwbServiceService(); serviceStorage = const YwbServiceStorage(); applicationService = Dev.demoMode ? const DemoYwbApplicationService() : const YwbApplicationService(); - applicationStorage = const YwbApplicationStorage(); + applicationStorage = YwbApplicationStorage(); } } diff --git a/lib/school/ywb/storage/application.dart b/lib/school/ywb/storage/application.dart index 891215add..8017eaa39 100644 --- a/lib/school/ywb/storage/application.dart +++ b/lib/school/ywb/storage/application.dart @@ -14,7 +14,7 @@ class _K { class YwbApplicationStorage { Box get box => HiveInit.ywb; - const YwbApplicationStorage(); + YwbApplicationStorage(); List? getApplicationListOf(YwbApplicationType type) => (box.safeGet(_K.applicationListOf(type)) as List?)?.cast(); @@ -23,4 +23,7 @@ class YwbApplicationStorage { box.safePut(_K.applicationListOf(type), newV); Listenable listenApplicationListOf(YwbApplicationType type) => box.listenable(keys: [_K.applicationListOf(type)]); + + late final $applicationFamily = + box.providerFamily, YwbApplicationType>(_K.applicationListOf, getApplicationListOf); } diff --git a/lib/storage/hive/init.dart b/lib/storage/hive/init.dart index 923dccb5c..ad701428b 100644 --- a/lib/storage/hive/init.dart +++ b/lib/storage/hive/init.dart @@ -59,10 +59,10 @@ class HiveInit { settings = await core.openBox('settings'), meta = await core.openBox('meta'), timetable = await core.openBox('timetable'), + dev = await core.openBox("dev"), ...cacheBoxes = [ yellowPages = await cache.openBox('yellow-pages'), eduEmail = await cache.openBox('edu-email'), - dev = await core.openBox("dev"), game = await core.openBox("game"), if (!kIsWeb) cookies = await cache.openBox('cookies'), if (!kIsWeb) expense = await cache.openBox('expense'), diff --git a/lib/utils/hive.dart b/lib/utils/hive.dart index 8c311cae4..2bb69893a 100644 --- a/lib/utils/hive.dart +++ b/lib/utils/hive.dart @@ -81,7 +81,6 @@ class BoxChangeStreamNotifier extends ChangeNotifier { } } - extension BoxProviderX on Box { /// For generic class, like [List] or [Map], please specify the [get] for type conversion. AutoDisposeStateNotifierProvider, T?> provider(dynamic key, [T? Function()? get]) { @@ -94,6 +93,20 @@ extension BoxProviderX on Box { }); } + /// For generic class, like [List] or [Map], please specify the [get] for type conversion. + AutoDisposeStateNotifierProviderFamily, T?, Arg> providerFamily( + dynamic Function(Arg arg) keyOf, + T? Function(Arg arg) get, + ) { + return StateNotifierProvider.autoDispose.family, T?, Arg>((ref, arg) { + return BoxFieldNotifier( + get(arg), + listenable(keys: [keyOf(arg)]), + () => get(arg), + ); + }); + } + AutoDisposeChangeNotifierProvider changeProvider(List keys) { return ChangeNotifierProvider.autoDispose((ref) { return BoxChangeNotifier(listenable(keys: keys)); @@ -107,8 +120,8 @@ extension BoxProviderX on Box { } ChangeNotifierProviderFamily streamProviderFamily({dynamic key}) { - return ChangeNotifierProvider.family((ref, filter) { - return BoxChangeStreamNotifier(watch(key: key), filter); + return ChangeNotifierProvider.family((ref, arg) { + return BoxChangeStreamNotifier(watch(key: key), arg); }); } }