Page MenuHomePhorge

D8541.1768495818.diff
No OneTemporary

Size
20 KB
Referenced Files
None
Subscribers
None

D8541.1768495818.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
@@ -84,6 +84,10 @@
import { ChatContext } from './chat-context.js';
import type { ChatNavigationProp } from './chat.react.js';
+import {
+ MessageEditingContext,
+ type MessageEditingContextType,
+} from './message-editing-context.react.js';
import type { RemoveEditMode } from './message-list-types.js';
import TypeaheadTooltip from './typeahead-tooltip.react.js';
import Button from '../components/button.react.js';
@@ -173,6 +177,7 @@
) => Promise<SendEditMessageResponse>,
+navigation: ?ChatNavigationProp<'MessageList'>,
+overlayContext: ?OverlayContextType,
+ +messageEditingContext: ?MessageEditingContextType,
};
type State = {
+text: string,
@@ -432,8 +437,8 @@
}
if (
- this.props.inputState?.editState.editedMessage &&
- !prevProps.inputState?.editState.editedMessage
+ this.props.messageEditingContext?.editState.editedMessage &&
+ !prevProps.messageEditingContext?.editState.editedMessage
) {
this.blockNavigation();
}
@@ -766,7 +771,9 @@
return;
}
this.setState({ text, textEdited: true });
- this.props.inputState?.setEditedMessageChanged(this.isMessageEdited(text));
+ this.props.messageEditingContext?.setEditedMessageChanged(
+ this.isMessageEdited(text),
+ );
if (this.isEditMode()) {
return;
}
@@ -870,7 +877,7 @@
};
isEditMode = () => {
- const editState = this.props.inputState?.editState;
+ const editState = this.props.messageEditingContext?.editState;
const isThisThread =
editState?.editedMessage?.threadID === this.props.threadInfo.id;
return editState && editState.editedMessage !== null && isThisThread;
@@ -946,7 +953,7 @@
};
getEditedMessage = () => {
- const editState = this.props.inputState?.editState;
+ const editState = this.props.messageEditingContext?.editState;
return editState?.editedMessage;
};
@@ -970,7 +977,7 @@
};
exitEditMode = () => {
- this.props.inputState?.setEditedMessage(null, () => {
+ this.props.messageEditingContext?.setEditedMessage(null, () => {
this.unblockNavigation();
this.updateText(this.props.draft);
this.focusAndUpdateButtonsVisibility();
@@ -999,7 +1006,7 @@
const { action } = e.data;
e.preventDefault();
const saveExit = () => {
- this.props.inputState?.setEditedMessage(null, () => {
+ this.props.messageEditingContext?.setEditedMessage(null, () => {
this.setState({ isExitingDuringEditMode: true }, () => {
if (!this.props.navigation) {
return;
@@ -1251,7 +1258,9 @@
parentThreadInfo,
);
- const editedMessageInfo = inputState?.editState.editedMessage;
+ const messageEditingContext = React.useContext(MessageEditingContext);
+
+ const editedMessageInfo = messageEditingContext?.editState.editedMessage;
const editedMessagePreview = useMessagePreview(
editedMessageInfo,
props.threadInfo,
@@ -1285,6 +1294,7 @@
editMessage={editMessage}
navigation={props.navigation}
overlayContext={overlayContext}
+ messageEditingContext={messageEditingContext}
/>
);
}
diff --git a/native/chat/composed-message.react.js b/native/chat/composed-message.react.js
--- a/native/chat/composed-message.react.js
+++ b/native/chat/composed-message.react.js
@@ -23,6 +23,7 @@
import { useComposedMessageMaxWidth } from './composed-message-width.js';
import { FailedSend } from './failed-send.react.js';
import { InlineEngagement } from './inline-engagement.react.js';
+import { MessageEditingContext } from './message-editing-context.react.js';
import { MessageHeader } from './message-header.react.js';
import { useNavigateToSidebar } from './sidebar-navigation.js';
import SwipeableMessage from './swipeable-message.react.js';
@@ -298,15 +299,18 @@
const navigateToSidebar = useNavigateToSidebar(props.item);
const contentAndHeaderOpacity = useContentAndHeaderOpacity(props.item);
const deliveryIconOpacity = useDeliveryIconOpacity(props.item);
+
+ const messageEditingContext = React.useContext(MessageEditingContext);
const progress = useDerivedValue(() => {
const isThisThread =
- inputState?.editState.editedMessage?.threadID ===
+ messageEditingContext?.editState.editedMessage?.threadID ===
props.item.threadInfo.id;
const isHighlighted =
- inputState?.editState.editedMessage?.id === props.item.messageInfo.id &&
- isThisThread;
+ messageEditingContext?.editState.editedMessage?.id ===
+ props.item.messageInfo.id && isThisThread;
return withTiming(isHighlighted ? 1 : 0);
});
+
const editedMessageStyle = useAnimatedStyle(() => {
const backgroundColor = interpolateColor(
progress.value,
diff --git a/native/chat/message-editing-context-provider.react.js b/native/chat/message-editing-context-provider.react.js
new file mode 100644
--- /dev/null
+++ b/native/chat/message-editing-context-provider.react.js
@@ -0,0 +1,74 @@
+// @flow
+
+import * as React from 'react';
+
+import type { MessageInfo } from 'lib/types/message-types.js';
+
+import {
+ type EditState,
+ MessageEditingContext,
+} from './message-editing-context.react.js';
+
+const defaultEditState = {
+ editedMessage: null,
+ isEditedMessageChanged: false,
+};
+
+type Props = {
+ +children: React.Node,
+};
+function MessageEditingContextProvider(props: Props): React.Node {
+ const [editState, setEditState] = React.useState<EditState>(defaultEditState);
+
+ const pendingCallbacksRef = React.useRef([]);
+
+ const setEditedMessage = React.useCallback(
+ (editedMessage: ?MessageInfo, callback?: () => void) => {
+ if (callback) {
+ pendingCallbacksRef.current.push(callback);
+ }
+ setEditState({ editedMessage, isEditedMessageChanged: false });
+ },
+ [],
+ );
+
+ React.useEffect(() => {
+ if (pendingCallbacksRef.current.length === 0) {
+ return;
+ }
+ for (const callback of pendingCallbacksRef.current) {
+ callback();
+ }
+ pendingCallbacksRef.current = [];
+ }, [editState]);
+
+ const setEditedMessageChanged = React.useCallback(
+ (isEditedMessageChanged: boolean) => {
+ setEditState(prevEditState => ({
+ ...prevEditState,
+ isEditedMessageChanged,
+ }));
+ },
+ [],
+ );
+
+ const contextValue = React.useMemo(
+ () => ({
+ editState,
+ setEditedMessage,
+ setEditedMessageChanged,
+ }),
+ [editState, setEditedMessage, setEditedMessageChanged],
+ );
+
+ return (
+ <MessageEditingContext.Provider value={contextValue}>
+ {props.children}
+ </MessageEditingContext.Provider>
+ );
+}
+
+const MemoizedMessageEditingContextProvider: React.ComponentType<Props> =
+ React.memo<Props>(MessageEditingContextProvider);
+
+export default MemoizedMessageEditingContextProvider;
diff --git a/native/chat/message-editing-context.react.js b/native/chat/message-editing-context.react.js
new file mode 100644
--- /dev/null
+++ b/native/chat/message-editing-context.react.js
@@ -0,0 +1,24 @@
+// @flow
+
+import * as React from 'react';
+
+import type { MessageInfo } from 'lib/types/message-types.js';
+
+export type EditState = {
+ +editedMessage: ?MessageInfo,
+ +isEditedMessageChanged: boolean,
+};
+
+export type MessageEditingContextType = {
+ +editState: EditState,
+ +setEditedMessage: (
+ editedMessage: ?MessageInfo,
+ callback?: () => void,
+ ) => void,
+ +setEditedMessageChanged: (isEditedMessageChanged: boolean) => void,
+};
+
+const MessageEditingContext: React.Context<?MessageEditingContextType> =
+ React.createContext<?MessageEditingContextType>(null);
+
+export { MessageEditingContext };
diff --git a/native/chat/text-message-tooltip-modal.react.js b/native/chat/text-message-tooltip-modal.react.js
--- a/native/chat/text-message-tooltip-modal.react.js
+++ b/native/chat/text-message-tooltip-modal.react.js
@@ -6,6 +6,7 @@
import { createMessageReply } from 'lib/shared/message-utils.js';
+import { MessageEditingContext } from './message-editing-context.react.js';
import { useNavigateToThread } from './message-list-types.js';
import { useOnPressReport } from './message-report-utils.js';
import { useAnimatedNavigateToSidebar } from './sidebar-navigation.js';
@@ -66,11 +67,14 @@
[],
);
+ const messageEditingContext = React.useContext(MessageEditingContext);
+
const { messageInfo } = route.params.item;
const onPressEdit = React.useCallback(() => {
invariant(
- inputState,
- 'inputState should be set in TextMessageTooltipModal.onPressEdit',
+ inputState && messageEditingContext,
+ 'inputState and messageEditingContext should be set in ' +
+ 'TextMessageTooltipModal.onPressEdit',
);
const updateInputBar = () => {
inputState.editInputMessage({
@@ -79,9 +83,10 @@
});
};
const enterEditMode = () => {
- inputState.setEditedMessage(messageInfo, updateInputBar);
+ messageEditingContext.setEditedMessage(messageInfo, updateInputBar);
};
- const { editedMessage, isEditedMessageChanged } = inputState.editState;
+ const { editedMessage, isEditedMessageChanged } =
+ messageEditingContext.editState;
if (isEditedMessageChanged && editedMessage) {
exitEditAlert({
onDiscard: enterEditMode,
@@ -89,7 +94,7 @@
} else {
enterEditMode();
}
- }, [inputState, messageInfo, text]);
+ }, [inputState, messageEditingContext, messageInfo, text]);
const renderEditIcon = React.useCallback(
style => <SWMansionIcon name="edit-1" style={style} size={16} />,
[],
diff --git a/native/chat/text-message.react.js b/native/chat/text-message.react.js
--- a/native/chat/text-message.react.js
+++ b/native/chat/text-message.react.js
@@ -15,6 +15,7 @@
import type { ChatNavigationProp } from './chat.react.js';
import ComposedMessage from './composed-message.react.js';
import { InnerTextMessage } from './inner-text-message.react.js';
+import { MessageEditingContext } from './message-editing-context.react.js';
import {
MessagePressResponderContext,
type MessagePressResponderContextType,
@@ -22,7 +23,6 @@
import textMessageSendFailed from './text-message-send-failed.js';
import { getMessageTooltipKey } from './utils.js';
import { ChatContext, type ChatContextType } from '../chat/chat-context.js';
-import { InputStateContext } from '../input/input-state.js';
import { MarkdownContext } from '../markdown/markdown-context.js';
import type { AppNavigationProp } from '../navigation/app-navigator.react';
import {
@@ -249,7 +249,6 @@
const overlayContext = React.useContext(OverlayContext);
const chatContext = React.useContext(ChatContext);
const markdownContext = React.useContext(MarkdownContext);
- const inputContext = React.useContext(InputStateContext);
invariant(markdownContext, 'markdownContext should be set');
const { linkModalActive, clearMarkdownContextData } = markdownContext;
@@ -266,8 +265,9 @@
props.item.messageInfo,
);
- const isThisMessageEdited =
- inputContext?.editState.editedMessage?.id === props.item.messageInfo.id;
+ const messageEditingContext = React.useContext(MessageEditingContext);
+ const editMessageID = messageEditingContext?.editState.editedMessage?.id;
+ const isThisMessageEdited = editMessageID === props.item.messageInfo.id;
const canEditMessage =
useCanEditMessage(props.item.threadInfo, props.item.messageInfo) &&
diff --git a/native/input/input-state-container.react.js b/native/input/input-state-container.react.js
--- a/native/input/input-state-container.react.js
+++ b/native/input/input-state-container.react.js
@@ -65,7 +65,6 @@
type RawMultimediaMessageInfo,
type SendMessageResult,
type SendMessagePayload,
- type MessageInfo,
} from 'lib/types/message-types.js';
import type { RawImagesMessageInfo } from 'lib/types/messages/images.js';
import type {
@@ -106,7 +105,6 @@
import {
type EditInputBarMessageParameters,
- type EditState,
InputStateContext,
type PendingMultimediaUploads,
type MultimediaProcessingStep,
@@ -168,15 +166,10 @@
};
type State = {
+pendingUploads: PendingMultimediaUploads,
- +editState: EditState,
};
class InputStateContainer extends React.PureComponent<Props, State> {
state: State = {
pendingUploads: {},
- editState: {
- editedMessage: null,
- isEditedMessageChanged: false,
- },
};
sendCallbacks: Array<() => void> = [];
activeURIs = new Map();
@@ -407,8 +400,7 @@
inputStateSelector = createSelector(
(state: State) => state.pendingUploads,
- (state: State) => state.editState,
- (pendingUploads: PendingMultimediaUploads, editState: EditState) => ({
+ (pendingUploads: PendingMultimediaUploads) => ({
pendingUploads,
sendTextMessage: this.sendTextMessage,
sendMultimediaMessage: this.sendMultimediaMessage,
@@ -422,9 +414,6 @@
uploadInProgress: this.uploadInProgress,
reportURIDisplayed: this.reportURIDisplayed,
setPendingThreadUpdateHandler: this.setPendingThreadUpdateHandler,
- editState,
- setEditedMessage: this.setEditedMessage,
- setEditedMessageChanged: this.setEditedMessageChanged,
scrollToMessage: this.scrollToMessage,
addScrollToMessageListener: this.addScrollToMessageListener,
removeScrollToMessageListener: this.removeScrollToMessageListener,
@@ -1427,21 +1416,6 @@
this.editInputBarCallbacks.push(callbackEditInputBar);
};
- setEditedMessage = (editedMessage: ?MessageInfo, callback?: () => void) => {
- this.setState(
- {
- editState: { editedMessage, isEditedMessageChanged: false },
- },
- callback,
- );
- };
-
- setEditedMessageChanged = (isEditedMessageChanged: boolean) => {
- this.setState(prevState => ({
- editState: { ...prevState.editState, isEditedMessageChanged },
- }));
- };
-
removeEditInputMessageListener = (
callbackEditInputBar: (params: EditInputBarMessageParameters) => void,
) => {
diff --git a/native/input/input-state.js b/native/input/input-state.js
--- a/native/input/input-state.js
+++ b/native/input/input-state.js
@@ -3,7 +3,6 @@
import * as React from 'react';
import type { NativeMediaSelection } from 'lib/types/media-types.js';
-import type { MessageInfo } from 'lib/types/message-types.js';
import type { RawTextMessageInfo } from 'lib/types/messages/text.js';
import type { ThreadInfo } from 'lib/types/thread-types.js';
@@ -23,11 +22,6 @@
[localMessageID: string]: MessagePendingUploads,
};
-export type EditState = {
- +editedMessage: ?MessageInfo,
- +isEditedMessageChanged: boolean,
-};
-
export type EditInputBarMessageParameters = {
+message: string,
+mode: 'prepend' | 'replace',
@@ -65,12 +59,6 @@
threadID: string,
pendingThreadUpdateHandler: ?(ThreadInfo) => mixed,
) => void,
- +editState: EditState,
- +setEditedMessage: (
- editedMessage: ?MessageInfo,
- callback?: () => void,
- ) => void,
- +setEditedMessageChanged: (isEditedMessageChanged: boolean) => void,
+scrollToMessage: (messageKey: string) => void,
+addScrollToMessageListener: ((messageKey: string) => void) => void,
+removeScrollToMessageListener: ((messageKey: string) => void) => void,
diff --git a/native/root.react.js b/native/root.react.js
--- a/native/root.react.js
+++ b/native/root.react.js
@@ -26,6 +26,7 @@
import NativeEditThreadAvatarProvider from './avatars/native-edit-thread-avatar-provider.react.js';
import NativeEditUserAvatarProvider from './avatars/native-edit-user-avatar-provider.react.js';
import ChatContextProvider from './chat/chat-context-provider.react.js';
+import MessageEditingContextProvider from './chat/message-editing-context-provider.react.js';
import { FeatureFlagsProvider } from './components/feature-flags-provider.react.js';
import PersistedStateGate from './components/persisted-state-gate.js';
import ConnectedStatusBar from './connected-status-bar.react.js';
@@ -260,41 +261,43 @@
<NavContext.Provider value={navContext}>
<RootContext.Provider value={rootContext}>
<InputStateContainer>
- <SafeAreaProvider initialMetrics={initialWindowMetrics}>
- <ActionSheetProvider>
- <ENSCacheProvider provider={provider}>
- <MediaCacheProvider persistence={filesystemMediaCache}>
- <NativeEditUserAvatarProvider>
- <NativeEditThreadAvatarProvider>
- <MarkdownContextProvider>
- <ChatContextProvider>
- <MessageSearchProvider>
- <RegistrationContextProvider>
- <SQLiteDataHandler />
- <ConnectedStatusBar />
- <ReduxPersistGate
- persistor={getPersistor()}
- >
- {gated}
- </ReduxPersistGate>
- <PersistedStateGate>
- <Socket
- detectUnsupervisedBackgroundRef={
- detectUnsupervisedBackgroundRef
- }
- />
- </PersistedStateGate>
- {navigation}
- </RegistrationContextProvider>
- </MessageSearchProvider>
- </ChatContextProvider>
- </MarkdownContextProvider>
- </NativeEditThreadAvatarProvider>
- </NativeEditUserAvatarProvider>
- </MediaCacheProvider>
- </ENSCacheProvider>
- </ActionSheetProvider>
- </SafeAreaProvider>
+ <MessageEditingContextProvider>
+ <SafeAreaProvider initialMetrics={initialWindowMetrics}>
+ <ActionSheetProvider>
+ <ENSCacheProvider provider={provider}>
+ <MediaCacheProvider persistence={filesystemMediaCache}>
+ <NativeEditUserAvatarProvider>
+ <NativeEditThreadAvatarProvider>
+ <MarkdownContextProvider>
+ <ChatContextProvider>
+ <MessageSearchProvider>
+ <RegistrationContextProvider>
+ <SQLiteDataHandler />
+ <ConnectedStatusBar />
+ <ReduxPersistGate
+ persistor={getPersistor()}
+ >
+ {gated}
+ </ReduxPersistGate>
+ <PersistedStateGate>
+ <Socket
+ detectUnsupervisedBackgroundRef={
+ detectUnsupervisedBackgroundRef
+ }
+ />
+ </PersistedStateGate>
+ {navigation}
+ </RegistrationContextProvider>
+ </MessageSearchProvider>
+ </ChatContextProvider>
+ </MarkdownContextProvider>
+ </NativeEditThreadAvatarProvider>
+ </NativeEditUserAvatarProvider>
+ </MediaCacheProvider>
+ </ENSCacheProvider>
+ </ActionSheetProvider>
+ </SafeAreaProvider>
+ </MessageEditingContextProvider>
</InputStateContainer>
</RootContext.Provider>
</NavContext.Provider>

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 15, 4:50 PM (13 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5938921
Default Alt Text
D8541.1768495818.diff (20 KB)

Event Timeline