From 80e540681b2e0709e749a53bec16e51e48b71236 Mon Sep 17 00:00:00 2001 From: prathusa <35161910+prathusa@users.noreply.github.com> Date: Fri, 3 Oct 2025 01:21:03 -0700 Subject: [PATCH] fix(mobile): Add timeout for missing video file --- .../repositories/storage.repository.dart | 3 ++- mobile/lib/services/upload.service.dart | 13 ++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/mobile/lib/infrastructure/repositories/storage.repository.dart b/mobile/lib/infrastructure/repositories/storage.repository.dart index 164fa04529..3de2b0f32f 100644 --- a/mobile/lib/infrastructure/repositories/storage.repository.dart +++ b/mobile/lib/infrastructure/repositories/storage.repository.dart @@ -36,7 +36,8 @@ class StorageRepository { try { final entity = await AssetEntity.fromId(asset.id); - file = await entity?.originFileWithSubtype; + // Use a timeout to avoid hanging on Live Photos whose paired video is unavailable (e.g., shared albums) + file = await entity?.originFileWithSubtype.timeout(const Duration(seconds: 5)); if (file == null) { log.warning( "Cannot get motion file for asset ${asset.id}, name: ${asset.name}, created on: ${asset.createdAt}", diff --git a/mobile/lib/services/upload.service.dart b/mobile/lib/services/upload.service.dart index e8e98562f7..2c83699745 100644 --- a/mobile/lib/services/upload.service.dart +++ b/mobile/lib/services/upload.service.dart @@ -303,6 +303,7 @@ class UploadService { } File? file; + bool uploadAsLive = entity.isLivePhoto; /// iOS LivePhoto has two files: a photo and a video. /// They are uploaded separately, with video file being upload first, then returned with the assetId @@ -314,8 +315,14 @@ class UploadService { /// The cancel operation will only cancel the video group (normal group), the photo group will not /// be touched, as the video file is already uploaded. - if (entity.isLivePhoto) { + if (uploadAsLive) { file = await _storageRepository.getMotionFileForAsset(asset); + // Fallback: if motion video is unavailable (e.g., shared album or old format), upload still photo only + if (file == null) { + _logger.warning('Live Photo motion file missing for ${asset.id} (${asset.name}); uploading still image only'); + file = await _storageRepository.getFileForAsset(asset.id); + uploadAsLive = false; + } } else { file = await _storageRepository.getFileForAsset(asset.id); } @@ -324,11 +331,11 @@ class UploadService { return null; } - final originalFileName = entity.isLivePhoto ? p.setExtension(asset.name, p.extension(file.path)) : asset.name; + final originalFileName = uploadAsLive ? p.setExtension(asset.name, p.extension(file.path)) : asset.name; String metadata = UploadTaskMetadata( localAssetId: asset.id, - isLivePhotos: entity.isLivePhoto, + isLivePhotos: uploadAsLive, livePhotoVideoId: '', ).toJson();