Skip to content

Commit 2b49955

Browse files
Leslie NgoLeslie Ngo
Leslie Ngo
authored and
Leslie Ngo
committed
topic edit modal: Add a new edit-topic UI
Fixes: zulip#5365
1 parent 943d68e commit 2b49955

File tree

12 files changed

+159
-192
lines changed

12 files changed

+159
-192
lines changed

src/ZulipMobile.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +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';
19+
import TopicEditModalProvider from './boot/TopicEditModalProvider';
2020

2121
initializeSentry();
2222

@@ -56,11 +56,11 @@ export default function ZulipMobile(): Node {
5656
<AppEventHandlers>
5757
<TranslationProvider>
5858
<ThemeProvider>
59-
<TopicModalProvider>
59+
<TopicEditModalProvider>
6060
<ActionSheetProvider>
6161
<ZulipNavigationContainer />
6262
</ActionSheetProvider>
63-
</TopicModalProvider>
63+
</TopicEditModalProvider>
6464
</ThemeProvider>
6565
</TranslationProvider>
6666
</AppEventHandlers>

src/action-sheets/index.js

+10-16
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,7 @@ type TopicArgs = {
7777
zulipFeatureLevel: number,
7878
dispatch: Dispatch,
7979
_: GetText,
80-
startEditTopic: (
81-
streamId: number,
82-
topic: string,
83-
streamsById: Map<number, Stream>,
84-
_: GetText,
85-
) => Promise<void>,
80+
startEditTopic: (streamId: number, topic: string) => Promise<void>,
8681
...
8782
};
8883

@@ -260,8 +255,8 @@ const toggleResolveTopic = async ({ auth, streamId, topic, _, streams, zulipFeat
260255
const editTopic = {
261256
title: 'Edit topic',
262257
errorMessage: 'Failed to resolve topic',
263-
action: ({ streamId, topic, streams, _, startEditTopic }) => {
264-
startEditTopic(streamId, topic, streams, _);
258+
action: ({ streamId, topic, startEditTopic }) => {
259+
startEditTopic(streamId, topic);
265260
},
266261
};
267262

@@ -516,10 +511,14 @@ export const constructTopicActionButtons = (args: {|
516511

517512
const buttons = [];
518513
const unreadCount = getUnreadCountForTopic(unread, streamId, topic);
514+
const isAdmin = roleIsAtLeast(ownUserRole, Role.Admin);
519515
if (unreadCount > 0) {
520516
buttons.push(markTopicAsRead);
521517
}
522-
buttons.push(editTopic);
518+
// Set back to isAdmin after testing feature
519+
if (true) {
520+
buttons.push(editTopic);
521+
}
523522
if (isTopicMuted(streamId, topic, mute)) {
524523
buttons.push(unmuteTopic);
525524
} else {
@@ -530,7 +529,7 @@ export const constructTopicActionButtons = (args: {|
530529
} else {
531530
buttons.push(unresolveTopic);
532531
}
533-
if (roleIsAtLeast(ownUserRole, Role.Admin)) {
532+
if (isAdmin) {
534533
buttons.push(deleteTopic);
535534
}
536535
const sub = subscriptions.get(streamId);
@@ -681,12 +680,7 @@ export const showTopicActionSheet = (args: {|
681680
showActionSheetWithOptions: ShowActionSheetWithOptions,
682681
callbacks: {|
683682
dispatch: Dispatch,
684-
startEditTopic: (
685-
streamId: number,
686-
topic: string,
687-
streamsById: Map<number, Stream>,
688-
_: GetText,
689-
) => Promise<void>,
683+
startEditTopic: (streamId: number, topic: string) => Promise<void>,
690684
_: GetText,
691685
|},
692686
backgroundData: $ReadOnly<{

src/boot/TopicEditModalProvider.js

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/* @flow strict-local */
2+
import React, { createContext, useState, useCallback, useContext } from 'react';
3+
import type { Context, Node } from 'react';
4+
import { useSelector } from '../react-redux';
5+
import TopicEditModal from '../topics/TopicEditModal';
6+
import { getAuth, getZulipFeatureLevel, getStreamsById } from '../selectors';
7+
import { TranslationContext } from './TranslationProvider';
8+
9+
type Props = $ReadOnly<{|
10+
children: Node,
11+
|}>;
12+
13+
type StartEditTopicContext = (
14+
streamId: number,
15+
topic: string,
16+
) => Promise<void>;
17+
18+
// $FlowIssue[incompatible-type]
19+
const TopicModal: Context<StartEditTopicContext> = createContext(undefined);
20+
21+
export const useStartEditTopic = ():StartEditTopicContext => useContext(TopicModal);
22+
23+
export default function TopicEditModalProvider(props: Props): Node {
24+
const { children } = props;
25+
const auth = useSelector(getAuth);
26+
const zulipFeatureLevel = useSelector(getZulipFeatureLevel);
27+
const streamsById = useSelector(getStreamsById);
28+
const _ = useContext(TranslationContext);
29+
30+
const [topicModalProviderState, setTopicModalProviderState] = useState({
31+
visible: false,
32+
streamId: -1,
33+
topic: '',
34+
});
35+
36+
const startEditTopic = useCallback(
37+
async (streamId: number, topic: string) => {
38+
const { visible } = topicModalProviderState;
39+
if (visible) {
40+
return;
41+
}
42+
setTopicModalProviderState({
43+
visible: true,
44+
streamId,
45+
topic,
46+
});
47+
}, [topicModalProviderState]);
48+
49+
const closeEditTopicModal = useCallback(() => {
50+
setTopicModalProviderState({
51+
visible: false,
52+
streamId: -1,
53+
topic: '',
54+
});
55+
}, []);
56+
57+
return (
58+
<TopicModal.Provider value={startEditTopic}>
59+
<TopicEditModal
60+
topicModalProviderState={topicModalProviderState}
61+
closeEditTopicModal={closeEditTopicModal}
62+
auth={auth}
63+
zulipFeatureLevel={zulipFeatureLevel}
64+
streamsById={streamsById}
65+
_={_}
66+
/>
67+
{children}
68+
</TopicModal.Provider>
69+
);
70+
}

src/boot/TopicModalProvider.js

-92
This file was deleted.

src/chat/ChatScreen.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import { showErrorAlert } from '../utils/info';
3030
import { TranslationContext } from '../boot/TranslationProvider';
3131
import * as api from '../api';
3232
import { useConditionalEffect } from '../reactUtils';
33-
import { useTopicModalHandler } from '../boot/TopicModalProvider';
33+
import { useStartEditTopic } from '../boot/TopicEditModalProvider';
3434

3535
type Props = $ReadOnly<{|
3636
navigation: AppNavigationProp<'chat'>,
@@ -128,7 +128,7 @@ const useMessagesWithFetch = args => {
128128
export default function ChatScreen(props: Props): Node {
129129
const { route, navigation } = props;
130130
const { backgroundColor } = React.useContext(ThemeContext);
131-
const { startEditTopic } = useTopicModalHandler();
131+
const startEditTopic = useStartEditTopic();
132132

133133
const { narrow, editMessage } = route.params;
134134
const setEditMessage = useCallback(

src/search/SearchMessagesCard.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { createStyleSheet } from '../styles';
99
import LoadingIndicator from '../common/LoadingIndicator';
1010
import SearchEmptyState from '../common/SearchEmptyState';
1111
import MessageList from '../webview/MessageList';
12-
import { useTopicModalHandler } from '../boot/TopicModalProvider';
12+
import { useStartEditTopic } from '../boot/TopicEditModalProvider';
1313

1414
const styles = createStyleSheet({
1515
results: {
@@ -25,7 +25,7 @@ type Props = $ReadOnly<{|
2525

2626
export default function SearchMessagesCard(props: Props): Node {
2727
const { narrow, isFetching, messages } = props;
28-
const { startEditTopic } = useTopicModalHandler();
28+
const startEditTopic = useStartEditTopic();
2929

3030
if (isFetching) {
3131
// Display loading indicator only if there are no messages to

src/streams/TopicItem.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
import { getMute } from '../mute/muteModel';
2626
import { getUnread } from '../unread/unreadModel';
2727
import { getOwnUserRole } from '../permissionSelectors';
28-
import { useTopicModalHandler } from '../boot/TopicModalProvider';
28+
import { useStartEditTopic } from '../boot/TopicEditModalProvider';
2929

3030
const componentStyles = createStyleSheet({
3131
selectedRow: {
@@ -71,7 +71,7 @@ export default function TopicItem(props: Props): Node {
7171
useActionSheet().showActionSheetWithOptions;
7272
const _ = useContext(TranslationContext);
7373
const dispatch = useDispatch();
74-
const { startEditTopic } = useTopicModalHandler();
74+
const startEditTopic = useStartEditTopic();
7575
const backgroundData = useSelector(state => ({
7676
auth: getAuth(state),
7777
mute: getMute(state),

src/title/TitleStream.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { showStreamActionSheet, showTopicActionSheet } from '../action-sheets';
2727
import type { ShowActionSheetWithOptions } from '../action-sheets';
2828
import { getUnread } from '../unread/unreadModel';
2929
import { getOwnUserRole } from '../permissionSelectors';
30-
import { useTopicModalHandler } from '../boot/TopicModalProvider';
30+
import { useStartEditTopic } from '../boot/TopicEditModalProvider';
3131

3232
type Props = $ReadOnly<{|
3333
narrow: Narrow,
@@ -68,7 +68,7 @@ export default function TitleStream(props: Props): Node {
6868
const showActionSheetWithOptions: ShowActionSheetWithOptions =
6969
useActionSheet().showActionSheetWithOptions;
7070
const _ = useContext(TranslationContext);
71-
const { startEditTopic } = useTopicModalHandler();
71+
const startEditTopic = useStartEditTopic();
7272

7373
return (
7474
<TouchableWithoutFeedback

0 commit comments

Comments
 (0)