fix live photo play button not updating
This commit is contained in:
@@ -17,6 +17,7 @@ import 'package:immich_mobile/pages/common/gallery_stacked_children.dart';
|
||||
import 'package:immich_mobile/providers/app_settings.provider.dart';
|
||||
import 'package:immich_mobile/providers/asset_viewer/asset_stack.provider.dart';
|
||||
import 'package:immich_mobile/providers/asset_viewer/current_asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/asset_viewer/is_motion_video_playing.provider.dart';
|
||||
import 'package:immich_mobile/providers/asset_viewer/show_controls.provider.dart';
|
||||
import 'package:immich_mobile/providers/asset_viewer/video_player_value_provider.dart';
|
||||
import 'package:immich_mobile/providers/haptic_feedback.provider.dart';
|
||||
@@ -55,7 +56,6 @@ class GalleryViewerPage extends HookConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final totalAssets = useState(renderList.totalAssets);
|
||||
final isZoomed = useState(false);
|
||||
final isPlayingMotionVideo = useValueNotifier(false);
|
||||
final stackIndex = useState(0);
|
||||
final localPosition = useRef<Offset?>(null);
|
||||
final currentIndex = useValueNotifier(initialIndex);
|
||||
@@ -192,7 +192,7 @@ class GalleryViewerPage extends HookConsumerWidget {
|
||||
},
|
||||
onLongPressStart: asset.isMotionPhoto
|
||||
? (_, __, ___) {
|
||||
isPlayingMotionVideo.value = true;
|
||||
ref.read(isPlayingMotionVideoProvider.notifier).playing = true;
|
||||
}
|
||||
: null,
|
||||
imageProvider: ImmichImage.imageProvider(asset: asset),
|
||||
@@ -226,7 +226,6 @@ class GalleryViewerPage extends HookConsumerWidget {
|
||||
child: NativeVideoViewerPage(
|
||||
key: key,
|
||||
asset: asset,
|
||||
isPlayingMotionVideo: isPlayingMotionVideo,
|
||||
image: Image(
|
||||
key: ValueKey(asset),
|
||||
image: ImmichImage.imageProvider(
|
||||
@@ -245,7 +244,7 @@ class GalleryViewerPage extends HookConsumerWidget {
|
||||
}
|
||||
|
||||
PhotoViewGalleryPageOptions buildAsset(BuildContext context, int index) {
|
||||
isPlayingMotionVideo.value = false;
|
||||
ref.read(isPlayingMotionVideoProvider.notifier).playing = false;
|
||||
var newAsset = loadAsset(index);
|
||||
final stackId = newAsset.stackId;
|
||||
if (stackId != null && currentIndex.value == index) {
|
||||
@@ -278,7 +277,7 @@ class GalleryViewerPage extends HookConsumerWidget {
|
||||
return;
|
||||
}
|
||||
|
||||
if (asset.isImage && !isPlayingMotionVideo.value) {
|
||||
if (asset.isImage && !ref.read(isPlayingMotionVideoProvider)) {
|
||||
isZoomed.value = state != PhotoViewScaleState.initial;
|
||||
ref.read(showControlsProvider.notifier).show =
|
||||
!isZoomed.value;
|
||||
@@ -324,7 +323,6 @@ class GalleryViewerPage extends HookConsumerWidget {
|
||||
|
||||
currentIndex.value = value;
|
||||
stackIndex.value = 0;
|
||||
isPlayingMotionVideo.value = false;
|
||||
|
||||
ref.read(currentAssetProvider.notifier).set(newAsset);
|
||||
if (newAsset.isVideo || newAsset.isMotionPhoto) {
|
||||
@@ -345,7 +343,6 @@ class GalleryViewerPage extends HookConsumerWidget {
|
||||
child: GalleryAppBar(
|
||||
key: const ValueKey('app-bar'),
|
||||
showInfo: showInfo,
|
||||
isPlayingMotionVideo: isPlayingMotionVideo,
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
|
||||
@@ -8,6 +8,7 @@ import 'package:immich_mobile/entities/asset.entity.dart';
|
||||
import 'package:immich_mobile/entities/store.entity.dart';
|
||||
import 'package:immich_mobile/providers/app_settings.provider.dart';
|
||||
import 'package:immich_mobile/providers/asset_viewer/current_asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/asset_viewer/is_motion_video_playing.provider.dart';
|
||||
import 'package:immich_mobile/providers/asset_viewer/video_player_controls_provider.dart';
|
||||
import 'package:immich_mobile/providers/asset_viewer/video_player_value_provider.dart';
|
||||
import 'package:immich_mobile/services/api.service.dart';
|
||||
@@ -26,15 +27,10 @@ class NativeVideoViewerPage extends HookConsumerWidget {
|
||||
final bool showControls;
|
||||
final Widget image;
|
||||
|
||||
/// Whether to display the video part of the motion photo
|
||||
/// TODO: this should probably be a provider
|
||||
final ValueNotifier<bool>? isPlayingMotionVideo;
|
||||
|
||||
const NativeVideoViewerPage({
|
||||
super.key,
|
||||
required this.asset,
|
||||
required this.image,
|
||||
this.isPlayingMotionVideo,
|
||||
this.showControls = true,
|
||||
});
|
||||
|
||||
@@ -48,10 +44,7 @@ class NativeVideoViewerPage extends HookConsumerWidget {
|
||||
final controller = useState<NativeVideoPlayerController?>(null);
|
||||
final lastVideoPosition = useRef(-1);
|
||||
final isBuffering = useRef(false);
|
||||
|
||||
useListenable(isPlayingMotionVideo);
|
||||
final showMotionVideo =
|
||||
isPlayingMotionVideo != null && isPlayingMotionVideo!.value;
|
||||
final showMotionVideo = useState(false);
|
||||
|
||||
// When a video is opened through the timeline, `isCurrent` will immediately be true.
|
||||
// When swiping from video A to video B, `isCurrent` will initially be true for video A and false for video B.
|
||||
@@ -65,6 +58,25 @@ class NativeVideoViewerPage extends HookConsumerWidget {
|
||||
|
||||
final log = Logger('NativeVideoViewerPage');
|
||||
|
||||
ref.listen(isPlayingMotionVideoProvider, (_, value) async {
|
||||
final videoController = controller.value;
|
||||
if (!asset.isMotionPhoto || videoController == null || !context.mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
showMotionVideo.value = value;
|
||||
try {
|
||||
if (value) {
|
||||
await videoController.seekTo(0);
|
||||
await videoController.play();
|
||||
} else {
|
||||
await videoController.pause();
|
||||
}
|
||||
} catch (error) {
|
||||
log.severe('Error toggling motion video: $error');
|
||||
}
|
||||
});
|
||||
|
||||
Future<VideoSource?> createSource() async {
|
||||
if (!context.mounted) {
|
||||
return null;
|
||||
@@ -227,9 +239,7 @@ class NativeVideoViewerPage extends HookConsumerWidget {
|
||||
ref.read(videoPlaybackValueProvider.notifier).value = videoPlayback;
|
||||
|
||||
try {
|
||||
if (asset.isVideo ||
|
||||
isPlayingMotionVideo == null ||
|
||||
isPlayingMotionVideo!.value) {
|
||||
if (asset.isVideo || showMotionVideo.value) {
|
||||
await videoController.play();
|
||||
}
|
||||
await videoController.setVolume(0.9);
|
||||
@@ -307,24 +317,6 @@ class NativeVideoViewerPage extends HookConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
void onToggleMotionVideo() async {
|
||||
final videoController = controller.value;
|
||||
if (videoController == null || !context.mounted) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (isPlayingMotionVideo!.value) {
|
||||
await videoController.seekTo(0);
|
||||
await videoController.play();
|
||||
} else {
|
||||
await videoController.pause();
|
||||
}
|
||||
} catch (error) {
|
||||
log.severe('Error toggling motion video: $error');
|
||||
}
|
||||
}
|
||||
|
||||
void removeListeners(NativeVideoPlayerController controller) {
|
||||
controller.onPlaybackPositionChanged
|
||||
.removeListener(onPlaybackPositionChanged);
|
||||
@@ -397,16 +389,8 @@ class NativeVideoViewerPage extends HookConsumerWidget {
|
||||
() => isVisible.value = true,
|
||||
);
|
||||
|
||||
if (isPlayingMotionVideo != null) {
|
||||
isPlayingMotionVideo!.addListener(onToggleMotionVideo);
|
||||
}
|
||||
|
||||
return () {
|
||||
timer?.cancel();
|
||||
if (isPlayingMotionVideo != null) {
|
||||
isPlayingMotionVideo!.removeListener(onToggleMotionVideo);
|
||||
}
|
||||
|
||||
final playerController = controller.value;
|
||||
if (playerController == null) {
|
||||
return;
|
||||
@@ -430,7 +414,8 @@ class NativeVideoViewerPage extends HookConsumerWidget {
|
||||
if (aspectRatio.value != null)
|
||||
Visibility.maintain(
|
||||
key: ValueKey(asset),
|
||||
visible: (asset.isVideo || showMotionVideo) && isVisible.value,
|
||||
visible:
|
||||
(asset.isVideo || showMotionVideo.value) && isVisible.value,
|
||||
child: Center(
|
||||
key: ValueKey(asset),
|
||||
child: AspectRatio(
|
||||
|
||||
Reference in New Issue
Block a user