fix(web): prevent Safari from overwriting live photo image with video (#26898)

When downloading a live photo, Safari overwrites the image file with
the motion video because both share the same base filename. Append
'-motion' suffix to the video filename to prevent collision.

For example, IMG_1234.heic and IMG_1234.mov become IMG_1234.heic
and IMG_1234-motion.mov.

Fixes #23055
This commit is contained in:
Saurav Sharma 2026-03-27 00:07:05 +05:30 committed by GitHub
parent 8c6adf7157
commit e2d26ebdea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 8 additions and 2 deletions

View File

@ -78,7 +78,7 @@ describe('AssetService', () => {
const asset = assetFactory.build({ originalFileName: 'asset.heic', livePhotoVideoId: '1' });
await handleDownloadAsset(asset, { edited: false });
expect($t).toHaveBeenNthCalledWith(1, 'downloading_asset_filename', { values: { filename: 'asset.heic' } });
expect($t).toHaveBeenNthCalledWith(2, 'downloading_asset_filename', { values: { filename: 'asset.mov' } });
expect($t).toHaveBeenNthCalledWith(2, 'downloading_asset_filename', { values: { filename: 'asset-motion.mov' } });
expect(toastManager.primary).toHaveBeenCalledWith('formatter');
});
});

View File

@ -319,8 +319,14 @@ export const handleDownloadAsset = async (asset: AssetResponseDto, { edited }: {
if (asset.livePhotoVideoId) {
const motionAsset = await getAssetInfo({ ...authManager.params, id: asset.livePhotoVideoId });
if (!isAndroidMotionVideo(motionAsset) || get(preferences)?.download.includeEmbeddedVideos) {
const motionFilename = motionAsset.originalFileName;
const lastDotIndex = motionFilename.lastIndexOf('.');
const motionDownloadFilename =
lastDotIndex > 0
? `${motionFilename.slice(0, lastDotIndex)}-motion${motionFilename.slice(lastDotIndex)}`
: `${motionFilename}-motion`;
assets.push({
filename: motionAsset.originalFileName,
filename: motionDownloadFilename,
id: asset.livePhotoVideoId,
cacheKey: motionAsset.thumbhash,
});