Riverpod Providers
Riverpod Providers
Section titled “Riverpod Providers”市场层的所有 Riverpod provider 集中在 lib/core/market/market_providers.dart。手动声明(无 codegen),风格和 lib/core/providers.dart 一致。
marketConfigProvider
Section titled “marketConfigProvider”final marketConfigProvider = Provider<MarketConfig>( (ref) => MarketConfig.defaultConfig,);市场配置。默认指向官方仓库。要指向自己的 fork,在 ProviderScope 里 override:
ProviderScope( overrides: [ marketConfigProvider.overrideWithValue( const MarketConfig(owner: 'my-org', repo: 'my-market', branch: 'main'), ), ], child: const MoodPetApp(),)marketCacheProvider
Section titled “marketCacheProvider”final marketCacheProvider = FutureProvider<MarketCache>((ref) async { final support = await getApplicationSupportDirectory(); final root = Directory('${support.path}/moodpet/market-cache'); return MarketCache(root);});磁盘缓存单例。根目录 <appSupportDir>/moodpet/market-cache/。
marketRepositoryProvider
Section titled “marketRepositoryProvider”final marketRepositoryProvider = FutureProvider<MarketRepository>((ref) async { final config = ref.watch(marketConfigProvider); final cache = await ref.watch(marketCacheProvider.future); return MarketRepository(config, cache);});仓库单例。依赖 config 和 cache。
pluginInstallerProvider
Section titled “pluginInstallerProvider”final pluginInstallerProvider = FutureProvider<PluginInstaller>((ref) async { final repository = await ref.watch(marketRepositoryProvider.future); return PluginInstaller(repository);});安装器单例。
updateCheckerProvider
Section titled “updateCheckerProvider”final updateCheckerProvider = FutureProvider<UpdateChecker>((ref) async { final repository = await ref.watch(marketRepositoryProvider.future); final manager = await ref.watch(pluginManagerProvider.future); return UpdateChecker(repository, manager);});更新检查器单例。依赖仓库和 pluginManagerProvider(来自 providers.dart)。
三个目录列表 provider,UI watch 它们渲染 Tab:
marketFriendListProvider
Section titled “marketFriendListProvider”final marketFriendListProvider = FutureProvider<List<MarketPlugin>>((ref) async { final repo = await ref.watch(marketRepositoryProvider.future); return repo.listDirectory(MarketDir.friend);});marketApplicationListProvider
Section titled “marketApplicationListProvider”final marketApplicationListProvider = FutureProvider<List<MarketPlugin>>((ref) async { final repo = await ref.watch(marketRepositoryProvider.future); return repo.listDirectory(MarketDir.application);});marketPacksListProvider
Section titled “marketPacksListProvider”final marketPacksListProvider = FutureProvider<List<MarketPlugin>>((ref) async { final repo = await ref.watch(marketRepositoryProvider.future); return repo.listDirectory(MarketDir.packs);});marketUpdatesProvider
Section titled “marketUpdatesProvider”final marketUpdatesProvider = FutureProvider<List<PluginUpdate>>((ref) async { final checker = await ref.watch(updateCheckerProvider.future); return checker.checkAll();});可用更新列表。UI watch 它决定是否显示红点。
UI 里的用法
Section titled “UI 里的用法”watch + when
Section titled “watch + when”final friendsAsync = ref.watch(marketFriendListProvider);
friendsAsync.when( loading: () => const Center(child: CircularProgressIndicator()), error: (e, _) => Center(child: Text('加载失败: $e')), data: (friends) => GridView.builder( itemCount: friends.length, itemBuilder: (context, i) => MarketPluginCard(plugin: friends[i]), ),);// 刷新一个目录ref.invalidate(marketFriendListProvider);
// 刷新所有ref.invalidate(marketFriendListProvider);ref.invalidate(marketApplicationListProvider);ref.invalidate(marketPacksListProvider);ref.invalidate(marketUpdatesProvider);invalidate 会清掉 provider 的缓存值,下次 watch 时重新执行——走 MarketRepository.listDirectory,先查 MarketCache(5 分钟 TTL),未命中才走网络。
下拉刷新用 ref.refresh(provider.future):
RefreshIndicator( onRefresh: () => ref.refresh(marketFriendListProvider.future).then((_) {}), child: ...,)安装/更新成功后刷新 pluginManagerProvider(让新插件出现在已安装列表)和 marketUpdatesProvider(更新红点):
final result = await installer.install(plugin);if (result.success) { ref.invalidate(pluginManagerProvider); ref.invalidate(marketUpdatesProvider);}判断已安装 + 有更新
Section titled “判断已安装 + 有更新”final manager = ref.watch(pluginManagerProvider).maybeWhen( data: (m) => m, orElse: () => null,);final isInstalled = manager?.pluginById(plugin.id) != null;
final updatableIds = ref.watch(marketUpdatesProvider).maybeWhen( data: (updates) => updates.map((u) => u.pluginId).toSet(), orElse: () => const <String>{},);final isUpdatable = isInstalled && updatableIds.contains(plugin.id);卡片三态:未安装 → “安装”;已安装有更新 → “更新”;已安装无更新 → “已安装”。