From e0b2fa5a1bd2f7de66b420d6e6e8be2dcd039875 Mon Sep 17 00:00:00 2001 From: ashilkn Date: Sat, 29 Jun 2024 16:45:47 +0530 Subject: [PATCH] [mob][photos] Improve swipe to select accuracy --- mobile/lib/main.dart | 13 ++-- .../component/gallery_file_widget.dart | 22 +++---- .../grid/gallery_grid_view_widget.dart | 2 - .../component/group/lazy_group_gallery.dart | 64 ++++++++++++++----- mobile/lib/ui/viewer/gallery/gallery.dart | 3 - .../gallery/state/gallery_context_state.dart | 2 - 6 files changed, 65 insertions(+), 41 deletions(-) diff --git a/mobile/lib/main.dart b/mobile/lib/main.dart index 8f56fe2aca..a66a4ffc09 100644 --- a/mobile/lib/main.dart +++ b/mobile/lib/main.dart @@ -48,7 +48,6 @@ import 'package:photos/services/trash_sync_service.dart'; import 'package:photos/services/update_service.dart'; import 'package:photos/services/user_remote_flag_service.dart'; import 'package:photos/services/user_service.dart'; -import "package:photos/states/pointer_position_provider.dart"; import 'package:photos/ui/tools/app_lock.dart'; import 'package:photos/ui/tools/lock_screen.dart'; import 'package:photos/utils/crypto_util.dart'; @@ -93,13 +92,11 @@ Future _runInForeground(AdaptiveThemeMode? savedThemeMode) async { runApp( AppLock( - builder: (args) => PointerPositionProvider( - child: EnteApp( - _runBackgroundTask, - _killBGTask, - locale, - savedThemeMode, - ), + builder: (args) => EnteApp( + _runBackgroundTask, + _killBGTask, + locale, + savedThemeMode, ), lockScreen: const LockScreen(), enabled: Configuration.instance.shouldShowLockScreen(), diff --git a/mobile/lib/ui/viewer/gallery/component/gallery_file_widget.dart b/mobile/lib/ui/viewer/gallery/component/gallery_file_widget.dart index 17e2911013..0535b363c6 100644 --- a/mobile/lib/ui/viewer/gallery/component/gallery_file_widget.dart +++ b/mobile/lib/ui/viewer/gallery/component/gallery_file_widget.dart @@ -13,6 +13,7 @@ import "package:photos/states/pointer_position_provider.dart"; import "package:photos/theme/ente_theme.dart"; import "package:photos/ui/viewer/file/detail_page.dart"; import "package:photos/ui/viewer/file/thumbnail_widget.dart"; +import "package:photos/ui/viewer/gallery/component/group/lazy_group_gallery.dart"; import "package:photos/ui/viewer/gallery/gallery.dart"; import "package:photos/ui/viewer/gallery/state/gallery_context_state.dart"; import "package:photos/utils/file_util.dart"; @@ -57,11 +58,17 @@ class _GalleryFileWidgetState extends State { if (mounted) { Future.delayed(const Duration(seconds: 1), () { try { - final scrollController = - GalleryContextState.of(context)!.scrollController; final RenderBox renderBox = _globalKey.currentContext?.findRenderObject() as RenderBox; - final position = renderBox.localToGlobal(Offset.zero); + final groupGalleryGlobalKey = + GroupGalleryGlobalKey.of(context).globalKey; + final RenderBox groupGalleryRenderBox = + groupGalleryGlobalKey.currentContext?.findRenderObject() + as RenderBox; + final position = renderBox.localToGlobal( + Offset.zero, + ancestor: groupGalleryRenderBox, + ); final size = renderBox.size; final bbox = Rect.fromLTWH( position.dx, @@ -76,14 +83,7 @@ class _GalleryFileWidgetState extends State { if (widget.selectedFiles?.files.isEmpty ?? true) return; _insideBboxPrevValue = _insideBbox; - final bboxAccountingToScrollPos = Rect.fromLTWH( - bbox.left, - bbox.top - scrollController.offset, - bbox.width, - bbox.height, - ); - - if (bboxAccountingToScrollPos.contains(event)) { + if (bbox.contains(event)) { _insideBbox = true; } else { _insideBbox = false; diff --git a/mobile/lib/ui/viewer/gallery/component/grid/gallery_grid_view_widget.dart b/mobile/lib/ui/viewer/gallery/component/grid/gallery_grid_view_widget.dart index c810197a22..1d5362825b 100644 --- a/mobile/lib/ui/viewer/gallery/component/grid/gallery_grid_view_widget.dart +++ b/mobile/lib/ui/viewer/gallery/component/grid/gallery_grid_view_widget.dart @@ -4,7 +4,6 @@ import 'package:photos/models/file/file.dart'; import "package:photos/models/selected_files.dart"; import "package:photos/ui/viewer/gallery/component/gallery_file_widget.dart"; import "package:photos/ui/viewer/gallery/gallery.dart"; -import "package:photos/ui/viewer/gallery/state/gallery_context_state.dart"; class GalleryGridViewWidget extends StatelessWidget { final List filesInGroup; @@ -30,7 +29,6 @@ class GalleryGridViewWidget extends StatelessWidget { return GridView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), - controller: GalleryContextState.of(context)!.scrollController, // to disable GridView's scrolling itemBuilder: (context, index) { return GalleryFileWidget( diff --git a/mobile/lib/ui/viewer/gallery/component/group/lazy_group_gallery.dart b/mobile/lib/ui/viewer/gallery/component/group/lazy_group_gallery.dart index 299d84d7d3..6f58c195aa 100644 --- a/mobile/lib/ui/viewer/gallery/component/group/lazy_group_gallery.dart +++ b/mobile/lib/ui/viewer/gallery/component/group/lazy_group_gallery.dart @@ -7,6 +7,7 @@ import 'package:photos/core/constants.dart'; import 'package:photos/events/files_updated_event.dart'; import 'package:photos/models/file/file.dart'; import 'package:photos/models/selected_files.dart'; +import "package:photos/states/pointer_position_provider.dart"; import 'package:photos/theme/ente_theme.dart'; import "package:photos/ui/viewer/gallery/component/grid/place_holder_grid_view_widget.dart"; import "package:photos/ui/viewer/gallery/component/group/group_gallery.dart"; @@ -61,6 +62,7 @@ class _LazyGroupGalleryState extends State { late StreamSubscription? _reloadEventSubscription; late StreamSubscription _currentIndexSubscription; bool? _shouldRender; + final _groupGalleryGlobalKey = GlobalKey(); @override void initState() { @@ -233,21 +235,29 @@ class _LazyGroupGalleryState extends State { ), ], ), - _shouldRender! - ? GroupGallery( - photoGridSize: widget.photoGridSize, - files: _filesInGroup, - tag: widget.tag, - asyncLoader: widget.asyncLoader, - selectedFiles: widget.selectedFiles, - limitSelectionToOne: widget.limitSelectionToOne, - ) - // todo: perf eval should we have separate PlaceHolder for Groups - // instead of creating a large cached view - : PlaceHolderGridViewWidget( - _filesInGroup.length, - widget.photoGridSize, - ), + PointerPositionProvider( + child: GroupGalleryGlobalKey( + globalKey: _groupGalleryGlobalKey, + child: SizedBox( + key: _groupGalleryGlobalKey, + child: _shouldRender! + ? GroupGallery( + photoGridSize: widget.photoGridSize, + files: _filesInGroup, + tag: widget.tag, + asyncLoader: widget.asyncLoader, + selectedFiles: widget.selectedFiles, + limitSelectionToOne: widget.limitSelectionToOne, + ) + // todo: perf eval should we have separate PlaceHolder for Groups + // instead of creating a large cached view + : PlaceHolderGridViewWidget( + _filesInGroup.length, + widget.photoGridSize, + ), + ), + ), + ), ], ); } @@ -265,3 +275,27 @@ class _LazyGroupGalleryState extends State { } } } + +class GroupGalleryGlobalKey extends InheritedWidget { + const GroupGalleryGlobalKey({ + super.key, + required this.globalKey, + required super.child, + }); + + final GlobalKey globalKey; + + static GroupGalleryGlobalKey? maybeOf(BuildContext context) { + return context.dependOnInheritedWidgetOfExactType(); + } + + static GroupGalleryGlobalKey of(BuildContext context) { + final GroupGalleryGlobalKey? result = maybeOf(context); + assert(result != null, 'No GroupGalleryGlobalKey found in context'); + return result!; + } + + @override + bool updateShouldNotify(GroupGalleryGlobalKey oldWidget) => + globalKey != oldWidget.globalKey; +} diff --git a/mobile/lib/ui/viewer/gallery/gallery.dart b/mobile/lib/ui/viewer/gallery/gallery.dart index f970700ee2..3155617060 100644 --- a/mobile/lib/ui/viewer/gallery/gallery.dart +++ b/mobile/lib/ui/viewer/gallery/gallery.dart @@ -108,7 +108,6 @@ class GalleryState extends State { final _forceReloadEventSubscriptions = >[]; late String _logTag; bool _sortOrderAsc = false; - final _scrollController = ScrollController(); List _allFiles = []; @override @@ -245,7 +244,6 @@ class GalleryState extends State { subscription.cancel(); } _debouncer.cancelDebounce(); - _scrollController.dispose(); super.dispose(); } @@ -260,7 +258,6 @@ class GalleryState extends State { sortOrderAsc: _sortOrderAsc, inSelectionMode: widget.inSelectionMode, type: widget.groupType, - scrollController: _scrollController, child: MultipleGroupsGalleryView( itemScroller: _itemScroller, groupedFiles: currentGroupedFiles, diff --git a/mobile/lib/ui/viewer/gallery/state/gallery_context_state.dart b/mobile/lib/ui/viewer/gallery/state/gallery_context_state.dart index f66a32e1da..2d23ec53fb 100644 --- a/mobile/lib/ui/viewer/gallery/state/gallery_context_state.dart +++ b/mobile/lib/ui/viewer/gallery/state/gallery_context_state.dart @@ -6,13 +6,11 @@ class GalleryContextState extends InheritedWidget { final bool sortOrderAsc; final bool inSelectionMode; final GroupType type; - final ScrollController scrollController; const GalleryContextState({ this.inSelectionMode = false, this.type = GroupType.day, required this.sortOrderAsc, - required this.scrollController, required Widget child, Key? key, }) : super(key: key, child: child);