Page MenuHomePhabricator

D5971.id19950.diff
No OneTemporary

D5971.id19950.diff

diff --git a/native/chat/sidebar-list-modal.react.js b/native/chat/sidebar-list-modal.react.js
--- a/native/chat/sidebar-list-modal.react.js
+++ b/native/chat/sidebar-list-modal.react.js
@@ -1,7 +1,7 @@
// @flow
import * as React from 'react';
-import { TextInput, FlatList, View } from 'react-native';
+import { View } from 'react-native';
import { useSearchSidebars } from 'lib/hooks/search-threads';
import type { ThreadInfo, SidebarInfo } from 'lib/types/thread-types';
@@ -9,26 +9,16 @@
import ExtendedArrow from '../components/arrow-extended.react';
import Arrow from '../components/arrow.react';
import Button from '../components/button.react';
-import Modal from '../components/modal.react';
-import Search from '../components/search.react';
import type { RootNavigationProp } from '../navigation/root-navigator.react';
import type { NavigationRoute } from '../navigation/route-names';
-import { useColors, useIndicatorStyle, useStyles } from '../themes/colors';
-import { waitForModalInputFocus } from '../utils/timers';
-import { useNavigateToThread } from './message-list-types';
+import { useColors, useStyles } from '../themes/colors';
import { SidebarItem } from './sidebar-item.react';
+import ThreadListModal from './thread-list-modal.react';
export type SidebarListModalParams = {
+threadInfo: ThreadInfo,
};
-function keyExtractor(sidebarInfo: SidebarInfo) {
- return sidebarInfo.threadInfo.id;
-}
-function getItemLayout(data: ?$ReadOnlyArray<SidebarInfo>, index: number) {
- return { length: 24, offset: 24 * index, index };
-}
-
type Props = {
+navigation: RootNavigationProp<'SidebarListModal'>,
+route: NavigationRoute<'SidebarListModal'>,
@@ -41,45 +31,16 @@
onChangeSearchInputText,
} = useSearchSidebars(props.route.params.threadInfo);
- const searchTextInputRef = React.useRef();
- const setSearchTextInputRef = React.useCallback(
- async (textInput: ?React.ElementRef<typeof TextInput>) => {
- searchTextInputRef.current = textInput;
- if (!textInput) {
- return;
- }
- await waitForModalInputFocus();
- if (searchTextInputRef.current) {
- searchTextInputRef.current.focus();
- }
- },
- [],
- );
-
- const navigateToThread = useNavigateToThread();
- const onPressItem = React.useCallback(
- (threadInfo: ThreadInfo) => {
- setSearchState({
- text: '',
- results: new Set(),
- });
- if (searchTextInputRef.current) {
- searchTextInputRef.current.blur();
- }
- navigateToThread({ threadInfo });
- },
- [navigateToThread, setSearchState],
- );
-
- const styles = useStyles(unboundStyles);
-
const numOfSidebarsWithExtendedArrow = React.useMemo(
() => listData.length - 1,
[listData],
);
- const renderItem = React.useCallback(
- (row: { item: SidebarInfo, index: number, ... }) => {
+ const createRenderItem = React.useCallback(
+ (
+ onPressItem: (threadInfo: ThreadInfo) => void,
+ // eslint-disable-next-line react/display-name
+ ) => (row: { item: SidebarInfo, index: number, ... }) => {
let extendArrow: boolean = false;
if (row.index < numOfSidebarsWithExtendedArrow) {
extendArrow = true;
@@ -92,29 +53,18 @@
/>
);
},
- [onPressItem, numOfSidebarsWithExtendedArrow],
+ [numOfSidebarsWithExtendedArrow],
);
- const indicatorStyle = useIndicatorStyle();
return (
- <Modal>
- <Search
- searchText={searchState.text}
- onChangeText={onChangeSearchInputText}
- containerStyle={styles.search}
- placeholder="Search threads"
- ref={setSearchTextInputRef}
- />
- <FlatList
- data={listData}
- renderItem={renderItem}
- keyExtractor={keyExtractor}
- getItemLayout={getItemLayout}
- keyboardShouldPersistTaps="handled"
- initialNumToRender={20}
- indicatorStyle={indicatorStyle}
- />
- </Modal>
+ <ThreadListModal
+ createRenderItem={createRenderItem}
+ listData={listData}
+ searchState={searchState}
+ setSearchState={setSearchState}
+ onChangeSearchInputText={onChangeSearchInputText}
+ threadInfo={props.route.params.threadInfo}
+ />
);
}
@@ -177,9 +127,6 @@
position: 'absolute',
top: -6,
},
- search: {
- marginBottom: 8,
- },
sidebar: {
backgroundColor: 'listBackground',
paddingLeft: 0,
diff --git a/native/chat/thread-list-modal.react.js b/native/chat/thread-list-modal.react.js
new file mode 100644
--- /dev/null
+++ b/native/chat/thread-list-modal.react.js
@@ -0,0 +1,115 @@
+// @flow
+
+import * as React from 'react';
+import { TextInput, FlatList, StyleSheet } from 'react-native';
+
+import type { ThreadSearchState } from 'lib/hooks/search-threads';
+import type { ChatThreadItem } from 'lib/selectors/chat-selectors';
+import type { ThreadInfo, SidebarInfo } from 'lib/types/thread-types';
+
+import Modal from '../components/modal.react';
+import Search from '../components/search.react';
+import { useIndicatorStyle } from '../themes/colors';
+import { waitForModalInputFocus } from '../utils/timers';
+import { useNavigateToThread } from './message-list-types';
+
+function keyExtractor(sidebarInfo: SidebarInfo | ChatThreadItem) {
+ return sidebarInfo.threadInfo.id;
+}
+function getItemLayout(
+ data: ?$ReadOnlyArray<SidebarInfo | ChatThreadItem>,
+ index: number,
+) {
+ return { length: 24, offset: 24 * index, index };
+}
+
+type Props<U> = {
+ +threadInfo: ThreadInfo,
+ +createRenderItem: (
+ onPressItem: (threadInfo: ThreadInfo) => void,
+ ) => (row: {
+ item: U,
+ index: number,
+ ...
+ }) => React.Node,
+ +listData: $ReadOnlyArray<U>,
+ +searchState: ThreadSearchState,
+ +setSearchState: Function,
+ +onChangeSearchInputText: (text: string) => mixed,
+};
+function ThreadListModal<U: SidebarInfo | ChatThreadItem>(
+ props: Props<U>,
+): React.Node {
+ const {
+ searchState,
+ setSearchState,
+ onChangeSearchInputText,
+ listData,
+ createRenderItem,
+ } = props;
+
+ const searchTextInputRef = React.useRef();
+ const setSearchTextInputRef = React.useCallback(
+ async (textInput: ?React.ElementRef<typeof TextInput>) => {
+ searchTextInputRef.current = textInput;
+ if (!textInput) {
+ return;
+ }
+ await waitForModalInputFocus();
+ if (searchTextInputRef.current) {
+ searchTextInputRef.current.focus();
+ }
+ },
+ [],
+ );
+
+ const navigateToThread = useNavigateToThread();
+ const onPressItem = React.useCallback(
+ (threadInfo: ThreadInfo) => {
+ setSearchState({
+ text: '',
+ results: new Set(),
+ });
+ if (searchTextInputRef.current) {
+ searchTextInputRef.current.blur();
+ }
+ navigateToThread({ threadInfo });
+ },
+ [navigateToThread, setSearchState],
+ );
+
+ const renderItem = React.useMemo(() => createRenderItem(onPressItem), [
+ createRenderItem,
+ onPressItem,
+ ]);
+
+ const indicatorStyle = useIndicatorStyle();
+ return (
+ <Modal>
+ <Search
+ searchText={searchState.text}
+ onChangeText={onChangeSearchInputText}
+ containerStyle={styles.search}
+ placeholder="Search subchannels"
+ ref={setSearchTextInputRef}
+ />
+ <FlatList
+ data={listData}
+ renderItem={renderItem}
+ keyExtractor={keyExtractor}
+ getItemLayout={getItemLayout}
+ keyboardShouldPersistTaps="handled"
+ initialNumToRender={20}
+ indicatorStyle={indicatorStyle}
+ />
+ </Modal>
+ );
+}
+
+const styles = StyleSheet.create({
+ search: {
+ marginBottom: 8,
+ },
+});
+
+export default ThreadListModal;

File Metadata

Mime Type
text/plain
Expires
Sun, Nov 24, 1:35 PM (20 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2575999
Default Alt Text
D5971.id19950.diff (7 KB)

Event Timeline