Files
2026-07-11 21:51:34 -05:00

100 lines
2.8 KiB
Dart

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:mirror_core/mirror_core.dart';
import 'settings_provider.dart';
final plexServiceProvider = Provider<PlexService?>((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, PlexBrowseState>(
PlexBrowseNotifier.new);
class PlexBrowseState {
final List<PlexLibrary> libraries;
final PlexLibrary? currentLibrary;
final List<PlexItem> items;
final List<String> breadcrumb;
final String? error;
const PlexBrowseState({
this.libraries = const [],
this.currentLibrary,
this.items = const [],
this.breadcrumb = const [],
this.error,
});
}
class PlexBrowseNotifier extends AsyncNotifier<PlexBrowseState> {
@override
Future<PlexBrowseState> 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<void> 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<void> 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<void> 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();
}
}