From d62b3db985dc5ec25b900a9d64bb48a95a419e0a Mon Sep 17 00:00:00 2001 From: dab246 Date: Thu, 18 Dec 2025 16:33:32 +0700 Subject: [PATCH] feat(ai-scribe): Add `Enter` to send prompt directly and `Shift + Enter` to add new line --- .../widgets/search/ai_scribe_bar.dart | 44 +++++++++++++------ 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/scribe/lib/scribe/ai/presentation/widgets/search/ai_scribe_bar.dart b/scribe/lib/scribe/ai/presentation/widgets/search/ai_scribe_bar.dart index 0bab182f7..eec55b5c4 100644 --- a/scribe/lib/scribe/ai/presentation/widgets/search/ai_scribe_bar.dart +++ b/scribe/lib/scribe/ai/presentation/widgets/search/ai_scribe_bar.dart @@ -1,6 +1,7 @@ import 'package:core/presentation/resources/image_paths.dart'; import 'package:core/presentation/views/button/tmail_button_widget.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:scribe/scribe.dart'; typedef OnCustomPromptCallback = void Function(String customPrompt); @@ -22,6 +23,7 @@ class AIScribeBar extends StatefulWidget { class _AIScribeBarState extends State { final TextEditingController _controller = TextEditingController(); final ValueNotifier _isButtonEnabled = ValueNotifier(false); + final FocusNode _focusNode = FocusNode(); @override void initState() { @@ -34,6 +36,7 @@ class _AIScribeBarState extends State { _controller.removeListener(_onTextChanged); _controller.dispose(); _isButtonEnabled.dispose(); + _focusNode.dispose(); super.dispose(); } @@ -68,20 +71,23 @@ class _AIScribeBarState extends State { child: Row( children: [ Expanded( - child: TextField( - controller: _controller, - decoration: InputDecoration( - hintText: ScribeLocalizations.of(context).inputPlaceholder, - hintStyle: AIScribeTextStyles.searchBarHint, - border: InputBorder.none, - contentPadding: const EdgeInsets.symmetric(vertical: 8), - isDense: true, + child: KeyboardListener( + focusNode: _focusNode, + onKeyEvent: _handleKeyboardEvent, + child: TextField( + controller: _controller, + decoration: InputDecoration( + hintText: ScribeLocalizations.of(context).inputPlaceholder, + hintStyle: AIScribeTextStyles.searchBarHint, + border: InputBorder.none, + contentPadding: const EdgeInsets.symmetric(vertical: 8), + isDense: true, + ), + style: AIScribeTextStyles.searchBar, + maxLines: null, + keyboardType: TextInputType.multiline, + cursorHeight: 16, ), - style: AIScribeTextStyles.searchBar, - maxLines: null, - keyboardType: TextInputType.multiline, - cursorHeight: 16, - onSubmitted: (_) => _onSendPressed(), ), ), const SizedBox(width: AIScribeSizes.fieldSpacing), @@ -104,4 +110,16 @@ class _AIScribeBarState extends State { ), ); } + + void _handleKeyboardEvent(KeyEvent event) { + if (event is KeyDownEvent && event.logicalKey == LogicalKeyboardKey.enter) { + final keys = HardwareKeyboard.instance.logicalKeysPressed; + final isShiftPressed = keys.contains(LogicalKeyboardKey.shiftLeft) || + keys.contains(LogicalKeyboardKey.shiftRight); + + if (!isShiftPressed) { + _onSendPressed(); + } + } + } }