From e0edb3d7aa27cc4b7872e80ca2b6408166e2cbe8 Mon Sep 17 00:00:00 2001 From: Divyanshu patil Date: Sun, 14 Dec 2025 18:35:29 +0530 Subject: [PATCH 01/15] wip: android image pasting --- .../components/ComposerInput.tsx | 112 +++++++++++++----- package.json | 1 + yarn.lock | 5 + 3 files changed, 88 insertions(+), 30 deletions(-) diff --git a/app/containers/MessageComposer/components/ComposerInput.tsx b/app/containers/MessageComposer/components/ComposerInput.tsx index 178ca3b58b1..b67a3352e25 100644 --- a/app/containers/MessageComposer/components/ComposerInput.tsx +++ b/app/containers/MessageComposer/components/ComposerInput.tsx @@ -1,8 +1,9 @@ import React, { forwardRef, memo, useCallback, useEffect, useImperativeHandle } from 'react'; -import { TextInput, StyleSheet, type TextInputProps, InteractionManager } from 'react-native'; +import { TextInput, Platform, StyleSheet, type TextInputProps, InteractionManager } from 'react-native'; import { useDebouncedCallback } from 'use-debounce'; import { useDispatch } from 'react-redux'; import { type RouteProp, useFocusEffect, useRoute } from '@react-navigation/native'; +import { type OnChangeSelectionEvent, TypeRichTextInput } from 'react-native-typerich'; import { textInputDebounceTime } from '../../../lib/constants/debounceConfig'; import I18n from '../../../i18n'; @@ -68,6 +69,9 @@ export const ComposerInput = memo( const usedCannedResponse = route.params?.usedCannedResponse; const prevAction = usePrevious(action); + const isAndroid = Platform.OS === 'android'; + // const isAndroid = true; + // subscribe to changes on mic state to update draft after a message is sent useMicOrSend(); const { saveMessageDraft } = useAutoSaveDraft(textRef.current); @@ -157,7 +161,7 @@ export const ComposerInput = memo( useImperativeHandle(ref, () => ({ getTextAndClear: () => { const text = textRef.current; - setInput('', undefined, true); + setInput(''); return text; }, getText: () => textRef.current, @@ -175,7 +179,11 @@ export const ComposerInput = memo( saveMessageDraft(''); } - inputRef.current?.setNativeProps?.({ text }); + if (isAndroid) { + inputRef.current?.setValue(text); + } else { + inputRef.current?.setNativeProps?.({ text }); // keep TextInput path + } if (selection) { // setSelection won't trigger onSelectionChange, so we need it to be ran after new text is set @@ -198,6 +206,7 @@ export const ComposerInput = memo( const onChangeText: TextInputProps['onChangeText'] = text => { textRef.current = text; debouncedOnChangeText(text); + console.log(text); setInput(text); }; @@ -205,20 +214,35 @@ export const ComposerInput = memo( selectionRef.current = e.nativeEvent.selection; }; - const onFocus: TextInputProps['onFocus'] = () => { - setFocused(true); + const onChangeSelection = (e: OnChangeSelectionEvent) => { + const { start, end } = e; + const selection = { start, end }; + console.log('selection========', e); + selectionRef.current = selection; + console.log('sel', selection); }; - const onTouchStart: TextInputProps['onTouchStart'] = () => { + const handleFocus = () => { setFocused(true); }; - const onBlur: TextInputProps['onBlur'] = () => { + const handleBlur = () => { if (!iOSBackSwipe.current) { setFocused(false); stopAutocomplete(); } }; + const onFocus: TextInputProps['onFocus'] = () => { + handleFocus(); + }; + + const onTouchStart: TextInputProps['onTouchStart'] = () => { + setFocused(true); + }; + + const onBlur: TextInputProps['onBlur'] = () => { + handleBlur(); + }; const onAutocompleteItemSelected: IAutocompleteItemProps['onPress'] = async item => { if (item.type === 'loading') { @@ -365,27 +389,55 @@ export const ComposerInput = memo( }; return ( - { - inputRef.current = component; - }} - blurOnSubmit={false} - onChangeText={onChangeText} - onTouchStart={onTouchStart} - onSelectionChange={onSelectionChange} - onFocus={onFocus} - onBlur={onBlur} - underlineColorAndroid='transparent' - defaultValue='' - multiline - {...(autocompleteType ? { autoComplete: 'off', autoCorrect: false, autoCapitalize: 'none' } : {})} - keyboardAppearance={theme === 'light' ? 'light' : 'dark'} - // eslint-disable-next-line no-nested-ternary - testID={`message-composer-input${tmid ? '-thread' : sharing ? '-share' : ''}`} - /> + <> + {isAndroid ? ( + { + inputRef.current = component; + }} + // blurOnSubmit={false} // not needed + onChangeText={onChangeText} + onTouchStart={onTouchStart} + onChangeSelection={onChangeSelection} + onFocus={handleFocus} + onBlur={handleBlur} + // underlineColorAndroid='transparent' // by default behaiviour + defaultValue='' + multiline + {...(autocompleteType ? { autoComplete: 'off', autoCorrect: false, autoCapitalize: 'none' } : {})} + keyboardAppearance={theme === 'light' ? 'light' : 'dark'} + // eslint-disable-next-line no-nested-ternary + testID={`message-composer-input${tmid ? '-thread' : sharing ? '-share' : ''}`} + onPasteImageData={e => console.log(e)} + /> + ) : ( + { + inputRef.current = component; + }} + blurOnSubmit={false} + onChangeText={onChangeText} + onTouchStart={onTouchStart} + onSelectionChange={onSelectionChange} + onFocus={onFocus} + onBlur={onBlur} + underlineColorAndroid='transparent' + defaultValue='' + multiline + {...(autocompleteType ? { autoCompdete: 'off', autoCorrect: false, autoCapitalize: 'none' } : {})} + keyboardAppearance={theme === 'light' ? 'light' : 'dark'} + // eslint-disable-next-line no-nested-ternary + testID={`message-composer-input${tmid ? '-thread' : sharing ? '-share' : ''}`} + /> + )} + ); }) ); @@ -397,9 +449,9 @@ const styles = StyleSheet.create({ maxHeight: MAX_HEIGHT, paddingTop: 12, paddingBottom: 12, - fontSize: 16, textAlignVertical: 'center', ...sharedStyles.textRegular, - lineHeight: 22 + lineHeight: 22, + fontSize: 16 } }); diff --git a/package.json b/package.json index 18036f1628e..5f38637b112 100644 --- a/package.json +++ b/package.json @@ -121,6 +121,7 @@ "react-native-skeleton-placeholder": "5.2.4", "react-native-slowlog": "1.0.2", "react-native-svg": "^15.12.1", + "react-native-typerich": "^0.1.7", "react-native-url-polyfill": "2.0.0", "react-native-webview": "^13.15.0", "react-redux": "8.0.5", diff --git a/yarn.lock b/yarn.lock index 42818383dc4..264dbe81177 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12658,6 +12658,11 @@ react-native-svg@^15.12.1: css-tree "^1.1.3" warn-once "0.1.1" +react-native-typerich@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/react-native-typerich/-/react-native-typerich-0.1.7.tgz#2570e79b5d9b0643513faf4fdc8283bcb0cdfc2c" + integrity sha512-bzrBPOkcURETXMLxYAV+Z9idFFiqV9QATHiR+8YGkkdZTYWEkwZJsUCPdFY0JYwY3vhu92cBE+I5M/dE9t7JsA== + react-native-url-polyfill@2.0.0, react-native-url-polyfill@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/react-native-url-polyfill/-/react-native-url-polyfill-2.0.0.tgz#db714520a2985cff1d50ab2e66279b9f91ffd589" From 3c27dd2831c050672653d4a1c9a9339e384ea640 Mon Sep 17 00:00:00 2001 From: Divyanshu patil Date: Sun, 14 Dec 2025 20:26:20 +0530 Subject: [PATCH 02/15] fix: keep spacing while setting input and trim while sending --- app/containers/MessageComposer/MessageComposer.tsx | 2 +- app/containers/MessageComposer/components/ComposerInput.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/containers/MessageComposer/MessageComposer.tsx b/app/containers/MessageComposer/MessageComposer.tsx index 0c39eea5946..8d96c6b342d 100644 --- a/app/containers/MessageComposer/MessageComposer.tsx +++ b/app/containers/MessageComposer/MessageComposer.tsx @@ -91,7 +91,7 @@ export const MessageComposer = ({ return; } - const textFromInput = composerInputComponentRef.current.getTextAndClear(); + const textFromInput = composerInputComponentRef.current.getTextAndClear().trim(); if (action === 'edit') { return editRequest?.({ id: selectedMessages[0], msg: textFromInput, rid }); diff --git a/app/containers/MessageComposer/components/ComposerInput.tsx b/app/containers/MessageComposer/components/ComposerInput.tsx index b67a3352e25..04fcf644d55 100644 --- a/app/containers/MessageComposer/components/ComposerInput.tsx +++ b/app/containers/MessageComposer/components/ComposerInput.tsx @@ -172,7 +172,7 @@ export const ComposerInput = memo( })); const setInput: TSetInput = (text, selection, forceUpdateDraftMessage) => { - const message = text.trim(); + const message = text; textRef.current = message; if (forceUpdateDraftMessage) { From 88b87f347c8726a2d9e42a0b6623af1eb6273958 Mon Sep 17 00:00:00 2001 From: Divyanshu patil Date: Sun, 14 Dec 2025 22:28:24 +0530 Subject: [PATCH 03/15] fix: message modal opening and user fast typing cursor jumps --- app/containers/MessageComposer/MessageComposer.tsx | 9 ++++++--- .../MessageComposer/components/ComposerInput.tsx | 8 ++++---- package.json | 2 +- yarn.lock | 8 ++++---- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/app/containers/MessageComposer/MessageComposer.tsx b/app/containers/MessageComposer/MessageComposer.tsx index 8d96c6b342d..a71c8f7116e 100644 --- a/app/containers/MessageComposer/MessageComposer.tsx +++ b/app/containers/MessageComposer/MessageComposer.tsx @@ -33,7 +33,7 @@ export const MessageComposer = ({ }): ReactElement | null => { 'use memo'; - const composerInputRef = useRef(null); + const composerInputRef = useRef(null); const composerInputComponentRef = useRef({ getTextAndClear: () => '', getText: () => '', @@ -91,7 +91,7 @@ export const MessageComposer = ({ return; } - const textFromInput = composerInputComponentRef.current.getTextAndClear().trim(); + const textFromInput = composerInputComponentRef.current.getTextAndClear(); if (action === 'edit') { return editRequest?.({ id: selectedMessages[0], msg: textFromInput, rid }); @@ -170,7 +170,10 @@ export const MessageComposer = ({ }; const accessibilityFocusOnInput = () => { - const node = findNodeHandle(composerInputRef.current); + const input = composerInputRef.current; + + const hostRef = input?.getNativeRef?.() ?? input; + const node = findNodeHandle(hostRef); if (node) { AccessibilityInfo.setAccessibilityFocus(node); } diff --git a/app/containers/MessageComposer/components/ComposerInput.tsx b/app/containers/MessageComposer/components/ComposerInput.tsx index 04fcf644d55..3b535d0f3ff 100644 --- a/app/containers/MessageComposer/components/ComposerInput.tsx +++ b/app/containers/MessageComposer/components/ComposerInput.tsx @@ -70,7 +70,7 @@ export const ComposerInput = memo( const prevAction = usePrevious(action); const isAndroid = Platform.OS === 'android'; - // const isAndroid = true; + // const isAndroid = false; // subscribe to changes on mic state to update draft after a message is sent useMicOrSend(); @@ -172,7 +172,7 @@ export const ComposerInput = memo( })); const setInput: TSetInput = (text, selection, forceUpdateDraftMessage) => { - const message = text; + const message = text.trim(); textRef.current = message; if (forceUpdateDraftMessage) { @@ -207,7 +207,7 @@ export const ComposerInput = memo( textRef.current = text; debouncedOnChangeText(text); console.log(text); - setInput(text); + setInput(text, undefined, true); }; const onSelectionChange: TextInputProps['onSelectionChange'] = e => { @@ -394,7 +394,7 @@ export const ComposerInput = memo( { inputRef.current = component; diff --git a/package.json b/package.json index 5f38637b112..57a40291b16 100644 --- a/package.json +++ b/package.json @@ -121,7 +121,7 @@ "react-native-skeleton-placeholder": "5.2.4", "react-native-slowlog": "1.0.2", "react-native-svg": "^15.12.1", - "react-native-typerich": "^0.1.7", + "react-native-typerich": "^0.1.9", "react-native-url-polyfill": "2.0.0", "react-native-webview": "^13.15.0", "react-redux": "8.0.5", diff --git a/yarn.lock b/yarn.lock index 264dbe81177..7db0c949d79 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12658,10 +12658,10 @@ react-native-svg@^15.12.1: css-tree "^1.1.3" warn-once "0.1.1" -react-native-typerich@^0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/react-native-typerich/-/react-native-typerich-0.1.7.tgz#2570e79b5d9b0643513faf4fdc8283bcb0cdfc2c" - integrity sha512-bzrBPOkcURETXMLxYAV+Z9idFFiqV9QATHiR+8YGkkdZTYWEkwZJsUCPdFY0JYwY3vhu92cBE+I5M/dE9t7JsA== +react-native-typerich@^0.1.9: + version "0.1.9" + resolved "https://registry.yarnpkg.com/react-native-typerich/-/react-native-typerich-0.1.9.tgz#6a533ec53f20786ea2e520f6ca88c5ebdd8bc1d3" + integrity sha512-F/8/Rf5yRFF05JIpwxGvfFL4BwSUmIPYtXsII14iBo2/jsyj7JPWJiPI7bP74BRXcTrDDXXDH7Zs+aD4kogC2Q== react-native-url-polyfill@2.0.0, react-native-url-polyfill@^2.0.0: version "2.0.0" From 3a66e6a78f0771b63ffda425f16a566483888e33 Mon Sep 17 00:00:00 2001 From: Divyanshu patil Date: Mon, 15 Dec 2025 00:05:34 +0530 Subject: [PATCH 04/15] feat: image pasting with ShareView --- .../components/ComposerInput.tsx | 71 +++++++++++++++++-- 1 file changed, 67 insertions(+), 4 deletions(-) diff --git a/app/containers/MessageComposer/components/ComposerInput.tsx b/app/containers/MessageComposer/components/ComposerInput.tsx index 3b535d0f3ff..07ab2b88ef9 100644 --- a/app/containers/MessageComposer/components/ComposerInput.tsx +++ b/app/containers/MessageComposer/components/ComposerInput.tsx @@ -1,10 +1,11 @@ import React, { forwardRef, memo, useCallback, useEffect, useImperativeHandle } from 'react'; -import { TextInput, Platform, StyleSheet, type TextInputProps, InteractionManager } from 'react-native'; +import { TextInput, Platform, StyleSheet, type TextInputProps, InteractionManager, Alert } from 'react-native'; import { useDebouncedCallback } from 'use-debounce'; import { useDispatch } from 'react-redux'; import { type RouteProp, useFocusEffect, useRoute } from '@react-navigation/native'; -import { type OnChangeSelectionEvent, TypeRichTextInput } from 'react-native-typerich'; +import { type OnChangeSelectionEvent, type onPasteImageEventData, TypeRichTextInput } from 'react-native-typerich'; +import { canUploadFile } from '../../../lib/methods/helpers'; import { textInputDebounceTime } from '../../../lib/constants/debounceConfig'; import I18n from '../../../i18n'; import { @@ -16,7 +17,7 @@ import { } from '../interfaces'; import { useAutocompleteParams, useFocused, useMessageComposerApi, useMicOrSend } from '../context'; import { fetchIsAllOrHere, getMentionRegexp } from '../helpers'; -import { useAutoSaveDraft } from '../hooks'; +import { useAutoSaveDraft, useCanUploadFile } from '../hooks'; import sharedStyles from '../../../views/Styles'; import { useTheme } from '../../../theme'; import { userTyping } from '../../../actions/room'; @@ -43,6 +44,8 @@ import { usePrevious } from '../../../lib/hooks/usePrevious'; import { type ChatsStackParamList } from '../../../stacks/types'; import { loadDraftMessage } from '../../../lib/methods/draftMessage'; import useIOSBackSwipeHandler from '../hooks/useIOSBackSwipeHandler'; +import { getSubscriptionByRoomId } from '../../../lib/database/services/Subscription'; +import { getThreadById } from '../../../lib/database/services/Thread'; const defaultSelection: IInputSelection = { start: 0, end: 0 }; @@ -69,6 +72,11 @@ export const ComposerInput = memo( const usedCannedResponse = route.params?.usedCannedResponse; const prevAction = usePrevious(action); + const permissionToUpload = useCanUploadFile(rid); + const { FileUpload_MediaTypeWhiteList, FileUpload_MaxFileSize } = useAppSelector(state => state.settings); + const allowList = FileUpload_MediaTypeWhiteList as string; + const maxFileSize = FileUpload_MaxFileSize as number; + const isAndroid = Platform.OS === 'android'; // const isAndroid = false; @@ -388,6 +396,59 @@ export const ComposerInput = memo( dispatch(userTyping(rid, isTyping)); }; + const startShareView = () => ({ + selectedMessages, + text: '' + }); + + const finishShareView = (text = '', quotes = []) => setQuotesAndText?.(text, quotes); + + const handleOnPaste = async (e: onPasteImageEventData) => { + if (e.error) { + handleError(e.error.message); + return; + } + console.log(e); + if (!rid) return; + + const room = await getSubscriptionByRoomId(rid); + let thread; + if (tmid) { + thread = await getThreadById(tmid); + } + + const file = { + filename: e.fileName, + size: e.fileSize, + mime: e.type, + path: e.uri + } as any; + + const canUploadResult = canUploadFile({ + file, + allowList, + maxFileSize, + permissionToUploadFile: permissionToUpload + }); + if (canUploadResult.success) { + Navigation.navigate('ShareView', { + room, + thread: thread || tmid, + attachments: [file], + action, + finishShareView, + startShareView + }); + } else { + handleError(canUploadResult.error); + console.log('error block'); + } + }; + + const handleError = (error?: string) => { + Alert.alert(I18n.t('Error_uploading'), error && I18n.isTranslated(error) ? I18n.t(error) : error); + }; + return ( <> {isAndroid ? ( @@ -412,7 +473,9 @@ export const ComposerInput = memo( keyboardAppearance={theme === 'light' ? 'light' : 'dark'} // eslint-disable-next-line no-nested-ternary testID={`message-composer-input${tmid ? '-thread' : sharing ? '-share' : ''}`} - onPasteImageData={e => console.log(e)} + onPasteImageData={e => { + handleOnPaste(e); + }} /> ) : ( Date: Mon, 15 Dec 2025 00:34:41 +0530 Subject: [PATCH 05/15] fix: autoComplete typo in ComposerInput --- app/containers/MessageComposer/components/ComposerInput.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/containers/MessageComposer/components/ComposerInput.tsx b/app/containers/MessageComposer/components/ComposerInput.tsx index 07ab2b88ef9..f42f3143b83 100644 --- a/app/containers/MessageComposer/components/ComposerInput.tsx +++ b/app/containers/MessageComposer/components/ComposerInput.tsx @@ -494,7 +494,7 @@ export const ComposerInput = memo( underlineColorAndroid='transparent' defaultValue='' multiline - {...(autocompleteType ? { autoCompdete: 'off', autoCorrect: false, autoCapitalize: 'none' } : {})} + {...(autocompleteType ? { autoComplete: 'off', autoCorrect: false, autoCapitalize: 'none' } : {})} keyboardAppearance={theme === 'light' ? 'light' : 'dark'} // eslint-disable-next-line no-nested-ternary testID={`message-composer-input${tmid ? '-thread' : sharing ? '-share' : ''}`} From 855ee288aa045cf79d23a24dbed1f741e3507296 Mon Sep 17 00:00:00 2001 From: Divyanshu patil Date: Mon, 15 Dec 2025 00:50:05 +0530 Subject: [PATCH 06/15] fix: null check on room, forceUpdateDraftMessage param to ensure draft is clear --- .../MessageComposer/components/ComposerInput.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/containers/MessageComposer/components/ComposerInput.tsx b/app/containers/MessageComposer/components/ComposerInput.tsx index f42f3143b83..76da922b5eb 100644 --- a/app/containers/MessageComposer/components/ComposerInput.tsx +++ b/app/containers/MessageComposer/components/ComposerInput.tsx @@ -169,7 +169,7 @@ export const ComposerInput = memo( useImperativeHandle(ref, () => ({ getTextAndClear: () => { const text = textRef.current; - setInput(''); + setInput('', undefined, true); return text; }, getText: () => textRef.current, @@ -412,6 +412,12 @@ export const ComposerInput = memo( if (!rid) return; const room = await getSubscriptionByRoomId(rid); + + if (!room) { + handleError('Room not found'); + return; + } + let thread; if (tmid) { thread = await getThreadById(tmid); From 2bac128e5ed9c43002eb7b197c474bf6fae9fede Mon Sep 17 00:00:00 2001 From: Divyanshu patil Date: Mon, 15 Dec 2025 01:59:31 +0530 Subject: [PATCH 07/15] refactor: IShareAttachment types, image paste handler name --- .../MessageComposer/components/ComposerInput.tsx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/containers/MessageComposer/components/ComposerInput.tsx b/app/containers/MessageComposer/components/ComposerInput.tsx index 76da922b5eb..6955fa945d4 100644 --- a/app/containers/MessageComposer/components/ComposerInput.tsx +++ b/app/containers/MessageComposer/components/ComposerInput.tsx @@ -46,6 +46,7 @@ import { loadDraftMessage } from '../../../lib/methods/draftMessage'; import useIOSBackSwipeHandler from '../hooks/useIOSBackSwipeHandler'; import { getSubscriptionByRoomId } from '../../../lib/database/services/Subscription'; import { getThreadById } from '../../../lib/database/services/Thread'; +import { type IShareAttachment } from '../../../definitions'; const defaultSelection: IInputSelection = { start: 0, end: 0 }; @@ -403,7 +404,7 @@ export const ComposerInput = memo( const finishShareView = (text = '', quotes = []) => setQuotesAndText?.(text, quotes); - const handleOnPaste = async (e: onPasteImageEventData) => { + const handleOnImagePaste = async (e: onPasteImageEventData) => { if (e.error) { handleError(e.error.message); return; @@ -428,7 +429,7 @@ export const ComposerInput = memo( size: e.fileSize, mime: e.type, path: e.uri - } as any; + } as IShareAttachment; const canUploadResult = canUploadFile({ file, @@ -479,9 +480,7 @@ export const ComposerInput = memo( keyboardAppearance={theme === 'light' ? 'light' : 'dark'} // eslint-disable-next-line no-nested-ternary testID={`message-composer-input${tmid ? '-thread' : sharing ? '-share' : ''}`} - onPasteImageData={e => { - handleOnPaste(e); - }} + onPasteImageData={handleOnImagePaste} /> ) : ( Date: Mon, 15 Dec 2025 02:00:41 +0530 Subject: [PATCH 08/15] chore: upate react-native-typerich version to 0.1.10 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 57a40291b16..08915905515 100644 --- a/package.json +++ b/package.json @@ -121,7 +121,7 @@ "react-native-skeleton-placeholder": "5.2.4", "react-native-slowlog": "1.0.2", "react-native-svg": "^15.12.1", - "react-native-typerich": "^0.1.9", + "react-native-typerich": "^0.1.10", "react-native-url-polyfill": "2.0.0", "react-native-webview": "^13.15.0", "react-redux": "8.0.5", diff --git a/yarn.lock b/yarn.lock index 7db0c949d79..e56065ecd6c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12658,10 +12658,10 @@ react-native-svg@^15.12.1: css-tree "^1.1.3" warn-once "0.1.1" -react-native-typerich@^0.1.9: - version "0.1.9" - resolved "https://registry.yarnpkg.com/react-native-typerich/-/react-native-typerich-0.1.9.tgz#6a533ec53f20786ea2e520f6ca88c5ebdd8bc1d3" - integrity sha512-F/8/Rf5yRFF05JIpwxGvfFL4BwSUmIPYtXsII14iBo2/jsyj7JPWJiPI7bP74BRXcTrDDXXDH7Zs+aD4kogC2Q== +react-native-typerich@^0.1.10: + version "0.1.10" + resolved "https://registry.yarnpkg.com/react-native-typerich/-/react-native-typerich-0.1.10.tgz#0914b4000c20194ad50103ae51510e9a0c56eb37" + integrity sha512-ktO7UF44uTAcAG42m5U9TiooefpGGXapVNAewODI2MbvE7Xx2xIv2I7TQpXURTG1SfjXzx3C8C4Mp95q0ACt3w== react-native-url-polyfill@2.0.0, react-native-url-polyfill@^2.0.0: version "2.0.0" From 9719e2d6d5e913e91349c6fac2e9a134c8eec641 Mon Sep 17 00:00:00 2001 From: Divyanshu patil Date: Mon, 15 Dec 2025 17:58:34 +0530 Subject: [PATCH 09/15] cleanup: logs --- .../MessageComposer/components/ComposerInput.tsx | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/app/containers/MessageComposer/components/ComposerInput.tsx b/app/containers/MessageComposer/components/ComposerInput.tsx index 6955fa945d4..d234f3a082b 100644 --- a/app/containers/MessageComposer/components/ComposerInput.tsx +++ b/app/containers/MessageComposer/components/ComposerInput.tsx @@ -79,7 +79,6 @@ export const ComposerInput = memo( const maxFileSize = FileUpload_MaxFileSize as number; const isAndroid = Platform.OS === 'android'; - // const isAndroid = false; // subscribe to changes on mic state to update draft after a message is sent useMicOrSend(); @@ -215,7 +214,6 @@ export const ComposerInput = memo( const onChangeText: TextInputProps['onChangeText'] = text => { textRef.current = text; debouncedOnChangeText(text); - console.log(text); setInput(text, undefined, true); }; @@ -226,9 +224,7 @@ export const ComposerInput = memo( const onChangeSelection = (e: OnChangeSelectionEvent) => { const { start, end } = e; const selection = { start, end }; - console.log('selection========', e); selectionRef.current = selection; - console.log('sel', selection); }; const handleFocus = () => { @@ -409,7 +405,6 @@ export const ComposerInput = memo( handleError(e.error.message); return; } - console.log(e); if (!rid) return; const room = await getSubscriptionByRoomId(rid); @@ -448,7 +443,6 @@ export const ComposerInput = memo( }); } else { handleError(canUploadResult.error); - console.log('error block'); } }; @@ -462,7 +456,7 @@ export const ComposerInput = memo( { inputRef.current = component; @@ -471,7 +465,7 @@ export const ComposerInput = memo( onChangeText={onChangeText} onTouchStart={onTouchStart} onChangeSelection={onChangeSelection} - onFocus={handleFocus} + onFocus={handleFocus} // typerich onFocus / onBlur events doesn't pass any arguments to callbacks onBlur={handleBlur} // underlineColorAndroid='transparent' // by default behaiviour defaultValue='' From bb91f3c51e66e4e165d65b1669dae6f274be4005 Mon Sep 17 00:00:00 2001 From: Divyanshu patil Date: Mon, 15 Dec 2025 20:03:46 +0530 Subject: [PATCH 10/15] fix: ios app crash on opening app --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 08915905515..8b6242818d3 100644 --- a/package.json +++ b/package.json @@ -121,7 +121,7 @@ "react-native-skeleton-placeholder": "5.2.4", "react-native-slowlog": "1.0.2", "react-native-svg": "^15.12.1", - "react-native-typerich": "^0.1.10", + "react-native-typerich": "^0.1.11", "react-native-url-polyfill": "2.0.0", "react-native-webview": "^13.15.0", "react-redux": "8.0.5", diff --git a/yarn.lock b/yarn.lock index e56065ecd6c..5e91a5feb27 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12658,10 +12658,10 @@ react-native-svg@^15.12.1: css-tree "^1.1.3" warn-once "0.1.1" -react-native-typerich@^0.1.10: - version "0.1.10" - resolved "https://registry.yarnpkg.com/react-native-typerich/-/react-native-typerich-0.1.10.tgz#0914b4000c20194ad50103ae51510e9a0c56eb37" - integrity sha512-ktO7UF44uTAcAG42m5U9TiooefpGGXapVNAewODI2MbvE7Xx2xIv2I7TQpXURTG1SfjXzx3C8C4Mp95q0ACt3w== +react-native-typerich@^0.1.11: + version "0.1.11" + resolved "https://registry.yarnpkg.com/react-native-typerich/-/react-native-typerich-0.1.11.tgz#762d49983327f4a7f58ca264f0345d5dd17b3b79" + integrity sha512-t+0dJLonRZhOy2gZh0IgTLBamrXeNUgT3LtpbO4l0OVKEhEczlDy/IdNQuFY78XuoOmRod5oyO437Co6EdHp9w== react-native-url-polyfill@2.0.0, react-native-url-polyfill@^2.0.0: version "2.0.0" From c21e7dc22b387a1abe9c85dc2948d8d7935670a8 Mon Sep 17 00:00:00 2001 From: Divyanshu patil Date: Fri, 19 Dec 2025 21:12:45 +0530 Subject: [PATCH 11/15] fix: context menu text paste, draft saving, programmatic multiline setValue --- .../MessageComposer/components/ComposerInput.tsx | 4 +++- package.json | 2 +- yarn.lock | 8 ++++---- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app/containers/MessageComposer/components/ComposerInput.tsx b/app/containers/MessageComposer/components/ComposerInput.tsx index d234f3a082b..6d90d5aa4e4 100644 --- a/app/containers/MessageComposer/components/ComposerInput.tsx +++ b/app/containers/MessageComposer/components/ComposerInput.tsx @@ -155,6 +155,8 @@ export const ComposerInput = memo( const text = textRef.current; const newText = `${text.substr(0, start)}@${text.substr(start, end - start)}${text.substr(end)}`; setInput(newText, { start: start + 1, end: start === end ? start + 1 : end + 1 }); + // todo mention command here + setAutocompleteParams({ text: '', type: '@' }); }); }); @@ -214,7 +216,7 @@ export const ComposerInput = memo( const onChangeText: TextInputProps['onChangeText'] = text => { textRef.current = text; debouncedOnChangeText(text); - setInput(text, undefined, true); + setInput(text); }; const onSelectionChange: TextInputProps['onSelectionChange'] = e => { diff --git a/package.json b/package.json index d82c457a432..05b7bea6a64 100644 --- a/package.json +++ b/package.json @@ -120,7 +120,7 @@ "react-native-skeleton-placeholder": "5.2.4", "react-native-slowlog": "1.0.2", "react-native-svg": "^15.12.1", - "react-native-typerich": "^0.1.11", + "react-native-typerich": "^0.1.14", "react-native-url-polyfill": "2.0.0", "react-native-webview": "^13.15.0", "react-redux": "8.0.5", diff --git a/yarn.lock b/yarn.lock index 45927331d0d..a8a3c533e1a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12653,10 +12653,10 @@ react-native-svg@^15.12.1: css-tree "^1.1.3" warn-once "0.1.1" -react-native-typerich@^0.1.11: - version "0.1.11" - resolved "https://registry.yarnpkg.com/react-native-typerich/-/react-native-typerich-0.1.11.tgz#762d49983327f4a7f58ca264f0345d5dd17b3b79" - integrity sha512-t+0dJLonRZhOy2gZh0IgTLBamrXeNUgT3LtpbO4l0OVKEhEczlDy/IdNQuFY78XuoOmRod5oyO437Co6EdHp9w== +react-native-typerich@^0.1.14: + version "0.1.14" + resolved "https://registry.yarnpkg.com/react-native-typerich/-/react-native-typerich-0.1.14.tgz#fa44d60339b22ad86d72d29719ec986932a2b3d1" + integrity sha512-z7PaY1otdacwe1h4K0uSrGz1tjXW9Sq3g0SCdhww1K+jNgWhQ1ilQh79zC9W9IFMp1cRF/RU/hDEecHTjox4Tg== react-native-url-polyfill@2.0.0, react-native-url-polyfill@^2.0.0: version "2.0.0" From 57b6564f3b1be1db3e0030d59f1e53f86d78ce4e Mon Sep 17 00:00:00 2001 From: Divyanshu patil Date: Wed, 24 Dec 2025 01:39:44 +0530 Subject: [PATCH 12/15] chore: added api changes --- .../MessageComposer/components/ComposerInput.tsx | 2 +- package.json | 2 +- yarn.lock | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/containers/MessageComposer/components/ComposerInput.tsx b/app/containers/MessageComposer/components/ComposerInput.tsx index 6d90d5aa4e4..71da7e5c7b3 100644 --- a/app/containers/MessageComposer/components/ComposerInput.tsx +++ b/app/containers/MessageComposer/components/ComposerInput.tsx @@ -190,7 +190,7 @@ export const ComposerInput = memo( } if (isAndroid) { - inputRef.current?.setValue(text); + inputRef.current?.setText(text); } else { inputRef.current?.setNativeProps?.({ text }); // keep TextInput path } diff --git a/package.json b/package.json index 72ecd28abee..8827873a731 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ "react-native-skeleton-placeholder": "5.2.4", "react-native-slowlog": "1.0.2", "react-native-svg": "^15.12.1", - "react-native-typerich": "^0.1.14", + "react-native-typerich": "^1.1.1", "react-native-url-polyfill": "2.0.0", "react-native-webview": "^13.15.0", "react-redux": "8.0.5", diff --git a/yarn.lock b/yarn.lock index 48ff65ffc9a..22931fffafb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12854,10 +12854,10 @@ react-native-svg@^15.12.1: css-tree "^1.1.3" warn-once "0.1.1" -react-native-typerich@^0.1.14: - version "0.1.14" - resolved "https://registry.yarnpkg.com/react-native-typerich/-/react-native-typerich-0.1.14.tgz#fa44d60339b22ad86d72d29719ec986932a2b3d1" - integrity sha512-z7PaY1otdacwe1h4K0uSrGz1tjXW9Sq3g0SCdhww1K+jNgWhQ1ilQh79zC9W9IFMp1cRF/RU/hDEecHTjox4Tg== +react-native-typerich@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/react-native-typerich/-/react-native-typerich-1.1.1.tgz#4e391bf61b88a261a358154cc1ffd1f3a1ce477a" + integrity sha512-TeBufzO9T4EKPMougv+ssD59+UnFwWL0JM2FKqXhihn+3z4MFCfRDuD7qd6vP3Vh+WIyUINW4GKm9XlqYeC6Lw== react-native-url-polyfill@2.0.0, react-native-url-polyfill@^2.0.0: version "2.0.0" From 7147f9c8b59780a5a0007f3f0fc290e904e3a698 Mon Sep 17 00:00:00 2001 From: Divyanshu patil Date: Thu, 22 Jan 2026 20:30:27 +0530 Subject: [PATCH 13/15] feat: iOS image pasting --- .../components/ComposerInput.tsx | 98 ++++++------------- ios/Podfile.lock | 34 ++++++- ios/RocketChatRN.xcodeproj/project.pbxproj | 8 +- package.json | 2 +- yarn.lock | 8 +- 5 files changed, 71 insertions(+), 79 deletions(-) diff --git a/app/containers/MessageComposer/components/ComposerInput.tsx b/app/containers/MessageComposer/components/ComposerInput.tsx index 61f4ef19f4f..486ea2bfe62 100644 --- a/app/containers/MessageComposer/components/ComposerInput.tsx +++ b/app/containers/MessageComposer/components/ComposerInput.tsx @@ -1,5 +1,5 @@ import React, { forwardRef, memo, useCallback, useEffect, useImperativeHandle } from 'react'; -import { TextInput, Platform, StyleSheet, type TextInputProps, InteractionManager, Alert } from 'react-native'; +import { StyleSheet, type TextInputProps, InteractionManager, Alert } from 'react-native'; import { useDebouncedCallback } from 'use-debounce'; import { useDispatch } from 'react-redux'; import { type RouteProp, useFocusEffect, useRoute } from '@react-navigation/native'; @@ -78,8 +78,6 @@ export const ComposerInput = memo( const allowList = FileUpload_MediaTypeWhiteList as string; const maxFileSize = FileUpload_MaxFileSize as number; - const isAndroid = Platform.OS === 'android'; - // subscribe to changes on mic state to update draft after a message is sent useMicOrSend(); const { saveMessageDraft } = useAutoSaveDraft(textRef.current); @@ -189,11 +187,7 @@ export const ComposerInput = memo( saveMessageDraft(''); } - if (isAndroid) { - inputRef.current?.setText(text); - } else { - inputRef.current?.setNativeProps?.({ text }); // keep TextInput path - } + inputRef.current?.setText(text); if (selection) { // setSelection won't trigger onSelectionChange, so we need it to be ran after new text is set @@ -219,10 +213,6 @@ export const ComposerInput = memo( setInput(text); }; - const onSelectionChange: TextInputProps['onSelectionChange'] = e => { - selectionRef.current = e.nativeEvent.selection; - }; - const onChangeSelection = (e: OnChangeSelectionEvent) => { const { start, end } = e; const selection = { start, end }; @@ -239,18 +229,11 @@ export const ComposerInput = memo( stopAutocomplete(); } }; - const onFocus: TextInputProps['onFocus'] = () => { - handleFocus(); - }; const onTouchStart: TextInputProps['onTouchStart'] = () => { setFocused(true); }; - const onBlur: TextInputProps['onBlur'] = () => { - handleBlur(); - }; - const onAutocompleteItemSelected: IAutocompleteItemProps['onPress'] = async item => { if (item.type === 'loading') { return null; @@ -403,8 +386,10 @@ export const ComposerInput = memo( const finishShareView = (text = '', quotes = []) => setQuotesAndText?.(text, quotes); const handleOnImagePaste = async (e: onPasteImageEventData) => { - if (e.error) { + console.log(e); + if (e.error?.message) { handleError(e.error.message); + console.log('error detected'); return; } if (!rid) return; @@ -444,6 +429,8 @@ export const ComposerInput = memo( startShareView }); } else { + console.log('can upload error'); + handleError(canUploadResult.error); } }; @@ -454,53 +441,30 @@ export const ComposerInput = memo( return ( <> - {isAndroid ? ( - { - inputRef.current = component; - }} - // blurOnSubmit={false} // not needed - onChangeText={onChangeText} - onTouchStart={onTouchStart} - onChangeSelection={onChangeSelection} - onFocus={handleFocus} // typerich onFocus / onBlur events doesn't pass any arguments to callbacks - onBlur={handleBlur} - // underlineColorAndroid='transparent' // by default behaiviour - defaultValue='' - multiline - {...(autocompleteType ? { autoComplete: 'off', autoCorrect: false, autoCapitalize: 'none' } : {})} - keyboardAppearance={theme === 'light' ? 'light' : 'dark'} - // eslint-disable-next-line no-nested-ternary - testID={`message-composer-input${tmid ? '-thread' : sharing ? '-share' : ''}`} - onPasteImageData={handleOnImagePaste} - /> - ) : ( - { - inputRef.current = component; - }} - blurOnSubmit={false} - onChangeText={onChangeText} - onTouchStart={onTouchStart} - onSelectionChange={onSelectionChange} - onFocus={onFocus} - onBlur={onBlur} - underlineColorAndroid='transparent' - defaultValue='' - multiline - {...(autocompleteType ? { autoComplete: 'off', autoCorrect: false, autoCapitalize: 'none' } : {})} - keyboardAppearance={theme === 'light' ? 'light' : 'dark'} - // eslint-disable-next-line no-nested-ternary - testID={`message-composer-input${tmid ? '-thread' : sharing ? '-share' : ''}`} - /> - )} + { + inputRef.current = component; + }} + // blurOnSubmit={false} // not needed + onChangeText={onChangeText} + onTouchStart={onTouchStart} + onChangeSelection={onChangeSelection} + onFocus={handleFocus} // typerich onFocus / onBlur events doesn't pass any arguments to callbacks + onBlur={handleBlur} + // underlineColorAndroid='transparent' // by default behaiviour + defaultValue='' + multiline + editable + {...(autocompleteType ? { autoComplete: 'off', autoCorrect: false, autoCapitalize: 'none' } : {})} + keyboardAppearance={theme === 'light' ? 'light' : 'dark'} + // eslint-disable-next-line no-nested-ternary + testID={`message-composer-input${tmid ? '-thread' : sharing ? '-share' : ''}`} + onPasteImageData={handleOnImagePaste} + /> ); }) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 99a6053f60c..be5903c5735 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -232,7 +232,7 @@ PODS: - libwebp/sharpyuv (1.5.0) - libwebp/webp (1.5.0): - libwebp/sharpyuv - - MobileCrypto (0.2.0): + - MobileCrypto (0.2.1): - DoubleConversion - glog - hermes-engine @@ -2162,6 +2162,30 @@ PODS: - React-logger (= 0.79.4) - React-perflogger (= 0.79.4) - React-utils (= 0.79.4) + - ReactNativeTypeRich (2.2.2): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2024.11.18.00) + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-hermes + - React-ImageManager + - React-jsi + - React-NativeModulesApple + - React-RCTFabric + - React-renderercss + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - Yoga - RNBootSplash (6.3.8): - DoubleConversion - glog @@ -2736,6 +2760,7 @@ DEPENDENCIES: - ReactAppDependencyProvider (from `build/generated/ios`) - ReactCodegen (from `build/generated/ios`) - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) + - ReactNativeTypeRich (from `../node_modules/react-native-typerich`) - RNBootSplash (from `../node_modules/react-native-bootsplash`) - "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)" - "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)" @@ -2994,6 +3019,8 @@ EXTERNAL SOURCES: :path: build/generated/ios ReactCommon: :path: "../node_modules/react-native/ReactCommon" + ReactNativeTypeRich: + :path: "../node_modules/react-native-typerich" RNBootSplash: :path: "../node_modules/react-native-bootsplash" RNCAsyncStorage: @@ -3082,7 +3109,7 @@ SPEC CHECKSUMS: libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7 libdav1d: 23581a4d8ec811ff171ed5e2e05cd27bad64c39f libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8 - MobileCrypto: 60a1e43e26a9d6851ae2aa7294b8041c9e9220b7 + MobileCrypto: a424494b2f45bec9dbe60e3f6d16a40aedefe7b7 nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851 @@ -3159,6 +3186,7 @@ SPEC CHECKSUMS: ReactAppDependencyProvider: bf62814e0fde923f73fc64b7e82d76c63c284da9 ReactCodegen: 2f22969ab54e1aace69c9b5d3085e0a3b405a9a6 ReactCommon: 177fca841e97b2c0e288e86097b8be04c6e7ae36 + ReactNativeTypeRich: 02d0ff53a6c1ed2b8bad7e98e8499927d0ed3ec1 RNBootSplash: 1280eeb18d887de0a45bb4923d4fc56f25c8b99c RNCAsyncStorage: edb872909c88d8541c0bfade3f86cd7784a7c6b3 RNCClipboard: 4fd4b093bd9d0be5ad62ea73884eda7745ad23d0 @@ -3185,7 +3213,7 @@ SPEC CHECKSUMS: SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654 WatermelonDB: 4c846c8cb94eef3cba90fa034d15310163226703 - Yoga: dfabf1234ccd5ac41d1b1d43179f024366ae9831 + Yoga: 2a3a4c38a8441b6359d5e5914d35db7b2b67aebd ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5 PODFILE CHECKSUM: 199f6fbbe6fb415c822cca992e6152000ac55b3e diff --git a/ios/RocketChatRN.xcodeproj/project.pbxproj b/ios/RocketChatRN.xcodeproj/project.pbxproj index 29cc9563241..5e7acce4ec7 100644 --- a/ios/RocketChatRN.xcodeproj/project.pbxproj +++ b/ios/RocketChatRN.xcodeproj/project.pbxproj @@ -1825,7 +1825,7 @@ inputFileListPaths = ( ); inputPaths = ( - "$TARGET_BUILD_DIR/$INFOPLIST_PATH", + $TARGET_BUILD_DIR/$INFOPLIST_PATH, ); name = "Upload source maps to Bugsnag"; outputFileListPaths = ( @@ -1845,7 +1845,7 @@ inputFileListPaths = ( ); inputPaths = ( - "$TARGET_BUILD_DIR/$INFOPLIST_PATH", + $TARGET_BUILD_DIR/$INFOPLIST_PATH, ); name = "Upload source maps to Bugsnag"; outputFileListPaths = ( @@ -2593,7 +2593,7 @@ "$(inherited)", "$(SRCROOT)/../node_modules/rn-extensions-share/ios/**", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", - "$PODS_CONFIGURATION_BUILD_DIR/Firebase", + $PODS_CONFIGURATION_BUILD_DIR/Firebase, ); INFOPLIST_FILE = ShareRocketChatRN/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.1; @@ -2669,7 +2669,7 @@ "$(inherited)", "$(SRCROOT)/../node_modules/rn-extensions-share/ios/**", "$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**", - "$PODS_CONFIGURATION_BUILD_DIR/Firebase", + $PODS_CONFIGURATION_BUILD_DIR/Firebase, ); INFOPLIST_FILE = ShareRocketChatRN/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.1; diff --git a/package.json b/package.json index 97f24a0966d..6b8c1ea795c 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ "react-native-skeleton-placeholder": "5.2.4", "react-native-slowlog": "1.0.2", "react-native-svg": "^15.12.1", - "react-native-typerich": "^1.1.1", + "react-native-typerich": "^2.2.2", "react-native-url-polyfill": "2.0.0", "react-native-webview": "^13.15.0", "react-redux": "8.0.5", diff --git a/yarn.lock b/yarn.lock index 258c47c0de5..69a0aad9836 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12854,10 +12854,10 @@ react-native-svg@^15.12.1: css-tree "^1.1.3" warn-once "0.1.1" -react-native-typerich@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/react-native-typerich/-/react-native-typerich-1.1.1.tgz#4e391bf61b88a261a358154cc1ffd1f3a1ce477a" - integrity sha512-TeBufzO9T4EKPMougv+ssD59+UnFwWL0JM2FKqXhihn+3z4MFCfRDuD7qd6vP3Vh+WIyUINW4GKm9XlqYeC6Lw== +react-native-typerich@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/react-native-typerich/-/react-native-typerich-2.2.2.tgz#1958b24e7fdc15e0bfbd9408ae801f8d0cdfb3b2" + integrity sha512-4bPw8t5bR0C8KwRgHJgh5R1NOD2nnwQ89BDl9wEh3xV469EkcpqZsS03+EetTSanMUJ84F0RYNBhxTlXi7sKjw== react-native-url-polyfill@2.0.0, react-native-url-polyfill@^2.0.0: version "2.0.0" From 5e125590ec79898928868a655f9f752702430f23 Mon Sep 17 00:00:00 2001 From: Divyanshu patil Date: Fri, 23 Jan 2026 11:12:12 +0530 Subject: [PATCH 14/15] refactor: removed editable prop as it should be default --- .../MessageComposer/components/ComposerInput.tsx | 1 - ios/Podfile.lock | 4 ++-- package.json | 2 +- yarn.lock | 8 ++++---- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/containers/MessageComposer/components/ComposerInput.tsx b/app/containers/MessageComposer/components/ComposerInput.tsx index 486ea2bfe62..390e6b4aea2 100644 --- a/app/containers/MessageComposer/components/ComposerInput.tsx +++ b/app/containers/MessageComposer/components/ComposerInput.tsx @@ -458,7 +458,6 @@ export const ComposerInput = memo( // underlineColorAndroid='transparent' // by default behaiviour defaultValue='' multiline - editable {...(autocompleteType ? { autoComplete: 'off', autoCorrect: false, autoCapitalize: 'none' } : {})} keyboardAppearance={theme === 'light' ? 'light' : 'dark'} // eslint-disable-next-line no-nested-ternary diff --git a/ios/Podfile.lock b/ios/Podfile.lock index be5903c5735..9e8971ccf3c 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -2162,7 +2162,7 @@ PODS: - React-logger (= 0.79.4) - React-perflogger (= 0.79.4) - React-utils (= 0.79.4) - - ReactNativeTypeRich (2.2.2): + - ReactNativeTypeRich (2.2.3): - DoubleConversion - glog - hermes-engine @@ -3186,7 +3186,7 @@ SPEC CHECKSUMS: ReactAppDependencyProvider: bf62814e0fde923f73fc64b7e82d76c63c284da9 ReactCodegen: 2f22969ab54e1aace69c9b5d3085e0a3b405a9a6 ReactCommon: 177fca841e97b2c0e288e86097b8be04c6e7ae36 - ReactNativeTypeRich: 02d0ff53a6c1ed2b8bad7e98e8499927d0ed3ec1 + ReactNativeTypeRich: 6a694ffe0297e6f7fa7bf82899e448459112fe81 RNBootSplash: 1280eeb18d887de0a45bb4923d4fc56f25c8b99c RNCAsyncStorage: edb872909c88d8541c0bfade3f86cd7784a7c6b3 RNCClipboard: 4fd4b093bd9d0be5ad62ea73884eda7745ad23d0 diff --git a/package.json b/package.json index 6b8c1ea795c..78a4aca9256 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ "react-native-skeleton-placeholder": "5.2.4", "react-native-slowlog": "1.0.2", "react-native-svg": "^15.12.1", - "react-native-typerich": "^2.2.2", + "react-native-typerich": "^2.2.3", "react-native-url-polyfill": "2.0.0", "react-native-webview": "^13.15.0", "react-redux": "8.0.5", diff --git a/yarn.lock b/yarn.lock index 69a0aad9836..81ece270054 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12854,10 +12854,10 @@ react-native-svg@^15.12.1: css-tree "^1.1.3" warn-once "0.1.1" -react-native-typerich@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/react-native-typerich/-/react-native-typerich-2.2.2.tgz#1958b24e7fdc15e0bfbd9408ae801f8d0cdfb3b2" - integrity sha512-4bPw8t5bR0C8KwRgHJgh5R1NOD2nnwQ89BDl9wEh3xV469EkcpqZsS03+EetTSanMUJ84F0RYNBhxTlXi7sKjw== +react-native-typerich@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/react-native-typerich/-/react-native-typerich-2.2.3.tgz#5ba1a913b0cf68fd57cb9b07ea240865ad8befd3" + integrity sha512-8kQi+9hRGIVjoUIE7RjyL84FXVsDb3YEdKFO6QIL85TkWVVfWXFSi5x/w2gxhQ8Tl3dtePSd6+m3JcVUyW/eDg== react-native-url-polyfill@2.0.0, react-native-url-polyfill@^2.0.0: version "2.0.0" From 61ccbe252ebc48ae2a845955904d4de388438d4e Mon Sep 17 00:00:00 2001 From: Divyanshu patil Date: Sun, 25 Jan 2026 21:32:55 +0530 Subject: [PATCH 15/15] fix(ios): autocorrect not leaving space in middle of message --- ios/Podfile.lock | 4 ++-- package.json | 2 +- yarn.lock | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 9e8971ccf3c..cef75bacfef 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -2162,7 +2162,7 @@ PODS: - React-logger (= 0.79.4) - React-perflogger (= 0.79.4) - React-utils (= 0.79.4) - - ReactNativeTypeRich (2.2.3): + - ReactNativeTypeRich (2.2.4): - DoubleConversion - glog - hermes-engine @@ -3186,7 +3186,7 @@ SPEC CHECKSUMS: ReactAppDependencyProvider: bf62814e0fde923f73fc64b7e82d76c63c284da9 ReactCodegen: 2f22969ab54e1aace69c9b5d3085e0a3b405a9a6 ReactCommon: 177fca841e97b2c0e288e86097b8be04c6e7ae36 - ReactNativeTypeRich: 6a694ffe0297e6f7fa7bf82899e448459112fe81 + ReactNativeTypeRich: 4702fc21cb380789c8c66d5ee652aab0e6719588 RNBootSplash: 1280eeb18d887de0a45bb4923d4fc56f25c8b99c RNCAsyncStorage: edb872909c88d8541c0bfade3f86cd7784a7c6b3 RNCClipboard: 4fd4b093bd9d0be5ad62ea73884eda7745ad23d0 diff --git a/package.json b/package.json index 78a4aca9256..17c24a0b327 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ "react-native-skeleton-placeholder": "5.2.4", "react-native-slowlog": "1.0.2", "react-native-svg": "^15.12.1", - "react-native-typerich": "^2.2.3", + "react-native-typerich": "^2.2.4", "react-native-url-polyfill": "2.0.0", "react-native-webview": "^13.15.0", "react-redux": "8.0.5", diff --git a/yarn.lock b/yarn.lock index 81ece270054..8dd7b7fc4aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12854,10 +12854,10 @@ react-native-svg@^15.12.1: css-tree "^1.1.3" warn-once "0.1.1" -react-native-typerich@^2.2.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/react-native-typerich/-/react-native-typerich-2.2.3.tgz#5ba1a913b0cf68fd57cb9b07ea240865ad8befd3" - integrity sha512-8kQi+9hRGIVjoUIE7RjyL84FXVsDb3YEdKFO6QIL85TkWVVfWXFSi5x/w2gxhQ8Tl3dtePSd6+m3JcVUyW/eDg== +react-native-typerich@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/react-native-typerich/-/react-native-typerich-2.2.4.tgz#da51f5f3990a287ffad348c202f432957303363c" + integrity sha512-0TQbkpwDvbR0mQk4d/l5CcVXphvFo0VnKt4XhO5wYZ+6SlsVmBrTVuMZ0ASbD2xOfNI5pHgcRbW6YgWHbq+uBg== react-native-url-polyfill@2.0.0, react-native-url-polyfill@^2.0.0: version "2.0.0"