Page MenuHomePhorge

D6641.1765285753.diff
No OneTemporary

Size
8 KB
Referenced Files
None
Subscribers
None

D6641.1765285753.diff

diff --git a/native/chat/chat-input-bar.react.js b/native/chat/chat-input-bar.react.js
--- a/native/chat/chat-input-bar.react.js
+++ b/native/chat/chat-input-bar.react.js
@@ -69,6 +69,8 @@
import Button from '../components/button.react';
import ClearableTextInput from '../components/clearable-text-input.react';
+import type { SyncedSelectionData } from '../components/selectable-text-input';
+import SelectableTextInput from '../components/selectable-text-input.react';
import SWMansionIcon from '../components/swmansion-icon.react';
import { type InputState, InputStateContext } from '../input/input-state';
import { getKeyboardHeight } from '../keyboard/keyboard';
@@ -89,7 +91,7 @@
} from '../navigation/route-names';
import { useSelector } from '../redux/redux-utils';
import { type Colors, useStyles, useColors } from '../themes/colors';
-import type { LayoutEvent, SelectionChangeEvent } from '../types/react-native';
+import type { LayoutEvent } from '../types/react-native';
import { type AnimatedViewStyle, AnimatedView } from '../types/styles';
import { runTiming } from '../utils/animation-utils';
import { nativeTypeaheadRegex } from '../utils/typeahead-utils';
@@ -155,11 +157,12 @@
+text: string,
+textEdited: boolean,
+buttonsExpanded: boolean,
- +selection: Selection,
+ +selectionState: SyncedSelectionData,
};
class ChatInputBar extends React.PureComponent<Props, State> {
textInput: ?React.ElementRef<typeof TextInput>;
clearableTextInput: ?ClearableTextInput;
+ selectableTextInput: ?React.ElementRef<typeof SelectableTextInput>;
expandoButtonsOpen: Value;
targetExpandoButtonsOpen: Value;
@@ -178,7 +181,7 @@
text: props.draft,
textEdited: false,
buttonsExpanded: true,
- selection: { start: 0, end: 0 },
+ selectionState: { text: props.draft, selection: { start: 0, end: 0 } },
};
this.setUpActionIconAnimations();
@@ -471,8 +474,8 @@
}
const typeaheadRegexMatches = getTypeaheadRegexMatches(
- this.state.text,
- this.state.selection,
+ this.state.selectionState.text,
+ this.state.selectionState.selection,
nativeTypeaheadRegex,
);
@@ -607,18 +610,19 @@
{this.state.buttonsExpanded ? null : expandoButton}
</View>
</AnimatedView>
- <ClearableTextInput
+ <SelectableTextInput
allowImagePasteForThreadID={this.props.threadInfo.id}
value={this.state.text}
onChangeText={this.updateText}
- selection={this.state.selection}
- onSelectionChange={this.updateSelection}
+ selection={this.state.selectionState.selection}
+ onUpdateSyncedSelectionData={this.updateSelectionState}
placeholder="Send a message..."
placeholderTextColor={this.props.colors.listInputButton}
multiline={true}
style={this.props.styles.textInput}
textInputRef={this.textInputRef}
- ref={this.clearableTextInputRef}
+ clearableTextInputRef={this.clearableTextInputRef}
+ ref={this.selectableTextInputRef}
selectionColor={`#${this.props.threadInfo.color}`}
/>
<AnimatedView style={this.sendButtonContainerStyle}>
@@ -649,13 +653,19 @@
this.clearableTextInput = clearableTextInput;
};
+ selectableTextInputRef = (
+ selectableTextInput: ?React.ElementRef<typeof SelectableTextInput>,
+ ) => {
+ this.selectableTextInput = selectableTextInput;
+ };
+
updateText = (text: string) => {
this.setState({ text, textEdited: true });
this.saveDraft(text);
};
- updateSelection: (event: SelectionChangeEvent) => void = event => {
- this.setState({ selection: event.nativeEvent.selection });
+ updateSelectionState: (data: SyncedSelectionData) => void = data => {
+ this.setState({ selectionState: data });
};
saveDraft = _throttle(text => {
@@ -669,10 +679,11 @@
}, 400);
focusAndUpdateTextAndSelection = (text: string, selection: Selection) => {
+ this.selectableTextInput?.prepareForSelectionMutation(text, selection);
this.setState({
text,
textEdited: true,
- selection,
+ selectionState: { text, selection },
});
this.saveDraft(text);
diff --git a/native/components/selectable-text-input.js b/native/components/selectable-text-input.js
new file mode 100644
--- /dev/null
+++ b/native/components/selectable-text-input.js
@@ -0,0 +1,25 @@
+// @flow
+
+import * as React from 'react';
+
+import type { Selection } from 'lib/shared/typeahead-utils';
+
+import type { ClearableTextInputProps } from './clearable-text-input';
+import ClearableTextInput from './clearable-text-input.react';
+
+export type SyncedSelectionData = {
+ +text: string,
+ +selection: Selection,
+};
+
+export type SelectableTextInputProps = {
+ ...ClearableTextInputProps,
+ +clearableTextInputRef: (
+ clearableTextInput: ?React.ElementRef<typeof ClearableTextInput>,
+ ) => mixed,
+ +onUpdateSyncedSelectionData: (data: SyncedSelectionData) => mixed,
+};
+
+export type SelectableTextInputRef = {
+ +prepareForSelectionMutation: (text: string, selection: Selection) => void,
+};
diff --git a/native/components/selectable-text-input.react.ios.js b/native/components/selectable-text-input.react.ios.js
new file mode 100644
--- /dev/null
+++ b/native/components/selectable-text-input.react.ios.js
@@ -0,0 +1,44 @@
+// @flow
+
+import * as React from 'react';
+
+import ClearableTextInput from './clearable-text-input.react';
+import type {
+ SelectableTextInputProps,
+ SelectableTextInputRef,
+} from './selectable-text-input';
+
+const SelectableTextInput = React.forwardRef(function BaseSelectableTextInput(
+ props,
+ ref,
+): React.Node {
+ const { clearableTextInputRef, onUpdateSyncedSelectionData, ...rest } = props;
+
+ const clearableTextInputRefCallback = React.useCallback(
+ (clearableTextInput: ?React.ElementRef<typeof ClearableTextInput>) => {
+ clearableTextInputRef(clearableTextInput);
+ },
+ [clearableTextInputRef],
+ );
+
+ const prepareForSelectionMutation = React.useCallback(() => {}, []);
+ const ourRef = React.useMemo(
+ () => ({
+ prepareForSelectionMutation,
+ }),
+ [prepareForSelectionMutation],
+ );
+
+ React.useImperativeHandle(ref, () => ourRef, [ourRef]);
+
+ return <ClearableTextInput {...rest} ref={clearableTextInputRefCallback} />;
+});
+
+const MemoizedSelectableTextInput: React.AbstractComponent<
+ SelectableTextInputProps,
+ SelectableTextInputRef,
+> = React.memo<SelectableTextInputProps, SelectableTextInputRef>(
+ SelectableTextInput,
+);
+
+export default MemoizedSelectableTextInput;
diff --git a/native/components/selectable-text-input.react.js b/native/components/selectable-text-input.react.js
new file mode 100644
--- /dev/null
+++ b/native/components/selectable-text-input.react.js
@@ -0,0 +1,44 @@
+// @flow
+
+import * as React from 'react';
+
+import ClearableTextInput from './clearable-text-input.react';
+import type {
+ SelectableTextInputProps,
+ SelectableTextInputRef,
+} from './selectable-text-input';
+
+const SelectableTextInput = React.forwardRef(function BaseSelectableTextInput(
+ props,
+ ref,
+): React.Node {
+ const { clearableTextInputRef, onUpdateSyncedSelectionData, ...rest } = props;
+
+ const clearableTextInputRefCallback = React.useCallback(
+ (clearableTextInput: ?React.ElementRef<typeof ClearableTextInput>) => {
+ clearableTextInputRef(clearableTextInput);
+ },
+ [clearableTextInputRef],
+ );
+
+ const prepareForSelectionMutation = React.useCallback(() => {}, []);
+ const ourRef = React.useMemo(
+ () => ({
+ prepareForSelectionMutation,
+ }),
+ [prepareForSelectionMutation],
+ );
+
+ React.useImperativeHandle(ref, () => ourRef, [ourRef]);
+
+ return <ClearableTextInput {...rest} ref={clearableTextInputRefCallback} />;
+});
+
+const MemoizedSelectableTextInput: React.AbstractComponent<
+ SelectableTextInputProps,
+ SelectableTextInputRef,
+> = React.memo<SelectableTextInputProps, SelectableTextInputRef>(
+ SelectableTextInput,
+);
+
+export default MemoizedSelectableTextInput;

File Metadata

Mime Type
text/plain
Expires
Tue, Dec 9, 1:09 PM (12 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5854509
Default Alt Text
D6641.1765285753.diff (8 KB)

Event Timeline