@@ -15,6 +15,7 @@ import { BlueButton, GrayButton, OutlineButtonBlack } from './general/Buttons'
15
15
import { useIsEmbedded } from '../../contexts/EmbeddedContext'
16
16
import useCurrentUser from '../../hooks/useCurrentUser'
17
17
import { SendPreferenceConfiguratorModal , ShiftEnterForNewline , ShiftEnterToSend } from './SendPreferenceConfigurator'
18
+ import { KeyCombinations , useKeyboardCommands } from './useKeyboardCommands'
18
19
19
20
export const ChatBox = ( {
20
21
disabled,
@@ -36,6 +37,7 @@ export const ChatBox = ({
36
37
handleContinue,
37
38
handleSubmit,
38
39
handleReset,
40
+ isMobile,
39
41
} : {
40
42
disabled : boolean
41
43
currentModel : string
@@ -56,6 +58,7 @@ export const ChatBox = ({
56
58
handleContinue : ( message : string ) => void
57
59
handleSubmit : ( message : string ) => void
58
60
handleReset : ( ) => void
61
+ isMobile : boolean
59
62
} ) => {
60
63
const { courseId } = useParams ( )
61
64
const isEmbedded = useIsEmbedded ( )
@@ -67,14 +70,23 @@ export const ChatBox = ({
67
70
const [ fileTypeAlertOpen , setFileTypeAlertOpen ] = useState < boolean > ( false )
68
71
const [ sendPreferenceConfiguratorOpen , setSendPreferenceConfiguratorOpen ] = useState < boolean > ( false )
69
72
const sendButtonRef = useRef < HTMLButtonElement > ( null )
70
-
71
73
const textFieldRef = useRef < HTMLInputElement > ( null )
72
74
const [ message , setMessage ] = useState < string > ( '' )
73
75
74
76
const acuallyDisabled = disabled || message . length === 0
75
77
76
78
const { t } = useTranslation ( )
77
79
80
+ const [ isModelSelectorOpen , setIsModelSelectorOpen ] = useState < boolean > ( false )
81
+ useKeyboardCommands ( {
82
+ resetChat : handleReset ,
83
+ openModelSelector : ( ) => {
84
+ setIsModelSelectorOpen ( true )
85
+ } ,
86
+ } ) // @todo what key combination to open model selector
87
+
88
+ const isShiftEnterSend = user ?. preferences ?. sendShortcutMode === 'shift+enter' || ! user ?. preferences ?. sendShortcutMode
89
+
78
90
const handleDeleteFile = ( ) => {
79
91
if ( fileInputRef . current ) {
80
92
fileInputRef . current . value = ''
@@ -166,7 +178,7 @@ export const ChatBox = ({
166
178
onSubmit = { onSubmit }
167
179
onKeyDown = { ( e ) => {
168
180
if ( e . key === 'Enter' ) {
169
- if ( user ?. preferences ?. sendShortcutMode === 'enter' ) {
181
+ if ( ! isShiftEnterSend ) {
170
182
if ( e . shiftKey ) {
171
183
// Do nothing with this event, it will result in a newline being inserted
172
184
} else {
@@ -225,18 +237,30 @@ export const ChatBox = ({
225
237
/>
226
238
</ IconButton >
227
239
</ Tooltip >
228
- < Tooltip title = { t ( 'chat:emptyConversation' ) } arrow placement = "top" >
240
+ < Tooltip title = { t ( 'chat:emptyConversationTooltip' , { hint : KeyCombinations . RESET_CHAT ?. hint } ) } arrow placement = "top" >
229
241
< IconButton onClick = { handleReset } >
230
242
< RestartAltIcon />
231
243
</ IconButton >
232
244
</ Tooltip >
233
245
{ fileName && < Chip sx = { { borderRadius : 100 } } label = { fileName } onDelete = { handleDeleteFile } /> }
234
246
{ ! isEmbedded && (
235
- < ModelSelector currentModel = { currentModel } setModel = { setModel } availableModels = { availableModels } isTokenLimitExceeded = { isTokenLimitExceeded } />
247
+ < ModelSelector
248
+ currentModel = { currentModel }
249
+ setModel = { setModel }
250
+ availableModels = { availableModels }
251
+ isTokenLimitExceeded = { isTokenLimitExceeded }
252
+ isOpen = { isModelSelectorOpen }
253
+ setIsOpen = { ( open ) => {
254
+ setIsModelSelectorOpen ( open )
255
+ if ( ! open ) {
256
+ setTimeout ( ( ) => textFieldRef . current ?. focus ( ) , 0 ) // setTimeout required here...
257
+ }
258
+ } }
259
+ />
236
260
) }
237
261
</ Box >
238
262
239
- < Tooltip title = { disabled ? t ( 'chat:cancelResponse' ) : t ( 'chat:shiftEnter ' ) } arrow placement = "top" >
263
+ < Tooltip title = { disabled ? t ( 'chat:cancelResponse' ) : isShiftEnterSend ? t ( 'chat:shiftEnterSend' ) : t ( 'chat:enterSend ') } arrow placement = "top" >
240
264
< IconButton type = { disabled ? 'button' : 'submit' } ref = { sendButtonRef } >
241
265
{ disabled ? < StopIcon /> : < Send /> }
242
266
</ IconButton >
@@ -271,19 +295,21 @@ export const ChatBox = ({
271
295
</ Tooltip >
272
296
</ Box >
273
297
274
- < Typography
275
- sx = { {
276
- display : { sm : 'none' , md : 'block' } ,
277
- ml : 'auto' ,
278
- opacity : acuallyDisabled ? 0 : 1 ,
279
- transition : 'opacity 0.2s ease-in-out' ,
280
- fontSize : '14px' ,
281
- } }
282
- variant = "body1"
283
- color = "textSecondary"
284
- >
285
- { user ?. preferences ?. sendShortcutMode === 'enter' ? < ShiftEnterForNewline t = { t } /> : < ShiftEnterToSend t = { t } /> }
286
- </ Typography >
298
+ { ! isMobile && (
299
+ < Typography
300
+ sx = { {
301
+ display : { sm : 'none' , md : 'block' } ,
302
+ ml : 'auto' ,
303
+ opacity : acuallyDisabled ? 0 : 1 ,
304
+ transition : 'opacity 0.2s ease-in-out' ,
305
+ fontSize : '14px' ,
306
+ } }
307
+ variant = "body1"
308
+ color = "textSecondary"
309
+ >
310
+ { isShiftEnterSend ? < ShiftEnterToSend t = { t } /> : < ShiftEnterForNewline t = { t } /> }
311
+ </ Typography >
312
+ ) }
287
313
288
314
{ ! isEmbedded && (
289
315
< Tooltip
0 commit comments