diff --git a/native/chat/subchannel-item.react.js b/native/chat/subchannel-item.react.js
new file mode 100644
--- /dev/null
+++ b/native/chat/subchannel-item.react.js
@@ -0,0 +1,115 @@
+// @flow
+
+import * as React from 'react';
+import { Text, View } from 'react-native';
+
+import type { ChatThreadItem } from 'lib/selectors/chat-selectors';
+import { shortAbsoluteDate } from 'lib/utils/date-utils';
+
+import { SingleLine } from '../components/single-line.react';
+import SWMansionIcon from '../components/swmansion-icon.react';
+import { useStyles } from '../themes/colors';
+import MessagePreview from './message-preview.react';
+
+type Props = {
+ +subchannelInfo: ChatThreadItem,
+};
+function SubchannelItem(props: Props): React.Node {
+ const {
+ lastUpdatedTime,
+ threadInfo,
+ mostRecentMessageInfo,
+ } = props.subchannelInfo;
+
+ const lastActivity = shortAbsoluteDate(lastUpdatedTime);
+
+ const styles = useStyles(unboundStyles);
+ const unreadStyle = threadInfo.currentUser.unread ? styles.unread : null;
+
+ const lastMessage = React.useMemo(() => {
+ if (!mostRecentMessageInfo) {
+ return (
+
+ No messages
+
+ );
+ }
+ return (
+
+ );
+ }, [mostRecentMessageInfo, threadInfo, styles]);
+
+ return (
+
+
+
+
+
+
+ {threadInfo.uiName}
+
+
+
+ {lastMessage}
+ {lastActivity}
+
+
+ );
+}
+
+const subchannelHeight = 24;
+const unboundStyles = {
+ outerView: {
+ flex: 1,
+ flexDirection: 'column',
+ justifyContent: 'center',
+ paddingVertical: 8,
+ paddingHorizontal: 16,
+ height: 60,
+ },
+ itemRowContainer: {
+ flexDirection: 'row',
+ height: subchannelHeight,
+ alignItems: 'center',
+ },
+ unread: {
+ color: 'listForegroundLabel',
+ fontWeight: 'bold',
+ },
+ name: {
+ color: 'listForegroundSecondaryLabel',
+ flex: 1,
+ fontSize: 16,
+ paddingLeft: 3,
+ paddingBottom: 2,
+ },
+ lastActivity: {
+ color: 'listForegroundTertiaryLabel',
+ fontSize: 14,
+ marginLeft: 10,
+ },
+ iconWrapper: {
+ marginRight: 8,
+ alignItems: 'center',
+ },
+ icon: {
+ fontSize: 22,
+ color: 'listForegroundSecondaryLabel',
+ alignItems: 'center',
+ height: 24,
+ },
+ noMessages: {
+ color: 'listForegroundTertiaryLabel',
+ flex: 1,
+ fontSize: 14,
+ fontStyle: 'italic',
+ },
+};
+
+export { SubchannelItem, subchannelHeight };
diff --git a/native/chat/subchannels-list-modal.react.js b/native/chat/subchannels-list-modal.react.js
new file mode 100644
--- /dev/null
+++ b/native/chat/subchannels-list-modal.react.js
@@ -0,0 +1,102 @@
+// @flow
+
+import * as React from 'react';
+import { View } from 'react-native';
+
+import { useSearchSubchannels } from 'lib/hooks/search-threads';
+import type { ChatThreadItem } from 'lib/selectors/chat-selectors';
+import { type ThreadInfo } from 'lib/types/thread-types';
+
+import Button from '../components/button.react';
+import type { RootNavigationProp } from '../navigation/root-navigator.react';
+import type { NavigationRoute } from '../navigation/route-names';
+import { useColors, useStyles } from '../themes/colors';
+import { SubchannelItem } from './subchannel-item.react';
+import ThreadListModal from './thread-list-modal.react';
+
+export type SubchannelListModalParams = {
+ +threadInfo: ThreadInfo,
+};
+
+type Props = {
+ +navigation: RootNavigationProp<'SubchannelsListModal'>,
+ +route: NavigationRoute<'SubchannelsListModal'>,
+};
+function SubchannelListModal(props: Props): React.Node {
+ const {
+ listData,
+ searchState,
+ setSearchState,
+ onChangeSearchInputText,
+ } = useSearchSubchannels(props.route.params.threadInfo);
+
+ const createRenderItem = React.useCallback(
+ (
+ onPressItem: (threadInfo: ThreadInfo) => void,
+ // eslint-disable-next-line react/display-name
+ ) => (row: { item: ChatThreadItem, index: number, ... }) => {
+ return ;
+ },
+ [],
+ );
+
+ return (
+
+ );
+}
+
+function Item(props: {
+ onPressItem: (threadInfo: ThreadInfo) => void,
+ subchannelInfo: ChatThreadItem,
+}): React.Node {
+ const { onPressItem, subchannelInfo } = props;
+ const { threadInfo } = subchannelInfo;
+
+ const onPressButton = React.useCallback(() => onPressItem(threadInfo), [
+ onPressItem,
+ threadInfo,
+ ]);
+
+ const colors = useColors();
+ const styles = useStyles(unboundStyles);
+
+ return (
+
+ );
+}
+
+const unboundStyles = {
+ subchannel: {
+ backgroundColor: 'listBackground',
+ paddingLeft: 0,
+ paddingRight: 5,
+ },
+ subchannelItemContainer: {
+ flex: 1,
+ },
+ subchannelRowContainer: {
+ flex: 1,
+ flexDirection: 'row',
+ },
+};
+
+export default SubchannelListModal;
diff --git a/native/navigation/root-navigator.react.js b/native/navigation/root-navigator.react.js
--- a/native/navigation/root-navigator.react.js
+++ b/native/navigation/root-navigator.react.js
@@ -25,6 +25,7 @@
import ColorSelectorModal from '../chat/settings/color-selector-modal.react';
import ComposeSubchannelModal from '../chat/settings/compose-subchannel-modal.react';
import SidebarListModal from '../chat/sidebar-list-modal.react';
+import SubchannelsListModal from '../chat/subchannels-list-modal.react';
import CustomServerModal from '../profile/custom-server-modal.react';
import AppNavigator from './app-navigator.react';
import { defaultStackScreenOptions } from './options';
@@ -42,6 +43,7 @@
ColorSelectorModalRouteName,
ComposeSubchannelModalRouteName,
SidebarListModalRouteName,
+ SubchannelsListModalRouteName,
type ScreenParamList,
type RootParamList,
TermsAndPrivacyRouteName,
@@ -228,6 +230,11 @@
component={SidebarListModal}
options={modalOverlayScreenOptions}
/>
+
);
}
diff --git a/native/navigation/route-names.js b/native/navigation/route-names.js
--- a/native/navigation/route-names.js
+++ b/native/navigation/route-names.js
@@ -16,6 +16,7 @@
import type { ThreadSettingsMemberTooltipModalParams } from '../chat/settings/thread-settings-member-tooltip-modal.react';
import type { ThreadSettingsParams } from '../chat/settings/thread-settings.react';
import type { SidebarListModalParams } from '../chat/sidebar-list-modal.react';
+import type { SubchannelListModalParams } from '../chat/subchannels-list-modal.react';
import type { TextMessageTooltipModalParams } from '../chat/text-message-tooltip-modal.react';
import type { CameraModalParams } from '../media/camera-modal.react';
import type { ImageModalParams } from '../media/image-modal.react';
@@ -62,6 +63,7 @@
export const RobotextMessageTooltipModalRouteName =
'RobotextMessageTooltipModal';
export const SidebarListModalRouteName = 'SidebarListModal';
+export const SubchannelsListModalRouteName = 'SubchannelsListModal';
export const TabNavigatorRouteName = 'TabNavigator';
export const TextMessageTooltipModalRouteName = 'TextMessageTooltipModal';
export const ThreadPickerModalRouteName = 'ThreadPickerModal';
@@ -82,6 +84,7 @@
+SidebarListModal: SidebarListModalParams,
+ImagePasteModal: ImagePasteModalParams,
+TermsAndPrivacyModal: TermsAndPrivacyModalParams,
+ +SubchannelsListModal: SubchannelListModalParams,
};
export type MessageTooltipRouteNames =