mirror of
				https://github.com/immich-app/immich.git
				synced 2025-10-30 18:22:37 -04:00 
			
		
		
		
	Implemented a mechanism to extract the correct time zone from the GPS coordinate if presented in the file's EXIF, and to convert the timestamp to the correct UTC time so that the time will show correctly based on the mobile/web local time zone.
		
			
				
	
	
		
			102 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
			
		
		
	
	
			102 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Dart
		
	
	
	
	
	
| import 'package:flutter/foundation.dart';
 | |
| import 'package:hooks_riverpod/hooks_riverpod.dart';
 | |
| import 'package:immich_mobile/modules/home/services/asset.service.dart';
 | |
| import 'package:immich_mobile/shared/services/device_info.service.dart';
 | |
| import 'package:collection/collection.dart';
 | |
| import 'package:intl/intl.dart';
 | |
| import 'package:openapi/api.dart';
 | |
| import 'package:photo_manager/photo_manager.dart';
 | |
| 
 | |
| class AssetNotifier extends StateNotifier<List<AssetResponseDto>> {
 | |
|   final AssetService _assetService;
 | |
|   final DeviceInfoService _deviceInfoService = DeviceInfoService();
 | |
| 
 | |
|   AssetNotifier(this._assetService) : super([]);
 | |
| 
 | |
|   getAllAsset() async {
 | |
|     var allAssets = await _assetService.getAllAsset();
 | |
| 
 | |
|     if (allAssets != null) {
 | |
|       state = allAssets;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   clearAllAsset() {
 | |
|     state = [];
 | |
|   }
 | |
| 
 | |
|   onNewAssetUploaded(AssetResponseDto newAsset) {
 | |
|     state = [...state, newAsset];
 | |
|   }
 | |
| 
 | |
|   deleteAssets(Set<AssetResponseDto> deleteAssets) async {
 | |
|     var deviceInfo = await _deviceInfoService.getDeviceInfo();
 | |
|     var deviceId = deviceInfo["deviceId"];
 | |
|     var deleteIdList = <String>[];
 | |
|     // Delete asset from device
 | |
|     for (var asset in deleteAssets) {
 | |
|       // Delete asset on device if present
 | |
|       if (asset.deviceId == deviceId) {
 | |
|         var localAsset = await AssetEntity.fromId(asset.deviceAssetId);
 | |
| 
 | |
|         if (localAsset != null) {
 | |
|           deleteIdList.add(localAsset.id);
 | |
|         }
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     try {
 | |
|       await PhotoManager.editor.deleteWithIds(deleteIdList);
 | |
|     } catch (e) {
 | |
|       debugPrint("Delete asset from device failed: $e");
 | |
|     }
 | |
| 
 | |
|     // Delete asset on server
 | |
|     List<DeleteAssetResponseDto>? deleteAssetResult =
 | |
|         await _assetService.deleteAssets(deleteAssets);
 | |
| 
 | |
|     if (deleteAssetResult == null) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     for (var asset in deleteAssetResult) {
 | |
|       if (asset.status == DeleteAssetStatus.SUCCESS) {
 | |
|         state =
 | |
|             state.where((immichAsset) => immichAsset.id != asset.id).toList();
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| final assetProvider =
 | |
|     StateNotifierProvider<AssetNotifier, List<AssetResponseDto>>((ref) {
 | |
|   return AssetNotifier(ref.watch(assetServiceProvider));
 | |
| });
 | |
| 
 | |
| final assetGroupByDateTimeProvider = StateProvider((ref) {
 | |
|   var assets = ref.watch(assetProvider);
 | |
| 
 | |
|   assets.sortByCompare<DateTime>(
 | |
|     (e) => DateTime.parse(e.createdAt),
 | |
|     (a, b) => b.compareTo(a),
 | |
|   );
 | |
|   return assets.groupListsBy(
 | |
|     (element) => DateFormat('y-MM-dd')
 | |
|         .format(DateTime.parse(element.createdAt).toLocal()),
 | |
|   );
 | |
| });
 | |
| 
 | |
| final assetGroupByMonthYearProvider = StateProvider((ref) {
 | |
|   var assets = ref.watch(assetProvider);
 | |
| 
 | |
|   assets.sortByCompare<DateTime>(
 | |
|     (e) => DateTime.parse(e.createdAt),
 | |
|     (a, b) => b.compareTo(a),
 | |
|   );
 | |
| 
 | |
|   return assets.groupListsBy(
 | |
|     (element) => DateFormat('MMMM, y')
 | |
|         .format(DateTime.parse(element.createdAt).toLocal()),
 | |
|   );
 | |
| });
 |