diff --git a/web/account/log-in-form.react.js b/web/account/log-in-form.react.js --- a/web/account/log-in-form.react.js +++ b/web/account/log-in-form.react.js @@ -4,6 +4,7 @@ import * as React from 'react'; import { logInActionTypes, logIn } from 'lib/actions/user-actions'; +import { useModalContext } from 'lib/components/modal-provider.react'; import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors'; import { oldValidUsernameRegex, @@ -22,7 +23,6 @@ import Button from '../components/button.react'; import LoadingIndicator from '../loading-indicator.react'; import Input from '../modals/input.react'; -import { useModalContext } from '../modals/modal-provider.react'; import { useSelector } from '../redux/redux-utils'; import { webLogInExtraInfoSelector } from '../selectors/account-selectors'; import css from './log-in-form.css'; diff --git a/web/app.react.js b/web/app.react.js --- a/web/app.react.js +++ b/web/app.react.js @@ -13,6 +13,10 @@ fetchEntriesActionTypes, updateCalendarQueryActionTypes, } from 'lib/actions/entry-actions'; +import { + ModalProvider, + useModalContext, +} from 'lib/components/modal-provider.react'; import { createLoadingStatusSelector, combineLoadingStatuses, @@ -31,7 +35,6 @@ import InputStateContainer from './input/input-state-container.react'; import LoadingIndicator from './loading-indicator.react'; import { MenuProvider } from './menu-provider.react'; -import { ModalProvider, useModalContext } from './modals/modal-provider.react'; import { updateNavInfoActionType } from './redux/action-types'; import DeviceIDUpdater from './redux/device-id-updater'; import DisconnectedBar from './redux/disconnected-bar'; diff --git a/web/calendar/day.react.js b/web/calendar/day.react.js --- a/web/calendar/day.react.js +++ b/web/calendar/day.react.js @@ -10,6 +10,7 @@ createLocalEntry, createLocalEntryActionType, } from 'lib/actions/entry-actions'; +import { useModalContext } from 'lib/components/modal-provider.react'; import { onScreenThreadInfos as onScreenThreadInfosSelector } from 'lib/selectors/thread-selectors'; import { entryKey } from 'lib/shared/entry-utils'; import type { EntryInfo } from 'lib/types/entry-types'; @@ -23,7 +24,6 @@ import LogInFirstModal from '../modals/account/log-in-first-modal.react'; import HistoryModal from '../modals/history/history-modal.react'; -import { useModalContext } from '../modals/modal-provider.react'; import ThreadPickerModal from '../modals/threads/thread-picker-modal.react'; import { useSelector } from '../redux/redux-utils'; import { htmlTargetFromEvent } from '../vector-utils'; diff --git a/web/calendar/entry.react.js b/web/calendar/entry.react.js --- a/web/calendar/entry.react.js +++ b/web/calendar/entry.react.js @@ -14,6 +14,7 @@ deleteEntry, concurrentModificationResetActionType, } from 'lib/actions/entry-actions'; +import { useModalContext } from 'lib/components/modal-provider.react'; import { threadInfoSelector } from 'lib/selectors/thread-selectors'; import { entryKey } from 'lib/shared/entry-utils'; import { colorIsDark, threadHasPermission } from 'lib/shared/thread-utils'; @@ -45,7 +46,6 @@ import LogInFirstModal from '../modals/account/log-in-first-modal.react'; import ConcurrentModificationModal from '../modals/concurrent-modification-modal.react'; import HistoryModal from '../modals/history/history-modal.react'; -import { useModalContext } from '../modals/modal-provider.react'; import { useSelector } from '../redux/redux-utils'; import { nonThreadCalendarQuery } from '../selectors/nav-selectors'; import { HistoryVector, DeleteVector } from '../vectors.react'; diff --git a/web/calendar/filter-panel.react.js b/web/calendar/filter-panel.react.js --- a/web/calendar/filter-panel.react.js +++ b/web/calendar/filter-panel.react.js @@ -12,6 +12,7 @@ import { useDispatch } from 'react-redux'; import Switch from 'react-switch'; +import { useModalContext } from 'lib/components/modal-provider.react'; import { filteredThreadIDsSelector, includeDeletedSelector, @@ -26,7 +27,6 @@ } from 'lib/types/filter-types'; import type { Dispatch } from 'lib/types/redux-types'; -import { useModalContext } from '../modals/modal-provider.react'; import ThreadSettingsModal from '../modals/threads/settings/thread-settings-modal.react'; import { useSelector } from '../redux/redux-utils'; import { diff --git a/web/chat/chat-thread-list-see-more-sidebars.react.js b/web/chat/chat-thread-list-see-more-sidebars.react.js --- a/web/chat/chat-thread-list-see-more-sidebars.react.js +++ b/web/chat/chat-thread-list-see-more-sidebars.react.js @@ -4,9 +4,9 @@ import * as React from 'react'; import { IoIosMore } from 'react-icons/io'; +import { useModalContext } from 'lib/components/modal-provider.react'; import type { ThreadInfo } from 'lib/types/thread-types'; -import { useModalContext } from '../modals/modal-provider.react'; import SidebarsModal from '../modals/threads/sidebars/sidebars-modal.react'; import css from './chat-thread-list.css'; diff --git a/web/chat/thread-menu.react.js b/web/chat/thread-menu.react.js --- a/web/chat/thread-menu.react.js +++ b/web/chat/thread-menu.react.js @@ -6,6 +6,7 @@ leaveThread, leaveThreadActionTypes, } from 'lib/actions/thread-actions'; +import { useModalContext } from 'lib/components/modal-provider.react'; import { usePromoteSidebar } from 'lib/hooks/promote-sidebar.react'; import { childThreadInfos } from 'lib/selectors/thread-selectors'; import { @@ -26,7 +27,6 @@ import MenuItem from '../components/menu-item.react'; import Menu from '../components/menu.react'; import SidebarPromoteModal from '../modals/chat/sidebar-promote-modal.react'; -import { useModalContext } from '../modals/modal-provider.react'; import ConfirmLeaveThreadModal from '../modals/threads/confirm-leave-thread-modal.react'; import ComposeSubchannelModal from '../modals/threads/create/compose-subchannel-modal.react'; import ThreadMembersModal from '../modals/threads/members/members-modal.react'; diff --git a/web/input/input-state-container.react.js b/web/input/input-state-container.react.js --- a/web/input/input-state-container.react.js +++ b/web/input/input-state-container.react.js @@ -28,6 +28,7 @@ type MultimediaUploadCallbacks, type MultimediaUploadExtras, } from 'lib/actions/upload-actions'; +import { useModalContext } from 'lib/components/modal-provider.react'; import { getNextLocalUploadID } from 'lib/media/media-utils'; import { pendingToRealizedThreadIDsSelector } from 'lib/selectors/thread-selectors'; import { @@ -73,7 +74,6 @@ import { validateFile, preloadImage } from '../media/media-utils'; import InvalidUploadModal from '../modals/chat/invalid-upload.react'; -import { useModalContext } from '../modals/modal-provider.react'; import { useSelector } from '../redux/redux-utils'; import { nonThreadCalendarQuery } from '../selectors/nav-selectors'; import { type PendingMultimediaUpload, InputStateContext } from './input-state'; diff --git a/web/media/multimedia-modal.react.js b/web/media/multimedia-modal.react.js --- a/web/media/multimedia-modal.react.js +++ b/web/media/multimedia-modal.react.js @@ -4,7 +4,8 @@ import * as React from 'react'; import { XCircle as XCircleIcon } from 'react-feather'; -import { useModalContext } from '../modals/modal-provider.react'; +import { useModalContext } from 'lib/components/modal-provider.react'; + import css from './media.css'; type BaseProps = { diff --git a/web/media/multimedia.react.js b/web/media/multimedia.react.js --- a/web/media/multimedia.react.js +++ b/web/media/multimedia.react.js @@ -10,8 +10,9 @@ AlertCircle as AlertCircleIcon, } from 'react-feather'; +import { useModalContext } from 'lib/components/modal-provider.react'; + import { type PendingMultimediaUpload } from '../input/input-state'; -import { useModalContext } from '../modals/modal-provider.react'; import css from './media.css'; import MultimediaModal from './multimedia-modal.react'; diff --git a/web/modals/account/log-in-first-modal.react.js b/web/modals/account/log-in-first-modal.react.js --- a/web/modals/account/log-in-first-modal.react.js +++ b/web/modals/account/log-in-first-modal.react.js @@ -2,7 +2,8 @@ import * as React from 'react'; -import { useModalContext } from '../../modals/modal-provider.react'; +import { useModalContext } from 'lib/components/modal-provider.react'; + import css from '../../style.css'; import Modal from '../modal.react'; import LogInModal from './log-in-modal.react'; diff --git a/web/modals/account/log-in-modal.react.js b/web/modals/account/log-in-modal.react.js --- a/web/modals/account/log-in-modal.react.js +++ b/web/modals/account/log-in-modal.react.js @@ -2,8 +2,9 @@ import * as React from 'react'; +import { useModalContext } from 'lib/components/modal-provider.react'; + import LoginForm from '../../account/log-in-form.react'; -import { useModalContext } from '../modal-provider.react'; import Modal from '../modal.react'; function LoginModal(): React.Node { diff --git a/web/modals/alert.react.js b/web/modals/alert.react.js --- a/web/modals/alert.react.js +++ b/web/modals/alert.react.js @@ -2,9 +2,10 @@ import * as React from 'react'; +import { useModalContext } from 'lib/components/modal-provider.react'; + import Button from '../components/button.react'; import css from './alert.css'; -import { useModalContext } from './modal-provider.react'; import Modal from './modal.react'; type AlertProps = { diff --git a/web/modals/concurrent-modification-modal.react.js b/web/modals/concurrent-modification-modal.react.js --- a/web/modals/concurrent-modification-modal.react.js +++ b/web/modals/concurrent-modification-modal.react.js @@ -2,9 +2,10 @@ import * as React from 'react'; +import { useModalContext } from 'lib/components/modal-provider.react'; + import Button from '../components/button.react'; import css from './concurrent-modification-modal.css'; -import { useModalContext } from './modal-provider.react'; import Modal from './modal.react'; type Props = { diff --git a/web/modals/history/history-modal.react.js b/web/modals/history/history-modal.react.js --- a/web/modals/history/history-modal.react.js +++ b/web/modals/history/history-modal.react.js @@ -15,6 +15,7 @@ fetchRevisionsForEntryActionTypes, fetchRevisionsForEntry, } from 'lib/actions/entry-actions'; +import { useModalContext } from 'lib/components/modal-provider.react'; import { nonExcludeDeletedCalendarFiltersSelector } from 'lib/selectors/calendar-filter-selectors'; import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors'; import type { @@ -33,7 +34,6 @@ import { dateFromString } from 'lib/utils/date-utils'; import LoadingIndicator from '../../loading-indicator.react'; -import { useModalContext } from '../../modals/modal-provider.react'; import { useSelector } from '../../redux/redux-utils'; import { allDaysToEntries } from '../../selectors/entry-selectors'; import Modal from '../modal.react'; diff --git a/web/modals/modal-provider.react.js b/web/modals/modal-provider.react.js deleted file mode 100644 --- a/web/modals/modal-provider.react.js +++ /dev/null @@ -1,65 +0,0 @@ -// @flow - -import invariant from 'invariant'; -import * as React from 'react'; - -import { getUUID } from 'lib/utils/uuid'; - -type Props = { - +children: React.Node, -}; -type ModalContextType = { - +modals: $ReadOnlyArray<[React.Node, string]>, - +pushModal: React.Node => void, - +popModal: () => void, - +clearModals: () => void, -}; - -const ModalContext: React.Context = React.createContext( - { - modals: [], - pushModal: () => {}, - popModal: () => {}, - clearModals: () => {}, - }, -); - -function ModalProvider(props: Props): React.Node { - const { children } = props; - const [modals, setModals] = React.useState< - $ReadOnlyArray<[React.Node, string]>, - >([]); - const popModal = React.useCallback( - () => setModals(oldModals => oldModals.slice(0, -1)), - [], - ); - const pushModal = React.useCallback(newModal => { - const key = getUUID(); - setModals(oldModals => [...oldModals, [newModal, key]]); - }, []); - - const clearModals = React.useCallback(() => setModals([]), []); - - const value = React.useMemo( - () => ({ - modals, - pushModal, - popModal, - clearModals, - }), - [modals, pushModal, popModal, clearModals], - ); - - return ( - {children} - ); -} - -function useModalContext(): ModalContextType { - const context = React.useContext(ModalContext); - invariant(context, 'ModalContext not found'); - - return context; -} - -export { ModalProvider, useModalContext }; diff --git a/web/modals/threads/members/members-modal.react.js b/web/modals/threads/members/members-modal.react.js --- a/web/modals/threads/members/members-modal.react.js +++ b/web/modals/threads/members/members-modal.react.js @@ -2,6 +2,7 @@ import * as React from 'react'; +import { useModalContext } from 'lib/components/modal-provider.react'; import { threadInfoSelector } from 'lib/selectors/thread-selectors'; import { userStoreSearchIndex } from 'lib/selectors/user-selectors'; import { @@ -17,7 +18,6 @@ import Button from '../../../components/button.react'; import Tabs from '../../../components/tabs.react'; import { useSelector } from '../../../redux/redux-utils'; -import { useModalContext } from '../../modal-provider.react'; import SearchModal from '../../search-modal.react'; import AddMembersModal from './add-members-modal.react'; import ThreadMembersList from './members-list.react'; 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 @@ -6,6 +6,7 @@ deleteThreadActionTypes, deleteThread, } from 'lib/actions/thread-actions'; +import { useModalContext } from 'lib/components/modal-provider.react'; import { type SetState } from 'lib/types/hook-types'; import { type ThreadInfo } from 'lib/types/thread-types'; import { @@ -15,7 +16,6 @@ import SWMansionIcon from '../../../SWMansionIcon.react'; import Input from '../../input.react'; -import { useModalContext } from '../../modal-provider.react'; import SubmitSection from './submit-section.react'; import css from './thread-settings-delete-tab.css'; diff --git a/web/modals/threads/settings/thread-settings-modal.react.js b/web/modals/threads/settings/thread-settings-modal.react.js --- a/web/modals/threads/settings/thread-settings-modal.react.js +++ b/web/modals/threads/settings/thread-settings-modal.react.js @@ -7,6 +7,7 @@ deleteThreadActionTypes, changeThreadSettingsActionTypes, } from 'lib/actions/thread-actions'; +import { useModalContext } from 'lib/components/modal-provider.react'; import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors'; import { threadInfoSelector } from 'lib/selectors/thread-selectors'; import { getAvailableRelationshipButtons } from 'lib/shared/relationship-utils'; @@ -24,7 +25,6 @@ import Tabs from '../../../components/tabs.react'; import { useSelector } from '../../../redux/redux-utils'; -import { useModalContext } from '../../modal-provider.react'; import Modal from '../../modal.react'; import ThreadSettingsDeleteTab from './thread-settings-delete-tab.react'; import ThreadSettingsGeneralTab from './thread-settings-general-tab.react'; 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 @@ -6,6 +6,7 @@ changeThreadSettings, changeThreadSettingsActionTypes, } from 'lib/actions/thread-actions'; +import { useModalContext } from 'lib/components/modal-provider.react'; import { threadTypeDescriptions } from 'lib/shared/thread-utils'; import { type SetState } from 'lib/types/hook-types'; import { @@ -20,7 +21,6 @@ import EnumSettingsOption from '../../../components/enum-settings-option.react'; import SWMansionIcon from '../../../SWMansionIcon.react'; -import { useModalContext } from '../../modal-provider.react'; import SubmitSection from './submit-section.react'; import css from './thread-settings-privacy-tab.css'; diff --git a/web/modals/threads/sidebars/sidebar.react.js b/web/modals/threads/sidebars/sidebar.react.js --- a/web/modals/threads/sidebars/sidebar.react.js +++ b/web/modals/threads/sidebars/sidebar.react.js @@ -2,6 +2,7 @@ import * as React from 'react'; +import { useModalContext } from 'lib/components/modal-provider.react'; import type { ChatThreadItem } from 'lib/selectors/chat-selectors'; import { getMessagePreview } from 'lib/shared/message-utils'; import { shortAbsoluteDate } from 'lib/utils/date-utils'; @@ -9,7 +10,6 @@ import { getDefaultTextMessageRules } from '../../../markdown/rules.react'; import { useSelector } from '../../../redux/redux-utils'; import { useOnClickThread } from '../../../selectors/nav-selectors'; -import { useModalContext } from '../../modal-provider.react'; import css from './sidebars-modal.css'; type Props = { diff --git a/web/modals/threads/subchannels/subchannel.react.js b/web/modals/threads/subchannels/subchannel.react.js --- a/web/modals/threads/subchannels/subchannel.react.js +++ b/web/modals/threads/subchannels/subchannel.react.js @@ -2,6 +2,7 @@ import * as React from 'react'; +import { useModalContext } from 'lib/components/modal-provider.react'; import { type ChatThreadItem } from 'lib/selectors/chat-selectors'; import { getMessagePreview } from 'lib/shared/message-utils'; import { shortAbsoluteDate } from 'lib/utils/date-utils'; @@ -10,7 +11,6 @@ import { useSelector } from '../../../redux/redux-utils'; import { useOnClickThread } from '../../../selectors/nav-selectors'; import SWMansionIcon from '../../../SWMansionIcon.react'; -import { useModalContext } from '../../modal-provider.react'; import css from './subchannels-modal.css'; type Props = { diff --git a/web/settings/account-delete-modal.react.js b/web/settings/account-delete-modal.react.js --- a/web/settings/account-delete-modal.react.js +++ b/web/settings/account-delete-modal.react.js @@ -7,6 +7,7 @@ deleteAccount, deleteAccountActionTypes, } from 'lib/actions/user-actions'; +import { useModalContext } from 'lib/components/modal-provider.react'; import { preRequestUserStateSelector } from 'lib/selectors/account-selectors'; import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors'; import type { LogOutResult } from 'lib/types/account-types'; @@ -19,7 +20,6 @@ import Button from '../components/button.react'; import Input from '../modals/input.react'; -import { useModalContext } from '../modals/modal-provider.react'; import Modal from '../modals/modal.react'; import { useSelector } from '../redux/redux-utils'; import SWMansionIcon from '../SWMansionIcon.react.js'; diff --git a/web/settings/account-settings.react.js b/web/settings/account-settings.react.js --- a/web/settings/account-settings.react.js +++ b/web/settings/account-settings.react.js @@ -3,13 +3,13 @@ import * as React from 'react'; import { logOut, logOutActionTypes } from 'lib/actions/user-actions'; +import { useModalContext } from 'lib/components/modal-provider.react'; import { preRequestUserStateSelector } from 'lib/selectors/account-selectors'; import { useDispatchActionPromise, useServerCall, } from 'lib/utils/action-utils'; -import { useModalContext } from '../modals/modal-provider.react'; import { useSelector } from '../redux/redux-utils'; import SWMansionIcon from '../SWMansionIcon.react'; import css from './account-settings.css'; diff --git a/web/settings/danger-zone.react.js b/web/settings/danger-zone.react.js --- a/web/settings/danger-zone.react.js +++ b/web/settings/danger-zone.react.js @@ -2,8 +2,9 @@ import * as React from 'react'; +import { useModalContext } from 'lib/components/modal-provider.react'; + import Button from '../components/button.react.js'; -import { useModalContext } from '../modals/modal-provider.react.js'; import AccountDeleteModal from './account-delete-modal.react'; import css from './danger-zone.css'; diff --git a/web/settings/password-change-modal.js b/web/settings/password-change-modal.js --- a/web/settings/password-change-modal.js +++ b/web/settings/password-change-modal.js @@ -7,6 +7,7 @@ changeUserPasswordActionTypes, changeUserPassword, } from 'lib/actions/user-actions'; +import { useModalContext } from 'lib/components/modal-provider.react'; import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors'; import { type PasswordUpdate, @@ -20,7 +21,6 @@ import Button from '../components/button.react'; import Input from '../modals/input.react'; -import { useModalContext } from '../modals/modal-provider.react'; import Modal from '../modals/modal.react'; import { useSelector } from '../redux/redux-utils'; import css from './password-change-modal.css'; diff --git a/web/settings/relationship/block-list-modal.react.js b/web/settings/relationship/block-list-modal.react.js --- a/web/settings/relationship/block-list-modal.react.js +++ b/web/settings/relationship/block-list-modal.react.js @@ -2,10 +2,10 @@ import * as React from 'react'; +import { useModalContext } from 'lib/components/modal-provider.react'; import { userRelationshipStatus } from 'lib/types/relationship-types'; import type { AccountUserInfo } from 'lib/types/user-types'; -import { useModalContext } from '../../modals/modal-provider.react.js'; import BlockListRow from './block-list-row.react'; import BlockUsersModal from './block-users-modal.react'; import UserListModal from './user-list-modal.react'; diff --git a/web/settings/relationship/friend-list-modal.react.js b/web/settings/relationship/friend-list-modal.react.js --- a/web/settings/relationship/friend-list-modal.react.js +++ b/web/settings/relationship/friend-list-modal.react.js @@ -2,10 +2,10 @@ import * as React from 'react'; +import { useModalContext } from 'lib/components/modal-provider.react'; import { userRelationshipStatus } from 'lib/types/relationship-types'; import type { AccountUserInfo } from 'lib/types/user-types'; -import { useModalContext } from '../../modals/modal-provider.react.js'; import AddFriendsModal from './add-friends-modal.react'; import FriendListRow from './friend-list-row.react'; import UserListModal from './user-list-modal.react';