@@ -13,7 +13,13 @@ import {
1313 useImagePreview ,
1414} from '@open-webui-react-native/mobile/shared/features/image-preview-modal' ;
1515import { AppTextInput , AppInputProps , View , IconButton } from '@open-webui-react-native/mobile/shared/ui/ui-kit' ;
16- import { appConfigurationApi , ChatGenerationOption } from '@open-webui-react-native/shared/data-access/api' ;
16+ import {
17+ appConfigurationApi ,
18+ ChatGenerationOption ,
19+ ChatResponse ,
20+ tasksApi ,
21+ tasksService ,
22+ } from '@open-webui-react-native/shared/data-access/api' ;
1723import { AttachedImage , FileData , ImageData } from '@open-webui-react-native/shared/data-access/common' ;
1824import { withOfflineGuard } from '@open-webui-react-native/shared/features/network' ;
1925import { FeatureID , isFeatureEnabled } from '@open-webui-react-native/shared/utils/feature-flag' ;
@@ -31,11 +37,12 @@ interface FormChatInputProps<T extends FieldValues> extends AppInputProps {
3137 attachedImages : Observable < Array < ImageData > > ;
3238 onImageUploaded : ( image : ImageData ) => void ;
3339 onDeleteImagePress : ( fileName : string ) => void ;
34- chatId ?: string ;
40+ chat ?: ChatResponse ;
3541 modelId ?: string ;
3642 onChatCreated ?: ( id : string ) => void ;
3743 isLoading ?: boolean ;
3844 isSuggestionShown ?: boolean ;
45+ isResponseGenerating ?: boolean ;
3946}
4047
4148export interface FormChatInputSchema {
@@ -52,16 +59,18 @@ export function FormChatInput<T extends FieldValues>({
5259 attachedImages,
5360 onImageUploaded,
5461 onDeleteImagePress,
55- chatId ,
62+ chat ,
5663 modelId,
5764 onChatCreated,
5865 isLoading,
5966 isSuggestionShown,
67+ isResponseGenerating,
6068 ...restProps
6169} : FormChatInputProps < T > ) : ReactElement {
6270 const translate = useTranslation ( 'CHAT.FORM_CHAT_INPUT' ) ;
6371
6472 const { data : config } = appConfigurationApi . useGetAppConfiguration ( ) ;
73+ const stopTaskMutation = tasksApi . useStopTask ( ) ;
6574
6675 const { field } = useController ( { control, name } ) ;
6776
@@ -88,7 +97,7 @@ export function FormChatInput<T extends FieldValues>({
8897 return ToastService . showError ( translate ( 'TEXT_MODEL_NOT_SELECTED' ) ) ;
8998 }
9099 setIsMicrophonePreparing ( true ) ;
91- await openVoiceModeModal ( { chatId, modelId } ) ;
100+ await openVoiceModeModal ( { chatId : chat ?. id , modelId } ) ;
92101 setIsMicrophonePreparing ( false ) ;
93102 } ;
94103
@@ -110,6 +119,20 @@ export function FormChatInput<T extends FieldValues>({
110119 field . onChange ( text ) ;
111120 } ;
112121
122+ const onStopGenerationPress = async ( ) : Promise < void > => {
123+ if ( ! chat ) return ;
124+
125+ const chatId = chat . id ;
126+ const lastMessageId = chat . chat . history . currentId ;
127+
128+ const tasksData = await tasksService . getChatTasks ( chatId ) ;
129+ const taskId = tasksData ?. tasksIds [ 0 ] ;
130+
131+ if ( taskId ) {
132+ stopTaskMutation . mutate ( { taskId, chatId, lastMessageId } ) ;
133+ }
134+ } ;
135+
113136 return (
114137 < View >
115138 { isDictateMode ? (
@@ -144,6 +167,8 @@ export function FormChatInput<T extends FieldValues>({
144167 isSubmitDisabled = { ! isFeatureEnabled ( FeatureID . VOICE_MODE ) && isInputEmpty }
145168 onVoiceModePress = { onVoiceModePress }
146169 isVoiceModeAvailable = { isFeatureEnabled ( FeatureID . VOICE_MODE ) && isInputEmpty }
170+ onStopGenerationPress = { onStopGenerationPress }
171+ isResponseGenerating = { isResponseGenerating }
147172 isLoading = { isLoading || isMicrophonePreparing } >
148173 < View className = 'flex-row flex-1 justify-between' >
149174 < View className = 'gap-16 flex-row ' >
0 commit comments