From 6edf599595e41cb07f55d5fc455031a805623ec9 Mon Sep 17 00:00:00 2001 From: Chris Bobbe Date: Wed, 3 Feb 2021 20:47:36 -0500 Subject: [PATCH 1/4] ZulipMobile [nfc]: Use just one `ActionSheetProvider`, here. I don't see a reason why we'd need multiple `ActionSheetProviders`, wrapping more or less tightly the code that opens each action sheet. The examples in the docs have it wrap around the whole app [1]. I tested the message action sheet and the lightbox action sheet on iOS and Android and didn't notice any differences from the previous behavior. [1] https://github.com/expo/react-native-action-sheet --- src/ZulipMobile.js | 5 ++- src/chat/ChatScreen.js | 67 +++++++++++++++----------------- src/lightbox/LightboxScreen.js | 5 +-- src/search/SearchMessagesCard.js | 21 +++++----- 4 files changed, 46 insertions(+), 52 deletions(-) diff --git a/src/ZulipMobile.js b/src/ZulipMobile.js index d7391810f3f..59ca910cc7d 100644 --- a/src/ZulipMobile.js +++ b/src/ZulipMobile.js @@ -3,6 +3,7 @@ import React from 'react'; import { Platform, UIManager } from 'react-native'; import 'react-native-url-polyfill/auto'; import { SafeAreaProvider } from 'react-native-safe-area-context'; +import { ActionSheetProvider } from '@expo/react-native-action-sheet'; import RootErrorBoundary from './RootErrorBoundary'; import { BRAND_COLOR } from './styles'; @@ -52,7 +53,9 @@ export default (): React$Node => ( - + + + diff --git a/src/chat/ChatScreen.js b/src/chat/ChatScreen.js index 43212bb00b5..364dedda157 100644 --- a/src/chat/ChatScreen.js +++ b/src/chat/ChatScreen.js @@ -2,7 +2,6 @@ import React from 'react'; import { View } from 'react-native'; import { useIsFocused } from '@react-navigation/native'; -import { ActionSheetProvider } from '@expo/react-native-action-sheet'; import { useSelector, useDispatch } from '../react-redux'; import type { RouteProp } from '../react-navigation'; @@ -117,39 +116,37 @@ export default function ChatScreen(props: Props) { const streamColor = useSelector(state => getStreamColorForNarrow(state, narrow)); return ( - - - - - - - - {(() => { - if (!isNarrowValid) { - return ; - } else if (fetchError !== null) { - return ; - } else if (sayNoMessages) { - return ; - } else { - return ( - - ); - } - })()} - {showComposeBox && ( - setEditMessage(null)} - /> - )} - - - + + + + + + + {(() => { + if (!isNarrowValid) { + return ; + } else if (fetchError !== null) { + return ; + } else if (sayNoMessages) { + return ; + } else { + return ( + + ); + } + })()} + {showComposeBox && ( + setEditMessage(null)} + /> + )} + + ); } diff --git a/src/lightbox/LightboxScreen.js b/src/lightbox/LightboxScreen.js index 3a9a5012c6e..cc63632ef0f 100644 --- a/src/lightbox/LightboxScreen.js +++ b/src/lightbox/LightboxScreen.js @@ -1,7 +1,6 @@ /* @flow strict-local */ import React from 'react'; import { View } from 'react-native'; -import { ActionSheetProvider } from '@expo/react-native-action-sheet'; import type { Message } from '../types'; import type { RouteProp } from '../react-navigation'; @@ -30,9 +29,7 @@ export default function LightboxScreen(props: Props) { return ( ); } diff --git a/src/search/SearchMessagesCard.js b/src/search/SearchMessagesCard.js index a4d2b0dc06b..d4a8912c886 100644 --- a/src/search/SearchMessagesCard.js +++ b/src/search/SearchMessagesCard.js @@ -2,7 +2,6 @@ import React, { PureComponent } from 'react'; import { View } from 'react-native'; -import { ActionSheetProvider } from '@expo/react-native-action-sheet'; import type { Message } from '../types'; import { createStyleSheet } from '../styles'; @@ -49,17 +48,15 @@ export default class SearchMessagesCard extends PureComponent { return ( - - - + ); } From a3fab39d6d36bffca154c61be0934b09b2f8507d Mon Sep 17 00:00:00 2001 From: Wesley Aptekar-Cassels Date: Thu, 8 Apr 2021 14:51:16 +0800 Subject: [PATCH 2/4] TopicList [nfc]: Pass stream name into TopicItem This will be required for actionsheets to work properly. --- src/topics/TopicList.js | 6 ++++-- src/topics/TopicListScreen.js | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/topics/TopicList.js b/src/topics/TopicList.js index 36bb480f5e2..733610da13d 100644 --- a/src/topics/TopicList.js +++ b/src/topics/TopicList.js @@ -2,7 +2,7 @@ import React, { PureComponent } from 'react'; import { FlatList } from 'react-native'; -import type { TopicExtended } from '../types'; +import type { Stream, TopicExtended } from '../types'; import { createStyleSheet } from '../styles'; import TopicItem from '../streams/TopicItem'; import { LoadingIndicator, SearchEmptyState } from '../common'; @@ -15,13 +15,14 @@ const styles = createStyleSheet({ }); type Props = $ReadOnly<{| + stream: Stream, topics: ?(TopicExtended[]), onPress: (stream: string, topic: string) => void, |}>; export default class TopicList extends PureComponent { render() { - const { topics, onPress } = this.props; + const { stream, topics, onPress } = this.props; if (!topics) { return ; @@ -40,6 +41,7 @@ export default class TopicList extends PureComponent { renderItem={({ item }) => ( { handleFilterChange = (filter: string) => this.setState({ filter }); render() { - const { topics } = this.props; + const { stream, topics } = this.props; const { filter } = this.state; const filteredTopics = topics && topics.filter(topic => topic.name.toLowerCase().includes(filter.toLowerCase())); return ( - + ); } From c93db0f872938affb1aed0763257c37722922bcc Mon Sep 17 00:00:00 2001 From: Wesley Aptekar-Cassels Date: Thu, 8 Apr 2021 14:52:23 +0800 Subject: [PATCH 3/4] TopicItem [nfc]: Make stream name required. It will be needed for the actionsheet, and will cause bugs for it to not exist. --- src/streams/TopicItem.js | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/streams/TopicItem.js b/src/streams/TopicItem.js index e481ae3191a..2195ba4b4e9 100644 --- a/src/streams/TopicItem.js +++ b/src/streams/TopicItem.js @@ -22,7 +22,7 @@ const componentStyles = createStyleSheet({ }); type Props = $ReadOnly<{| - stream?: string, + stream: string, name: string, isMuted?: boolean, isSelected?: boolean, @@ -31,14 +31,7 @@ type Props = $ReadOnly<{| |}>; export default function TopicItem(props: Props) { - const { - name, - stream = '', - isMuted = false, - isSelected = false, - unreadCount = 0, - onPress, - } = props; + const { name, stream, isMuted = false, isSelected = false, unreadCount = 0, onPress } = props; return ( onPress(stream, name)} onLongPress={() => showToast(name)}> From 963487269e934e6e1d0bad4efc34b7d3232ab198 Mon Sep 17 00:00:00 2001 From: Wesley Aptekar-Cassels Date: Tue, 6 Apr 2021 17:28:10 +0800 Subject: [PATCH 4/4] TopicItem: Show actionsheet on long-press. --- src/streams/TopicItem.js | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/streams/TopicItem.js b/src/streams/TopicItem.js index 2195ba4b4e9..cd2ad31bdf3 100644 --- a/src/streams/TopicItem.js +++ b/src/streams/TopicItem.js @@ -1,10 +1,15 @@ /* @flow strict-local */ -import React from 'react'; +import React, { useContext } from 'react'; import { View } from 'react-native'; +import { useActionSheet } from '@expo/react-native-action-sheet'; import styles, { BRAND_COLOR, createStyleSheet } from '../styles'; import { RawLabel, Touchable, UnreadCount } from '../common'; -import { showToast } from '../utils/info'; +import { showHeaderActionSheet } from '../message/messageActionSheet'; +import type { ShowActionSheetWithOptions } from '../message/messageActionSheet'; +import { TranslationContext } from '../boot/TranslationProvider'; +import { useDispatch, useSelector } from '../react-redux'; +import { getAuth, getMute, getFlags, getSubscriptions, getOwnUser } from '../selectors'; const componentStyles = createStyleSheet({ selectedRow: { @@ -33,8 +38,31 @@ type Props = $ReadOnly<{| export default function TopicItem(props: Props) { const { name, stream, isMuted = false, isSelected = false, unreadCount = 0, onPress } = props; + const showActionSheetWithOptions: ShowActionSheetWithOptions = useActionSheet() + .showActionSheetWithOptions; + const _ = useContext(TranslationContext); + const dispatch = useDispatch(); + const backgroundData = useSelector(state => ({ + auth: getAuth(state), + mute: getMute(state), + subscriptions: getSubscriptions(state), + ownUser: getOwnUser(state), + flags: getFlags(state), + })); + return ( - onPress(stream, name)} onLongPress={() => showToast(name)}> + onPress(stream, name)} + onLongPress={() => { + showHeaderActionSheet({ + showActionSheetWithOptions, + callbacks: { dispatch, _ }, + backgroundData, + stream, + topic: name, + }); + }} + >