132 lines
3.4 KiB
Dart
132 lines
3.4 KiB
Dart
import 'package:flutter/widgets.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
|
|
import '../../core/contracts/library.dart';
|
|
import '../../core/contracts/tmdb.dart';
|
|
import '../../core/infra/emby_api/emby_headers.dart';
|
|
import '../../features/player/player_launcher.dart';
|
|
import '../../providers/di_providers.dart';
|
|
import '../../providers/session_provider.dart';
|
|
import '../../providers/tmdb_prefetch_provider.dart';
|
|
import 'platform_device_name.dart';
|
|
|
|
|
|
const _kContainerTypes = <String>{
|
|
'BoxSet',
|
|
'CollectionFolder',
|
|
'Folder',
|
|
'Playlist',
|
|
'UserView',
|
|
};
|
|
|
|
void goMediaDetail(BuildContext context, EmbyRawItem item, {WidgetRef? ref}) {
|
|
if (_kContainerTypes.contains(item.Type)) {
|
|
context.push(
|
|
Uri(
|
|
path: '/library/${item.Id}',
|
|
queryParameters: {
|
|
'collection': '1',
|
|
if (item.Name.isNotEmpty) 'title': item.Name,
|
|
},
|
|
).toString(),
|
|
);
|
|
return;
|
|
}
|
|
if (ref != null) {
|
|
ref.read(tmdbPrefetchProvider.notifier).prefetchItem(item, priority: true);
|
|
}
|
|
final isEpisode = item.Type == 'Episode';
|
|
final seriesId = isEpisode && (item.SeriesId?.isNotEmpty ?? false)
|
|
? item.SeriesId
|
|
: null;
|
|
final seasonId = isEpisode && (item.SeasonId?.isNotEmpty ?? false)
|
|
? item.SeasonId
|
|
: null;
|
|
final query = <String, String>{
|
|
if (seriesId != null) 'seriesId': seriesId,
|
|
if (seasonId != null) 'seasonId': seasonId,
|
|
};
|
|
context.push(
|
|
Uri(
|
|
path: '/media/${item.Id}',
|
|
queryParameters: query.isNotEmpty ? query : null,
|
|
).toString(),
|
|
extra: item,
|
|
);
|
|
}
|
|
|
|
|
|
Future<PlayerExitResult?> playFromTmdbOnServer(
|
|
BuildContext context,
|
|
WidgetRef ref, {
|
|
required String serverId,
|
|
required String itemId,
|
|
String? mediaSourceId,
|
|
int preferredSubtitleStreamIndex = -1,
|
|
int? preferredAudioStreamIndex,
|
|
bool fromStart = false,
|
|
int? startPositionTicks,
|
|
String? backdropUrl,
|
|
}) async {
|
|
final active = ref.read(activeSessionProvider);
|
|
if (active?.serverId != serverId) {
|
|
await ref.read(sessionProvider.notifier).switchSession(serverId);
|
|
}
|
|
if (!context.mounted) return null;
|
|
return PlayerLauncher.launch(
|
|
context: context,
|
|
itemId: itemId,
|
|
serverId: serverId,
|
|
mediaSourceId: mediaSourceId,
|
|
preferredSubtitleStreamIndex: preferredSubtitleStreamIndex,
|
|
preferredAudioStreamIndex: preferredAudioStreamIndex,
|
|
startPositionTicks: startPositionTicks,
|
|
fromStart: fromStart,
|
|
backdropUrl: backdropUrl,
|
|
ref: ref,
|
|
);
|
|
}
|
|
|
|
|
|
void goTmdbDetail(
|
|
BuildContext context, {
|
|
required int tmdbId,
|
|
required String mediaType,
|
|
TmdbRecommendation? seed,
|
|
}) {
|
|
if (mediaType != 'movie' && mediaType != 'tv') return;
|
|
context.push('/tmdb/$mediaType/$tmdbId', extra: seed);
|
|
}
|
|
|
|
|
|
Future<void> goMediaDetailOnServer(
|
|
BuildContext context,
|
|
WidgetRef ref, {
|
|
required String serverId,
|
|
required EmbyRawItem item,
|
|
}) async {
|
|
final activeId = ref.read(sessionProvider).value?.activeServerId;
|
|
if (serverId != activeId) {
|
|
await ref.read(sessionProvider.notifier).switchSession(serverId);
|
|
}
|
|
if (context.mounted) {
|
|
goMediaDetail(context, item);
|
|
}
|
|
}
|
|
|
|
|
|
Map<String, String> buildEmbyImageHeaders(
|
|
WidgetRef ref, {
|
|
required String token,
|
|
required String userId,
|
|
}) {
|
|
final deviceId = ref.read(deviceIdProvider).value ?? '';
|
|
return EmbyRequestHeaders.image(
|
|
deviceId: deviceId,
|
|
deviceName: kEmbyDeviceName,
|
|
token: token,
|
|
userId: userId,
|
|
);
|
|
}
|