From ea4fadd4721463d7972e587fe43756fd9714a767 Mon Sep 17 00:00:00 2001 From: Janhvi Patil Date: Thu, 19 Dec 2024 02:13:10 +0530 Subject: [PATCH] feat(mobile): channel list UI --- apps/mobile/app/[site_id]/(tabs)/_layout.tsx | 2 +- .../app/[site_id]/(tabs)/activity/_layout.tsx | 2 +- .../(tabs)/direct-messages/_layout.tsx | 2 +- .../app/[site_id]/(tabs)/home/_layout.tsx | 4 +- .../app/[site_id]/(tabs)/home/index.tsx | 106 +++++++++++++++++- .../app/[site_id]/(tabs)/profile/_layout.tsx | 2 +- .../app/[site_id]/(tabs)/profile/index.tsx | 2 +- apps/mobile/app/_layout.tsx | 2 +- apps/mobile/assets/icons/ChevronDownIcon.svg | 1 + apps/mobile/assets/icons/GlobeIcon.svg | 1 + apps/mobile/assets/icons/HashIcon.svg | 1 + apps/mobile/assets/icons/LockIcon.svg | 1 + apps/mobile/assets/icons/PlusIcon.svg | 1 + apps/mobile/assets/icons/SunMoonIcon.svg | 1 - .../features/chat/ChannelList/ChannelIcon.tsx | 18 +++ .../features/chat/ChannelList/ChannelList.tsx | 93 +++++++++++++++ .../nativewindui/ActivityIndicator.tsx | 2 +- .../AdaptiveSearchHeader.ios.tsx | 2 +- .../AdaptiveSearchHeader.tsx | 2 +- .../mobile/components/nativewindui/Button.tsx | 2 +- .../components/nativewindui/DrawerContent.tsx | 2 +- .../DropdownMenu/DropdownMenu.tsx | 2 +- apps/mobile/components/nativewindui/Form.tsx | 2 +- .../SearchInput/SearchInput.ios.tsx | 2 +- .../nativewindui/SearchInput/SearchInput.tsx | 2 +- .../nativewindui/TextField/TextField.tsx | 2 +- .../components/nativewindui/ThemeToggle.tsx | 2 +- .../mobile/components/nativewindui/Toggle.tsx | 2 +- apps/mobile/{lib => hooks}/useColorScheme.tsx | 0 apps/mobile/types/channels.ts | 32 ++++++ 30 files changed, 271 insertions(+), 24 deletions(-) create mode 100644 apps/mobile/assets/icons/ChevronDownIcon.svg create mode 100644 apps/mobile/assets/icons/GlobeIcon.svg create mode 100644 apps/mobile/assets/icons/HashIcon.svg create mode 100644 apps/mobile/assets/icons/LockIcon.svg create mode 100644 apps/mobile/assets/icons/PlusIcon.svg delete mode 100644 apps/mobile/assets/icons/SunMoonIcon.svg create mode 100644 apps/mobile/components/features/chat/ChannelList/ChannelIcon.tsx create mode 100644 apps/mobile/components/features/chat/ChannelList/ChannelList.tsx rename apps/mobile/{lib => hooks}/useColorScheme.tsx (100%) create mode 100644 apps/mobile/types/channels.ts diff --git a/apps/mobile/app/[site_id]/(tabs)/_layout.tsx b/apps/mobile/app/[site_id]/(tabs)/_layout.tsx index 992b7a99..6c18015b 100644 --- a/apps/mobile/app/[site_id]/(tabs)/_layout.tsx +++ b/apps/mobile/app/[site_id]/(tabs)/_layout.tsx @@ -5,7 +5,7 @@ import HomeIcon from '@assets/icons/HomeIcon.svg'; import ProfileIcon from '@assets/icons/ProfileIcon.svg'; import ChatIcon from '@assets/icons/ChatIcon.svg'; import BellIcon from '@assets/icons/BellIcon.svg'; -import { useColorScheme } from '@lib/useColorScheme' +import { useColorScheme } from '@hooks/useColorScheme' export default function TabLayout() { diff --git a/apps/mobile/app/[site_id]/(tabs)/activity/_layout.tsx b/apps/mobile/app/[site_id]/(tabs)/activity/_layout.tsx index b6267df1..23b136aa 100644 --- a/apps/mobile/app/[site_id]/(tabs)/activity/_layout.tsx +++ b/apps/mobile/app/[site_id]/(tabs)/activity/_layout.tsx @@ -1,4 +1,4 @@ -import { useColorScheme } from '@lib/useColorScheme'; +import { useColorScheme } from '@hooks/useColorScheme'; import { Stack } from 'expo-router'; const ActivityLayout = () => { diff --git a/apps/mobile/app/[site_id]/(tabs)/direct-messages/_layout.tsx b/apps/mobile/app/[site_id]/(tabs)/direct-messages/_layout.tsx index 409b6b3c..d40db126 100644 --- a/apps/mobile/app/[site_id]/(tabs)/direct-messages/_layout.tsx +++ b/apps/mobile/app/[site_id]/(tabs)/direct-messages/_layout.tsx @@ -1,4 +1,4 @@ -import { useColorScheme } from '@lib/useColorScheme'; +import { useColorScheme } from '@hooks/useColorScheme'; import { Stack } from 'expo-router'; const DirectMessagesLayout = () => { diff --git a/apps/mobile/app/[site_id]/(tabs)/home/_layout.tsx b/apps/mobile/app/[site_id]/(tabs)/home/_layout.tsx index 30ce9349..22a4a853 100644 --- a/apps/mobile/app/[site_id]/(tabs)/home/_layout.tsx +++ b/apps/mobile/app/[site_id]/(tabs)/home/_layout.tsx @@ -1,4 +1,4 @@ -import { useColorScheme } from '@lib/useColorScheme'; +import { useColorScheme } from '@hooks/useColorScheme'; import { Stack } from 'expo-router'; const HomeLayout = () => { @@ -13,7 +13,7 @@ const HomeLayout = () => { ) diff --git a/apps/mobile/app/[site_id]/(tabs)/home/index.tsx b/apps/mobile/app/[site_id]/(tabs)/home/index.tsx index ccf0eb73..3ef82c41 100644 --- a/apps/mobile/app/[site_id]/(tabs)/home/index.tsx +++ b/apps/mobile/app/[site_id]/(tabs)/home/index.tsx @@ -1,12 +1,112 @@ import { View } from 'react-native'; -import { Text } from '@components/nativewindui/Text'; import { ThemeToggle } from '@components/nativewindui/ThemeToggle'; +import ChannelList from '@components/features/chat/ChannelList/ChannelList'; export default function Home() { return ( - - Home + + console.log('channel selected')} + onLongPress={() => console.log('channel long pressed')} /> ) } \ No newline at end of file diff --git a/apps/mobile/app/[site_id]/(tabs)/profile/_layout.tsx b/apps/mobile/app/[site_id]/(tabs)/profile/_layout.tsx index c9b634dc..8476109e 100644 --- a/apps/mobile/app/[site_id]/(tabs)/profile/_layout.tsx +++ b/apps/mobile/app/[site_id]/(tabs)/profile/_layout.tsx @@ -1,4 +1,4 @@ -import { useColorScheme } from '@lib/useColorScheme'; +import { useColorScheme } from '@hooks/useColorScheme'; import { Stack } from 'expo-router'; const ProfileLayout = () => { diff --git a/apps/mobile/app/[site_id]/(tabs)/profile/index.tsx b/apps/mobile/app/[site_id]/(tabs)/profile/index.tsx index c9cdc44b..92d7e518 100644 --- a/apps/mobile/app/[site_id]/(tabs)/profile/index.tsx +++ b/apps/mobile/app/[site_id]/(tabs)/profile/index.tsx @@ -11,7 +11,7 @@ import { } from '@components/nativewindui/List'; import { Text } from '@components/nativewindui/Text'; import { cn } from '@lib/cn'; -import { useColorScheme } from '@lib/useColorScheme'; +import { useColorScheme } from '@hooks/useColorScheme'; import ChevronRightIcon from '@assets/icons/ChevronRightIcon.svg'; import { useFrappeGetCall } from 'frappe-react-sdk'; import AsyncStorage from '@react-native-async-storage/async-storage'; diff --git a/apps/mobile/app/_layout.tsx b/apps/mobile/app/_layout.tsx index c28958fc..3069148c 100644 --- a/apps/mobile/app/_layout.tsx +++ b/apps/mobile/app/_layout.tsx @@ -4,7 +4,7 @@ import "../global.css"; import { useEffect } from 'react'; import { GestureHandlerRootView } from 'react-native-gesture-handler'; import { BottomSheetModalProvider } from '@gorhom/bottom-sheet'; -import { useColorScheme, useInitialAndroidBarSync } from '@lib/useColorScheme'; +import { useColorScheme, useInitialAndroidBarSync } from '@hooks/useColorScheme'; import { NAV_THEME } from '@theme/index'; import { StatusBar } from 'expo-status-bar'; import { ActionSheetProvider } from '@expo/react-native-action-sheet'; diff --git a/apps/mobile/assets/icons/ChevronDownIcon.svg b/apps/mobile/assets/icons/ChevronDownIcon.svg new file mode 100644 index 00000000..1df7f440 --- /dev/null +++ b/apps/mobile/assets/icons/ChevronDownIcon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/mobile/assets/icons/GlobeIcon.svg b/apps/mobile/assets/icons/GlobeIcon.svg new file mode 100644 index 00000000..873c04fe --- /dev/null +++ b/apps/mobile/assets/icons/GlobeIcon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/mobile/assets/icons/HashIcon.svg b/apps/mobile/assets/icons/HashIcon.svg new file mode 100644 index 00000000..589a1a7c --- /dev/null +++ b/apps/mobile/assets/icons/HashIcon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/mobile/assets/icons/LockIcon.svg b/apps/mobile/assets/icons/LockIcon.svg new file mode 100644 index 00000000..8b477601 --- /dev/null +++ b/apps/mobile/assets/icons/LockIcon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/mobile/assets/icons/PlusIcon.svg b/apps/mobile/assets/icons/PlusIcon.svg new file mode 100644 index 00000000..ef338f28 --- /dev/null +++ b/apps/mobile/assets/icons/PlusIcon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/mobile/assets/icons/SunMoonIcon.svg b/apps/mobile/assets/icons/SunMoonIcon.svg deleted file mode 100644 index 5ecde848..00000000 --- a/apps/mobile/assets/icons/SunMoonIcon.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/apps/mobile/components/features/chat/ChannelList/ChannelIcon.tsx b/apps/mobile/components/features/chat/ChannelList/ChannelIcon.tsx new file mode 100644 index 00000000..0e20a0cf --- /dev/null +++ b/apps/mobile/components/features/chat/ChannelList/ChannelIcon.tsx @@ -0,0 +1,18 @@ +import GlobeIcon from '@assets/icons/GlobeIcon.svg'; +import HashIcon from '@assets/icons/HashIcon.svg'; +import LockIcon from '@assets/icons/LockIcon.svg'; + +const iconSize = 18 + +export const ChannelIcon = ({ type, fill, size = iconSize }: { type: string, fill?: string, size?: number }) => { + switch (type) { + case 'Open': + return + case 'Private': + return + case 'Public': + return + default: + return + } +} \ No newline at end of file diff --git a/apps/mobile/components/features/chat/ChannelList/ChannelList.tsx b/apps/mobile/components/features/chat/ChannelList/ChannelList.tsx new file mode 100644 index 00000000..a133d63c --- /dev/null +++ b/apps/mobile/components/features/chat/ChannelList/ChannelList.tsx @@ -0,0 +1,93 @@ +import React, { useState } from 'react'; +import { View, TouchableOpacity, Pressable, StyleSheet } from 'react-native'; +import { ChannelListItem } from '../../../../types/channels'; +import { ChannelIcon } from './ChannelIcon'; +import { Text } from '@components/nativewindui/Text'; +import ChevronDownIcon from '@assets/icons/ChevronDownIcon.svg'; +import ChevronRightIcon from '@assets/icons/ChevronRightIcon.svg'; +import { useColorScheme } from '@hooks/useColorScheme'; +import PlusIcon from '@assets/icons/PlusIcon.svg'; + +interface ChannelListProps { + channels: ChannelListItem[]; + onChannelSelect: (channelId: string) => void; + onLongPress: (channelId: string) => void; +} + +const ChannelList = ({ channels, onChannelSelect, onLongPress }: ChannelListProps) => { + + const [isExpanded, setIsExpanded] = useState(true) + const colors = useColorScheme() + + const toggleAccordion = () => { + setIsExpanded((prev) => !prev) + } + + return ( + + + Channels + {isExpanded ? : } + + {isExpanded && <> + {channels.map((channel) => ( + onChannelSelect(channel.name)} + onLongPress={() => onLongPress(channel.name)} + style={styles.channelRow} + > + + {channel.channel_name} + + ))} + console.log('Create channel pressed')}> + + Add Channel + + } + + ) +} + +const styles = StyleSheet.create({ + container: { + padding: 10, + }, + header: { + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'center', + paddingVertical: 12, + paddingHorizontal: 10, + }, + headerText: { + fontWeight: '600', + fontSize: 16, + }, + channelRow: { + flexDirection: 'row', + alignItems: 'center', + paddingVertical: 6, + paddingHorizontal: 10, + borderRadius: 10, + }, + channelText: { + marginLeft: 12, + fontSize: 16, + }, + addChannelButton: { + flexDirection: 'row', + alignItems: 'center', + paddingVertical: 12, + paddingHorizontal: 10, + borderRadius: 10, + }, + addChannelText: { + marginLeft: 12, + fontSize: 16, + }, +}) + +export default ChannelList diff --git a/apps/mobile/components/nativewindui/ActivityIndicator.tsx b/apps/mobile/components/nativewindui/ActivityIndicator.tsx index a1a10188..3ca1c18a 100644 --- a/apps/mobile/components/nativewindui/ActivityIndicator.tsx +++ b/apps/mobile/components/nativewindui/ActivityIndicator.tsx @@ -1,5 +1,5 @@ import { ActivityIndicator as RNActivityIndicator } from 'react-native'; -import { useColorScheme } from '@lib/useColorScheme'; +import { useColorScheme } from '@hooks/useColorScheme'; function ActivityIndicator(props: React.ComponentPropsWithoutRef) { const { colors } = useColorScheme(); diff --git a/apps/mobile/components/nativewindui/AdaptiveSearchHeader/AdaptiveSearchHeader.ios.tsx b/apps/mobile/components/nativewindui/AdaptiveSearchHeader/AdaptiveSearchHeader.ios.tsx index 3dabab08..eee178e8 100644 --- a/apps/mobile/components/nativewindui/AdaptiveSearchHeader/AdaptiveSearchHeader.ios.tsx +++ b/apps/mobile/components/nativewindui/AdaptiveSearchHeader/AdaptiveSearchHeader.ios.tsx @@ -9,7 +9,7 @@ import type { NativeStackNavigationOptions, NativeStackNavigationSearchBarOptions, } from './types'; -import { useColorScheme } from '@lib/useColorScheme'; +import { useColorScheme } from '@hooks/useColorScheme'; export function AdaptiveSearchHeader(props: AdaptiveSearchHeaderProps) { const id = React.useId(); diff --git a/apps/mobile/components/nativewindui/AdaptiveSearchHeader/AdaptiveSearchHeader.tsx b/apps/mobile/components/nativewindui/AdaptiveSearchHeader/AdaptiveSearchHeader.tsx index 4c7a5f17..bfed4945 100644 --- a/apps/mobile/components/nativewindui/AdaptiveSearchHeader/AdaptiveSearchHeader.tsx +++ b/apps/mobile/components/nativewindui/AdaptiveSearchHeader/AdaptiveSearchHeader.tsx @@ -26,7 +26,7 @@ import type { import { Button } from '@components/nativewindui/Button'; import { Text } from '@components/nativewindui/Text'; import { cn } from '@lib/cn'; -import { useColorScheme } from '@lib/useColorScheme'; +import { useColorScheme } from '@hooks/useColorScheme'; const SCREEN_OPTIONS = { headerShown: false, diff --git a/apps/mobile/components/nativewindui/Button.tsx b/apps/mobile/components/nativewindui/Button.tsx index a99efe1d..740e69ad 100644 --- a/apps/mobile/components/nativewindui/Button.tsx +++ b/apps/mobile/components/nativewindui/Button.tsx @@ -4,7 +4,7 @@ import * as React from 'react'; import { Platform, Pressable, PressableProps, View, ViewStyle } from 'react-native'; import { TextClassContext } from '@components/nativewindui/Text'; import { cn } from '@lib/cn'; -import { useColorScheme } from '@lib/useColorScheme'; +import { useColorScheme } from '@hooks/useColorScheme'; import { COLORS } from '@theme/colors'; const buttonVariants = cva('flex-row items-center justify-center gap-2', { diff --git a/apps/mobile/components/nativewindui/DrawerContent.tsx b/apps/mobile/components/nativewindui/DrawerContent.tsx index f6a249f4..086814aa 100644 --- a/apps/mobile/components/nativewindui/DrawerContent.tsx +++ b/apps/mobile/components/nativewindui/DrawerContent.tsx @@ -6,7 +6,7 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { Text } from '@components/nativewindui/Text'; import { Button } from '@components/nativewindui/Button'; import { cn } from '@lib/cn'; -import { useColorScheme } from '@lib/useColorScheme'; +import { useColorScheme } from '@hooks/useColorScheme'; import { COLORS } from '@theme/colors'; import CrossIcon from '@assets/icons/CrossIcon.svg'; import { SvgProps } from 'react-native-svg'; diff --git a/apps/mobile/components/nativewindui/DropdownMenu/DropdownMenu.tsx b/apps/mobile/components/nativewindui/DropdownMenu/DropdownMenu.tsx index 5e0fa207..4760b788 100644 --- a/apps/mobile/components/nativewindui/DropdownMenu/DropdownMenu.tsx +++ b/apps/mobile/components/nativewindui/DropdownMenu/DropdownMenu.tsx @@ -18,7 +18,7 @@ import { ActivityIndicator } from '@components/nativewindui/ActivityIndicator'; import { Text } from '@components/nativewindui/Text'; import { Button } from '@components/nativewindui/Button'; import { cn } from '@lib/cn'; -import { useColorScheme } from '@lib/useColorScheme'; +import { useColorScheme } from '@hooks/useColorScheme'; import CheckIcon from '@assets/icons/CheckIcon.svg'; import ChevronRightIcon from '@assets/icons/ChevronRightIcon.svg'; diff --git a/apps/mobile/components/nativewindui/Form.tsx b/apps/mobile/components/nativewindui/Form.tsx index e9a25939..7d02de65 100644 --- a/apps/mobile/components/nativewindui/Form.tsx +++ b/apps/mobile/components/nativewindui/Form.tsx @@ -3,7 +3,7 @@ import { Platform, View, ViewProps, ViewStyle } from 'react-native'; import { Text } from '@components/nativewindui/Text'; import { cn } from '@lib/cn'; -import { useColorScheme } from '@lib/useColorScheme'; +import { useColorScheme } from '@hooks/useColorScheme'; const Form = React.forwardRef(({ className, ...props }, ref) => { return ; diff --git a/apps/mobile/components/nativewindui/SearchInput/SearchInput.ios.tsx b/apps/mobile/components/nativewindui/SearchInput/SearchInput.ios.tsx index d89e0d8a..204d0f96 100644 --- a/apps/mobile/components/nativewindui/SearchInput/SearchInput.ios.tsx +++ b/apps/mobile/components/nativewindui/SearchInput/SearchInput.ios.tsx @@ -21,7 +21,7 @@ import type { SearchInputProps } from './types'; import { Text } from '@components/nativewindui/Text'; import { cn } from '@lib/cn'; -import { useColorScheme } from '@lib/useColorScheme'; +import { useColorScheme } from '@hooks/useColorScheme'; // Add as class when possible: https://github.com/marklawlor/nativewind/issues/522 const BORDER_CURVE: ViewStyle = { diff --git a/apps/mobile/components/nativewindui/SearchInput/SearchInput.tsx b/apps/mobile/components/nativewindui/SearchInput/SearchInput.tsx index a4ecf46f..2d6fcceb 100644 --- a/apps/mobile/components/nativewindui/SearchInput/SearchInput.tsx +++ b/apps/mobile/components/nativewindui/SearchInput/SearchInput.tsx @@ -9,7 +9,7 @@ import CrossIcon from '@assets/icons/CrossIcon.svg'; import { Button } from '@components/nativewindui/Button'; import { cn } from '@lib/cn'; -import { useColorScheme } from '@lib/useColorScheme'; +import { useColorScheme } from '@hooks/useColorScheme'; const SearchInput = React.forwardRef, SearchInputProps>( ( diff --git a/apps/mobile/components/nativewindui/TextField/TextField.tsx b/apps/mobile/components/nativewindui/TextField/TextField.tsx index a5862be5..1a878968 100644 --- a/apps/mobile/components/nativewindui/TextField/TextField.tsx +++ b/apps/mobile/components/nativewindui/TextField/TextField.tsx @@ -22,7 +22,7 @@ import CrossIcon from '@assets/icons/CrossIcon.svg'; import type { TextFieldProps, TextFieldRef } from './types'; import { cn } from '@lib/cn'; -import { useColorScheme } from '@lib/useColorScheme'; +import { useColorScheme } from '@hooks/useColorScheme'; const TextField = React.forwardRef( ( diff --git a/apps/mobile/components/nativewindui/ThemeToggle.tsx b/apps/mobile/components/nativewindui/ThemeToggle.tsx index 2ffab7df..2acd12fd 100644 --- a/apps/mobile/components/nativewindui/ThemeToggle.tsx +++ b/apps/mobile/components/nativewindui/ThemeToggle.tsx @@ -2,7 +2,7 @@ import { Pressable, View } from 'react-native'; import Animated, { LayoutAnimationConfig, ZoomInRotate } from 'react-native-reanimated'; import { cn } from '@lib/cn'; -import { useColorScheme } from '@lib/useColorScheme'; +import { useColorScheme } from '@hooks/useColorScheme'; import { COLORS } from '@theme/colors'; import SunIcon from '@assets/icons/SunIcon.svg'; diff --git a/apps/mobile/components/nativewindui/Toggle.tsx b/apps/mobile/components/nativewindui/Toggle.tsx index c50a1f32..692e9901 100644 --- a/apps/mobile/components/nativewindui/Toggle.tsx +++ b/apps/mobile/components/nativewindui/Toggle.tsx @@ -1,6 +1,6 @@ import { Switch } from 'react-native'; -import { useColorScheme } from '@lib/useColorScheme'; +import { useColorScheme } from '@hooks/useColorScheme'; import { COLORS } from '@theme/colors'; function Toggle(props: React.ComponentPropsWithoutRef) { diff --git a/apps/mobile/lib/useColorScheme.tsx b/apps/mobile/hooks/useColorScheme.tsx similarity index 100% rename from apps/mobile/lib/useColorScheme.tsx rename to apps/mobile/hooks/useColorScheme.tsx diff --git a/apps/mobile/types/channels.ts b/apps/mobile/types/channels.ts new file mode 100644 index 00000000..6fa122cf --- /dev/null +++ b/apps/mobile/types/channels.ts @@ -0,0 +1,32 @@ +export interface RavenChannel { + creation: string + name: string + modified: string + owner: string + modified_by: string + docstatus: 0 | 1 | 2 + parent?: string + parentfield?: string + parenttype?: string + idx?: number + /** Channel Name : Data */ + channel_name: string + /** Channel Description : Data */ + channel_description?: string + /** Type : Select */ + type: "Private" | "Public" | "Open" + /** Is Direct Message : Check */ + is_direct_message?: 0 | 1 + /** Is Self Message : Check */ + is_self_message?: 0 | 1 + /** Is Archived : Check */ + is_archived?: 0 | 1 + /** Last Message Timestamp : Datetime */ + last_message_timestamp?: string + /** Last Message Details : JSON */ + last_message_details?: any +} + +export type ChannelListItem = Pick \ No newline at end of file