Page MenuHomePhorge

D11031.1767420220.diff
No OneTemporary

Size
16 KB
Referenced Files
None
Subscribers
None

D11031.1767420220.diff

diff --git a/web/modals/threads/settings/thread-settings-delete-tab.react.js b/web/modals/threads/settings/thread-settings-delete-tab.react.js
--- a/web/modals/threads/settings/thread-settings-delete-tab.react.js
+++ b/web/modals/threads/settings/thread-settings-delete-tab.react.js
@@ -2,22 +2,14 @@
import * as React from 'react';
-import {
- deleteThreadActionTypes,
- useDeleteThread,
-} from 'lib/actions/thread-actions.js';
-import { useModalContext } from 'lib/components/modal-provider.react.js';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
-import { containedThreadInfos } from 'lib/selectors/thread-selectors.js';
import { type SetState } from 'lib/types/hook-types.js';
import type { ThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
-import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js';
import SubmitSection from './submit-section.react.js';
-import ThreadDeleteConfirmationModal from './thread-settings-delete-confirmation-modal.react.js';
import css from './thread-settings-delete-tab.css';
+import { useOnDeleteThread } from './thread-settings-utils.js';
import { buttonThemes } from '../../../components/button.react.js';
-import { useSelector } from '../../../redux/redux-utils.js';
type ThreadSettingsDeleteTabProps = {
+threadSettingsOperationInProgress: boolean,
@@ -36,69 +28,10 @@
errorMessage,
} = props;
- const modalContext = useModalContext();
- const dispatchActionPromise = useDispatchActionPromise();
- const callDeleteThread = useDeleteThread();
- const containedThreads = useSelector(
- state => containedThreadInfos(state)[threadInfo.id],
- );
- const shouldUseDeleteConfirmationModal = React.useMemo(
- () => containedThreads?.length > 0,
- [containedThreads?.length],
- );
-
- const popThreadDeleteConfirmationModal = React.useCallback(() => {
- if (shouldUseDeleteConfirmationModal) {
- modalContext.popModal();
- }
- }, [modalContext, shouldUseDeleteConfirmationModal]);
- const deleteThreadAction = React.useCallback(async () => {
- try {
- setErrorMessage('');
- const response = await callDeleteThread({ threadID: threadInfo.id });
- popThreadDeleteConfirmationModal();
- modalContext.popModal();
- return response;
- } catch (e) {
- popThreadDeleteConfirmationModal();
- setErrorMessage(
- e.message === 'invalid_credentials'
- ? 'permission not granted'
- : 'unknown error',
- );
- throw e;
- }
- }, [
- callDeleteThread,
- modalContext,
- popThreadDeleteConfirmationModal,
+ const onDeleteThread = useOnDeleteThread({
+ threadInfo,
setErrorMessage,
- threadInfo.id,
- ]);
- const dispatchDeleteThreadAction = React.useCallback(() => {
- void dispatchActionPromise(deleteThreadActionTypes, deleteThreadAction());
- }, [dispatchActionPromise, deleteThreadAction]);
- const onDelete = React.useCallback(
- (event: SyntheticEvent<HTMLElement>) => {
- event.preventDefault();
- if (shouldUseDeleteConfirmationModal) {
- modalContext.pushModal(
- <ThreadDeleteConfirmationModal
- threadInfo={threadInfo}
- onConfirmation={dispatchDeleteThreadAction}
- />,
- );
- } else {
- dispatchDeleteThreadAction();
- }
- },
- [
- dispatchDeleteThreadAction,
- modalContext,
- shouldUseDeleteConfirmationModal,
- threadInfo,
- ],
- );
+ });
return (
<form method="POST" className={css.container}>
@@ -117,7 +50,7 @@
</div>
<SubmitSection
errorMessage={errorMessage}
- onClick={onDelete}
+ onClick={onDeleteThread}
variant="filled"
buttonColor={buttonThemes.danger}
disabled={threadSettingsOperationInProgress}
diff --git a/web/modals/threads/settings/thread-settings-general-tab.react.js b/web/modals/threads/settings/thread-settings-general-tab.react.js
--- a/web/modals/threads/settings/thread-settings-general-tab.react.js
+++ b/web/modals/threads/settings/thread-settings-general-tab.react.js
@@ -3,21 +3,17 @@
import * as React from 'react';
import tinycolor from 'tinycolor2';
-import {
- changeThreadSettingsActionTypes,
- useChangeThreadSettings,
-} from 'lib/actions/thread-actions.js';
import { threadHasPermission } from 'lib/shared/thread-utils.js';
import { type SetState } from 'lib/types/hook-types.js';
import type { ThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
import { threadPermissions } from 'lib/types/thread-permission-types.js';
import { type ThreadChanges } from 'lib/types/thread-types.js';
-import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js';
import { firstLine } from 'lib/utils/string-utils.js';
import { chatNameMaxLength } from 'lib/utils/validation-utils.js';
import SubmitSection from './submit-section.react.js';
import css from './thread-settings-general-tab.css';
+import { useOnSaveGeneralThreadSettings } from './thread-settings-utils.js';
import EditThreadAvatar from '../../../avatars/edit-thread-avatar.react.js';
import LoadingIndicator from '../../../loading-indicator.react.js';
import Input from '../../input.react.js';
@@ -45,9 +41,6 @@
errorMessage,
} = props;
- const dispatchActionPromise = useDispatchActionPromise();
- const callChangeThreadSettings = useChangeThreadSettings();
-
const nameInputRef = React.useRef<?HTMLInputElement>();
React.useEffect(() => {
@@ -99,37 +92,12 @@
[setQueuedChanges, threadInfo.color],
);
- const changeThreadSettingsAction = React.useCallback(async () => {
- try {
- setErrorMessage('');
- return await callChangeThreadSettings({
- threadID: threadInfo.id,
- changes: queuedChanges,
- });
- } catch (e) {
- setErrorMessage('unknown_error');
- throw e;
- } finally {
- setQueuedChanges(Object.freeze({}));
- }
- }, [
- callChangeThreadSettings,
+ const onSaveGeneralThreadSettings = useOnSaveGeneralThreadSettings({
+ threadInfo,
queuedChanges,
- setErrorMessage,
setQueuedChanges,
- threadInfo.id,
- ]);
-
- const onSubmit = React.useCallback(
- (event: SyntheticEvent<HTMLElement>) => {
- event.preventDefault();
- void dispatchActionPromise(
- changeThreadSettingsActionTypes,
- changeThreadSettingsAction(),
- );
- },
- [changeThreadSettingsAction, dispatchActionPromise],
- );
+ setErrorMessage,
+ });
const threadNameInputDisabled = !threadHasPermission(
threadInfo,
@@ -188,7 +156,7 @@
<SubmitSection
variant="filled"
errorMessage={errorMessage}
- onClick={onSubmit}
+ onClick={onSaveGeneralThreadSettings}
disabled={threadSettingsOperationInProgress || !changeQueued}
>
{saveButtonContent}
diff --git a/web/modals/threads/settings/thread-settings-privacy-tab.react.js b/web/modals/threads/settings/thread-settings-privacy-tab.react.js
--- a/web/modals/threads/settings/thread-settings-privacy-tab.react.js
+++ b/web/modals/threads/settings/thread-settings-privacy-tab.react.js
@@ -2,21 +2,16 @@
import * as React from 'react';
-import {
- changeThreadSettingsActionTypes,
- useChangeThreadSettings,
-} from 'lib/actions/thread-actions.js';
-import { useModalContext } from 'lib/components/modal-provider.react.js';
import SWMansionIcon from 'lib/components/SWMansionIcon.react.js';
import { threadTypeDescriptions } from 'lib/shared/thread-utils.js';
import { type SetState } from 'lib/types/hook-types.js';
import type { ThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
import { threadTypes } from 'lib/types/thread-types-enum.js';
import { type ThreadChanges } from 'lib/types/thread-types.js';
-import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js';
import SubmitSection from './submit-section.react.js';
import css from './thread-settings-privacy-tab.css';
+import { useOnSavePrivacyThreadSettings } from './thread-settings-utils.js';
import EnumSettingsOption from '../../../components/enum-settings-option.react.js';
const { COMMUNITY_OPEN_SUBTHREAD, COMMUNITY_SECRET_SUBTHREAD } = threadTypes;
@@ -57,48 +52,17 @@
errorMessage,
} = props;
- const modalContext = useModalContext();
- const dispatchActionPromise = useDispatchActionPromise();
- const callChangeThreadSettings = useChangeThreadSettings();
-
const changeQueued: boolean = React.useMemo(
() => Object.values(queuedChanges).some(v => v !== null && v !== undefined),
[queuedChanges],
);
- const changeThreadSettingsAction = React.useCallback(async () => {
- try {
- setErrorMessage('');
- const response = await callChangeThreadSettings({
- threadID: threadInfo.id,
- changes: queuedChanges,
- });
- modalContext.popModal();
- return response;
- } catch (e) {
- setErrorMessage('unknown_error');
- setQueuedChanges(Object.freeze({}));
- throw e;
- }
- }, [
- callChangeThreadSettings,
- modalContext,
+ const onSavePrivacyThreadSettings = useOnSavePrivacyThreadSettings({
+ threadInfo,
queuedChanges,
- setErrorMessage,
setQueuedChanges,
- threadInfo.id,
- ]);
-
- const onSubmit = React.useCallback(
- (event: SyntheticEvent<HTMLElement>) => {
- event.preventDefault();
- void dispatchActionPromise(
- changeThreadSettingsActionTypes,
- changeThreadSettingsAction(),
- );
- },
- [changeThreadSettingsAction, dispatchActionPromise],
- );
+ setErrorMessage,
+ });
const onOpenSelected = React.useCallback(() => {
setQueuedChanges(prevQueuedChanges =>
@@ -161,7 +125,7 @@
<SubmitSection
variant="filled"
- onClick={onSubmit}
+ onClick={onSavePrivacyThreadSettings}
disabled={threadSettingsOperationInProgress || !changeQueued}
errorMessage={errorMessage}
>
diff --git a/web/modals/threads/settings/thread-settings-utils.js b/web/modals/threads/settings/thread-settings-utils.js
new file mode 100644
--- /dev/null
+++ b/web/modals/threads/settings/thread-settings-utils.js
@@ -0,0 +1,211 @@
+// @flow
+
+import * as React from 'react';
+
+import {
+ changeThreadSettingsActionTypes,
+ useChangeThreadSettings,
+ deleteThreadActionTypes,
+ useDeleteThread,
+} from 'lib/actions/thread-actions.js';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
+import { containedThreadInfos } from 'lib/selectors/thread-selectors.js';
+import { type SetState } from 'lib/types/hook-types.js';
+import type { ThreadInfo } from 'lib/types/minimally-encoded-thread-permissions-types.js';
+import { type ThreadChanges } from 'lib/types/thread-types.js';
+import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js';
+
+import ThreadDeleteConfirmationModal from './thread-settings-delete-confirmation-modal.react.js';
+import { useSelector } from '../../../redux/redux-utils.js';
+
+type UseOnSaveGeneralThreadSettingsParams = {
+ +threadInfo: ThreadInfo,
+ +queuedChanges: ThreadChanges,
+ +setQueuedChanges: SetState<ThreadChanges>,
+ +setErrorMessage: SetState<?string>,
+};
+
+function useOnSaveGeneralThreadSettings(
+ params: UseOnSaveGeneralThreadSettingsParams,
+): (event: SyntheticEvent<HTMLElement>) => mixed {
+ const { threadInfo, queuedChanges, setQueuedChanges, setErrorMessage } =
+ params;
+
+ const dispatchActionPromise = useDispatchActionPromise();
+ const callChangeThreadSettings = useChangeThreadSettings();
+
+ const changeThreadSettingsAction = React.useCallback(async () => {
+ try {
+ setErrorMessage('');
+ return await callChangeThreadSettings({
+ threadID: threadInfo.id,
+ changes: queuedChanges,
+ });
+ } catch (e) {
+ setErrorMessage('unknown_error');
+ throw e;
+ } finally {
+ setQueuedChanges(Object.freeze({}));
+ }
+ }, [
+ callChangeThreadSettings,
+ queuedChanges,
+ setErrorMessage,
+ setQueuedChanges,
+ threadInfo.id,
+ ]);
+
+ const onSubmit = React.useCallback(
+ (event: SyntheticEvent<HTMLElement>) => {
+ event.preventDefault();
+ void dispatchActionPromise(
+ changeThreadSettingsActionTypes,
+ changeThreadSettingsAction(),
+ );
+ },
+ [changeThreadSettingsAction, dispatchActionPromise],
+ );
+
+ return onSubmit;
+}
+
+type UseOnSavePrivacySettingsParams = {
+ +threadInfo: ThreadInfo,
+ +queuedChanges: ThreadChanges,
+ +setQueuedChanges: SetState<ThreadChanges>,
+ +setErrorMessage: SetState<?string>,
+};
+
+function useOnSavePrivacyThreadSettings(
+ params: UseOnSavePrivacySettingsParams,
+): (event: SyntheticEvent<HTMLElement>) => mixed {
+ const { threadInfo, queuedChanges, setQueuedChanges, setErrorMessage } =
+ params;
+
+ const modalContext = useModalContext();
+ const dispatchActionPromise = useDispatchActionPromise();
+ const callChangeThreadSettings = useChangeThreadSettings();
+
+ const changeThreadSettingsAction = React.useCallback(async () => {
+ try {
+ setErrorMessage('');
+ const response = await callChangeThreadSettings({
+ threadID: threadInfo.id,
+ changes: queuedChanges,
+ });
+ modalContext.popModal();
+ return response;
+ } catch (e) {
+ setErrorMessage('unknown_error');
+ setQueuedChanges(Object.freeze({}));
+ throw e;
+ }
+ }, [
+ callChangeThreadSettings,
+ modalContext,
+ queuedChanges,
+ setErrorMessage,
+ setQueuedChanges,
+ threadInfo.id,
+ ]);
+
+ const onSubmit = React.useCallback(
+ (event: SyntheticEvent<HTMLElement>) => {
+ event.preventDefault();
+ void dispatchActionPromise(
+ changeThreadSettingsActionTypes,
+ changeThreadSettingsAction(),
+ );
+ },
+ [changeThreadSettingsAction, dispatchActionPromise],
+ );
+
+ return onSubmit;
+}
+
+type UseOnDeleteParams = {
+ +threadInfo: ThreadInfo,
+ +setErrorMessage: SetState<?string>,
+};
+
+function useOnDeleteThread(
+ params: UseOnDeleteParams,
+): (event: SyntheticEvent<HTMLElement>) => mixed {
+ const { threadInfo, setErrorMessage } = params;
+
+ const modalContext = useModalContext();
+ const dispatchActionPromise = useDispatchActionPromise();
+ const callDeleteThread = useDeleteThread();
+ const containedThreads = useSelector(
+ state => containedThreadInfos(state)[threadInfo.id],
+ );
+
+ const shouldUseDeleteConfirmationModal = React.useMemo(
+ () => containedThreads?.length > 0,
+ [containedThreads?.length],
+ );
+
+ const popThreadDeleteConfirmationModal = React.useCallback(() => {
+ if (shouldUseDeleteConfirmationModal) {
+ modalContext.popModal();
+ }
+ }, [modalContext, shouldUseDeleteConfirmationModal]);
+
+ const deleteThreadAction = React.useCallback(async () => {
+ try {
+ setErrorMessage('');
+ const response = await callDeleteThread({ threadID: threadInfo.id });
+ popThreadDeleteConfirmationModal();
+ modalContext.popModal();
+ return response;
+ } catch (e) {
+ popThreadDeleteConfirmationModal();
+ setErrorMessage(
+ e.message === 'invalid_credentials'
+ ? 'permission not granted'
+ : 'unknown error',
+ );
+ throw e;
+ }
+ }, [
+ callDeleteThread,
+ modalContext,
+ popThreadDeleteConfirmationModal,
+ setErrorMessage,
+ threadInfo.id,
+ ]);
+
+ const dispatchDeleteThreadAction = React.useCallback(() => {
+ void dispatchActionPromise(deleteThreadActionTypes, deleteThreadAction());
+ }, [dispatchActionPromise, deleteThreadAction]);
+
+ const onDelete = React.useCallback(
+ (event: SyntheticEvent<HTMLElement>) => {
+ event.preventDefault();
+ if (shouldUseDeleteConfirmationModal) {
+ modalContext.pushModal(
+ <ThreadDeleteConfirmationModal
+ threadInfo={threadInfo}
+ onConfirmation={dispatchDeleteThreadAction}
+ />,
+ );
+ } else {
+ dispatchDeleteThreadAction();
+ }
+ },
+ [
+ dispatchDeleteThreadAction,
+ modalContext,
+ shouldUseDeleteConfirmationModal,
+ threadInfo,
+ ],
+ );
+
+ return onDelete;
+}
+
+export {
+ useOnSaveGeneralThreadSettings,
+ useOnSavePrivacyThreadSettings,
+ useOnDeleteThread,
+};

File Metadata

Mime Type
text/plain
Expires
Sat, Jan 3, 6:03 AM (16 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5878086
Default Alt Text
D11031.1767420220.diff (16 KB)

Event Timeline