mirror of
https://github.com/immich-app/immich.git
synced 2025-04-21 15:36:26 +02:00
* Update current asset to play video. * Updated location of currentAssetProvider update per feedback. * Added a playbackDelayFactor to the video viewer to resolve an issue in memories. Also adjusted the scale of the memory preview image to match the ratio of the video. This still appears to jump because the video preview doesn't seem to be the first frame for some reason :\ * add video indicator --------- Co-authored-by: Tom graham <tomg@questps.com.au> Co-authored-by: Alex <alex.tran1502@gmail.com>
This commit is contained in:
parent
9358b4dc7e
commit
69e88ef985
4 changed files with 43 additions and 4 deletions
mobile/lib
pages
widgets/memories
|
@ -26,6 +26,7 @@ import 'package:wakelock_plus/wakelock_plus.dart';
|
|||
class NativeVideoViewerPage extends HookConsumerWidget {
|
||||
final Asset asset;
|
||||
final bool showControls;
|
||||
final int playbackDelayFactor;
|
||||
final Widget image;
|
||||
|
||||
const NativeVideoViewerPage({
|
||||
|
@ -33,6 +34,7 @@ class NativeVideoViewerPage extends HookConsumerWidget {
|
|||
required this.asset,
|
||||
required this.image,
|
||||
this.showControls = true,
|
||||
this.playbackDelayFactor = 1,
|
||||
});
|
||||
|
||||
@override
|
||||
|
@ -317,12 +319,16 @@ class NativeVideoViewerPage extends HookConsumerWidget {
|
|||
}
|
||||
|
||||
// Delay the video playback to avoid a stutter in the swipe animation
|
||||
// Note, in some circumstances a longer delay is needed (eg: memories),
|
||||
// the playbackDelayFactor can be used for this
|
||||
// This delay seems like a hacky way to resolve underlying bugs in video
|
||||
// playback, but other resolutions failed thus far
|
||||
Timer(
|
||||
Platform.isIOS
|
||||
? const Duration(milliseconds: 300)
|
||||
? Duration(milliseconds: 300 * playbackDelayFactor)
|
||||
: imageToVideo
|
||||
? const Duration(milliseconds: 200)
|
||||
: const Duration(milliseconds: 400), () {
|
||||
? Duration(milliseconds: 200 * playbackDelayFactor)
|
||||
: Duration(milliseconds: 400 * playbackDelayFactor), () {
|
||||
if (!context.mounted) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ import 'package:flutter_hooks/flutter_hooks.dart';
|
|||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/entities/asset.entity.dart';
|
||||
import 'package:immich_mobile/models/memories/memory.model.dart';
|
||||
import 'package:immich_mobile/providers/asset_viewer/current_asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/asset_viewer/video_player_value_provider.dart';
|
||||
import 'package:immich_mobile/providers/haptic_feedback.provider.dart';
|
||||
import 'package:immich_mobile/widgets/common/immich_image.dart';
|
||||
import 'package:immich_mobile/widgets/memories/memory_bottom_info.dart';
|
||||
|
@ -13,6 +15,8 @@ import 'package:immich_mobile/widgets/memories/memory_epilogue.dart';
|
|||
import 'package:immich_mobile/widgets/memories/memory_progress_indicator.dart';
|
||||
|
||||
@RoutePage()
|
||||
|
||||
/// Expects [currentAssetProvider] to be set before navigating to this page
|
||||
class MemoryPage extends HookConsumerWidget {
|
||||
final List<Memory> memories;
|
||||
final int memoryIndex;
|
||||
|
@ -32,6 +36,7 @@ class MemoryPage extends HookConsumerWidget {
|
|||
"${currentAssetPage.value + 1}|${currentMemory.value.assets.length}",
|
||||
);
|
||||
const bgColor = Colors.black;
|
||||
final currentAsset = useState<Asset?>(null);
|
||||
|
||||
/// The list of all of the asset page controllers
|
||||
final memoryAssetPageControllers =
|
||||
|
@ -135,6 +140,14 @@ class MemoryPage extends HookConsumerWidget {
|
|||
ref.read(hapticFeedbackProvider.notifier).selectionClick();
|
||||
currentAssetPage.value = otherIndex;
|
||||
updateProgressText();
|
||||
|
||||
final asset = currentMemory.value.assets[otherIndex];
|
||||
currentAsset.value = asset;
|
||||
ref.read(currentAssetProvider.notifier).set(asset);
|
||||
if (asset.isVideo || asset.isMotionPhoto) {
|
||||
ref.read(videoPlaybackValueProvider.notifier).reset();
|
||||
}
|
||||
|
||||
// Wait for page change animation to finish
|
||||
await Future.delayed(const Duration(milliseconds: 400));
|
||||
// And then precache the next asset
|
||||
|
@ -274,6 +287,16 @@ class MemoryPage extends HookConsumerWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
if (currentAsset.value != null &&
|
||||
currentAsset.value!.isVideo)
|
||||
Positioned(
|
||||
bottom: 24,
|
||||
right: 32,
|
||||
child: Icon(
|
||||
Icons.videocam_outlined,
|
||||
color: Colors.grey[200],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -75,11 +75,12 @@ class MemoryCard extends StatelessWidget {
|
|||
key: ValueKey(asset.id),
|
||||
asset: asset,
|
||||
showControls: false,
|
||||
playbackDelayFactor: 2,
|
||||
image: ImmichImage(
|
||||
asset,
|
||||
width: context.width,
|
||||
height: context.height,
|
||||
fit: fit,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -4,6 +4,8 @@ import 'package:flutter/material.dart';
|
|||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/models/memories/memory.model.dart';
|
||||
import 'package:immich_mobile/widgets/asset_grid/thumbnail_placeholder.dart';
|
||||
import 'package:immich_mobile/providers/asset_viewer/current_asset.provider.dart';
|
||||
import 'package:immich_mobile/providers/asset_viewer/video_player_value_provider.dart';
|
||||
import 'package:immich_mobile/providers/memory.provider.dart';
|
||||
import 'package:immich_mobile/routing/router.dart';
|
||||
import 'package:immich_mobile/providers/haptic_feedback.provider.dart';
|
||||
|
@ -33,6 +35,13 @@ class MemoryLane extends HookConsumerWidget {
|
|||
),
|
||||
onTap: (memoryIndex) {
|
||||
ref.read(hapticFeedbackProvider.notifier).heavyImpact();
|
||||
if (memories[memoryIndex].assets.isNotEmpty) {
|
||||
final asset = memories[memoryIndex].assets[0];
|
||||
ref.read(currentAssetProvider.notifier).set(asset);
|
||||
if (asset.isVideo || asset.isMotionPhoto) {
|
||||
ref.read(videoPlaybackValueProvider.notifier).reset();
|
||||
}
|
||||
}
|
||||
context.pushRoute(
|
||||
MemoryRoute(
|
||||
memories: memories,
|
||||
|
|
Loading…
Add table
Reference in a new issue