mirror of
https://github.com/immich-app/immich.git
synced 2025-08-11 09:16:31 -04:00
* chore: bump dart sdk to 3.8 * chore: make build * make pigeon * chore: format files --------- Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
147 lines
5.0 KiB
Dart
147 lines
5.0 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:background_downloader/background_downloader.dart';
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
import 'package:immich_mobile/constants/constants.dart';
|
|
import 'package:immich_mobile/domain/models/store.model.dart';
|
|
import 'package:immich_mobile/entities/store.entity.dart';
|
|
import 'package:immich_mobile/extensions/string_extensions.dart';
|
|
import 'package:immich_mobile/models/upload/share_intent_attachment.model.dart';
|
|
import 'package:immich_mobile/routing/router.dart';
|
|
import 'package:immich_mobile/services/api.service.dart';
|
|
import 'package:immich_mobile/services/share_intent_service.dart';
|
|
import 'package:immich_mobile/services/upload.service.dart';
|
|
import 'package:path/path.dart';
|
|
|
|
final shareIntentUploadProvider = StateNotifierProvider<ShareIntentUploadStateNotifier, List<ShareIntentAttachment>>(
|
|
((ref) => ShareIntentUploadStateNotifier(
|
|
ref.watch(appRouterProvider),
|
|
ref.watch(uploadServiceProvider),
|
|
ref.watch(shareIntentServiceProvider),
|
|
)),
|
|
);
|
|
|
|
class ShareIntentUploadStateNotifier extends StateNotifier<List<ShareIntentAttachment>> {
|
|
final AppRouter router;
|
|
final UploadService _uploadService;
|
|
final ShareIntentService _shareIntentService;
|
|
|
|
ShareIntentUploadStateNotifier(this.router, this._uploadService, this._shareIntentService) : super([]) {
|
|
_uploadService.taskStatusStream.listen(_updateUploadStatus);
|
|
_uploadService.taskProgressStream.listen(_taskProgressCallback);
|
|
}
|
|
|
|
void init() {
|
|
_shareIntentService.onSharedMedia = onSharedMedia;
|
|
_shareIntentService.init();
|
|
}
|
|
|
|
void onSharedMedia(List<ShareIntentAttachment> attachments) {
|
|
router.removeWhere((route) => route.name == "ShareIntentRoute");
|
|
clearAttachments();
|
|
addAttachments(attachments);
|
|
router.push(ShareIntentRoute(attachments: attachments));
|
|
}
|
|
|
|
void addAttachments(List<ShareIntentAttachment> attachments) {
|
|
if (attachments.isEmpty) {
|
|
return;
|
|
}
|
|
state = [...state, ...attachments];
|
|
}
|
|
|
|
void removeAttachment(ShareIntentAttachment attachment) {
|
|
final updatedState = state.where((element) => element != attachment).toList();
|
|
if (updatedState.length != state.length) {
|
|
state = updatedState;
|
|
}
|
|
}
|
|
|
|
void clearAttachments() {
|
|
if (state.isEmpty) {
|
|
return;
|
|
}
|
|
|
|
state = [];
|
|
}
|
|
|
|
void _updateUploadStatus(TaskStatusUpdate task) async {
|
|
if (task.status == TaskStatus.canceled) {
|
|
return;
|
|
}
|
|
|
|
final taskId = task.task.taskId;
|
|
final uploadStatus = switch (task.status) {
|
|
TaskStatus.complete => UploadStatus.complete,
|
|
TaskStatus.failed => UploadStatus.failed,
|
|
TaskStatus.canceled => UploadStatus.canceled,
|
|
TaskStatus.enqueued => UploadStatus.enqueued,
|
|
TaskStatus.running => UploadStatus.running,
|
|
TaskStatus.paused => UploadStatus.paused,
|
|
TaskStatus.notFound => UploadStatus.notFound,
|
|
TaskStatus.waitingToRetry => UploadStatus.waitingToRetry,
|
|
};
|
|
|
|
state = [
|
|
for (final attachment in state)
|
|
if (attachment.id == taskId.toInt()) attachment.copyWith(status: uploadStatus) else attachment,
|
|
];
|
|
}
|
|
|
|
void _taskProgressCallback(TaskProgressUpdate update) {
|
|
// Ignore if the task is canceled or completed
|
|
if (update.progress == downloadFailed || update.progress == downloadCompleted) {
|
|
return;
|
|
}
|
|
|
|
final taskId = update.task.taskId;
|
|
state = [
|
|
for (final attachment in state)
|
|
if (attachment.id == taskId.toInt()) attachment.copyWith(uploadProgress: update.progress) else attachment,
|
|
];
|
|
}
|
|
|
|
Future<void> upload(File file) async {
|
|
final task = await _buildUploadTask(hash(file.path).toString(), file);
|
|
|
|
_uploadService.enqueueTasks([task]);
|
|
}
|
|
|
|
Future<UploadTask> _buildUploadTask(String id, File file, {Map<String, String>? fields}) async {
|
|
final serverEndpoint = Store.get(StoreKey.serverEndpoint);
|
|
final url = Uri.parse('$serverEndpoint/assets').toString();
|
|
final headers = ApiService.getRequestHeaders();
|
|
final deviceId = Store.get(StoreKey.deviceId);
|
|
|
|
final (baseDirectory, directory, filename) = await Task.split(filePath: file.path);
|
|
final stats = await file.stat();
|
|
final fileCreatedAt = stats.changed;
|
|
final fileModifiedAt = stats.modified;
|
|
|
|
final fieldsMap = {
|
|
'filename': filename,
|
|
'deviceAssetId': id,
|
|
'deviceId': deviceId,
|
|
'fileCreatedAt': fileCreatedAt.toUtc().toIso8601String(),
|
|
'fileModifiedAt': fileModifiedAt.toUtc().toIso8601String(),
|
|
'isFavorite': 'false',
|
|
'duration': '0',
|
|
if (fields != null) ...fields,
|
|
};
|
|
|
|
return UploadTask(
|
|
taskId: id,
|
|
httpRequestMethod: 'POST',
|
|
url: url,
|
|
headers: headers,
|
|
filename: filename,
|
|
fields: fieldsMap,
|
|
baseDirectory: baseDirectory,
|
|
directory: directory,
|
|
fileField: 'assetData',
|
|
group: kManualUploadGroup,
|
|
updates: Updates.statusAndProgress,
|
|
);
|
|
}
|
|
}
|