Skip to content

Commit 306a2f4

Browse files
committed
Merge branch 'main' of github.com:serverpod/starguide
2 parents 99042da + 8d5ae09 commit 306a2f4

1 file changed

Lines changed: 75 additions & 49 deletions

File tree

Lines changed: 75 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'package:flutter/material.dart';
2+
import 'package:flutter/services.dart';
23
import 'package:lucide_icons_flutter/lucide_icons.dart';
34
import 'package:starguide_flutter/config/constants.dart';
45

@@ -32,23 +33,28 @@ class _StarguideChatInputState extends State<StarguideChatInput> {
3233
final String hintText;
3334

3435
if (widget.numChatRequests >= kMaxChatRequests) {
35-
hintText = 'Clear the chat to start a new conversation.';
36+
hintText = 'Clear the chat to start aR new conversation.';
3637
} else if (widget.numChatRequests == 0) {
3738
hintText = 'Ask me anything about Serverpod...';
3839
} else {
3940
hintText = 'Ask a follow-up question...';
4041
}
4142

4243
return Container(
43-
padding:
44-
const EdgeInsets.only(left: 12.0, right: 8.0, top: 8.0, bottom: 8.0),
45-
child: Column(
44+
padding: const EdgeInsets.only(
45+
left: 12.0,
46+
right: 8.0,
47+
),
48+
child: Row(
49+
crossAxisAlignment: CrossAxisAlignment.end,
4650
children: [
47-
Row(
48-
children: [
49-
Expanded(
51+
Expanded(
52+
child: KeyboardListener(
53+
focusNode: widget.focusNode,
54+
onKeyEvent: (event) => _handleKeyboardEvents(event),
55+
child: Container(
56+
constraints: BoxConstraints(maxHeight: 400.0),
5057
child: TextField(
51-
focusNode: widget.focusNode,
5258
autofocus: true,
5359
enabled: widget.numChatRequests < kMaxChatRequests,
5460
buildCounter: (
@@ -60,56 +66,76 @@ class _StarguideChatInputState extends State<StarguideChatInput> {
6066
return const SizedBox();
6167
},
6268
maxLength: kMaxChatRequestLength,
63-
maxLines: 1,
64-
decoration: InputDecoration.collapsed(
69+
maxLines: null,
70+
minLines: 1,
71+
keyboardType: TextInputType.multiline,
72+
textInputAction: TextInputAction.newline,
73+
textAlignVertical: TextAlignVertical.top,
74+
decoration: InputDecoration(
6575
hintText: hintText,
6676
hintStyle: TextStyle(color: theme.disabledColor),
77+
border: InputBorder.none,
6778
),
6879
controller: widget.textController,
69-
onSubmitted: (value) {
70-
widget.onSend(widget.textController.text);
71-
widget.textController.clear();
72-
widget.focusNode.requestFocus();
73-
},
7480
),
7581
),
76-
if (widget.isGeneratingResponse)
77-
Container(
78-
padding: const EdgeInsets.all(10),
79-
width: 40,
80-
height: 40,
81-
child: CircularProgressIndicator(
82-
color: theme.colorScheme.primary,
83-
),
84-
)
85-
else
86-
TextButton(
87-
style: TextButton.styleFrom(
88-
backgroundColor: widget.focusNode.hasFocus
89-
? theme.colorScheme.primary
90-
: theme.dividerColor,
91-
shape: RoundedRectangleBorder(
92-
borderRadius: BorderRadius.circular(4),
82+
),
83+
),
84+
Padding(
85+
padding: const EdgeInsets.symmetric(vertical: 8),
86+
child: Column(
87+
children: [
88+
if (widget.isGeneratingResponse)
89+
Container(
90+
padding: const EdgeInsets.all(10),
91+
width: 40,
92+
height: 40,
93+
child: CircularProgressIndicator(
94+
color: theme.colorScheme.primary,
95+
),
96+
)
97+
else
98+
TextButton(
99+
style: TextButton.styleFrom(
100+
backgroundColor: widget.focusNode.hasFocus
101+
? theme.colorScheme.primary
102+
: theme.dividerColor,
103+
shape: RoundedRectangleBorder(
104+
borderRadius: BorderRadius.circular(4),
105+
),
106+
padding: const EdgeInsets.all(4),
107+
minimumSize: const Size(48, 48),
108+
),
109+
onPressed: widget.enabled ? _handleSubmit : null,
110+
child: const Icon(
111+
LucideIcons.rocket300,
112+
size: 20,
113+
color: Colors.white,
93114
),
94-
padding: const EdgeInsets.all(4),
95-
minimumSize: const Size(48, 48),
96-
),
97-
onPressed: widget.enabled
98-
? () {
99-
widget.onSend(widget.textController.text);
100-
widget.textController.clear();
101-
}
102-
: null,
103-
child: const Icon(
104-
LucideIcons.rocket300,
105-
size: 20,
106-
color: Colors.white,
107115
),
108-
),
109-
],
110-
),
116+
],
117+
),
118+
)
111119
],
112120
),
113121
);
114122
}
115-
}
123+
124+
void _handleKeyboardEvents(KeyEvent event) {
125+
if (event is KeyDownEvent) {
126+
final isEnterPressed = event.logicalKey == LogicalKeyboardKey.enter;
127+
final isShiftPressed = HardwareKeyboard.instance.isShiftPressed;
128+
129+
if (isEnterPressed && !isShiftPressed && widget.enabled) {
130+
_handleSubmit();
131+
}
132+
}
133+
}
134+
135+
void _handleSubmit() {
136+
if (widget.textController.text.trim().isNotEmpty) {
137+
widget.onSend(widget.textController.text);
138+
widget.textController.clear();
139+
}
140+
}
141+
}

0 commit comments

Comments
 (0)