From 6c61ff59ff6c5a7a9c60a88da9090e28cecbd8e6 Mon Sep 17 00:00:00 2001 From: dom Date: Thu, 28 May 2026 12:58:50 +0800 Subject: [PATCH] opt publish page Signed-off-by: dom --- .../common/publish/common_publish_page.dart | 59 ++++++++++--------- .../publish/common_rich_text_pub_page.dart | 40 ++++++------- lib/pages/dynamics_create/view.dart | 8 --- lib/pages/main/controller.dart | 2 +- lib/pages/video/reply_new/view.dart | 2 - lib/pages/video/send_danmaku/view.dart | 6 +- pubspec.lock | 6 +- pubspec.yaml | 2 +- 8 files changed, 55 insertions(+), 70 deletions(-) diff --git a/lib/pages/common/publish/common_publish_page.dart b/lib/pages/common/publish/common_publish_page.dart index b870d8722..0bf492a91 100644 --- a/lib/pages/common/publish/common_publish_page.dart +++ b/lib/pages/common/publish/common_publish_page.dart @@ -27,7 +27,8 @@ abstract class CommonPublishPage extends StatefulWidget { abstract class CommonPublishPageState extends State with WidgetsBindingObserver { - late final FocusNode focusNode; + late bool _paused = false; + final FocusNode focusNode = FocusNode(); late final controller = ChatBottomPanelContainerController( uiScale: Pref.uiScale, ); @@ -42,23 +43,19 @@ abstract class CommonPublishPageState bool hasPub = false; void initPubState(); + bool get handleKeyboard => Platform.isAndroid && widget.autofocus; + @override void initState() { super.initState(); - if (Platform.isAndroid) { + if (handleKeyboard) { WidgetsBinding.instance.addObserver(this); } - focusNode = FocusNode(); - initPubState(); if (widget.autofocus) { - Future.delayed(const Duration(milliseconds: 300), () { - if (mounted) { - focusNode.requestFocus(); - } - }); + _requestFocus(duration: const Duration(milliseconds: 300)); } } @@ -69,35 +66,41 @@ abstract class CommonPublishPageState } focusNode.dispose(); editController.dispose(); - if (Platform.isAndroid) { + if (handleKeyboard) { WidgetsBinding.instance.removeObserver(this); } super.dispose(); } - void _requestFocus() { - Future.delayed(const Duration(microseconds: 200), focusNode.requestFocus); + void _safeRequestFocus() { + if (mounted) { + focusNode.requestFocus(); + } + } + + void _requestFocus({Duration duration = const Duration(microseconds: 200)}) { + Future.delayed(duration, _safeRequestFocus); } @override void didChangeAppLifecycleState(AppLifecycleState state) { - if (state == AppLifecycleState.resumed) { - if (mounted && - widget.autofocus && - (panelType.value == PanelType.keyboard || - panelType.value == PanelType.none)) { - controller.restoreChatPanel(); - WidgetsBinding.instance.addPostFrameCallback((_) { - if (focusNode.hasFocus) { - focusNode.unfocus(); - _requestFocus(); - } else { - _requestFocus(); - } - }); + if (state == .resumed) { + if (_paused) { + _paused = false; + final panelType = this.panelType.value; + if (panelType == .keyboard || panelType == .none) { + WidgetsBinding.instance.addPostFrameCallback((_) { + if (focusNode.hasFocus) { + focusNode.unfocus(); + _requestFocus(); + } else { + _requestFocus(); + } + }); + } } - } else if (state == AppLifecycleState.paused) { - controller.keepChatPanel(); + } else if (state == .paused) { + _paused = true; if (focusNode.hasFocus) { focusNode.unfocus(); } diff --git a/lib/pages/common/publish/common_rich_text_pub_page.dart b/lib/pages/common/publish/common_rich_text_pub_page.dart index 7e5e89784..9c76d31cd 100644 --- a/lib/pages/common/publish/common_rich_text_pub_page.dart +++ b/lib/pages/common/publish/common_rich_text_pub_page.dart @@ -111,27 +111,23 @@ abstract class CommonRichTextPubPageState clipBehavior: Clip.none, children: [ GestureDetector( - onTap: () async { - controller.keepChatPanel(); - await PageUtils.imageView( - imgList: imageList - .map( - (img) => switch (img) { - FilePicModel e => SourceModel( - url: e.path, - sourceType: .fileImage, - ), - OpusPicModel e => SourceModel( - url: e.url!, - sourceType: .networkImage, - ), - }, - ) - .toList(), - initialPage: index, - ); - controller.restoreChatPanel(); - }, + onTap: () => PageUtils.imageView( + imgList: imageList + .map( + (img) => switch (img) { + FilePicModel e => SourceModel( + url: e.path, + sourceType: .fileImage, + ), + OpusPicModel e => SourceModel( + url: e.url!, + sourceType: .networkImage, + ), + }, + ) + .toList(), + initialPage: index, + ), onLongPress: () { Feedback.forLongPress(context); onClear(); @@ -328,7 +324,6 @@ abstract class CommonRichTextPubPageState late double _mentionOffset = 0; Future? onMention([bool fromClick = false]) async { - controller.keepChatPanel(); final res = await DynMentionPanel.onDynMention( context, offset: _mentionOffset, @@ -345,7 +340,6 @@ abstract class CommonRichTextPubPageState res.clear(); } } - controller.restoreChatPanel(); } void _onInsertUser(MentionItem e, bool fromClick) { diff --git a/lib/pages/dynamics_create/view.dart b/lib/pages/dynamics_create/view.dart index e582153cd..9eeb8614f 100644 --- a/lib/pages/dynamics_create/view.dart +++ b/lib/pages/dynamics_create/view.dart @@ -502,7 +502,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState { onPressed: _isEdit || _isPrivate.value ? null : () async { - controller.keepChatPanel(); DateTime nowDate = DateTime.now(); final selectedDate = await showDatePicker( context: context, @@ -548,7 +547,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState { ); } } - controller.restoreChatPanel(); }, child: const Text('定时发布'), ) @@ -653,7 +651,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState { Widget get voteBtn => ToolbarIconButton( onPressed: () async { - controller.keepChatPanel(); final voteItem = editController.items.firstWhereOrNull( (e) => e.type == RichTextType.vote, ); @@ -698,7 +695,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState { ); } } - controller.restoreChatPanel(); }, icon: const Icon(Icons.bar_chart_rounded, size: 24), tooltip: '投票', @@ -814,7 +810,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState { double _topicOffset = 0; Future _onSelectTopic() async { - controller.keepChatPanel(); TopicItem? res = await SelectTopicPanel.onSelectTopic( context, offset: _topicOffset, @@ -823,7 +818,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState { if (res != null) { _topic.value = Pair(first: res.id, second: res.name); } - controller.restoreChatPanel(); } @override @@ -881,7 +875,6 @@ class _CreateDynPanelState extends CommonRichTextPubPageState { } Future _onReserve() async { - controller.keepChatPanel(); final ReserveInfoData? reserveInfo = await Navigator.of(context).push( GetPageRoute( page: () => CreateReservePage(sid: _reserveCard.value?.id), @@ -890,6 +883,5 @@ class _CreateDynPanelState extends CommonRichTextPubPageState { if (reserveInfo != null) { _reserveCard.value = reserveInfo; } - controller.restoreChatPanel(); } } diff --git a/lib/pages/main/controller.dart b/lib/pages/main/controller.dart index 5896b48db..95bd293b9 100644 --- a/lib/pages/main/controller.dart +++ b/lib/pages/main/controller.dart @@ -233,7 +233,7 @@ class MainController extends GetxController } this.navigationBars = navigationBars; final defPage = Pref.defaultHomePage; - selectedIndex.value = navigationBars.indexWhere((e) => e == defPage); + selectedIndex.value = navigationBars.indexOf(defPage); } void checkDefaultSearch([bool shouldCheck = false]) { diff --git a/lib/pages/video/reply_new/view.dart b/lib/pages/video/reply_new/view.dart index 80820db2e..5bc51ab87 100644 --- a/lib/pages/video/reply_new/view.dart +++ b/lib/pages/video/reply_new/view.dart @@ -290,7 +290,6 @@ class _ReplyPageState extends CommonRichTextPubPageState { children: [ item( onTap: () async { - controller.keepChatPanel(); final ({String title, String url})? res = await Get.to( ReplySearchPage(type: widget.replyType, oid: widget.oid), ); @@ -301,7 +300,6 @@ class _ReplyPageState extends CommonRichTextPubPageState { rawText: '${res.url} ', ); } - controller.restoreChatPanel(); }, icon: Icon(Icons.post_add, size: 28, color: color), title: '插入内容', diff --git a/lib/pages/video/send_danmaku/view.dart b/lib/pages/video/send_danmaku/view.dart index a19c0326d..303b6835a 100644 --- a/lib/pages/video/send_danmaku/view.dart +++ b/lib/pages/video/send_danmaku/view.dart @@ -428,9 +428,8 @@ class _SendDanmakuPanelState extends CommonTextPubPageState { ); } - Future _showColorPicker() async { - controller.keepChatPanel(); - await showDialog( + void _showColorPicker() { + showDialog( context: context, builder: (context) => AlertDialog( clipBehavior: Clip.hardEdge, @@ -446,7 +445,6 @@ class _SendDanmakuPanelState extends CommonTextPubPageState { ), ), ); - controller.restoreChatPanel(); } @override diff --git a/pubspec.lock b/pubspec.lock index d82dffca6..5cece1f9b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -255,11 +255,11 @@ packages: dependency: "direct main" description: path: "packages/chat_bottom_container" - ref: main - resolved-ref: dba2bf10db4a6f89564d9be63ce17b18f0f7e3e5 + ref: dev + resolved-ref: "88d5d2c3c76855258ead306d8921ef706033beef" url: "https://github.com/bggRGjQaUbCoE/flutter_chat_packages.git" source: git - version: "0.3.2" + version: "0.5.0" checked_yaml: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 820daa68a..eaea8224f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -54,7 +54,7 @@ dependencies: chat_bottom_container: git: url: https://github.com/bggRGjQaUbCoE/flutter_chat_packages.git - ref: main + ref: dev path: packages/chat_bottom_container collection: ^1.19.1 connectivity_plus: ^7.1.1