100 lines
2.8 KiB
Dart
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();
|
|
}
|
|
}
|