Page MenuHomePhorge

D5972.1765053716.diff
No OneTemporary

Size
8 KB
Referenced Files
None
Subscribers
None

D5972.1765053716.diff

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,114 @@
+// @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 (
+ <Text style={styles.noMessages} numberOfLines={1}>
+ No messages
+ </Text>
+ );
+ }
+ return (
+ <MessagePreview
+ messageInfo={mostRecentMessageInfo}
+ threadInfo={threadInfo}
+ />
+ );
+ }, [mostRecentMessageInfo, threadInfo, styles]);
+
+ return (
+ <View style={styles.outerView}>
+ <View style={styles.itemRowContainer}>
+ <View style={styles.iconWrapper}>
+ <SWMansionIcon
+ name="message-square"
+ style={[styles.icon, unreadStyle]}
+ />
+ </View>
+ <SingleLine style={[styles.name, unreadStyle]}>
+ {threadInfo.uiName}
+ </SingleLine>
+ </View>
+ <View style={styles.itemRowContainer}>
+ {lastMessage}
+ <Text style={[styles.lastActivity, unreadStyle]}>{lastActivity}</Text>
+ </View>
+ </View>
+ );
+}
+
+const unboundStyles = {
+ outerView: {
+ flex: 1,
+ flexDirection: 'column',
+ justifyContent: 'center',
+ paddingVertical: 8,
+ paddingHorizontal: 16,
+ height: 60,
+ },
+ itemRowContainer: {
+ flexDirection: 'row',
+ height: 24,
+ 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 default SubchannelItem;
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,100 @@
+// @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);
+
+ return (
+ <ThreadListModal
+ createRenderItem={createRenderItem}
+ listData={listData}
+ searchState={searchState}
+ setSearchState={setSearchState}
+ onChangeSearchInputText={onChangeSearchInputText}
+ threadInfo={props.route.params.threadInfo}
+ searchPlaceholder="Search Subchannels"
+ />
+ );
+}
+
+const createRenderItem = (
+ onPressItem: (threadInfo: ThreadInfo) => void,
+ // eslint-disable-next-line react/display-name
+) => (row: { +item: ChatThreadItem, +index: number, ... }) => {
+ return <Item subchannelInfo={row.item} onPressItem={onPressItem} />;
+};
+
+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 (
+ <Button
+ iosFormat="highlight"
+ iosHighlightUnderlayColor={colors.listIosHighlightUnderlay}
+ iosActiveOpacity={0.85}
+ style={styles.subchannel}
+ onPress={onPressButton}
+ >
+ <View style={styles.subchannelRowContainer}>
+ <View style={styles.subchannelItemContainer}>
+ <SubchannelItem subchannelInfo={subchannelInfo} />
+ </View>
+ </View>
+ </Button>
+ );
+}
+
+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}
/>
+ <Root.Screen
+ name={SubchannelsListModalRouteName}
+ component={SubchannelsListModal}
+ options={modalOverlayScreenOptions}
+ />
</Root.Navigator>
);
}
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 =

File Metadata

Mime Type
text/plain
Expires
Sat, Dec 6, 8:41 PM (9 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5840715
Default Alt Text
D5972.1765053716.diff (8 KB)

Event Timeline