diff --git a/mobile/lib/domain/models/asset/base_asset.model.dart b/mobile/lib/domain/models/asset/base_asset.model.dart index cb40c8f76a904..33c8fa46e8fb1 100644 --- a/mobile/lib/domain/models/asset/base_asset.model.dart +++ b/mobile/lib/domain/models/asset/base_asset.model.dart @@ -45,12 +45,14 @@ sealed class BaseAsset { bool get isImage => type == AssetType.image; bool get isVideo => type == AssetType.video; - bool get isMotionPhoto => livePhotoVideoId != null; + /// True for remote assets with a paired live-photo video ([livePhotoVideoId] != null) + /// and for local assets whose playback style was resolved to [AssetPlaybackStyle.livePhoto]. + bool get isMotionPhoto => playbackStyle == AssetPlaybackStyle.livePhoto; bool get isAnimatedImage => playbackStyle == AssetPlaybackStyle.imageAnimated; AssetPlaybackStyle get playbackStyle { if (isVideo) return AssetPlaybackStyle.video; - if (isMotionPhoto) return AssetPlaybackStyle.livePhoto; + if (livePhotoVideoId != null) return AssetPlaybackStyle.livePhoto; if (isImage && durationInSeconds != null && durationInSeconds! > 0) return AssetPlaybackStyle.imageAnimated; if (isImage) return AssetPlaybackStyle.image; return AssetPlaybackStyle.unknown; diff --git a/mobile/lib/infrastructure/repositories/storage.repository.dart b/mobile/lib/infrastructure/repositories/storage.repository.dart index eaa6ce79f7fd1..1302e76090743 100644 --- a/mobile/lib/infrastructure/repositories/storage.repository.dart +++ b/mobile/lib/infrastructure/repositories/storage.repository.dart @@ -12,7 +12,6 @@ class StorageRepository { Future getFileForAsset(String assetId) async { File? file; - final log = Logger('StorageRepository'); try { final entity = await AssetEntity.fromId(assetId); @@ -34,37 +33,32 @@ class StorageRepository { } Future getMotionFileForAsset(LocalAsset asset) async { + return getMotionFileById(asset.id); + } + + Future getMotionFileById(String assetId) async { File? file; - final log = Logger('StorageRepository'); try { - final entity = await AssetEntity.fromId(asset.id); + final entity = await AssetEntity.fromId(assetId); file = await entity?.originFileWithSubtype; if (file == null) { - log.warning( - "Cannot get motion file for asset ${asset.id}, name: ${asset.name}, created on: ${asset.createdAt}", - ); + log.warning("Cannot get motion file for asset $assetId"); return null; } final exists = await file.exists(); if (!exists) { - log.warning("Motion file for asset ${asset.id} does not exist"); + log.warning("Motion file for asset $assetId does not exist"); return null; } } catch (error, stackTrace) { - log.warning( - "Error getting motion file for asset ${asset.id}, name: ${asset.name}, created on: ${asset.createdAt}", - error, - stackTrace, - ); + log.warning("Error getting motion file for asset $assetId", error, stackTrace); } return file; } Future getAssetEntityForAsset(LocalAsset asset) async { - final log = Logger('StorageRepository'); - AssetEntity? entity; try { @@ -130,8 +124,6 @@ class StorageRepository { } Future clearCache() async { - final log = Logger('StorageRepository'); - try { await PhotoManager.clearFileCache(); } catch (error, stackTrace) { diff --git a/mobile/lib/presentation/widgets/asset_viewer/video_viewer.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/video_viewer.widget.dart index 9285c01c41919..1c99f8ef410b9 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/video_viewer.widget.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/video_viewer.widget.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:io'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; @@ -100,9 +101,12 @@ class _NativeVideoViewerState extends ConsumerState with Widg if (!mounted) return null; try { - if (videoAsset.hasLocal && videoAsset.livePhotoVideoId == null) { + if (videoAsset.hasLocal) { final id = videoAsset is LocalAsset ? videoAsset.id : (videoAsset as RemoteAsset).localId!; - final file = await StorageRepository().getFileForAsset(id); + File? file = videoAsset.isMotionPhoto + ? await StorageRepository().getMotionFileById(id) + : await StorageRepository().getFileForAsset(id); + if (!mounted) return null; if (file == null) { diff --git a/mobile/lib/presentation/widgets/images/thumbnail_tile.widget.dart b/mobile/lib/presentation/widgets/images/thumbnail_tile.widget.dart index 2ceaf80db02a8..cfc46f0f4a910 100644 --- a/mobile/lib/presentation/widgets/images/thumbnail_tile.widget.dart +++ b/mobile/lib/presentation/widgets/images/thumbnail_tile.widget.dart @@ -287,8 +287,6 @@ class _AssetTypeIcons extends StatelessWidget { @override Widget build(BuildContext context) { final hasStack = asset is RemoteAsset && (asset as RemoteAsset).stackId != null; - final isLivePhoto = asset is RemoteAsset && asset.livePhotoVideoId != null; - return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.end, @@ -300,7 +298,7 @@ class _AssetTypeIcons extends StatelessWidget { padding: EdgeInsets.only(right: 10.0, top: 6.0), child: _TileOverlayIcon(Icons.burst_mode_rounded), ), - if (isLivePhoto) + if (asset.isMotionPhoto) const Padding( padding: EdgeInsets.only(right: 10.0, top: 6.0), child: _TileOverlayIcon(Icons.motion_photos_on_rounded),