Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F33126922
D8541.1768495818.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
20 KB
Referenced Files
None
Subscribers
None
D8541.1768495818.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D8541: [native] Factor out EditState into its own context
Attached
Detach File
Event Timeline
Log In to Comment