mirror of
https://github.com/immich-app/immich
synced 2026-08-15 13:03:57 +00:00
fix(mobile): video playback controls dead for backed up videos opened from search (#30587)
* key video player state by asset id instead of hero tag * expose id on BaseAsset instead of a separate playerKey
This commit is contained in:
parent
2314330c78
commit
35c2a90fca
9 changed files with 128 additions and 13 deletions
|
|
@ -77,6 +77,7 @@ sealed class BaseAsset {
|
|||
|
||||
// Overridden in subclasses
|
||||
AssetState get storage;
|
||||
String get id;
|
||||
String? get localId;
|
||||
String? get remoteId;
|
||||
String get heroTag;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
part of 'base_asset.model.dart';
|
||||
|
||||
class LocalAsset extends BaseAsset {
|
||||
@override
|
||||
final String id;
|
||||
final String? remoteAssetId;
|
||||
final String? cloudId;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ enum AssetVisibility { timeline, hidden, archive, locked }
|
|||
|
||||
// Model for an asset stored in the server
|
||||
class RemoteAsset extends BaseAsset {
|
||||
@override
|
||||
final String id;
|
||||
final String? localAssetId;
|
||||
final String? thumbHash;
|
||||
|
|
|
|||
|
|
@ -93,8 +93,8 @@ class _DriftSlideshowPageState extends ConsumerState<DriftSlideshowPage> with Si
|
|||
|
||||
if (asset.isImage) {
|
||||
_createTimer();
|
||||
} else if (ref.read(videoPlayerProvider(asset.heroTag)).status == VideoPlaybackStatus.paused) {
|
||||
unawaited(ref.read(videoPlayerProvider(asset.heroTag).notifier).play());
|
||||
} else if (ref.read(videoPlayerProvider(asset.id)).status == VideoPlaybackStatus.paused) {
|
||||
unawaited(ref.read(videoPlayerProvider(asset.id).notifier).play());
|
||||
} else {
|
||||
unawaited(_nextPage());
|
||||
}
|
||||
|
|
@ -113,7 +113,7 @@ class _DriftSlideshowPageState extends ConsumerState<DriftSlideshowPage> with Si
|
|||
final asset = widget.timeline.getAssetSafe(_index)!;
|
||||
|
||||
if (!asset.isImage) {
|
||||
unawaited(ref.read(videoPlayerProvider(asset.heroTag).notifier).pause());
|
||||
unawaited(ref.read(videoPlayerProvider(asset.id).notifier).pause());
|
||||
}
|
||||
|
||||
setState(() {
|
||||
|
|
@ -300,7 +300,7 @@ class _DriftSlideshowPageState extends ConsumerState<DriftSlideshowPage> with Si
|
|||
borderRadius: BorderRadius.zero,
|
||||
minHeight: 5,
|
||||
value:
|
||||
ref.read(videoPlayerProvider(asset.heroTag).select((s) => s.position)).inMilliseconds /
|
||||
ref.read(videoPlayerProvider(asset.id).select((s) => s.position)).inMilliseconds /
|
||||
asset.duration.inMilliseconds,
|
||||
);
|
||||
}
|
||||
|
|
@ -374,13 +374,13 @@ class _DriftSlideshowPageState extends ConsumerState<DriftSlideshowPage> with Si
|
|||
builder: (context, value, _) => buildPhotoView(scale * (1.0 + value * _kenBurnsZoom)),
|
||||
);
|
||||
} else {
|
||||
final status = ref.read(videoPlayerProvider(asset.heroTag).select((s) => s.status));
|
||||
final position = ref.read(videoPlayerProvider(asset.heroTag)).position;
|
||||
final status = ref.read(videoPlayerProvider(asset.id).select((s) => s.status));
|
||||
final position = ref.read(videoPlayerProvider(asset.id)).position;
|
||||
|
||||
if (status == VideoPlaybackStatus.completed && isCurrent && position.inMicroseconds > 0) {
|
||||
unawaited(_nextPage());
|
||||
} else if (status == VideoPlaybackStatus.playing) {
|
||||
unawaited(ref.read(videoPlayerProvider(asset.heroTag).notifier).setLoop(false));
|
||||
unawaited(ref.read(videoPlayerProvider(asset.id).notifier).setLoop(false));
|
||||
}
|
||||
|
||||
return PhotoView.customChild(
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ class ViewerBottomBar extends ConsumerWidget {
|
|||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (asset.isImage) OcrToggleButton(asset: asset),
|
||||
if (asset.isVideo) VideoControls(videoPlayerName: asset.heroTag),
|
||||
if (asset.isVideo) VideoControls(videoPlayerName: asset.id),
|
||||
if (!isReadonlyModeEnabled)
|
||||
ImmichColorOverride(
|
||||
color: Colors.white,
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ class _NativeVideoViewerState extends ConsumerState<NativeVideoViewer> with Widg
|
|||
bool _isVideoReady = false;
|
||||
bool _shouldPlayOnForeground = true;
|
||||
|
||||
VideoPlayerNotifier get _notifier => ref.read(videoPlayerProvider(widget.asset.heroTag).notifier);
|
||||
VideoPlayerNotifier get _notifier => ref.read(videoPlayerProvider(widget.asset.id).notifier);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
|
@ -304,7 +304,7 @@ class _NativeVideoViewerState extends ConsumerState<NativeVideoViewer> with Widg
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isCasting = ref.watch(castProvider.select((c) => c.isCasting));
|
||||
final status = ref.watch(videoPlayerProvider(widget.asset.heroTag).select((v) => v.status));
|
||||
final status = ref.watch(videoPlayerProvider(widget.asset.id).select((v) => v.status));
|
||||
|
||||
return IgnorePointer(
|
||||
child: Stack(
|
||||
|
|
|
|||
|
|
@ -67,9 +67,9 @@ class AssetViewerStateNotifier extends Notifier<AssetViewerState> {
|
|||
}
|
||||
state = state.copyWith(showingDetails: showing, showingControls: showing ? true : state.showingControls);
|
||||
|
||||
final heroTag = state.currentAsset?.heroTag;
|
||||
if (heroTag != null) {
|
||||
final notifier = ref.read(videoPlayerProvider(heroTag).notifier);
|
||||
final id = state.currentAsset?.id;
|
||||
if (id != null) {
|
||||
final notifier = ref.read(videoPlayerProvider(id).notifier);
|
||||
showing ? notifier.hold() : notifier.release();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue