Skip to content

Commit

Permalink
fix(mobile): android predictive gesture on album asset selection page
Browse files Browse the repository at this point in the history
  • Loading branch information
Gagan committed Jan 19, 2025
1 parent d249b63 commit 755eccf
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 13 deletions.
2 changes: 2 additions & 0 deletions mobile/assets/i18n/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
"album_viewer_appbar_share_remove": "Remove from album",
"album_viewer_appbar_share_to": "Share To",
"album_viewer_page_share_add_users": "Add users",
"album_viewer_add_photos_exit_dialog_title": "Confirm Exit",
"album_viewer_add_photos_exit_dialog_content": "Your selected photos will not be saved. Are you sure you want to exit this page?",
"all": "All",
"all_people_page_title": "People",
"all_videos_page_title": "Videos",
Expand Down
68 changes: 66 additions & 2 deletions mobile/lib/pages/album/album_asset_selection.page.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import 'package:auto_route/auto_route.dart';
import 'package:collection/collection.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/entities/asset.entity.dart';
import 'package:immich_mobile/extensions/asyncvalue_extensions.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/models/albums/asset_selection_page_result.model.dart';
import 'package:immich_mobile/providers/asset_viewer/render_list.provider.dart';
import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart';
import 'package:immich_mobile/widgets/asset_grid/immich_asset_grid.dart';
import 'package:immich_mobile/entities/asset.entity.dart';
import 'package:isar/isar.dart';

@RoutePage()
Expand Down Expand Up @@ -42,6 +43,9 @@ class AlbumAssetSelectionPage extends HookConsumerWidget {
preselectedAssets: existingAssets,
canDeselect: canDeselect,
showMultiSelectIndicator: false,
onPopInvoked: (selectedAssets) {
_onPopInvoked(context, existingAssets, selectedAssets);
},
);
}

Expand All @@ -51,7 +55,7 @@ class AlbumAssetSelectionPage extends HookConsumerWidget {
leading: IconButton(
icon: const Icon(Icons.close_rounded),
onPressed: () {
AutoRouter.of(context).popForced(null);
_onPopInvoked(context, existingAssets, selected.value);
},
),
title: selected.value.isEmpty
Expand Down Expand Up @@ -88,4 +92,64 @@ class AlbumAssetSelectionPage extends HookConsumerWidget {
),
);
}

Future<bool?> _showPopConfirmationDialog(BuildContext context) {
return showDialog<bool>(
context: context,
barrierDismissible: false, // user must tap button!
builder: (BuildContext context) {
return AlertDialog(
title: const Text('album_viewer_add_photos_exit_dialog_title').tr(),
content:
const Text('album_viewer_add_photos_exit_dialog_content').tr(),
actions: <Widget>[
TextButton(
onPressed: () => context.pop(false),
child: Text(
'action_common_cancel',
style: TextStyle(
color: context.primaryColor,
fontWeight: FontWeight.bold,
),
).tr(),
),
TextButton(
onPressed: () => context.pop(true),
child: Text(
'action_common_confirm',
style: TextStyle(
color: context.primaryColor,
fontWeight: FontWeight.bold,
),
).tr(),
),
],
);
},
);
}

void _onPopInvoked(
BuildContext context,
Set<Asset> existingAssets,
Set<Asset> selectedAssets,
) async {
if (!context.mounted) {
return;
}

final equality = const SetEquality<Asset>();
final hasNotSelectedAssets =
equality.equals(selectedAssets, existingAssets);

// Exit the page without warning if no new assets are selected
if (hasNotSelectedAssets) {
AutoRouter.of(context).popForced();
} else {
final result = await _showPopConfirmationDialog(context);
if (result == true) {
AutoRouter.of(context).popForced();
}
}
}
}
9 changes: 6 additions & 3 deletions mobile/lib/widgets/asset_grid/immich_asset_grid.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/entities/asset.entity.dart';
import 'package:immich_mobile/extensions/asyncvalue_extensions.dart';
import 'package:immich_mobile/providers/app_settings.provider.dart';
import 'package:immich_mobile/providers/asset_viewer/render_list.provider.dart';
import 'package:immich_mobile/services/app_settings.service.dart';
import 'package:immich_mobile/widgets/asset_grid/asset_grid_data_structure.dart';
import 'package:immich_mobile/widgets/asset_grid/immich_asset_grid_view.dart';
import 'package:immich_mobile/providers/app_settings.provider.dart';
import 'package:immich_mobile/services/app_settings.service.dart';
import 'package:immich_mobile/entities/asset.entity.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';

class ImmichAssetGrid extends HookConsumerWidget {
Expand All @@ -33,6 +33,7 @@ class ImmichAssetGrid extends HookConsumerWidget {
final bool shrinkWrap;
final bool showDragScroll;
final bool showStack;
final void Function(Set<Asset> selectedAssets)? onPopInvoked;

const ImmichAssetGrid({
super.key,
Expand All @@ -53,6 +54,7 @@ class ImmichAssetGrid extends HookConsumerWidget {
this.shrinkWrap = false,
this.showDragScroll = true,
this.showStack = false,
this.onPopInvoked,
});

@override
Expand Down Expand Up @@ -119,6 +121,7 @@ class ImmichAssetGrid extends HookConsumerWidget {
shrinkWrap: shrinkWrap,
showDragScroll: showDragScroll,
showStack: showStack,
onPopInvoked: onPopInvoked,
),
);
}
Expand Down
19 changes: 11 additions & 8 deletions mobile/lib/widgets/asset_grid/immich_asset_grid_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,25 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/entities/asset.entity.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/extensions/collection_extensions.dart';
import 'package:immich_mobile/extensions/theme_extensions.dart';
import 'package:immich_mobile/providers/asset_viewer/current_asset.provider.dart';
import 'package:immich_mobile/providers/asset_viewer/is_motion_video_playing.provider.dart';
import 'package:immich_mobile/providers/asset_viewer/scroll_notifier.provider.dart';
import 'package:immich_mobile/providers/asset_viewer/scroll_to_date_notifier.provider.dart';
import 'package:immich_mobile/providers/asset_viewer/show_controls.provider.dart';
import 'package:immich_mobile/providers/haptic_feedback.provider.dart';
import 'package:immich_mobile/providers/tab.provider.dart';
import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/widgets/asset_grid/asset_drag_region.dart';
import 'package:immich_mobile/widgets/asset_grid/control_bottom_app_bar.dart';
import 'package:immich_mobile/widgets/asset_grid/thumbnail_image.dart';
import 'package:immich_mobile/widgets/asset_grid/thumbnail_placeholder.dart';
import 'package:immich_mobile/widgets/common/immich_toast.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:immich_mobile/widgets/asset_grid/control_bottom_app_bar.dart';
import 'package:immich_mobile/routing/router.dart';
import 'package:immich_mobile/entities/asset.entity.dart';
import 'package:immich_mobile/providers/asset_viewer/scroll_to_date_notifier.provider.dart';
import 'package:immich_mobile/providers/haptic_feedback.provider.dart';
import 'package:immich_mobile/providers/tab.provider.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';

import 'asset_grid_data_structure.dart';
Expand Down Expand Up @@ -58,6 +58,7 @@ class ImmichAssetGridView extends ConsumerStatefulWidget {
final bool shrinkWrap;
final bool showDragScroll;
final bool showStack;
final void Function(Set<Asset> selectedAssets)? onPopInvoked;

const ImmichAssetGridView({
super.key,
Expand All @@ -78,6 +79,7 @@ class ImmichAssetGridView extends ConsumerStatefulWidget {
this.shrinkWrap = false,
this.showDragScroll = true,
this.showStack = false,
this.onPopInvoked,
});

@override
Expand Down Expand Up @@ -542,7 +544,8 @@ class ImmichAssetGridViewState extends ConsumerState<ImmichAssetGridView> {
Widget build(BuildContext context) {
return PopScope(
canPop: !(widget.selectionActive && _selectedAssets.isNotEmpty),
onPopInvokedWithResult: (didPop, _) => !didPop ? _deselectAll() : null,
onPopInvokedWithResult: (didPop, _) =>
!didPop ? widget.onPopInvoked?.call(_selectedAssets) : null,
child: Stack(
children: [
AssetDragRegion(
Expand Down

0 comments on commit 755eccf

Please sign in to comment.