From b8a1e5b5c033887bb70e986412f420a12a1f023f Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Sat, 23 Nov 2024 17:32:48 +0800 Subject: [PATCH] :dizzy: Optimize transition of pages --- lib/router.dart | 24 +--- lib/screens/post/post_editor.dart | 20 ++- lib/widgets/chat/chat_message_input.dart | 2 +- lib/widgets/post/post_media_pending_list.dart | 136 +++++++----------- 4 files changed, 73 insertions(+), 109 deletions(-) diff --git a/lib/router.dart b/lib/router.dart index 1fff01c..e85c2aa 100644 --- a/lib/router.dart +++ b/lib/router.dart @@ -48,7 +48,8 @@ final _appRoutes = [ GoRoute( path: '/post/write/:mode', name: 'postEditor', - pageBuilder: (context, state) => CustomTransitionPage( + builder: (context, state) => AppBackground( + isLessOptimization: true, child: PostEditorScreen( mode: state.pathParameters['mode']!, postEditId: int.tryParse( @@ -61,34 +62,17 @@ final _appRoutes = [ state.uri.queryParameters['reposting'] ?? '', ), ), - transitionsBuilder: - (context, animation, secondaryAnimation, child) { - return FadeThroughTransition( - animation: animation, - secondaryAnimation: secondaryAnimation, - fillColor: Colors.transparent, - child: AppBackground(isLessOptimization: true, child: child), - ); - }, ), ), GoRoute( path: '/post/:slug', name: 'postDetail', - pageBuilder: (context, state) => CustomTransitionPage( + builder: (context, state) => AppBackground( + isLessOptimization: true, child: PostDetailScreen( slug: state.pathParameters['slug']!, preload: state.extra as SnPost?, ), - transitionsBuilder: - (context, animation, secondaryAnimation, child) { - return FadeThroughTransition( - animation: animation, - secondaryAnimation: secondaryAnimation, - fillColor: Colors.transparent, - child: AppBackground(isLessOptimization: true, child: child), - ); - }, ), ), ], diff --git a/lib/screens/post/post_editor.dart b/lib/screens/post/post_editor.dart index 580b0a7..9645023 100644 --- a/lib/screens/post/post_editor.dart +++ b/lib/screens/post/post_editor.dart @@ -354,7 +354,25 @@ class _PostEditorScreenState extends State { ), if (_writeController.attachments.isNotEmpty) PostMediaPendingList( - controller: _writeController, + attachments: _writeController.attachments, + isBusy: _writeController.isBusy, + onUpdate: (int idx, PostWriteMedia updatedMedia) async { + _writeController.setIsBusy(true); + try { + _writeController.setAttachmentAt(idx, updatedMedia); + } finally { + _writeController.setIsBusy(false); + } + }, + onRemove: (int idx) async { + _writeController.setIsBusy(true); + try { + _writeController.removeAttachmentAt(idx); + } finally { + _writeController.setIsBusy(false); + } + }, + onUpdateBusy: (state) => _writeController.setIsBusy(state), ).padding(bottom: 8), Material( elevation: 2, diff --git a/lib/widgets/chat/chat_message_input.dart b/lib/widgets/chat/chat_message_input.dart index d372a08..aacce88 100644 --- a/lib/widgets/chat/chat_message_input.dart +++ b/lib/widgets/chat/chat_message_input.dart @@ -175,7 +175,7 @@ class ChatMessageInputState extends State { padding: _attachments.isNotEmpty ? const EdgeInsets.only(top: 8) : EdgeInsets.zero, - child: PostMediaPendingListRaw( + child: PostMediaPendingList( attachments: _attachments, isBusy: _isBusy, onUpdate: (idx, updatedMedia) async { diff --git a/lib/widgets/post/post_media_pending_list.dart b/lib/widgets/post/post_media_pending_list.dart index b41dceb..fe35510 100644 --- a/lib/widgets/post/post_media_pending_list.dart +++ b/lib/widgets/post/post_media_pending_list.dart @@ -17,53 +17,13 @@ import 'package:surface/widgets/attachment/attachment_detail.dart'; import 'package:surface/widgets/dialog.dart'; class PostMediaPendingList extends StatelessWidget { - final PostWriteController controller; - - const PostMediaPendingList({super.key, required this.controller}); - - Future _handleUpdate(int idx, PostWriteMedia updatedMedia) async { - controller.setIsBusy(true); - try { - controller.setAttachmentAt(idx, updatedMedia); - } finally { - controller.setIsBusy(false); - } - } - - Future _handleRemove(int idx) async { - controller.setIsBusy(true); - try { - controller.removeAttachmentAt(idx); - } finally { - controller.setIsBusy(false); - } - } - - @override - Widget build(BuildContext context) { - return ListenableBuilder( - listenable: controller, - builder: (context, _) { - return PostMediaPendingListRaw( - attachments: controller.attachments, - isBusy: controller.isBusy, - onUpdate: (idx, updatedMedia) => _handleUpdate(idx, updatedMedia), - onRemove: (idx) => _handleRemove(idx), - onUpdateBusy: (state) => controller.setIsBusy(state), - ); - }, - ); - } -} - -class PostMediaPendingListRaw extends StatelessWidget { final List attachments; final bool isBusy; final Future Function(int idx, PostWriteMedia updatedMedia)? onUpdate; final Future Function(int idx)? onRemove; final void Function(bool state)? onUpdateBusy; - const PostMediaPendingListRaw({ + const PostMediaPendingList({ super.key, required this.attachments, required this.isBusy, @@ -122,6 +82,53 @@ class PostMediaPendingListRaw extends StatelessWidget { } } + ContextMenu _buildContextMenu( + BuildContext context, int idx, PostWriteMedia media) { + return ContextMenu( + entries: [ + if (media.type == PostWriteMediaType.image && media.attachment != null) + MenuItem( + label: 'preview'.tr(), + icon: Symbols.preview, + onSelected: () { + context.pushTransparentRoute( + AttachmentDetailPopup(data: media.attachment!), + rootNavigator: true, + ); + }, + ), + if (media.type == PostWriteMediaType.image && media.attachment == null) + MenuItem( + label: 'crop'.tr(), + icon: Symbols.crop, + onSelected: () => _cropImage(context, idx), + ), + if (media.attachment != null && onRemove != null) + MenuItem( + label: 'delete'.tr(), + icon: Symbols.delete, + onSelected: isBusy ? null : () => _deleteAttachment(context, idx), + ), + if (media.attachment == null && onRemove != null) + MenuItem( + label: 'delete'.tr(), + icon: Symbols.delete, + onSelected: () { + onRemove!(idx); + }, + ) + else if (onRemove != null) + MenuItem( + label: 'unlink'.tr(), + icon: Symbols.link_off, + onSelected: () { + onRemove!(idx); + }, + ), + ], + ); + } + @override Widget build(BuildContext context) { final devicePixelRatio = MediaQuery.of(context).devicePixelRatio; @@ -136,52 +143,7 @@ class PostMediaPendingListRaw extends StatelessWidget { itemBuilder: (context, idx) { final media = attachments[idx]; return ContextMenuRegion( - contextMenu: ContextMenu( - entries: [ - if (media.type == PostWriteMediaType.image && - media.attachment != null) - MenuItem( - label: 'preview'.tr(), - icon: Symbols.preview, - onSelected: () { - context.pushTransparentRoute( - AttachmentDetailPopup(data: media.attachment!), - rootNavigator: true, - ); - }, - ), - if (media.type == PostWriteMediaType.image && - media.attachment == null) - MenuItem( - label: 'crop'.tr(), - icon: Symbols.crop, - onSelected: () => _cropImage(context, idx), - ), - if (media.attachment != null && onRemove != null) - MenuItem( - label: 'delete'.tr(), - icon: Symbols.delete, - onSelected: - isBusy ? null : () => _deleteAttachment(context, idx), - ), - if (media.attachment == null && onRemove != null) - MenuItem( - label: 'delete'.tr(), - icon: Symbols.delete, - onSelected: () { - onRemove!(idx); - }, - ) - else if (onRemove != null) - MenuItem( - label: 'unlink'.tr(), - icon: Symbols.link_off, - onSelected: () { - onRemove!(idx); - }, - ), - ], - ), + contextMenu: _buildContextMenu(context, idx, media), child: Container( decoration: BoxDecoration( border: Border.all(