From bc690dc61e50bb3730644075ba3dbbdc3d2a5fe5 Mon Sep 17 00:00:00 2001 From: Ming Ming Date: Thu, 23 May 2024 01:06:08 +0800 Subject: [PATCH] Migrate WillPopScope where we could --- app/lib/widget/collection_browser.dart | 372 +++++++++--------- app/lib/widget/image_editor.dart | 10 +- .../selectable_item_stream_list_mixin.dart | 1 + 3 files changed, 195 insertions(+), 188 deletions(-) diff --git a/app/lib/widget/collection_browser.dart b/app/lib/widget/collection_browser.dart index 63134d05..45025448 100644 --- a/app/lib/widget/collection_browser.dart +++ b/app/lib/widget/collection_browser.dart @@ -143,198 +143,202 @@ class _WrappedCollectionBrowserState extends State<_WrappedCollectionBrowser> @override Widget build(BuildContext context) { - return WillPopScope( - onWillPop: () async { - if (_bloc.state.isEditMode) { - _bloc.add(const _CancelEdit()); - return false; - } else if (_bloc.state.selectedItems.isNotEmpty) { - _bloc.add(const _SetSelectedItems(items: {})); - return false; - } else { - return true; - } - }, - child: Scaffold( - body: MultiBlocListener( - listeners: [ - _BlocListener( - listenWhen: (previous, current) => - previous.items != current.items, - listener: (context, state) { - _bloc.add(_TransformItems( - items: state.items, - )); - }, - ), - _BlocListener( - listenWhen: (previous, current) => - previous.editItems != current.editItems, - listener: (context, state) { - if (state.editItems != null) { - _bloc.add(_TransformEditItems( - items: state.editItems!, + return _BlocBuilder( + buildWhen: (previous, current) => + previous.isEditMode != current.isEditMode || + previous.selectedItems.isEmpty != current.selectedItems.isEmpty, + builder: (context, state) => PopScope( + canPop: !state.isEditMode && state.selectedItems.isEmpty, + onPopInvoked: (didPop) { + if (state.isEditMode) { + _bloc.add(const _CancelEdit()); + } else if (state.selectedItems.isNotEmpty) { + _bloc.add(const _SetSelectedItems(items: {})); + } + }, + child: Scaffold( + body: MultiBlocListener( + listeners: [ + _BlocListener( + listenWhen: (previous, current) => + previous.items != current.items, + listener: (context, state) { + _bloc.add(_TransformItems( + items: state.items, )); - } - }, - ), - _BlocListener( - listenWhen: (previous, current) => - previous.importResult != current.importResult, - listener: (context, state) { - if (state.importResult != null) { - Navigator.of(context).pushReplacementNamed( - CollectionBrowser.routeName, - arguments: CollectionBrowserArguments(state.importResult!), - ); - } - }, - ), - _BlocListener( - listenWhen: (previous, current) => - previous.isEditMode != current.isEditMode, - listener: (context, state) { - final c = KiwiContainer().resolve(); - final bloc = context.read<_Bloc>(); - final canSort = - CollectionAdapter.of(c, bloc.account, state.collection) - .isPermitted(CollectionCapability.manualSort); - if (canSort && - !SessionStorage().hasShowDragRearrangeNotification) { - SnackBarManager().showSnackBar(SnackBar( - content: - Text(L10n.global().albumEditDragRearrangeNotification), - duration: k.snackBarDurationNormal, - )); - SessionStorage().hasShowDragRearrangeNotification = true; - } - }, - ), - _BlocListenerT( - selector: (state) => state.error, - listener: (context, error) { - if (error != null && isPageVisible()) { - final String content; - if (error.error is _ArchiveFailedError) { - content = L10n.global().archiveSelectedFailureNotification( - (error.error as _ArchiveFailedError).count); - } else if (error.error is _RemoveFailedError) { - content = L10n.global().deleteSelectedFailureNotification( - (error.error as _RemoveFailedError).count); - } else { - content = exception_util.toUserString(error.error); - } - SnackBarManager().showSnackBar(SnackBar( - content: Text(content), - duration: k.snackBarDurationNormal, - )); - } - }, - ), - _BlocListener( - listenWhen: (previous, current) => - previous.message != current.message, - listener: (context, state) { - if (state.message != null && isPageVisible()) { - SnackBarManager().showSnackBar(SnackBar( - content: Text(state.message!), - duration: k.snackBarDurationNormal, - )); - } - }, - ), - ], - child: Stack( - fit: StackFit.expand, - children: [ - FingerListener( - onPointerMove: (event) => _onPointerMove(context, event), - onFingerChanged: (finger) { - setState(() { - _finger = finger; - }); }, - child: GestureDetector( - onScaleStart: (_) { - _bloc.add(const _StartScaling()); - }, - onScaleUpdate: (details) { - _bloc.add(_SetScale(details.scale)); - }, - onScaleEnd: (_) { - _bloc.add(const _EndScaling()); - }, - child: CustomScrollView( - controller: _scrollController, - physics: _finger >= 2 - ? const NeverScrollableScrollPhysics() - : null, - slivers: [ - _BlocBuilder( - buildWhen: (previous, current) => - previous.selectedItems.isEmpty != - current.selectedItems.isEmpty || - previous.isEditMode != current.isEditMode, - builder: (context, state) { - if (state.isEditMode) { - return const _EditAppBar(); - } else if (state.selectedItems.isNotEmpty) { - return const _SelectionAppBar(); - } else { - return const _AppBar(); - } - }, - ), - SliverToBoxAdapter( - child: _BlocBuilder( - buildWhen: (previous, current) => - previous.isLoading != current.isLoading, - builder: (context, state) => state.isLoading - ? const LinearProgressIndicator() - : const SizedBox(height: 4), - ), - ), - _BlocBuilder( - buildWhen: (previous, current) => - previous.isEditMode != current.isEditMode || - previous.scale != current.scale, - builder: (context, state) { - if (!state.isEditMode) { - return SliverTransitionedScale( - scale: state.scale, - baseSliver: const _ContentList(), - overlaySliver: const _ScalingList(), - ); - } else { - if (context.bloc.isCollectionCapabilityPermitted( - CollectionCapability.manualSort)) { - return const _EditContentList(); - } else { - return const _UnmodifiableEditContentList(); - } - } - }, - ), - ], - ), - ), ), - _BlocBuilder( - buildWhen: (previous, current) => - previous.isEditBusy != current.isEditBusy, - builder: (context, state) { - if (state.isEditBusy) { - return Container( - color: Colors.black.withOpacity(.5), - alignment: Alignment.center, - child: const CircularProgressIndicator(), + _BlocListener( + listenWhen: (previous, current) => + previous.editItems != current.editItems, + listener: (context, state) { + if (state.editItems != null) { + _bloc.add(_TransformEditItems( + items: state.editItems!, + )); + } + }, + ), + _BlocListener( + listenWhen: (previous, current) => + previous.importResult != current.importResult, + listener: (context, state) { + if (state.importResult != null) { + Navigator.of(context).pushReplacementNamed( + CollectionBrowser.routeName, + arguments: + CollectionBrowserArguments(state.importResult!), ); - } else { - return const SizedBox.shrink(); + } + }, + ), + _BlocListener( + listenWhen: (previous, current) => + previous.isEditMode != current.isEditMode, + listener: (context, state) { + final c = KiwiContainer().resolve(); + final bloc = context.read<_Bloc>(); + final canSort = + CollectionAdapter.of(c, bloc.account, state.collection) + .isPermitted(CollectionCapability.manualSort); + if (canSort && + !SessionStorage().hasShowDragRearrangeNotification) { + SnackBarManager().showSnackBar(SnackBar( + content: Text( + L10n.global().albumEditDragRearrangeNotification), + duration: k.snackBarDurationNormal, + )); + SessionStorage().hasShowDragRearrangeNotification = true; + } + }, + ), + _BlocListenerT( + selector: (state) => state.error, + listener: (context, error) { + if (error != null && isPageVisible()) { + final String content; + if (error.error is _ArchiveFailedError) { + content = L10n.global() + .archiveSelectedFailureNotification( + (error.error as _ArchiveFailedError).count); + } else if (error.error is _RemoveFailedError) { + content = L10n.global().deleteSelectedFailureNotification( + (error.error as _RemoveFailedError).count); + } else { + content = exception_util.toUserString(error.error); + } + SnackBarManager().showSnackBar(SnackBar( + content: Text(content), + duration: k.snackBarDurationNormal, + )); + } + }, + ), + _BlocListener( + listenWhen: (previous, current) => + previous.message != current.message, + listener: (context, state) { + if (state.message != null && isPageVisible()) { + SnackBarManager().showSnackBar(SnackBar( + content: Text(state.message!), + duration: k.snackBarDurationNormal, + )); } }, ), ], + child: Stack( + fit: StackFit.expand, + children: [ + FingerListener( + onPointerMove: (event) => _onPointerMove(context, event), + onFingerChanged: (finger) { + setState(() { + _finger = finger; + }); + }, + child: GestureDetector( + onScaleStart: (_) { + _bloc.add(const _StartScaling()); + }, + onScaleUpdate: (details) { + _bloc.add(_SetScale(details.scale)); + }, + onScaleEnd: (_) { + _bloc.add(const _EndScaling()); + }, + child: CustomScrollView( + controller: _scrollController, + physics: _finger >= 2 + ? const NeverScrollableScrollPhysics() + : null, + slivers: [ + _BlocBuilder( + buildWhen: (previous, current) => + previous.selectedItems.isEmpty != + current.selectedItems.isEmpty || + previous.isEditMode != current.isEditMode, + builder: (context, state) { + if (state.isEditMode) { + return const _EditAppBar(); + } else if (state.selectedItems.isNotEmpty) { + return const _SelectionAppBar(); + } else { + return const _AppBar(); + } + }, + ), + SliverToBoxAdapter( + child: _BlocBuilder( + buildWhen: (previous, current) => + previous.isLoading != current.isLoading, + builder: (context, state) => state.isLoading + ? const LinearProgressIndicator() + : const SizedBox(height: 4), + ), + ), + _BlocBuilder( + buildWhen: (previous, current) => + previous.isEditMode != current.isEditMode || + previous.scale != current.scale, + builder: (context, state) { + if (!state.isEditMode) { + return SliverTransitionedScale( + scale: state.scale, + baseSliver: const _ContentList(), + overlaySliver: const _ScalingList(), + ); + } else { + if (context.bloc.isCollectionCapabilityPermitted( + CollectionCapability.manualSort)) { + return const _EditContentList(); + } else { + return const _UnmodifiableEditContentList(); + } + } + }, + ), + ], + ), + ), + ), + _BlocBuilder( + buildWhen: (previous, current) => + previous.isEditBusy != current.isEditBusy, + builder: (context, state) { + if (state.isEditBusy) { + return Container( + color: Colors.black.withOpacity(.5), + alignment: Alignment.center, + child: const CircularProgressIndicator(), + ); + } else { + return const SizedBox.shrink(); + } + }, + ), + ], + ), ), ), ), diff --git a/app/lib/widget/image_editor.dart b/app/lib/widget/image_editor.dart index 3264607c..036c210d 100644 --- a/app/lib/widget/image_editor.dart +++ b/app/lib/widget/image_editor.dart @@ -128,10 +128,12 @@ class _ImageEditorState extends State { } Widget _buildContent(BuildContext context) { - return WillPopScope( - onWillPop: () async { - unawaited(_onBackButton(context)); - return false; + return PopScope( + canPop: false, + onPopInvoked: (didPop) { + if (!didPop) { + _onBackButton(context); + } }, child: ColoredBox( color: Colors.black, diff --git a/app/lib/widget/selectable_item_stream_list_mixin.dart b/app/lib/widget/selectable_item_stream_list_mixin.dart index 3c305ca2..4343d5b0 100644 --- a/app/lib/widget/selectable_item_stream_list_mixin.dart +++ b/app/lib/widget/selectable_item_stream_list_mixin.dart @@ -28,6 +28,7 @@ abstract class SelectableItem { StaggeredTile get staggeredTile => const StaggeredTile.count(1, 1); } +@Deprecated("Use SelectableItemList widget") mixin SelectableItemStreamListMixin on State { @override initState() {