import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/colors.dart'; import 'package:immich_mobile/providers/asset_viewer/video_player_provider.dart'; import 'package:immich_mobile/providers/cast.provider.dart'; import 'package:immich_mobile/widgets/asset_viewer/formatted_duration.dart'; class VideoPosition extends HookConsumerWidget { final String videoPlayerName; const VideoPosition({super.key, required this.videoPlayerName}); @override Widget build(BuildContext context, WidgetRef ref) { final isCasting = ref.watch(castProvider).isCasting; final (position, duration) = isCasting ? ref.watch(castProvider.select((c) => (c.currentTime, c.duration))) : ref.watch(videoPlayerProvider(videoPlayerName).select((v) => (v.position, v.duration))); final wasPlaying = useRef(true); return duration == Duration.zero ? const _VideoPositionPlaceholder() : Column( children: [ Padding( // align with slider's inherent padding padding: const EdgeInsets.symmetric(horizontal: 12.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [FormattedDuration(position), FormattedDuration(duration)], ), ), Row( children: [ Expanded( child: Slider( value: min(position.inMicroseconds / duration.inMicroseconds * 100, 100), min: 0, max: 100, thumbColor: Colors.white, activeColor: Colors.white, inactiveColor: whiteOpacity75, onChangeStart: (value) { final status = ref.read(videoPlayerProvider(videoPlayerName)).status; wasPlaying.value = status != VideoPlaybackStatus.paused; ref.read(videoPlayerProvider(videoPlayerName).notifier).pause(); }, onChangeEnd: (value) { if (wasPlaying.value) { ref.read(videoPlayerProvider(videoPlayerName).notifier).play(); } }, onChanged: (value) { final seekToDuration = (duration * (value / 100.0)); if (isCasting) { ref.read(castProvider.notifier).seekTo(seekToDuration); return; } ref.read(videoPlayerProvider(videoPlayerName).notifier).seekTo(seekToDuration); }, ), ), ], ), ], ); } } class _VideoPositionPlaceholder extends StatelessWidget { const _VideoPositionPlaceholder(); static void _onChangedDummy(_) {} @override Widget build(BuildContext context) { return const Column( children: [ Padding( padding: EdgeInsets.symmetric(horizontal: 12.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [FormattedDuration(Duration.zero), FormattedDuration(Duration.zero)], ), ), Row( children: [ Expanded( child: Slider( value: 0.0, min: 0, max: 100, thumbColor: Colors.white, activeColor: Colors.white, inactiveColor: whiteOpacity75, onChanged: _onChangedDummy, ), ), ], ), ], ); } }