From b785af962e266ebd0b451da91bc1d5606428bb87 Mon Sep 17 00:00:00 2001 From: YuvRaj-at-Unity Date: Tue, 13 Aug 2024 00:59:16 -0400 Subject: [PATCH 1/6] Fix null name --- mobile/lib/pages/editing/crop.page.dart | 12 ++- mobile/lib/pages/editing/edit.page.dart | 94 +++++++++---------- mobile/lib/routing/router.gr.dart | 35 ++++--- .../asset_viewer/bottom_gallery_bar.dart | 9 +- 4 files changed, 82 insertions(+), 68 deletions(-) diff --git a/mobile/lib/pages/editing/crop.page.dart b/mobile/lib/pages/editing/crop.page.dart index 8a21cdf76908f..a3ac34dfa0a67 100644 --- a/mobile/lib/pages/editing/crop.page.dart +++ b/mobile/lib/pages/editing/crop.page.dart @@ -3,6 +3,7 @@ import 'package:crop_image/crop_image.dart'; import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/utils/hooks/crop_controller_hook.dart'; +import 'package:immich_mobile/entities/asset.entity.dart'; import 'edit.page.dart'; import 'package:auto_route/auto_route.dart'; @@ -14,7 +15,8 @@ import 'package:auto_route/auto_route.dart'; @RoutePage() class CropImagePage extends HookWidget { final Image image; - const CropImagePage({super.key, required this.image}); + final Asset asset; + const CropImagePage({super.key, required this.image, required this.asset}); @override Widget build(BuildContext context) { @@ -34,7 +36,13 @@ class CropImagePage extends HookWidget { ), onPressed: () async { final croppedImage = await cropController.croppedImage(); - context.pushRoute(EditImageRoute(image: croppedImage)); + context.pushRoute( + EditImageRoute( + asset: asset, + image: croppedImage, + isEdited: true, + ), + ); }, ), ], diff --git a/mobile/lib/pages/editing/edit.page.dart b/mobile/lib/pages/editing/edit.page.dart index 22fb345e0f706..8e6083ac16fa6 100644 --- a/mobile/lib/pages/editing/edit.page.dart +++ b/mobile/lib/pages/editing/edit.page.dart @@ -24,18 +24,16 @@ import 'package:immich_mobile/providers/album/album.provider.dart'; @immutable @RoutePage() class EditImagePage extends ConsumerWidget { - final Asset? asset; - final Image? image; + final Asset asset; + final Image image; + final bool isEdited; const EditImagePage({ super.key, - this.image, - this.asset, - }) : assert( - (image != null && asset == null) || (image == null && asset != null), - 'Must supply one of asset or image', - ); - + required this.asset, + required this.image, + required this.isEdited, + }); Future _imageToUint8List(Image image) async { final Completer completer = Completer(); image.image.resolve(const ImageConfiguration()).addListener( @@ -60,17 +58,8 @@ class EditImagePage extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final ImageProvider provider = (asset != null) - ? ImmichImage.imageProvider(asset: asset!) - : (image != null) - ? image!.image - : throw Exception('Invalid image source type'); - - final Image imageWidget = (asset != null) - ? Image(image: ImmichImage.imageProvider(asset: asset!)) - : (image != null) - ? image! - : throw Exception('Invalid image source type'); + final Image imageWidget = + Image(image: ImmichImage.imageProvider(asset: asset)); return Scaffold( appBar: AppBar( @@ -85,44 +74,43 @@ class EditImagePage extends ConsumerWidget { Navigator.of(context).popUntil((route) => route.isFirst), ), actions: [ - if (image != null) - TextButton( - onPressed: () async { - try { - final Uint8List imageData = await _imageToUint8List(image!); - ImmichToast.show( - durationInSecond: 3, - context: context, - msg: 'Image Saved!', - gravity: ToastGravity.CENTER, - ); + TextButton( + onPressed: () async { + try { + final Uint8List imageData = await _imageToUint8List(image); + ImmichToast.show( + durationInSecond: 3, + context: context, + msg: 'Image Saved!', + gravity: ToastGravity.CENTER, + ); - await PhotoManager.editor.saveImage( - imageData, - title: '${asset!.fileName}_edited.jpg', - ); - await ref.read(albumProvider.notifier).getDeviceAlbums(); - Navigator.of(context).popUntil((route) => route.isFirst); - } catch (e) { - ImmichToast.show( - durationInSecond: 6, - context: context, - msg: 'Error: ${e.toString()}', - gravity: ToastGravity.BOTTOM, - ); - } - }, - child: Text( - 'Save to gallery', - style: Theme.of(context).textTheme.displayMedium, - ), + await PhotoManager.editor.saveImage( + imageData, + title: "${asset.fileName.split('.').first}_edited.jpg", + ); + await ref.read(albumProvider.notifier).getDeviceAlbums(); + Navigator.of(context).popUntil((route) => route.isFirst); + } catch (e) { + ImmichToast.show( + durationInSecond: 6, + context: context, + msg: 'Error: ${e.toString()}', + gravity: ToastGravity.BOTTOM, + ); + } + }, + child: Text( + 'Save to gallery', + style: Theme.of(context).textTheme.displayMedium, ), + ), ], ), body: Column( children: [ Expanded( - child: Image(image: provider), + child: image, ), Container( height: 80, @@ -148,7 +136,9 @@ class EditImagePage extends ConsumerWidget { color: Theme.of(context).iconTheme.color, ), onPressed: () { - context.pushRoute(CropImageRoute(image: imageWidget)); + context.pushRoute( + CropImageRoute(asset: asset, image: imageWidget), + ); }, ), Text('Crop', style: Theme.of(context).textTheme.displayMedium), diff --git a/mobile/lib/routing/router.gr.dart b/mobile/lib/routing/router.gr.dart index a4259676c7a6d..90fc4cb0fe96c 100644 --- a/mobile/lib/routing/router.gr.dart +++ b/mobile/lib/routing/router.gr.dart @@ -613,12 +613,14 @@ class CropImageRoute extends PageRouteInfo { CropImageRoute({ Key? key, required Image image, + required Asset asset, List? children, }) : super( CropImageRoute.name, args: CropImageRouteArgs( key: key, image: image, + asset: asset, ), initialChildren: children, ); @@ -632,6 +634,7 @@ class CropImageRoute extends PageRouteInfo { return CropImagePage( key: args.key, image: args.image, + asset: args.asset, ); }, ); @@ -641,15 +644,18 @@ class CropImageRouteArgs { const CropImageRouteArgs({ this.key, required this.image, + required this.asset, }); final Key? key; final Image image; + final Asset asset; + @override String toString() { - return 'CropImageRouteArgs{key: $key, image: $image}'; + return 'CropImageRouteArgs{key: $key, image: $image, asset: $asset}'; } } @@ -658,15 +664,17 @@ class CropImageRouteArgs { class EditImageRoute extends PageRouteInfo { EditImageRoute({ Key? key, - Image? image, - Asset? asset, + required Asset asset, + required Image image, + required bool isEdited, List? children, }) : super( EditImageRoute.name, args: EditImageRouteArgs( key: key, - image: image, asset: asset, + image: image, + isEdited: isEdited, ), initialChildren: children, ); @@ -676,12 +684,12 @@ class EditImageRoute extends PageRouteInfo { static PageInfo page = PageInfo( name, builder: (data) { - final args = data.argsAs( - orElse: () => const EditImageRouteArgs()); + final args = data.argsAs(); return EditImagePage( key: args.key, - image: args.image, asset: args.asset, + image: args.image, + isEdited: args.isEdited, ); }, ); @@ -690,19 +698,22 @@ class EditImageRoute extends PageRouteInfo { class EditImageRouteArgs { const EditImageRouteArgs({ this.key, - this.image, - this.asset, + required this.asset, + required this.image, + required this.isEdited, }); final Key? key; - final Image? image; + final Asset asset; + + final Image image; - final Asset? asset; + final bool isEdited; @override String toString() { - return 'EditImageRouteArgs{key: $key, image: $image, asset: $asset}'; + return 'EditImageRouteArgs{key: $key, asset: $asset, image: $image, isEdited: $isEdited}'; } } diff --git a/mobile/lib/widgets/asset_viewer/bottom_gallery_bar.dart b/mobile/lib/widgets/asset_viewer/bottom_gallery_bar.dart index d78b10270e06c..33d60b5a3af53 100644 --- a/mobile/lib/widgets/asset_viewer/bottom_gallery_bar.dart +++ b/mobile/lib/widgets/asset_viewer/bottom_gallery_bar.dart @@ -16,6 +16,7 @@ import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart' import 'package:immich_mobile/widgets/asset_viewer/video_controls.dart'; import 'package:immich_mobile/widgets/asset_grid/delete_dialog.dart'; import 'package:immich_mobile/routing/router.dart'; +import 'package:immich_mobile/widgets/common/immich_image.dart'; import 'package:immich_mobile/entities/asset.entity.dart'; import 'package:immich_mobile/providers/asset.provider.dart'; import 'package:immich_mobile/providers/server_info.provider.dart'; @@ -236,6 +237,7 @@ class BottomGalleryBar extends ConsumerWidget { } void handleEdit() async { + final image = Image(image: ImmichImage.imageProvider(asset: asset)); if (asset.isOffline) { ImmichToast.show( durationInSecond: 1, @@ -247,8 +249,11 @@ class BottomGalleryBar extends ConsumerWidget { } Navigator.of(context).push( MaterialPageRoute( - builder: (context) => - EditImagePage(asset: asset), // Send the Asset object + builder: (context) => EditImagePage( + asset: asset, + image: image, + isEdited: false, + ), ), ); } From 8bf1f8a16bb1bcd2aec6f058b14e494fb10352ae Mon Sep 17 00:00:00 2001 From: YuvRaj-at-Unity Date: Tue, 13 Aug 2024 01:14:53 -0400 Subject: [PATCH 2/6] Fix null name and Fix button --- mobile/lib/pages/editing/edit.page.dart | 52 ++++++++++++------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/mobile/lib/pages/editing/edit.page.dart b/mobile/lib/pages/editing/edit.page.dart index 8e6083ac16fa6..d6ce37c6c095c 100644 --- a/mobile/lib/pages/editing/edit.page.dart +++ b/mobile/lib/pages/editing/edit.page.dart @@ -75,34 +75,34 @@ class EditImagePage extends ConsumerWidget { ), actions: [ TextButton( - onPressed: () async { - try { - final Uint8List imageData = await _imageToUint8List(image); - ImmichToast.show( - durationInSecond: 3, - context: context, - msg: 'Image Saved!', - gravity: ToastGravity.CENTER, - ); - - await PhotoManager.editor.saveImage( - imageData, - title: "${asset.fileName.split('.').first}_edited.jpg", - ); - await ref.read(albumProvider.notifier).getDeviceAlbums(); - Navigator.of(context).popUntil((route) => route.isFirst); - } catch (e) { - ImmichToast.show( - durationInSecond: 6, - context: context, - msg: 'Error: ${e.toString()}', - gravity: ToastGravity.BOTTOM, - ); - } - }, + onPressed: isEdited + ? () async { + try { + final Uint8List imageData = + await _imageToUint8List(image); + await PhotoManager.editor.saveImage( + imageData, + title: + "${asset.fileName.substring(0, asset.fileName.length - 4)}_edited.jpg", + ); + await ref.read(albumProvider.notifier).getDeviceAlbums(); + Navigator.of(context).popUntil((route) => route.isFirst); + } catch (e) { + ImmichToast.show( + durationInSecond: 6, + context: context, + msg: 'Error: $e', + gravity: ToastGravity.CENTER, + ); + } + } + : null, child: Text( 'Save to gallery', - style: Theme.of(context).textTheme.displayMedium, + style: TextStyle( + color: + isEdited ? Theme.of(context).iconTheme.color : Colors.grey, + ), ), ), ], From 11fe9f6e99420c0760c5060f0c152306be63ed41 Mon Sep 17 00:00:00 2001 From: YuvRaj-at-Unity Date: Tue, 13 Aug 2024 01:18:35 -0400 Subject: [PATCH 3/6] Remove extension correctly --- mobile/lib/pages/editing/edit.page.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mobile/lib/pages/editing/edit.page.dart b/mobile/lib/pages/editing/edit.page.dart index d6ce37c6c095c..93c4fa44ac6a8 100644 --- a/mobile/lib/pages/editing/edit.page.dart +++ b/mobile/lib/pages/editing/edit.page.dart @@ -82,8 +82,7 @@ class EditImagePage extends ConsumerWidget { await _imageToUint8List(image); await PhotoManager.editor.saveImage( imageData, - title: - "${asset.fileName.substring(0, asset.fileName.length - 4)}_edited.jpg", + title: "${asset.fileName.split('.').first}_edited.jpg", ); await ref.read(albumProvider.notifier).getDeviceAlbums(); Navigator.of(context).popUntil((route) => route.isFirst); From b4afaaaf24da29faeffac7e16e537fcead56580f Mon Sep 17 00:00:00 2001 From: YuvRaj-at-Unity Date: Sat, 17 Aug 2024 18:51:42 -0400 Subject: [PATCH 4/6] Refactoring the code and formatting --- mobile/lib/pages/editing/edit.page.dart | 40 +++++++++++++------------ 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/mobile/lib/pages/editing/edit.page.dart b/mobile/lib/pages/editing/edit.page.dart index 93c4fa44ac6a8..3ec5092232f90 100644 --- a/mobile/lib/pages/editing/edit.page.dart +++ b/mobile/lib/pages/editing/edit.page.dart @@ -56,6 +56,26 @@ class EditImagePage extends ConsumerWidget { return completer.future; } + Future _saveEditedImage( + BuildContext context, Asset asset, Image image, WidgetRef ref,) async { + try { + final Uint8List imageData = await _imageToUint8List(image); + await PhotoManager.editor.saveImage( + imageData, + title: "${asset.fileName.split('.').first}_edited.jpg", + ); + await ref.read(albumProvider.notifier).getDeviceAlbums(); + Navigator.of(context).popUntil((route) => route.isFirst); + } catch (e) { + ImmichToast.show( + durationInSecond: 6, + context: context, + msg: 'Error: $e', + gravity: ToastGravity.CENTER, + ); + } + } + @override Widget build(BuildContext context, WidgetRef ref) { final Image imageWidget = @@ -76,25 +96,7 @@ class EditImagePage extends ConsumerWidget { actions: [ TextButton( onPressed: isEdited - ? () async { - try { - final Uint8List imageData = - await _imageToUint8List(image); - await PhotoManager.editor.saveImage( - imageData, - title: "${asset.fileName.split('.').first}_edited.jpg", - ); - await ref.read(albumProvider.notifier).getDeviceAlbums(); - Navigator.of(context).popUntil((route) => route.isFirst); - } catch (e) { - ImmichToast.show( - durationInSecond: 6, - context: context, - msg: 'Error: $e', - gravity: ToastGravity.CENTER, - ); - } - } + ? () => _saveEditedImage(context, asset, image, ref) : null, child: Text( 'Save to gallery', From 30495da23727fc2e2e4d7958fd1073ea3ef69abc Mon Sep 17 00:00:00 2001 From: YuvRaj-at-Unity Date: Sat, 17 Aug 2024 18:57:29 -0400 Subject: [PATCH 5/6] formatting --- mobile/lib/pages/editing/edit.page.dart | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mobile/lib/pages/editing/edit.page.dart b/mobile/lib/pages/editing/edit.page.dart index 3ec5092232f90..4495c7ecb1cdd 100644 --- a/mobile/lib/pages/editing/edit.page.dart +++ b/mobile/lib/pages/editing/edit.page.dart @@ -57,7 +57,11 @@ class EditImagePage extends ConsumerWidget { } Future _saveEditedImage( - BuildContext context, Asset asset, Image image, WidgetRef ref,) async { + BuildContext context, + Asset asset, + Image image, + WidgetRef ref, + ) async { try { final Uint8List imageData = await _imageToUint8List(image); await PhotoManager.editor.saveImage( From cb6503748ee01fb12e83a6b98e48481cae0b06c1 Mon Sep 17 00:00:00 2001 From: Yuvraj P Date: Mon, 19 Aug 2024 22:12:21 -0400 Subject: [PATCH 6/6] Fix for the extension name --- mobile/lib/pages/editing/edit.page.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mobile/lib/pages/editing/edit.page.dart b/mobile/lib/pages/editing/edit.page.dart index 4495c7ecb1cdd..b9017e940bb41 100644 --- a/mobile/lib/pages/editing/edit.page.dart +++ b/mobile/lib/pages/editing/edit.page.dart @@ -12,6 +12,7 @@ import 'package:immich_mobile/widgets/common/immich_toast.dart'; import 'package:auto_route/auto_route.dart'; import 'package:immich_mobile/routing/router.dart'; import 'package:photo_manager/photo_manager.dart'; +import 'package:path/path.dart' as p; import 'package:immich_mobile/providers/album/album.provider.dart'; /// A stateless widget that provides functionality for editing an image. @@ -66,7 +67,7 @@ class EditImagePage extends ConsumerWidget { final Uint8List imageData = await _imageToUint8List(image); await PhotoManager.editor.saveImage( imageData, - title: "${asset.fileName.split('.').first}_edited.jpg", + title: "${p.withoutExtension(asset.fileName)}_edited.jpg", ); await ref.read(albumProvider.notifier).getDeviceAlbums(); Navigator.of(context).popUntil((route) => route.isFirst);