import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:mirror_core/mirror_core.dart'; import 'settings_provider.dart'; final plexServiceProvider = Provider((ref) { final settings = ref.watch(settingsProvider).valueOrNull; if (settings == null || settings.plexHost == null || settings.plexToken == null) { return null; } return PlexService( host: settings.plexHost!, port: settings.plexPort, token: settings.plexToken!, ); }); final plexBrowseProvider = AsyncNotifierProvider( PlexBrowseNotifier.new); class PlexBrowseState { final List libraries; final PlexLibrary? currentLibrary; final List items; final List breadcrumb; final String? error; const PlexBrowseState({ this.libraries = const [], this.currentLibrary, this.items = const [], this.breadcrumb = const [], this.error, }); } class PlexBrowseNotifier extends AsyncNotifier { @override Future build() async { final service = ref.watch(plexServiceProvider); if (service == null) { return const PlexBrowseState(error: 'Configure Plex in Settings'); } final libraries = await service.fetchLibraries(); return PlexBrowseState(libraries: libraries); } Future openLibrary(PlexLibrary library) async { final service = ref.read(plexServiceProvider); if (service == null) return; state = const AsyncValue.loading(); state = await AsyncValue.guard(() async { final items = await service.fetchItems(library.id); return PlexBrowseState( libraries: state.valueOrNull?.libraries ?? [], currentLibrary: library, items: items, breadcrumb: [library.title], ); }); } Future openItem(PlexItem item) async { final service = ref.read(plexServiceProvider); if (service == null) return; if (item.type == 'show' || item.type == 'season' || item.type == 'artist' || item.type == 'album') { state = const AsyncValue.loading(); state = await AsyncValue.guard(() async { final children = await service.fetchChildren(item.id); final prev = state.valueOrNull; return PlexBrowseState( libraries: prev?.libraries ?? [], currentLibrary: prev?.currentLibrary, items: children, breadcrumb: [...(prev?.breadcrumb ?? []), item.title], ); }); } } Future goBack() async { final prev = state.valueOrNull; if (prev == null) return; if (prev.breadcrumb.length <= 1) { state = AsyncValue.data(PlexBrowseState( libraries: prev.libraries, )); } else { if (prev.currentLibrary != null) { await openLibrary(prev.currentLibrary!); } } } void refresh() { ref.invalidateSelf(); } }