1
0
Fork 0
mirror of https://github.com/immich-app/immich.git synced 2025-01-01 16:41:59 +00:00
immich/mobile/lib/services/image_viewer.service.dart
Fynn Petersen-Frey 6995cc2b38
refactor(mobile): encapsulate most access to photomanager in repository (#12754)
* refactor(mobile): encapsulate most access to photomanager in repository
2024-09-18 17:15:52 +02:00

117 lines
3.8 KiB
Dart

import 'dart:io';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/response_extensions.dart';
import 'package:immich_mobile/entities/asset.entity.dart';
import 'package:immich_mobile/interfaces/file_media.interface.dart';
import 'package:immich_mobile/providers/api.provider.dart';
import 'package:immich_mobile/repositories/file_media.repository.dart';
import 'package:immich_mobile/services/api.service.dart';
import 'package:logging/logging.dart';
import 'package:path_provider/path_provider.dart';
final imageViewerServiceProvider = Provider(
(ref) => ImageViewerService(
ref.watch(apiServiceProvider),
ref.watch(fileMediaRepositoryProvider),
),
);
class ImageViewerService {
final ApiService _apiService;
final IFileMediaRepository _fileMediaRepository;
final Logger _log = Logger("ImageViewerService");
ImageViewerService(this._apiService, this._fileMediaRepository);
Future<bool> downloadAsset(Asset asset) async {
File? imageFile;
File? videoFile;
try {
// Download LivePhotos image and motion part
if (asset.isImage && asset.livePhotoVideoId != null && Platform.isIOS) {
var imageResponse =
await _apiService.assetsApi.downloadAssetWithHttpInfo(
asset.remoteId!,
);
var motionResponse =
await _apiService.assetsApi.downloadAssetWithHttpInfo(
asset.livePhotoVideoId!,
);
if (imageResponse.statusCode != 200 ||
motionResponse.statusCode != 200) {
final failedResponse =
imageResponse.statusCode != 200 ? imageResponse : motionResponse;
_log.severe(
"Motion asset download failed",
failedResponse.toLoggerString(),
);
return false;
}
Asset? resultAsset;
final tempDir = await getTemporaryDirectory();
videoFile = await File('${tempDir.path}/livephoto.mov').create();
imageFile = await File('${tempDir.path}/livephoto.heic').create();
videoFile.writeAsBytesSync(motionResponse.bodyBytes);
imageFile.writeAsBytesSync(imageResponse.bodyBytes);
resultAsset = await _fileMediaRepository.saveLivePhoto(
image: imageFile,
video: videoFile,
title: asset.fileName,
);
if (resultAsset == null) {
_log.warning(
"Asset cannot be saved as a live photo. This is most likely a motion photo. Saving only the image file",
);
resultAsset = await _fileMediaRepository
.saveImage(imageResponse.bodyBytes, title: asset.fileName);
}
return resultAsset != null;
} else {
var res = await _apiService.assetsApi
.downloadAssetWithHttpInfo(asset.remoteId!);
if (res.statusCode != 200) {
_log.severe("Asset download failed", res.toLoggerString());
return false;
}
final Asset? resultAsset;
final relativePath = Platform.isAndroid ? 'DCIM/Immich' : null;
if (asset.isImage) {
resultAsset = await _fileMediaRepository.saveImage(
res.bodyBytes,
title: asset.fileName,
relativePath: relativePath,
);
} else {
final tempDir = await getTemporaryDirectory();
videoFile = await File('${tempDir.path}/${asset.fileName}').create();
videoFile.writeAsBytesSync(res.bodyBytes);
resultAsset = await _fileMediaRepository.saveVideo(
videoFile,
title: asset.fileName,
relativePath: relativePath,
);
}
return resultAsset != null;
}
} catch (error, stack) {
_log.severe("Error saving downloaded asset", error, stack);
return false;
} finally {
// Clear temp files
imageFile?.delete();
videoFile?.delete();
}
}
}