Skip to content

Commit 7147f9c

Browse files
feat: iOS image pasting
1 parent 5084495 commit 7147f9c

File tree

5 files changed

+71
-79
lines changed

5 files changed

+71
-79
lines changed

app/containers/MessageComposer/components/ComposerInput.tsx

Lines changed: 31 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, { forwardRef, memo, useCallback, useEffect, useImperativeHandle } from 'react';
2-
import { TextInput, Platform, StyleSheet, type TextInputProps, InteractionManager, Alert } from 'react-native';
2+
import { StyleSheet, type TextInputProps, InteractionManager, Alert } from 'react-native';
33
import { useDebouncedCallback } from 'use-debounce';
44
import { useDispatch } from 'react-redux';
55
import { type RouteProp, useFocusEffect, useRoute } from '@react-navigation/native';
@@ -78,8 +78,6 @@ export const ComposerInput = memo(
7878
const allowList = FileUpload_MediaTypeWhiteList as string;
7979
const maxFileSize = FileUpload_MaxFileSize as number;
8080

81-
const isAndroid = Platform.OS === 'android';
82-
8381
// subscribe to changes on mic state to update draft after a message is sent
8482
useMicOrSend();
8583
const { saveMessageDraft } = useAutoSaveDraft(textRef.current);
@@ -189,11 +187,7 @@ export const ComposerInput = memo(
189187
saveMessageDraft('');
190188
}
191189

192-
if (isAndroid) {
193-
inputRef.current?.setText(text);
194-
} else {
195-
inputRef.current?.setNativeProps?.({ text }); // keep TextInput path
196-
}
190+
inputRef.current?.setText(text);
197191

198192
if (selection) {
199193
// 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(
219213
setInput(text);
220214
};
221215

222-
const onSelectionChange: TextInputProps['onSelectionChange'] = e => {
223-
selectionRef.current = e.nativeEvent.selection;
224-
};
225-
226216
const onChangeSelection = (e: OnChangeSelectionEvent) => {
227217
const { start, end } = e;
228218
const selection = { start, end };
@@ -239,18 +229,11 @@ export const ComposerInput = memo(
239229
stopAutocomplete();
240230
}
241231
};
242-
const onFocus: TextInputProps['onFocus'] = () => {
243-
handleFocus();
244-
};
245232

246233
const onTouchStart: TextInputProps['onTouchStart'] = () => {
247234
setFocused(true);
248235
};
249236

250-
const onBlur: TextInputProps['onBlur'] = () => {
251-
handleBlur();
252-
};
253-
254237
const onAutocompleteItemSelected: IAutocompleteItemProps['onPress'] = async item => {
255238
if (item.type === 'loading') {
256239
return null;
@@ -403,8 +386,10 @@ export const ComposerInput = memo(
403386
const finishShareView = (text = '', quotes = []) => setQuotesAndText?.(text, quotes);
404387

405388
const handleOnImagePaste = async (e: onPasteImageEventData) => {
406-
if (e.error) {
389+
console.log(e);
390+
if (e.error?.message) {
407391
handleError(e.error.message);
392+
console.log('error detected');
408393
return;
409394
}
410395
if (!rid) return;
@@ -444,6 +429,8 @@ export const ComposerInput = memo(
444429
startShareView
445430
});
446431
} else {
432+
console.log('can upload error');
433+
447434
handleError(canUploadResult.error);
448435
}
449436
};
@@ -454,53 +441,30 @@ export const ComposerInput = memo(
454441

455442
return (
456443
<>
457-
{isAndroid ? (
458-
<TypeRichTextInput
459-
style={[styles.textInput]}
460-
color={colors.fontDefault}
461-
placeholder={placeholder}
462-
placeholderTextColor={colors.fontAnnotation}
463-
ref={component => {
464-
inputRef.current = component;
465-
}}
466-
// blurOnSubmit={false} // not needed
467-
onChangeText={onChangeText}
468-
onTouchStart={onTouchStart}
469-
onChangeSelection={onChangeSelection}
470-
onFocus={handleFocus} // typerich onFocus / onBlur events doesn't pass any arguments to callbacks
471-
onBlur={handleBlur}
472-
// underlineColorAndroid='transparent' // by default behaiviour
473-
defaultValue=''
474-
multiline
475-
{...(autocompleteType ? { autoComplete: 'off', autoCorrect: false, autoCapitalize: 'none' } : {})}
476-
keyboardAppearance={theme === 'light' ? 'light' : 'dark'}
477-
// eslint-disable-next-line no-nested-ternary
478-
testID={`message-composer-input${tmid ? '-thread' : sharing ? '-share' : ''}`}
479-
onPasteImageData={handleOnImagePaste}
480-
/>
481-
) : (
482-
<TextInput
483-
style={[styles.textInput, { color: colors.fontDefault }]}
484-
placeholder={placeholder}
485-
placeholderTextColor={colors.fontAnnotation}
486-
ref={component => {
487-
inputRef.current = component;
488-
}}
489-
blurOnSubmit={false}
490-
onChangeText={onChangeText}
491-
onTouchStart={onTouchStart}
492-
onSelectionChange={onSelectionChange}
493-
onFocus={onFocus}
494-
onBlur={onBlur}
495-
underlineColorAndroid='transparent'
496-
defaultValue=''
497-
multiline
498-
{...(autocompleteType ? { autoComplete: 'off', autoCorrect: false, autoCapitalize: 'none' } : {})}
499-
keyboardAppearance={theme === 'light' ? 'light' : 'dark'}
500-
// eslint-disable-next-line no-nested-ternary
501-
testID={`message-composer-input${tmid ? '-thread' : sharing ? '-share' : ''}`}
502-
/>
503-
)}
444+
<TypeRichTextInput
445+
style={[styles.textInput]}
446+
color={colors.fontDefault}
447+
placeholder={placeholder}
448+
placeholderTextColor={colors.fontAnnotation}
449+
ref={component => {
450+
inputRef.current = component;
451+
}}
452+
// blurOnSubmit={false} // not needed
453+
onChangeText={onChangeText}
454+
onTouchStart={onTouchStart}
455+
onChangeSelection={onChangeSelection}
456+
onFocus={handleFocus} // typerich onFocus / onBlur events doesn't pass any arguments to callbacks
457+
onBlur={handleBlur}
458+
// underlineColorAndroid='transparent' // by default behaiviour
459+
defaultValue=''
460+
multiline
461+
editable
462+
{...(autocompleteType ? { autoComplete: 'off', autoCorrect: false, autoCapitalize: 'none' } : {})}
463+
keyboardAppearance={theme === 'light' ? 'light' : 'dark'}
464+
// eslint-disable-next-line no-nested-ternary
465+
testID={`message-composer-input${tmid ? '-thread' : sharing ? '-share' : ''}`}
466+
onPasteImageData={handleOnImagePaste}
467+
/>
504468
</>
505469
);
506470
})

ios/Podfile.lock

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ PODS:
232232
- libwebp/sharpyuv (1.5.0)
233233
- libwebp/webp (1.5.0):
234234
- libwebp/sharpyuv
235-
- MobileCrypto (0.2.0):
235+
- MobileCrypto (0.2.1):
236236
- DoubleConversion
237237
- glog
238238
- hermes-engine
@@ -2162,6 +2162,30 @@ PODS:
21622162
- React-logger (= 0.79.4)
21632163
- React-perflogger (= 0.79.4)
21642164
- React-utils (= 0.79.4)
2165+
- ReactNativeTypeRich (2.2.2):
2166+
- DoubleConversion
2167+
- glog
2168+
- hermes-engine
2169+
- RCT-Folly (= 2024.11.18.00)
2170+
- RCTRequired
2171+
- RCTTypeSafety
2172+
- React-Core
2173+
- React-debug
2174+
- React-Fabric
2175+
- React-featureflags
2176+
- React-graphics
2177+
- React-hermes
2178+
- React-ImageManager
2179+
- React-jsi
2180+
- React-NativeModulesApple
2181+
- React-RCTFabric
2182+
- React-renderercss
2183+
- React-rendererdebug
2184+
- React-utils
2185+
- ReactCodegen
2186+
- ReactCommon/turbomodule/bridging
2187+
- ReactCommon/turbomodule/core
2188+
- Yoga
21652189
- RNBootSplash (6.3.8):
21662190
- DoubleConversion
21672191
- glog
@@ -2736,6 +2760,7 @@ DEPENDENCIES:
27362760
- ReactAppDependencyProvider (from `build/generated/ios`)
27372761
- ReactCodegen (from `build/generated/ios`)
27382762
- ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`)
2763+
- ReactNativeTypeRich (from `../node_modules/react-native-typerich`)
27392764
- RNBootSplash (from `../node_modules/react-native-bootsplash`)
27402765
- "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)"
27412766
- "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)"
@@ -2994,6 +3019,8 @@ EXTERNAL SOURCES:
29943019
:path: build/generated/ios
29953020
ReactCommon:
29963021
:path: "../node_modules/react-native/ReactCommon"
3022+
ReactNativeTypeRich:
3023+
:path: "../node_modules/react-native-typerich"
29973024
RNBootSplash:
29983025
:path: "../node_modules/react-native-bootsplash"
29993026
RNCAsyncStorage:
@@ -3082,7 +3109,7 @@ SPEC CHECKSUMS:
30823109
libavif: 84bbb62fb232c3018d6f1bab79beea87e35de7b7
30833110
libdav1d: 23581a4d8ec811ff171ed5e2e05cd27bad64c39f
30843111
libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8
3085-
MobileCrypto: 60a1e43e26a9d6851ae2aa7294b8041c9e9220b7
3112+
MobileCrypto: a424494b2f45bec9dbe60e3f6d16a40aedefe7b7
30863113
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
30873114
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
30883115
PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851
@@ -3159,6 +3186,7 @@ SPEC CHECKSUMS:
31593186
ReactAppDependencyProvider: bf62814e0fde923f73fc64b7e82d76c63c284da9
31603187
ReactCodegen: 2f22969ab54e1aace69c9b5d3085e0a3b405a9a6
31613188
ReactCommon: 177fca841e97b2c0e288e86097b8be04c6e7ae36
3189+
ReactNativeTypeRich: 02d0ff53a6c1ed2b8bad7e98e8499927d0ed3ec1
31623190
RNBootSplash: 1280eeb18d887de0a45bb4923d4fc56f25c8b99c
31633191
RNCAsyncStorage: edb872909c88d8541c0bfade3f86cd7784a7c6b3
31643192
RNCClipboard: 4fd4b093bd9d0be5ad62ea73884eda7745ad23d0
@@ -3185,7 +3213,7 @@ SPEC CHECKSUMS:
31853213
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
31863214
TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654
31873215
WatermelonDB: 4c846c8cb94eef3cba90fa034d15310163226703
3188-
Yoga: dfabf1234ccd5ac41d1b1d43179f024366ae9831
3216+
Yoga: 2a3a4c38a8441b6359d5e5914d35db7b2b67aebd
31893217
ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5
31903218

31913219
PODFILE CHECKSUM: 199f6fbbe6fb415c822cca992e6152000ac55b3e

ios/RocketChatRN.xcodeproj/project.pbxproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1825,7 +1825,7 @@
18251825
inputFileListPaths = (
18261826
);
18271827
inputPaths = (
1828-
"$TARGET_BUILD_DIR/$INFOPLIST_PATH",
1828+
$TARGET_BUILD_DIR/$INFOPLIST_PATH,
18291829
);
18301830
name = "Upload source maps to Bugsnag";
18311831
outputFileListPaths = (
@@ -1845,7 +1845,7 @@
18451845
inputFileListPaths = (
18461846
);
18471847
inputPaths = (
1848-
"$TARGET_BUILD_DIR/$INFOPLIST_PATH",
1848+
$TARGET_BUILD_DIR/$INFOPLIST_PATH,
18491849
);
18501850
name = "Upload source maps to Bugsnag";
18511851
outputFileListPaths = (
@@ -2593,7 +2593,7 @@
25932593
"$(inherited)",
25942594
"$(SRCROOT)/../node_modules/rn-extensions-share/ios/**",
25952595
"$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**",
2596-
"$PODS_CONFIGURATION_BUILD_DIR/Firebase",
2596+
$PODS_CONFIGURATION_BUILD_DIR/Firebase,
25972597
);
25982598
INFOPLIST_FILE = ShareRocketChatRN/Info.plist;
25992599
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
@@ -2669,7 +2669,7 @@
26692669
"$(inherited)",
26702670
"$(SRCROOT)/../node_modules/rn-extensions-share/ios/**",
26712671
"$(SRCROOT)/../node_modules/react-native-firebase/ios/RNFirebase/**",
2672-
"$PODS_CONFIGURATION_BUILD_DIR/Firebase",
2672+
$PODS_CONFIGURATION_BUILD_DIR/Firebase,
26732673
);
26742674
INFOPLIST_FILE = ShareRocketChatRN/Info.plist;
26752675
IPHONEOS_DEPLOYMENT_TARGET = 15.1;

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@
119119
"react-native-skeleton-placeholder": "5.2.4",
120120
"react-native-slowlog": "1.0.2",
121121
"react-native-svg": "^15.12.1",
122-
"react-native-typerich": "^1.1.1",
122+
"react-native-typerich": "^2.2.2",
123123
"react-native-url-polyfill": "2.0.0",
124124
"react-native-webview": "^13.15.0",
125125
"react-redux": "8.0.5",

yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12854,10 +12854,10 @@ react-native-svg@^15.12.1:
1285412854
css-tree "^1.1.3"
1285512855
warn-once "0.1.1"
1285612856

12857-
react-native-typerich@^1.1.1:
12858-
version "1.1.1"
12859-
resolved "https://registry.yarnpkg.com/react-native-typerich/-/react-native-typerich-1.1.1.tgz#4e391bf61b88a261a358154cc1ffd1f3a1ce477a"
12860-
integrity sha512-TeBufzO9T4EKPMougv+ssD59+UnFwWL0JM2FKqXhihn+3z4MFCfRDuD7qd6vP3Vh+WIyUINW4GKm9XlqYeC6Lw==
12857+
react-native-typerich@^2.2.2:
12858+
version "2.2.2"
12859+
resolved "https://registry.yarnpkg.com/react-native-typerich/-/react-native-typerich-2.2.2.tgz#1958b24e7fdc15e0bfbd9408ae801f8d0cdfb3b2"
12860+
integrity sha512-4bPw8t5bR0C8KwRgHJgh5R1NOD2nnwQ89BDl9wEh3xV469EkcpqZsS03+EetTSanMUJ84F0RYNBhxTlXi7sKjw==
1286112861

1286212862
react-native-url-polyfill@2.0.0, react-native-url-polyfill@^2.0.0:
1286312863
version "2.0.0"

0 commit comments

Comments
 (0)