diff --git a/native/chat/settings/color-selector-modal.react.js b/native/chat/settings/color-selector-modal.react.js --- a/native/chat/settings/color-selector-modal.react.js +++ b/native/chat/settings/color-selector-modal.react.js @@ -91,13 +91,23 @@ setColor(colorEditValue); close(); + const action = changeThreadSettingsActionTypes.started; + const threadID = props.route.params.threadInfo.id; dispatchActionPromise( changeThreadSettingsActionTypes, editColor(colorEditValue), - { customKeyName: `${changeThreadSettingsActionTypes.started}:color` }, + { + customKeyName: `${action}:${threadID}:color`, + }, ); }, - [setColor, close, dispatchActionPromise, editColor], + [ + setColor, + close, + dispatchActionPromise, + editColor, + props.route.params.threadInfo.id, + ], ); const { colorSelectorContainer, closeButton, closeButtonIcon } = props.styles; diff --git a/native/chat/settings/thread-settings-color.react.js b/native/chat/settings/thread-settings-color.react.js --- a/native/chat/settings/thread-settings-color.react.js +++ b/native/chat/settings/thread-settings-color.react.js @@ -99,16 +99,17 @@ }, }; -const loadingStatusSelector = createLoadingStatusSelector( - changeThreadSettingsActionTypes, - `${changeThreadSettingsActionTypes.started}:color`, -); - const ConnectedThreadSettingsColor: React.ComponentType = React.memo(function ConnectedThreadSettingsColor( props: BaseProps, ) { - const loadingStatus = useSelector(loadingStatusSelector); + const threadID = props.threadInfo.id; + const loadingStatus = useSelector( + createLoadingStatusSelector( + changeThreadSettingsActionTypes, + `${changeThreadSettingsActionTypes.started}:${threadID}:color`, + ), + ); const colors = useColors(); const styles = useStyles(unboundStyles); return ( diff --git a/native/chat/settings/thread-settings-description.react.js b/native/chat/settings/thread-settings-description.react.js --- a/native/chat/settings/thread-settings-description.react.js +++ b/native/chat/settings/thread-settings-description.react.js @@ -207,11 +207,14 @@ } const editDescriptionPromise = this.editDescription(description); + const action = changeThreadSettingsActionTypes.started; + const threadID = this.props.threadInfo.id; + this.props.dispatchActionPromise( changeThreadSettingsActionTypes, editDescriptionPromise, { - customKeyName: `${changeThreadSettingsActionTypes.started}:description`, + customKeyName: `${action}:${threadID}:description`, }, ); editDescriptionPromise.then(() => { @@ -289,16 +292,17 @@ }, }; -const loadingStatusSelector = createLoadingStatusSelector( - changeThreadSettingsActionTypes, - `${changeThreadSettingsActionTypes.started}:description`, -); - const ConnectedThreadSettingsDescription: React.ComponentType = React.memo(function ConnectedThreadSettingsDescription( props: BaseProps, ) { - const loadingStatus = useSelector(loadingStatusSelector); + const threadID = props.threadInfo.id; + const loadingStatus = useSelector( + createLoadingStatusSelector( + changeThreadSettingsActionTypes, + `${changeThreadSettingsActionTypes.started}:${threadID}:description`, + ), + ); const colors = useColors(); const styles = useStyles(unboundStyles); diff --git a/native/chat/settings/thread-settings-leave-thread.react.js b/native/chat/settings/thread-settings-leave-thread.react.js --- a/native/chat/settings/thread-settings-leave-thread.react.js +++ b/native/chat/settings/thread-settings-leave-thread.react.js @@ -93,9 +93,13 @@ }; onConfirmLeaveThread = () => { + const threadID = this.props.threadInfo.id; this.props.dispatchActionPromise( leaveThreadActionTypes, this.leaveThread(), + { + customKeyName: `${leaveThreadActionTypes.started}:${threadID}`, + }, ); }; @@ -143,15 +147,17 @@ }, }; -const loadingStatusSelector = createLoadingStatusSelector( - leaveThreadActionTypes, -); - const ConnectedThreadSettingsLeaveThread: React.ComponentType = React.memo(function ConnectedThreadSettingsLeaveThread( props: BaseProps, ) { - const loadingStatus = useSelector(loadingStatusSelector); + const threadID = props.threadInfo.id; + const loadingStatus = useSelector( + createLoadingStatusSelector( + leaveThreadActionTypes, + `${leaveThreadActionTypes.started}:${threadID}`, + ), + ); const otherUsersButNoOtherAdminsValue = useSelector( otherUsersButNoOtherAdmins(props.threadInfo.id), ); diff --git a/native/chat/settings/thread-settings-name.react.js b/native/chat/settings/thread-settings-name.react.js --- a/native/chat/settings/thread-settings-name.react.js +++ b/native/chat/settings/thread-settings-name.react.js @@ -151,10 +151,15 @@ } const editNamePromise = this.editName(name); + const action = changeThreadSettingsActionTypes.started; + const threadID = this.props.threadInfo.id; + this.props.dispatchActionPromise( changeThreadSettingsActionTypes, editNamePromise, - { customKeyName: `${changeThreadSettingsActionTypes.started}:name` }, + { + customKeyName: `${action}:${threadID}:name`, + }, ); editNamePromise.then(() => { this.props.setNameEditValue(null); @@ -211,16 +216,18 @@ }, }; -const loadingStatusSelector = createLoadingStatusSelector( - changeThreadSettingsActionTypes, - `${changeThreadSettingsActionTypes.started}:name`, -); - const ConnectedThreadSettingsName: React.ComponentType = React.memo(function ConnectedThreadSettingsName(props: BaseProps) { const styles = useStyles(unboundStyles); const colors = useColors(); - const loadingStatus = useSelector(loadingStatusSelector); + + const threadID = props.threadInfo.id; + const loadingStatus = useSelector( + createLoadingStatusSelector( + changeThreadSettingsActionTypes, + `${changeThreadSettingsActionTypes.started}:${threadID}:name`, + ), + ); const dispatchActionPromise = useDispatchActionPromise(); const callChangeThreadSettings = useServerCall(changeThreadSettings); diff --git a/native/chat/settings/thread-settings.react.js b/native/chat/settings/thread-settings.react.js --- a/native/chat/settings/thread-settings.react.js +++ b/native/chat/settings/thread-settings.react.js @@ -1108,34 +1108,10 @@ }, }; -const editNameLoadingStatusSelector = createLoadingStatusSelector( - changeThreadSettingsActionTypes, - `${changeThreadSettingsActionTypes.started}:name`, -); -const editColorLoadingStatusSelector = createLoadingStatusSelector( - changeThreadSettingsActionTypes, - `${changeThreadSettingsActionTypes.started}:color`, -); -const editDescriptionLoadingStatusSelector = createLoadingStatusSelector( - changeThreadSettingsActionTypes, - `${changeThreadSettingsActionTypes.started}:description`, -); -const leaveThreadLoadingStatusSelector = createLoadingStatusSelector( - leaveThreadActionTypes, -); - -const somethingIsSaving = ( +const threadMembersChangeIsSaving = ( state: AppState, threadMembers: $ReadOnlyArray, ) => { - if ( - editNameLoadingStatusSelector(state) === 'loading' || - editColorLoadingStatusSelector(state) === 'loading' || - editDescriptionLoadingStatusSelector(state) === 'loading' || - leaveThreadLoadingStatusSelector(state) === 'loading' - ) { - return true; - } for (const threadMember of threadMembers) { const removeUserLoadingStatus = createLoadingStatusSelector( removeUsersFromThreadActionTypes, @@ -1207,9 +1183,41 @@ const resolvedChildThreadInfos = useResolvedOptionalThreadInfos( boundChildThreadInfos, ); - const boundSomethingIsSaving = useSelector(state => - somethingIsSaving(state, threadMembers), - ); + + const somethingIsSaving = useSelector(state => { + const editNameLoadingStatus = createLoadingStatusSelector( + changeThreadSettingsActionTypes, + `${changeThreadSettingsActionTypes.started}:${threadID}:name`, + )(state); + + const editColorLoadingStatus = createLoadingStatusSelector( + changeThreadSettingsActionTypes, + `${changeThreadSettingsActionTypes.started}:${threadID}:color`, + )(state); + + const editDescriptionLoadingStatus = createLoadingStatusSelector( + changeThreadSettingsActionTypes, + `${changeThreadSettingsActionTypes.started}:${threadID}:description`, + )(state); + + const leaveThreadLoadingStatus = createLoadingStatusSelector( + leaveThreadActionTypes, + `${leaveThreadActionTypes.started}:${threadID}`, + )(state); + + const boundThreadMembersChangeIsSaving = threadMembersChangeIsSaving( + state, + threadMembers, + ); + + return ( + boundThreadMembersChangeIsSaving || + editNameLoadingStatus === 'loading' || + editColorLoadingStatus === 'loading' || + editDescriptionLoadingStatus === 'loading' || + leaveThreadLoadingStatus === 'loading' + ); + }); const { navigation } = props; React.useEffect(() => { @@ -1217,14 +1225,14 @@ invariant(tabNavigation, 'ChatNavigator should be within TabNavigator'); const onTabPress = () => { - if (navigation.isFocused() && !boundSomethingIsSaving) { + if (navigation.isFocused() && !somethingIsSaving) { navigation.popToTop(); } }; tabNavigation.addListener('tabPress', onTabPress); return () => tabNavigation.removeListener('tabPress', onTabPress); - }, [navigation, boundSomethingIsSaving]); + }, [navigation, somethingIsSaving]); const styles = useStyles(unboundStyles); const indicatorStyle = useIndicatorStyle(); @@ -1241,7 +1249,7 @@ threadInfo={resolvedThreadInfo} parentThreadInfo={resolvedParentThreadInfo} childThreadInfos={resolvedChildThreadInfos} - somethingIsSaving={boundSomethingIsSaving} + somethingIsSaving={somethingIsSaving} styles={styles} indicatorStyle={indicatorStyle} overlayContext={overlayContext}