From 13c9c79aeec77edc33b1a926843b005c14acccc7 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Wed, 2 Oct 2024 22:21:59 +0300 Subject: move files around (#5576) --- src/screens/Messages/ChatList.tsx | 345 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 345 insertions(+) create mode 100644 src/screens/Messages/ChatList.tsx (limited to 'src/screens/Messages/ChatList.tsx') diff --git a/src/screens/Messages/ChatList.tsx b/src/screens/Messages/ChatList.tsx new file mode 100644 index 000000000..6cf561d11 --- /dev/null +++ b/src/screens/Messages/ChatList.tsx @@ -0,0 +1,345 @@ +import React, {useCallback, useEffect, useMemo, useState} from 'react' +import {View} from 'react-native' +import {ChatBskyConvoDefs} from '@atproto/api' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' +import {useFocusEffect} from '@react-navigation/native' +import {NativeStackScreenProps} from '@react-navigation/native-stack' + +import {useAppState} from '#/lib/hooks/useAppState' +import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender' +import {MessagesTabNavigatorParams} from '#/lib/routes/types' +import {cleanError} from '#/lib/strings/errors' +import {logger} from '#/logger' +import {isNative} from '#/platform/detection' +import {MESSAGE_SCREEN_POLL_INTERVAL} from '#/state/messages/convo/const' +import {useMessagesEventBus} from '#/state/messages/events' +import {useListConvosQuery} from '#/state/queries/messages/list-converations' +import {List} from '#/view/com/util/List' +import {ViewHeader} from '#/view/com/util/ViewHeader' +import {CenteredView} from '#/view/com/util/Views' +import {atoms as a, useBreakpoints, useTheme, web} from '#/alf' +import {Button, ButtonIcon, ButtonText} from '#/components/Button' +import {DialogControlProps, useDialogControl} from '#/components/Dialog' +import {NewChat} from '#/components/dms/dialogs/NewChatDialog' +import {MessagesNUX} from '#/components/dms/MessagesNUX' +import {useRefreshOnFocus} from '#/components/hooks/useRefreshOnFocus' +import {ArrowRotateCounterClockwise_Stroke2_Corner0_Rounded as Retry} from '#/components/icons/ArrowRotateCounterClockwise' +import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' +import {Message_Stroke2_Corner0_Rounded as Message} from '#/components/icons/Message' +import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus' +import {SettingsSliderVertical_Stroke2_Corner0_Rounded as SettingsSlider} from '#/components/icons/SettingsSlider' +import {Link} from '#/components/Link' +import {ListFooter} from '#/components/Lists' +import {Loader} from '#/components/Loader' +import {Text} from '#/components/Typography' +import {ChatListItem} from './components/ChatListItem' + +type Props = NativeStackScreenProps + +function renderItem({item}: {item: ChatBskyConvoDefs.ConvoView}) { + return +} + +function keyExtractor(item: ChatBskyConvoDefs.ConvoView) { + return item.id +} + +export function MessagesScreen({navigation, route}: Props) { + const {_} = useLingui() + const t = useTheme() + const newChatControl = useDialogControl() + const {gtMobile} = useBreakpoints() + const pushToConversation = route.params?.pushToConversation + + // Whenever we have `pushToConversation` set, it means we pressed a notification for a chat without being on + // this tab. We should immediately push to the conversation after pressing the notification. + // After we push, reset with `setParams` so that this effect will fire next time we press a notification, even if + // the conversation is the same as before + useEffect(() => { + if (pushToConversation) { + navigation.navigate('MessagesConversation', { + conversation: pushToConversation, + }) + navigation.setParams({pushToConversation: undefined}) + } + }, [navigation, pushToConversation]) + + // Request the poll interval to be 10s (or whatever the MESSAGE_SCREEN_POLL_INTERVAL is set to in the future) + // but only when the screen is active + const messagesBus = useMessagesEventBus() + const state = useAppState() + const isActive = state === 'active' + useFocusEffect( + useCallback(() => { + if (isActive) { + const unsub = messagesBus.requestPollInterval( + MESSAGE_SCREEN_POLL_INTERVAL, + ) + return () => unsub() + } + }, [messagesBus, isActive]), + ) + + const renderButton = useCallback(() => { + return ( + + + + ) + }, [_, t]) + + const initialNumToRender = useInitialNumToRender({minItemHeight: 80}) + const [isPTRing, setIsPTRing] = useState(false) + + const { + data, + isLoading, + isFetchingNextPage, + hasNextPage, + fetchNextPage, + isError, + error, + refetch, + } = useListConvosQuery() + + useRefreshOnFocus(refetch) + + const conversations = useMemo(() => { + if (data?.pages) { + return data.pages.flatMap(page => page.convos) + } + return [] + }, [data]) + + const onRefresh = useCallback(async () => { + setIsPTRing(true) + try { + await refetch() + } catch (err) { + logger.error('Failed to refresh conversations', {message: err}) + } + setIsPTRing(false) + }, [refetch, setIsPTRing]) + + const onEndReached = useCallback(async () => { + if (isFetchingNextPage || !hasNextPage || isError) return + try { + await fetchNextPage() + } catch (err) { + logger.error('Failed to load more conversations', {message: err}) + } + }, [isFetchingNextPage, hasNextPage, isError, fetchNextPage]) + + const onNewChat = useCallback( + (conversation: string) => + navigation.navigate('MessagesConversation', {conversation}), + [navigation], + ) + + const onNavigateToSettings = useCallback(() => { + navigation.navigate('MessagesSettings') + }, [navigation]) + + if (conversations.length < 1) { + return ( + + + + + {gtMobile ? ( + + ) : ( + + )} + + {isLoading ? ( + + + + ) : ( + <> + {isError ? ( + <> + + + + Whoops! + + + {cleanError(error)} + + + + + + ) : ( + <> + + + + Nothing here + + + You have no conversations yet. Start one! + + + + )} + + )} + + + {!isLoading && !isError && ( + + )} + + ) + } + + return ( + + + {!gtMobile && ( + + )} + + + } + ListFooterComponent={ + + } + onEndReachedThreshold={isNative ? 1.5 : 0} + initialNumToRender={initialNumToRender} + windowSize={11} + // @ts-ignore our .web version only -sfn + desktopFixedHeight + /> + + ) +} + +function DesktopHeader({ + newChatControl, + onNavigateToSettings, +}: { + newChatControl: DialogControlProps + onNavigateToSettings: () => void +}) { + const t = useTheme() + const {_} = useLingui() + const {gtMobile, gtTablet} = useBreakpoints() + + if (!gtMobile) { + return null + } + + return ( + + + Messages + + + + {gtTablet && ( + + )} + + + ) +} -- cgit 1.4.1