Skip to content

Commit 2bf5e83

Browse files
Leslie NgoLeslie Ngo
authored andcommitted
topic edit modal [nfc]: Add TopicModalProvider context component.
Contains visibility context and handler callback context. Sets up context for modal handler to be called inside topic action sheets.
1 parent c35b883 commit 2bf5e83

File tree

2 files changed

+104
-3
lines changed

2 files changed

+104
-3
lines changed

src/ZulipMobile.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import CompatibilityChecker from './boot/CompatibilityChecker';
1616
import AppEventHandlers from './boot/AppEventHandlers';
1717
import { initializeSentry } from './sentry';
1818
import ZulipSafeAreaProvider from './boot/ZulipSafeAreaProvider';
19+
import TopicModalProvider from './boot/TopicModalProvider';
1920

2021
initializeSentry();
2122

@@ -55,9 +56,11 @@ export default function ZulipMobile(): Node {
5556
<AppEventHandlers>
5657
<TranslationProvider>
5758
<ThemeProvider>
58-
<ActionSheetProvider>
59-
<ZulipNavigationContainer />
60-
</ActionSheetProvider>
59+
<TopicModalProvider>
60+
<ActionSheetProvider>
61+
<ZulipNavigationContainer />
62+
</ActionSheetProvider>
63+
</TopicModalProvider>
6164
</ThemeProvider>
6265
</TranslationProvider>
6366
</AppEventHandlers>

src/boot/TopicModalProvider.js

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import React, {
2+
createContext,
3+
useState,
4+
useMemo,
5+
useCallback,
6+
useContext }
7+
from 'react';
8+
import type { Context } from 'react';
9+
import { useSelector } from '../react-redux';
10+
import TopicEditModal from '../topics/TopicEditModal';
11+
import type { Stream, GetText } from '../types';
12+
import { fetchSomeMessageIdForConversation } from '../message/fetchActions';
13+
import { getAuth, getZulipFeatureLevel } from '../selectors';
14+
15+
type Props = $ReadOnly<{|
16+
children: Node,
17+
|}>;
18+
19+
type TopicModalContext = $ReadOnly<{|
20+
startEditTopic: (
21+
streamId: number,
22+
topic: string,
23+
streamsById: Map<number, Stream>,
24+
_: GetText,
25+
) => void,
26+
closeEditTopicModal: () => void,
27+
|}>;
28+
29+
const TopicModal: Context<TopicModalContext> = createContext();
30+
31+
export const useTopicModalHandler = () => useContext(TopicModal);
32+
33+
export default function TopicModalProvider(props: Props) {
34+
const { children } = props;
35+
const auth = useSelector(getAuth);
36+
const zulipFeatureLevel = useSelector(getZulipFeatureLevel);
37+
const [topicModalState, setTopicModalState] = useState({
38+
visible: false,
39+
topic: '',
40+
fetchArgs: {
41+
auth: null,
42+
messageId: null,
43+
zulipFeatureLevel: null
44+
}
45+
});
46+
47+
const startEditTopic = useCallback(async (
48+
streamId,
49+
topic,
50+
streamsById,
51+
_,
52+
) => {
53+
const messageId = await fetchSomeMessageIdForConversation(
54+
auth,
55+
streamId,
56+
topic,
57+
streamsById,
58+
zulipFeatureLevel,
59+
);
60+
if (messageId == null) {
61+
throw new Error(
62+
_('No messages in topic: {streamAndTopic}', {
63+
streamAndTopic: `#${streamsById.get(streamId)?.name ?? 'unknown'} > ${topic}`,
64+
}),
65+
);
66+
}
67+
setTopicModalState({
68+
visible: true,
69+
topic,
70+
fetchArgs: { auth, messageId, zulipFeatureLevel }
71+
});
72+
}, [auth, zulipFeatureLevel]);
73+
74+
const closeEditTopicModal = useCallback(() => {
75+
setTopicModalState({
76+
visible: false,
77+
topic: null,
78+
fetchArgs: { auth: null, messageId: null, zulipFeatureLevel: null }
79+
});
80+
}, []);
81+
82+
const topicModalHandler = useMemo(() => ({
83+
startEditTopic,
84+
closeEditTopicModal,
85+
}), [startEditTopic, closeEditTopicModal]);
86+
87+
return (
88+
<TopicModal.Provider value={topicModalHandler}>
89+
{topicModalState.visible && (
90+
<TopicEditModal
91+
topicModalState={topicModalState}
92+
topicModalHandler={topicModalHandler}
93+
/>
94+
)}
95+
{children}
96+
</TopicModal.Provider>
97+
);
98+
}

0 commit comments

Comments
 (0)