diff --git a/web/app.react.js b/web/app.react.js
--- a/web/app.react.js
+++ b/web/app.react.js
@@ -1,16 +1,15 @@
// @flow
+import { config as faConfig } from '@fortawesome/fontawesome-svg-core';
+import invariant from 'invariant';
import '@fontsource/inter';
import '@fontsource/inter/500.css';
import '@fontsource/inter/600.css';
-
import '@fontsource/ibm-plex-sans';
import '@fontsource/ibm-plex-sans/500.css';
import '@fontsource/ibm-plex-sans/600.css';
-
import 'basscss/css/basscss.min.css';
import './theme.css';
-import { config as faConfig } from '@fortawesome/fontawesome-svg-core';
import _isEqual from 'lodash/fp/isEqual';
import * as React from 'react';
import { DndProvider } from 'react-dnd';
@@ -35,6 +34,7 @@
import Chat from './chat/chat.react';
import InputStateContainer from './input/input-state-container.react';
import LoadingIndicator from './loading-indicator.react';
+import { ModalContext } from './modals/modal-provider.react';
import DisconnectedBar from './redux/disconnected-bar';
import DisconnectedBarVisibilityHandler from './redux/disconnected-bar-visibility-handler';
import FocusHandler from './redux/focus-handler.react';
@@ -83,6 +83,7 @@
+activeThreadCurrentlyUnread: boolean,
// Redux dispatch functions
+dispatch: Dispatch,
+ +setModal: (?React.Node) => void,
};
type State = {
+modal: ?React.Node,
@@ -182,7 +183,7 @@
{mainContent}
-
+
);
}
@@ -227,6 +228,11 @@
const dispatch = useDispatch();
+ const modalContext = React.useContext(ModalContext);
+ invariant(modalContext, 'ModalContext not found');
+
+ const { setModal } = modalContext;
+
return (
);
},
diff --git a/web/modals/modal-provider.react.js b/web/modals/modal-provider.react.js
new file mode 100644
--- /dev/null
+++ b/web/modals/modal-provider.react.js
@@ -0,0 +1,37 @@
+// @flow
+
+import * as React from 'react';
+type Props = {
+ +children: React.Node,
+};
+type ModalContextType = {
+ +modal: ?React.Node,
+ +setModal: (?React.Node) => void,
+ +clearModal: () => void,
+};
+
+const ModalContext: React.Context = React.createContext(
+ {
+ modal: null,
+ setModal: () => {},
+ clearModal: () => {},
+ },
+);
+
+function ModalProvider(props: Props): React.Node {
+ const { children } = props;
+ const [modal, setModal] = React.useState(null);
+ const clearModal = React.useCallback(() => setModal(null), [setModal]);
+
+ const handleClick = React.useCallback((component: ?React.Node) => {
+ setModal(component);
+ }, []);
+
+ return (
+
+ {children}
+
+ );
+}
+
+export { ModalProvider, ModalContext };
diff --git a/web/root.js b/web/root.js
--- a/web/root.js
+++ b/web/root.js
@@ -9,6 +9,7 @@
import { reduxLoggerMiddleware } from 'lib/utils/action-logger';
import HotRoot from './hot';
+import { ModalProvider } from './modals/modal-provider.react';
import { reducer } from './redux/redux-setup';
import type { AppState, Action } from './redux/redux-setup';
@@ -21,7 +22,9 @@
const RootProvider = (): React.Node => (
-
+
+
+
);