Implemented operation to delete asset in database
This commit is contained in:
parent
f7f4e9c710
commit
78dbe4061b
12 changed files with 135 additions and 48 deletions
|
@ -0,0 +1,52 @@
|
|||
import 'dart:convert';
|
||||
|
||||
class DeleteAssetResponse {
|
||||
final String id;
|
||||
final String status;
|
||||
|
||||
DeleteAssetResponse({
|
||||
required this.id,
|
||||
required this.status,
|
||||
});
|
||||
|
||||
DeleteAssetResponse copyWith({
|
||||
String? id,
|
||||
String? status,
|
||||
}) {
|
||||
return DeleteAssetResponse(
|
||||
id: id ?? this.id,
|
||||
status: status ?? this.status,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'id': id,
|
||||
'status': status,
|
||||
};
|
||||
}
|
||||
|
||||
factory DeleteAssetResponse.fromMap(Map<String, dynamic> map) {
|
||||
return DeleteAssetResponse(
|
||||
id: map['id'] ?? '',
|
||||
status: map['status'] ?? '',
|
||||
);
|
||||
}
|
||||
|
||||
String toJson() => json.encode(toMap());
|
||||
|
||||
factory DeleteAssetResponse.fromJson(String source) => DeleteAssetResponse.fromMap(json.decode(source));
|
||||
|
||||
@override
|
||||
String toString() => 'DeleteAssetResponse(id: $id, status: $status)';
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (identical(this, other)) return true;
|
||||
|
||||
return other is DeleteAssetResponse && other.id == id && other.status == status;
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => id.hashCode ^ status.hashCode;
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:immich_mobile/modules/home/models/delete_asset_response.model.dart';
|
||||
import 'package:immich_mobile/modules/home/services/asset.service.dart';
|
||||
import 'package:immich_mobile/shared/models/immich_asset.model.dart';
|
||||
import 'package:immich_mobile/shared/services/device_info.service.dart';
|
||||
|
@ -29,6 +30,16 @@ class AssetNotifier extends StateNotifier<List<ImmichAsset>> {
|
|||
var deviceId = deviceInfo["deviceId"];
|
||||
|
||||
// Delete asset on server
|
||||
List<DeleteAssetResponse>? deleteAssetResult = await _assetService.deleteAssets(deleteAssets);
|
||||
if (deleteAssetResult == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var asset in deleteAssetResult) {
|
||||
if (asset.status == 'success') {
|
||||
state = state.where((immichAsset) => immichAsset.id != asset.id).toList();
|
||||
}
|
||||
}
|
||||
|
||||
// Delete asset from device
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:immich_mobile/modules/home/models/get_all_asset_respose.model.dart';
|
||||
import 'package:immich_mobile/modules/home/models/delete_asset_response.model.dart';
|
||||
import 'package:immich_mobile/modules/home/models/get_all_asset_response.model.dart';
|
||||
import 'package:immich_mobile/shared/models/immich_asset.model.dart';
|
||||
import 'package:immich_mobile/shared/models/immich_asset_with_exif.model.dart';
|
||||
import 'package:immich_mobile/shared/services/network.service.dart';
|
||||
|
@ -89,7 +90,24 @@ class AssetService {
|
|||
}
|
||||
}
|
||||
|
||||
deleteAssets(Set<ImmichAsset> deleteAssets) async {
|
||||
return null;
|
||||
Future<List<DeleteAssetResponse>?> deleteAssets(Set<ImmichAsset> deleteAssets) async {
|
||||
try {
|
||||
var payload = [];
|
||||
|
||||
for (var asset in deleteAssets) {
|
||||
payload.add(asset.id);
|
||||
}
|
||||
|
||||
var res = await _networkService.deleteRequest(url: "asset/", data: {"ids": payload});
|
||||
|
||||
List<dynamic> decodedData = jsonDecode(res.toString());
|
||||
|
||||
List<DeleteAssetResponse> result = List.from(decodedData.map((a) => DeleteAssetResponse.fromMap(a)));
|
||||
|
||||
return result;
|
||||
} catch (e) {
|
||||
debugPrint("Error getAllAsset ${e.toString()}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,8 +27,10 @@ class DeleteDialog extends ConsumerWidget {
|
|||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
// onConfirmed();
|
||||
ref.watch(assetProvider.notifier).deleteAssets(homePageState.selectedItems);
|
||||
ref.watch(homePageStateProvider.notifier).disableMultiSelect();
|
||||
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(
|
||||
"Delete",
|
||||
|
|
|
@ -102,8 +102,6 @@ class ThumbnailImage extends HookConsumerWidget {
|
|||
child: CircularProgressIndicator(value: downloadProgress.progress),
|
||||
),
|
||||
errorWidget: (context, url, error) {
|
||||
debugPrint("Error Loading Thumbnail Widget $error");
|
||||
cacheKey.value += 1;
|
||||
return Icon(
|
||||
Icons.image_not_supported_outlined,
|
||||
color: Theme.of(context).primaryColor,
|
||||
|
|
|
@ -19,29 +19,14 @@ class HomePage extends HookConsumerWidget {
|
|||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
ScrollController _scrollController = useScrollController();
|
||||
// List<ImmichAssetGroupByDate> _assetGroup = ref.watch(assetProvider);
|
||||
var assetGroupByDateTime = ref.watch(assetGroupByDateTimeProvider);
|
||||
List<Widget> _imageGridGroup = [];
|
||||
var isMultiSelectEnable = ref.watch(homePageStateProvider).isMultiSelectEnable;
|
||||
var homePageState = ref.watch(homePageStateProvider);
|
||||
|
||||
_scrollControllerCallback() {
|
||||
var endOfPage = _scrollController.position.maxScrollExtent;
|
||||
|
||||
if (_scrollController.offset >= endOfPage - (endOfPage * 0.1) && !_scrollController.position.outOfRange) {
|
||||
// ref.read(assetProvider.notifier).getOlderAsset();
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() {
|
||||
ref.read(assetProvider.notifier).getAllAsset();
|
||||
|
||||
// ref.read(assetProvider.notifier).getAllAssetsWithPagination();
|
||||
|
||||
_scrollController.addListener(_scrollControllerCallback);
|
||||
return () {
|
||||
_scrollController.removeListener(_scrollControllerCallback);
|
||||
};
|
||||
return null;
|
||||
}, []);
|
||||
|
||||
onPopBackFromBackupPage() {
|
||||
|
|
|
@ -15,7 +15,7 @@ class LoginForm extends HookConsumerWidget {
|
|||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final usernameController = useTextEditingController(text: 'testuser@email.com');
|
||||
final passwordController = useTextEditingController(text: 'password');
|
||||
final serverEndpointController = useTextEditingController(text: 'http://192.168.1.216:2283');
|
||||
final serverEndpointController = useTextEditingController(text: 'http://192.168.1.103:2283');
|
||||
|
||||
return Center(
|
||||
child: ConstrainedBox(
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
|
@ -11,7 +13,7 @@ import 'package:immich_mobile/shared/services/backup.service.dart';
|
|||
import 'package:photo_manager/photo_manager.dart';
|
||||
|
||||
class BackupNotifier extends StateNotifier<BackUpState> {
|
||||
BackupNotifier(this.ref)
|
||||
BackupNotifier({this.ref})
|
||||
: super(
|
||||
BackUpState(
|
||||
backupProgress: BackUpProgressEnum.idle,
|
||||
|
@ -32,9 +34,10 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|||
),
|
||||
);
|
||||
|
||||
final Ref ref;
|
||||
Ref? ref;
|
||||
final BackupService _backupService = BackupService();
|
||||
final ServerInfoService _serverInfoService = ServerInfoService();
|
||||
final StreamController _onAssetBackupStreamCtrl = StreamController.broadcast();
|
||||
|
||||
void getBackupInfo() async {
|
||||
_updateServerInfo();
|
||||
|
@ -103,7 +106,7 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|||
state = state.copyWith(backupProgress: BackUpProgressEnum.idle, progressInPercentage: 0.0);
|
||||
}
|
||||
|
||||
void _onAssetUploaded() {
|
||||
void _onAssetUploaded(String deviceAssetId, String deviceId) {
|
||||
state =
|
||||
state.copyWith(backingUpAssetCount: state.backingUpAssetCount - 1, assetOnDatabase: state.assetOnDatabase + 1);
|
||||
|
||||
|
@ -136,36 +139,37 @@ class BackupNotifier extends StateNotifier<BackUpState> {
|
|||
}
|
||||
|
||||
void resumeBackup() {
|
||||
debugPrint("[resumeBackup]");
|
||||
var authState = ref.read(authenticationProvider);
|
||||
var authState = ref?.read(authenticationProvider);
|
||||
|
||||
// Check if user is login
|
||||
var accessKey = Hive.box(userInfoBox).get(accessTokenKey);
|
||||
|
||||
// User has been logged out return
|
||||
if (accessKey == null || !authState.isAuthenticated) {
|
||||
debugPrint("[resumeBackup] not authenticated - abort");
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if this device is enable backup by the user
|
||||
if ((authState.deviceInfo.deviceId == authState.deviceId) && authState.deviceInfo.isAutoBackup) {
|
||||
// check if backup is alreayd in process - then return
|
||||
if (state.backupProgress == BackUpProgressEnum.inProgress) {
|
||||
debugPrint("[resumeBackup] Backup is already in progress - abort");
|
||||
if (authState != null) {
|
||||
if (accessKey == null || !authState.isAuthenticated) {
|
||||
debugPrint("[resumeBackup] not authenticated - abort");
|
||||
return;
|
||||
}
|
||||
|
||||
// Run backup
|
||||
debugPrint("[resumeBackup] Start back up");
|
||||
startBackupProcess();
|
||||
}
|
||||
// Check if this device is enable backup by the user
|
||||
if ((authState.deviceInfo.deviceId == authState.deviceId) && authState.deviceInfo.isAutoBackup) {
|
||||
// check if backup is alreayd in process - then return
|
||||
if (state.backupProgress == BackUpProgressEnum.inProgress) {
|
||||
debugPrint("[resumeBackup] Backup is already in progress - abort");
|
||||
return;
|
||||
}
|
||||
|
||||
debugPrint("[resumeBackup] User disables auto backup");
|
||||
return;
|
||||
// Run backup
|
||||
debugPrint("[resumeBackup] Start back up");
|
||||
startBackupProcess();
|
||||
}
|
||||
|
||||
debugPrint("[resumeBackup] User disables auto backup");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final backupProvider = StateNotifierProvider<BackupNotifier, BackUpState>((ref) {
|
||||
return BackupNotifier(ref);
|
||||
return BackupNotifier(ref: ref);
|
||||
});
|
||||
|
|
|
@ -26,7 +26,7 @@ class BackupService {
|
|||
return result.cast<String>();
|
||||
}
|
||||
|
||||
backupAsset(List<AssetEntity> assetList, CancelToken cancelToken, Function singleAssetDoneCb,
|
||||
backupAsset(List<AssetEntity> assetList, CancelToken cancelToken, Function(String, String) singleAssetDoneCb,
|
||||
Function(int, int) uploadProgress) async {
|
||||
var dio = Dio();
|
||||
dio.interceptors.add(AuthenticatedRequestInterceptor());
|
||||
|
@ -77,7 +77,7 @@ class BackupService {
|
|||
);
|
||||
|
||||
if (res.statusCode == 201) {
|
||||
singleAssetDoneCb();
|
||||
singleAssetDoneCb(entity.id, deviceId);
|
||||
}
|
||||
}
|
||||
} on DioError catch (e) {
|
||||
|
|
|
@ -7,6 +7,24 @@ import 'package:immich_mobile/constants/hive_box.dart';
|
|||
import 'package:immich_mobile/utils/dio_http_interceptor.dart';
|
||||
|
||||
class NetworkService {
|
||||
Future<dynamic> deleteRequest({required String url, dynamic data}) async {
|
||||
try {
|
||||
var dio = Dio();
|
||||
dio.interceptors.add(AuthenticatedRequestInterceptor());
|
||||
|
||||
var savedEndpoint = Hive.box(userInfoBox).get(serverEndpointKey);
|
||||
Response res = await dio.delete('$savedEndpoint/$url', data: data);
|
||||
|
||||
if (res.statusCode == 200) {
|
||||
return res;
|
||||
}
|
||||
} on DioError catch (e) {
|
||||
debugPrint("DioError: ${e.response}");
|
||||
} catch (e) {
|
||||
debugPrint("ERROR getRequest: ${e.toString()}");
|
||||
}
|
||||
}
|
||||
|
||||
Future<dynamic> getRequest({required String url}) async {
|
||||
try {
|
||||
var dio = Dio();
|
||||
|
|
|
@ -81,7 +81,6 @@ export class AssetController {
|
|||
return await this.assetService.getAllAssets(authUser, query);
|
||||
}
|
||||
|
||||
|
||||
@Get('/')
|
||||
async getAllAssetsNoPagination(@GetAuthUser() authUser: AuthUserDto) {
|
||||
return await this.assetService.getAllAssetsNoPagination(authUser);
|
||||
|
|
Loading…
Add table
Reference in a new issue