mirror of
				https://github.com/immich-app/immich.git
				synced 2025-11-03 19:17:11 -05: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>
		
			
				
	
	
		
			191 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			191 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
import 'package:background_downloader/background_downloader.dart';
 | 
						|
import 'package:easy_localization/easy_localization.dart';
 | 
						|
import 'package:flutter/material.dart';
 | 
						|
import 'package:fluttertoast/fluttertoast.dart';
 | 
						|
import 'package:hooks_riverpod/hooks_riverpod.dart';
 | 
						|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
 | 
						|
import 'package:immich_mobile/models/download/download_state.model.dart';
 | 
						|
import 'package:immich_mobile/models/download/livephotos_medatada.model.dart';
 | 
						|
import 'package:immich_mobile/services/album.service.dart';
 | 
						|
import 'package:immich_mobile/services/download.service.dart';
 | 
						|
import 'package:immich_mobile/entities/asset.entity.dart';
 | 
						|
import 'package:immich_mobile/services/share.service.dart';
 | 
						|
import 'package:immich_mobile/widgets/common/immich_toast.dart';
 | 
						|
import 'package:immich_mobile/widgets/common/share_dialog.dart';
 | 
						|
 | 
						|
class DownloadStateNotifier extends StateNotifier<DownloadState> {
 | 
						|
  final DownloadService _downloadService;
 | 
						|
  final ShareService _shareService;
 | 
						|
  final AlbumService _albumService;
 | 
						|
 | 
						|
  DownloadStateNotifier(this._downloadService, this._shareService, this._albumService)
 | 
						|
    : super(
 | 
						|
        const DownloadState(
 | 
						|
          downloadStatus: TaskStatus.complete,
 | 
						|
          showProgress: false,
 | 
						|
          taskProgress: <String, DownloadInfo>{},
 | 
						|
        ),
 | 
						|
      ) {
 | 
						|
    _downloadService.onImageDownloadStatus = _downloadImageCallback;
 | 
						|
    _downloadService.onVideoDownloadStatus = _downloadVideoCallback;
 | 
						|
    _downloadService.onLivePhotoDownloadStatus = _downloadLivePhotoCallback;
 | 
						|
    _downloadService.onTaskProgress = _taskProgressCallback;
 | 
						|
  }
 | 
						|
 | 
						|
  void _updateDownloadStatus(String taskId, TaskStatus status) {
 | 
						|
    if (status == TaskStatus.canceled) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    state = state.copyWith(
 | 
						|
      taskProgress: <String, DownloadInfo>{}
 | 
						|
        ..addAll(state.taskProgress)
 | 
						|
        ..addAll({
 | 
						|
          taskId: DownloadInfo(
 | 
						|
            progress: state.taskProgress[taskId]?.progress ?? 0,
 | 
						|
            fileName: state.taskProgress[taskId]?.fileName ?? '',
 | 
						|
            status: status,
 | 
						|
          ),
 | 
						|
        }),
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  // Download live photo callback
 | 
						|
  void _downloadLivePhotoCallback(TaskStatusUpdate update) {
 | 
						|
    _updateDownloadStatus(update.task.taskId, update.status);
 | 
						|
 | 
						|
    switch (update.status) {
 | 
						|
      case TaskStatus.complete:
 | 
						|
        if (update.task.metaData.isEmpty) {
 | 
						|
          return;
 | 
						|
        }
 | 
						|
        final livePhotosId = LivePhotosMetadata.fromJson(update.task.metaData).id;
 | 
						|
        _downloadService.saveLivePhotos(update.task, livePhotosId);
 | 
						|
        _onDownloadComplete(update.task.taskId);
 | 
						|
        break;
 | 
						|
 | 
						|
      default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // Download image callback
 | 
						|
  void _downloadImageCallback(TaskStatusUpdate update) {
 | 
						|
    _updateDownloadStatus(update.task.taskId, update.status);
 | 
						|
 | 
						|
    switch (update.status) {
 | 
						|
      case TaskStatus.complete:
 | 
						|
        _downloadService.saveImageWithPath(update.task);
 | 
						|
        _onDownloadComplete(update.task.taskId);
 | 
						|
        break;
 | 
						|
 | 
						|
      default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  // Download video callback
 | 
						|
  void _downloadVideoCallback(TaskStatusUpdate update) {
 | 
						|
    _updateDownloadStatus(update.task.taskId, update.status);
 | 
						|
 | 
						|
    switch (update.status) {
 | 
						|
      case TaskStatus.complete:
 | 
						|
        _downloadService.saveVideo(update.task);
 | 
						|
        _onDownloadComplete(update.task.taskId);
 | 
						|
        break;
 | 
						|
 | 
						|
      default:
 | 
						|
        break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  void _taskProgressCallback(TaskProgressUpdate update) {
 | 
						|
    // Ignore if the task is canceled or completed
 | 
						|
    if (update.progress == -2 || update.progress == -1) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    state = state.copyWith(
 | 
						|
      showProgress: true,
 | 
						|
      taskProgress: <String, DownloadInfo>{}
 | 
						|
        ..addAll(state.taskProgress)
 | 
						|
        ..addAll({
 | 
						|
          update.task.taskId: DownloadInfo(
 | 
						|
            progress: update.progress,
 | 
						|
            fileName: update.task.filename,
 | 
						|
            status: TaskStatus.running,
 | 
						|
          ),
 | 
						|
        }),
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  void _onDownloadComplete(String id) {
 | 
						|
    Future.delayed(const Duration(seconds: 2), () {
 | 
						|
      state = state.copyWith(
 | 
						|
        taskProgress: <String, DownloadInfo>{}
 | 
						|
          ..addAll(state.taskProgress)
 | 
						|
          ..remove(id),
 | 
						|
      );
 | 
						|
 | 
						|
      if (state.taskProgress.isEmpty) {
 | 
						|
        state = state.copyWith(showProgress: false);
 | 
						|
      }
 | 
						|
      _albumService.refreshDeviceAlbums();
 | 
						|
    });
 | 
						|
  }
 | 
						|
 | 
						|
  Future<List<bool>> downloadAllAsset(List<Asset> assets) async {
 | 
						|
    return await _downloadService.downloadAll(assets);
 | 
						|
  }
 | 
						|
 | 
						|
  void downloadAsset(Asset asset) async {
 | 
						|
    await _downloadService.download(asset);
 | 
						|
  }
 | 
						|
 | 
						|
  void cancelDownload(String id) async {
 | 
						|
    final isCanceled = await _downloadService.cancelDownload(id);
 | 
						|
 | 
						|
    if (isCanceled) {
 | 
						|
      state = state.copyWith(
 | 
						|
        taskProgress: <String, DownloadInfo>{}
 | 
						|
          ..addAll(state.taskProgress)
 | 
						|
          ..remove(id),
 | 
						|
      );
 | 
						|
    }
 | 
						|
 | 
						|
    if (state.taskProgress.isEmpty) {
 | 
						|
      state = state.copyWith(showProgress: false);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  void shareAsset(Asset asset, BuildContext context) async {
 | 
						|
    showDialog(
 | 
						|
      context: context,
 | 
						|
      builder: (BuildContext buildContext) {
 | 
						|
        _shareService.shareAsset(asset, context).then((bool status) {
 | 
						|
          if (!status) {
 | 
						|
            ImmichToast.show(
 | 
						|
              context: context,
 | 
						|
              msg: 'image_viewer_page_state_provider_share_error'.tr(),
 | 
						|
              toastType: ToastType.error,
 | 
						|
              gravity: ToastGravity.BOTTOM,
 | 
						|
            );
 | 
						|
          }
 | 
						|
          buildContext.pop();
 | 
						|
        });
 | 
						|
        return const ShareDialog();
 | 
						|
      },
 | 
						|
      barrierDismissible: false,
 | 
						|
      useRootNavigator: false,
 | 
						|
    );
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
final downloadStateProvider = StateNotifierProvider<DownloadStateNotifier, DownloadState>(
 | 
						|
  ((ref) => DownloadStateNotifier(
 | 
						|
    ref.watch(downloadServiceProvider),
 | 
						|
    ref.watch(shareServiceProvider),
 | 
						|
    ref.watch(albumServiceProvider),
 | 
						|
  )),
 | 
						|
);
 |