From 5d0e4ed4413020a142ea73ef087a035d7625ad12 Mon Sep 17 00:00:00 2001 From: bggRGjQaUbCoE Date: Mon, 7 Oct 2024 17:03:05 +0800 Subject: [PATCH] opt: reply panel request focus onResume keep emoji panel onPause --- .../video/detail/reply_new/reply_page.dart | 85 +++++++++++++------ pubspec.lock | 9 +- pubspec.yaml | 7 +- 3 files changed, 70 insertions(+), 31 deletions(-) diff --git a/lib/pages/video/detail/reply_new/reply_page.dart b/lib/pages/video/detail/reply_new/reply_page.dart index 9333861c..c242d2ab 100644 --- a/lib/pages/video/detail/reply_new/reply_page.dart +++ b/lib/pages/video/detail/reply_new/reply_page.dart @@ -7,7 +7,6 @@ import 'package:chat_bottom_container/chat_bottom_container.dart'; import 'package:flutter/material.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; -import 'package:PiliPalaX/common/widgets/no_splash_factory.dart'; import 'package:PiliPalaX/http/video.dart'; import 'package:PiliPalaX/models/common/reply_type.dart'; import 'package:PiliPalaX/models/video/reply/emote.dart'; @@ -45,7 +44,7 @@ class ReplyPage extends StatefulWidget { } class _ReplyPageState extends State - with SingleTickerProviderStateMixin { + with SingleTickerProviderStateMixin, WidgetsBindingObserver { late final _focusNode = FocusNode(); late final _controller = ChatBottomPanelContainerController(); late final TextEditingController _replyContentController = @@ -65,6 +64,7 @@ class _ReplyPageState extends State @override void initState() { super.initState(); + WidgetsBinding.instance.addObserver(this); if (widget.savedReply != null && widget.savedReply!.isNotEmpty) { _enablePublish = true; @@ -87,37 +87,69 @@ class _ReplyPageState extends State _enableSend.close(); _focusNode.dispose(); _replyContentController.dispose(); + WidgetsBinding.instance.removeObserver(this); super.dispose(); } + void _requestFocus() async { + await Future.delayed(const Duration(microseconds: 200)); + _focusNode.requestFocus(); + } + + @override + void didChangeAppLifecycleState(AppLifecycleState state) { + if (state == AppLifecycleState.resumed) { + if (mounted && _selectKeyboard) { + WidgetsBinding.instance.addPostFrameCallback((timeStamp) async { + if (_focusNode.hasFocus) { + _focusNode.unfocus(); + _requestFocus(); + } else { + _requestFocus(); + } + }); + } + } else if (state == AppLifecycleState.paused) { + _controller.keepChatPanel(); + if (_focusNode.hasFocus) { + _focusNode.unfocus(); + } + } + } + @override Widget build(BuildContext context) { return MediaQuery.removePadding( - removeTop: true, - context: context, - child: Scaffold( - resizeToAvoidBottomInset: false, - backgroundColor: Colors.transparent, - body: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Expanded( - child: InkWell( - highlightColor: Colors.transparent, - splashColor: Colors.transparent, - splashFactory: NoSplashFactory(), - onTap: () { - FocusScope.of(context).unfocus(); - Get.back(); - }, + removeTop: true, + context: context, + child: GestureDetector( + onTap: Get.back, + child: LayoutBuilder( + builder: (_, constraints) { + bool isH = constraints.maxWidth > constraints.maxHeight; + late double padding = constraints.maxWidth * 0.12; + return Padding( + padding: EdgeInsets.symmetric(horizontal: isH ? padding : 0), + child: Scaffold( + resizeToAvoidBottomInset: false, + backgroundColor: Colors.transparent, + body: GestureDetector( + onTap: () {}, + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + _buildInputView(), + _buildImagePreview(), + _buildPanelContainer(), + ], + ), ), ), - _buildInputView(), - _buildImagePreview(), - _buildPanelContainer(), - ], - ), - )); + ); + }, + ), + ), + ); } Widget _buildPanelContainer() { @@ -160,7 +192,7 @@ class _ReplyPageState extends State } Widget _buildEmojiPickerPanel() { - double height = 200; + double height = 170; final keyboardHeight = _controller.keyboardHeight; if (keyboardHeight != 0) { height = max(height, keyboardHeight); @@ -213,6 +245,7 @@ class _ReplyPageState extends State Widget _buildInputView() { return Container( clipBehavior: Clip.hardEdge, + margin: EdgeInsets.only(top: MediaQuery.of(context).padding.top), decoration: BoxDecoration( borderRadius: const BorderRadius.only( topLeft: Radius.circular(12), diff --git a/pubspec.lock b/pubspec.lock index af548b34..d9425649 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -258,10 +258,11 @@ packages: chat_bottom_container: dependency: "direct main" description: - name: chat_bottom_container - sha256: fc2e690892699604524bf4a4c7ba9b3281ae060c90154b55b38116ce7812c3d8 - url: "https://pub.dev" - source: hosted + path: "packages/chat_bottom_container" + ref: main + resolved-ref: "5bd612a5ee2f0025460ec50090044209b3d43cb2" + url: "https://github.com/pye52/flutter_chat_packages.git" + source: git version: "0.2.0" checked_yaml: dependency: transitive diff --git a/pubspec.yaml b/pubspec.yaml index eebf457e..ecca6901 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -158,7 +158,12 @@ dependencies: marquee: ^2.2.3 #富文本 extended_text: ^14.0.1 - chat_bottom_container: ^0.2.0 + # chat_bottom_container: ^0.2.0 + chat_bottom_container: + git: + url: https://github.com/pye52/flutter_chat_packages.git + ref: main + path: packages/chat_bottom_container image_picker: ^1.1.2