import 'package:extended_text/extended_text.dart'; import 'package:extended_text_field/extended_text_field.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:aslan/app_localizations.dart'; import 'package:aslan/chatvibe_ui/components/at_debounce_widget.dart'; import 'package:provider/provider.dart'; import 'package:aslan/chatvibe_core/constants/at_emoji_datas.dart'; import 'package:aslan/chatvibe_core/constants/at_screen.dart'; import 'package:aslan/chatvibe_core/utilities/at_keybord_util.dart'; import 'package:aslan/main.dart'; import 'package:aslan/chatvibe_managers/dynamic_content_manager.dart'; import 'package:aslan/chatvibe_ui/widgets/dynamic/comment/comment_gift_page.dart'; ///聊天输入框 class CommentInput extends StatefulWidget { String? toUserName; String toUserId; String dynamicContentId; Function(String text)? callBack; Function()? deleteCallBack; Function(int count)? sendGiftCallBack; CommentInput( this.toUserId, this.dynamicContentId, { this.toUserName, this.callBack, this.deleteCallBack, this.sendGiftCallBack, }); @override _CommentInputState createState() => _CommentInputState(); } class _CommentInputState extends State with RouteAware { bool showSend = false; final FocusNode _focusNode = FocusNode(); TextEditingController controller = TextEditingController(); @override void initState() { super.initState(); restState(); _focusNode.addListener((){ if(_focusNode.hasFocus){ Provider.of(context, listen: false).updateShowEmojiState( false, () { setState(() {}); }, ); } }); HardwareKeyboard.instance.addHandler(_handleKeyEvent); } bool _handleKeyEvent(KeyEvent event) { // 检查是否是删除键 final isDeleteKey = event.logicalKey == LogicalKeyboardKey.backspace || event.logicalKey == LogicalKeyboardKey.delete; if (isDeleteKey) { if (event is KeyDownEvent) { // 删除键按下 if (controller.text.isEmpty) { widget.deleteCallBack?.call(); } } } // 返回 false 让其他部件也能处理这个事件 return false; } @override void didChangeDependencies() { super.didChangeDependencies(); // 注册路由观察 final route = ModalRoute.of(context); if (route is PageRoute) { routeObserver.subscribe(this, route); } } @override void didPopNext() { _focusNode.unfocus(); FocusScope.of(context).unfocus(); // 彻底取消当前上下文的所有焦点 } @override void dispose() { _focusNode.dispose(); routeObserver.unsubscribe(this); super.dispose(); } @override Widget build(BuildContext context) { return float(context); } Widget float(BuildContext context) { return Column( mainAxisSize: MainAxisSize.min, children: [_input(), _emoji(), _gift()], ); } _gift() { return Selector( selector: (c, p) => p.showGift, shouldRebuild: (prev, next) => prev != next, builder: (_, showGift, __) { return Visibility( visible: showGift, child: CommentGiftPage( widget.toUserId, widget.dynamicContentId, sendGiftCallBack: widget.sendGiftCallBack, ), ); }, ); } _emoji() { return Selector( selector: (c, p) => p.showEmoji, shouldRebuild: (prev, next) => prev != next, builder: (_, showEmoji, __) { return Visibility( visible: showEmoji, child: Container( color: Colors.white, height: 150.w, child: GridView.builder( padding: EdgeInsets.symmetric(horizontal: 15.w), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 8, crossAxisSpacing: 8.w, mainAxisSpacing: 8.w, ), itemBuilder: (c, index) { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { var text = ATEmojiDatas.smileys[index]; final TextEditingValue value = controller.value; controller.value = value.copyWith( text: value.text + text, selection: TextSelection.fromPosition( TextPosition(offset: text.length), ), ); showSend = true; setState(() {}); }, child: Padding( padding: EdgeInsets.all(4.0.w), child: ExtendedText( ATEmojiDatas.smileys[index], // specialTextSpanBuilder: MySpecialTextSpanBuilder(), style: TextStyle(fontSize: sp(15)), ), ), ); }, itemCount: ATEmojiDatas.smileys.length, ), ), ); }, ); } void restState() { Provider.of(context, listen: false).updateShowEmojiState( false, () { setState(() {}); }, ); Provider.of(context, listen: false).updateShowGiftState( false, () { setState(() {}); }, ); } _input() { return Selector( selector: (c, p) => p.showGift, shouldRebuild: (prev, next) => prev != next, builder: (_, showGift, __) { return Visibility( visible: !showGift, child: Container( decoration: BoxDecoration(color: Colors.white), padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 12.w), height: 56.w, child: Row( children: [ ATDebounceWidget( child: Image.asset( "atu_images/dynamic/at_icon_dynamic_emoji.png", height: 35.w, ), onTap: () { ATKeybordUtil.conceal(context); Provider.of( context, listen: false, ).updateShowEmojiState( !Provider.of( context, listen: false, ).showEmoji, () { setState(() {}); }, ); Provider.of( context, listen: false, ).updateShowGiftState(false, () { setState(() {}); }); }, ), SizedBox(width: 8.w), Expanded( child: Container( decoration: BoxDecoration( color: Color(0xff7726FF).withOpacity(0.1), borderRadius: BorderRadius.circular(height(5)), ), child: Row( children: [ Expanded( child: ExtendedTextField( focusNode: _focusNode, controller: controller, autofocus: false, onChanged: (s) { setState(() { showSend = controller.text.isNotEmpty; }); }, onSubmitted: (s) { if (s.isNotEmpty) { showSend = false; setState(() {}); controller.clear(); } }, decoration: InputDecoration( hintText: widget.toUserName == null || (widget.toUserName?.isEmpty ?? false) ? ATAppLocalizations.of( context, )!.saySomething : "${ATAppLocalizations.of(context)!.reply}@${widget.toUserName}", fillColor: Colors.transparent, hintStyle: TextStyle( color: Colors.grey, fontSize: sp(13), ), contentPadding: const EdgeInsets.symmetric( horizontal: 15, ), counterText: '', border: OutlineInputBorder( borderRadius: BorderRadius.circular(height(5)), borderSide: BorderSide.none, ), filled: true, ), style: TextStyle( fontSize: ScreenUtil().setSp(13), color: Colors.black.withOpacity(1), ), ), ), ATDebounceWidget( onTap: () { showSend = false; Provider.of( context, listen: false, ).updateShowEmojiState(false, () { setState(() {}); }); if (widget.dynamicContentId.isNotEmpty && controller.text.isNotEmpty) { widget.callBack?.call(controller.text); controller.text = ""; } }, child: Container( padding: EdgeInsets.all(4.w), width: 30.w, height: 30.w, child: Image.asset( showSend ? "atu_images/dynamic/at_icon_comment_input_message_send_en.png" : "atu_images/dynamic/at_icon_comment_input_message_send_no.png", ), ), ), SizedBox(width: 3.w), ], ), ), ), SizedBox(width: 8.w), widget.sendGiftCallBack != null ? ATDebounceWidget( child: Image.asset( "atu_images/dynamic/at_icon_dynamic_comment_gift.png", height: 35.w, ), onTap: () { Provider.of( context, listen: false, ).updateShowGiftState( !Provider.of( context, listen: false, ).showGift, () { setState(() {}); }, ); Provider.of( context, listen: false, ).updateShowEmojiState(false, () { setState(() {}); }); }, ) : Container(), ], ), ), ); }, ); } }