Add error states

chats-router
Justin 2 years ago
parent c48b4adc81
commit 1c179cd4a0

@ -27,7 +27,7 @@ const ChatMessageListIntro = () => {
};
const handleReportChat = () => {
dispatch(initReport(chat?.account));
dispatch(initReport(chat?.account as any));
acceptChat.mutate();
};

@ -7,8 +7,7 @@ import React, { useState, useEffect, useRef, useLayoutEffect } from 'react';
import { useIntl, defineMessages } from 'react-intl';
import { openModal } from 'soapbox/actions/modals';
import { initReportById } from 'soapbox/actions/reports';
import { Avatar, Divider, HStack, Spinner, Stack, Text } from 'soapbox/components/ui';
import { Avatar, Button, Divider, HStack, Spinner, Stack, Text } from 'soapbox/components/ui';
import DropdownMenuContainer from 'soapbox/containers/dropdown_menu_container';
// import emojify from 'soapbox/features/emoji/emoji';
import PlaceholderChatMessage from 'soapbox/features/placeholder/components/placeholder-chat-message';
@ -68,10 +67,21 @@ const ChatMessageList: React.FC<IChatMessageList> = ({ chat, autosize }) => {
const [scrollPosition, setScrollPosition] = useState(0);
const { deleteChatMessage, markChatAsRead } = useChat(chat.id);
const { data: chatMessages, isLoading, isFetching, isFetched, fetchNextPage, isFetchingNextPage, isPlaceholderData } = useChatMessages(chat.id);
const {
data: chatMessages,
fetchNextPage,
isError,
isFetched,
isFetching,
isFetchingNextPage,
isLoading,
isPlaceholderData,
refetch,
} = useChatMessages(chat.id);
const formattedChatMessages = chatMessages || [];
const me = useAppSelector(state => state.me);
const me = useAppSelector((state) => state.me);
const isBlocked = useAppSelector((state) => state.getIn(['relationships', chat.account, 'blocked_by']));
const node = useRef<HTMLDivElement>(null);
const messagesEnd = useRef<HTMLDivElement>(null);
@ -89,16 +99,14 @@ const ChatMessageList: React.FC<IChatMessageList> = ({ chat, autosize }) => {
};
const getFormattedTimestamp = (chatMessage: ChatMessageEntity) => {
return intl.formatDate(
new Date(chatMessage.created_at), {
return intl.formatDate(new Date(chatMessage.created_at), {
hour12: false,
year: 'numeric',
month: 'short',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
},
);
});
};
const setBubbleRef = (c: HTMLDivElement) => {
@ -295,7 +303,7 @@ const ChatMessageList: React.FC<IChatMessageList> = ({ chat, autosize }) => {
</div>
<div className={classNames({ 'order-1': !isMyMessage })}>
<Avatar src={isMyMessage ? account?.avatar : chat.account.avatar} size={34} />
<Avatar src={isMyMessage ? account?.avatar as string : chat.account.avatar as string} size={34} />
</div>
</HStack>
</HStack>
@ -383,6 +391,44 @@ const ChatMessageList: React.FC<IChatMessageList> = ({ chat, autosize }) => {
);
}
if (isBlocked) {
return (
<Stack alignItems='center' justifyContent='center' className='h-full flex-grow'>
<Stack alignItems='center' space={2}>
<Avatar src={chat.account.avatar_static} size={75} />
<Text align='center'>
<>
<Text tag='span'>You are blocked by</Text>
{' '}
<Text tag='span' theme='primary'>@{chat.account.acct}</Text>
</>
</Text>
</Stack>
</Stack>
);
}
if (isError) {
return (
<Stack alignItems='center' justifyContent='center' className='h-full flex-grow'>
<Stack space={4}>
<Stack space={1}>
<Text size='lg' weight='bold' align='center'>Whoops!</Text>
<Text theme='muted' align='center'>
We encountered a network failure.
</Text>
</Stack>
<div className='mx-auto'>
<Button theme='primary' onClick={() => refetch()}>
Try again
</Button>
</div>
</Stack>
</Stack>
);
}
return (
<div className='h-full flex flex-col px-4 flex-grow overflow-y-scroll space-y-6' onScroll={handleScroll} ref={node}> {/* style={{ height: autosize ? 'calc(100vh - 16rem)' : undefined }} */}
{!isLoading ? (

@ -31,7 +31,7 @@ const ChatSettings = () => {
message: 'Blocking will prevent this profile from direct messaging you and viewing your content. You can unblock later.',
confirm: 'Block',
confirmationTheme: 'primary',
onConfirm: () => dispatch(blockAccount(chat?.account.id)),
onConfirm: () => dispatch(blockAccount(chat?.account.id as string)),
}));
};
@ -48,7 +48,7 @@ const ChatSettings = () => {
};
const handleReportChat = () => {
dispatch(initReport(chat?.account));
dispatch(initReport(chat?.account as any));
};
if (!chat) {

@ -0,0 +1,24 @@
export type IAccount = {
acct: string
avatar: string
avatar_static: string
bot: boolean
created_at: string
discoverable: boolean
display_name: string
followers_count: number
following_count: number
group: boolean
header: string
header_static: string
id: string
last_status_at: string
location: string
locked: boolean
note: string
statuses_count: number
url: string
username: string
verified: boolean
website: string
}

@ -1,12 +1,15 @@
import { useInfiniteQuery, useMutation } from '@tanstack/react-query';
import { useEffect, useState } from 'react';
import { fetchRelationships } from 'soapbox/actions/accounts';
import snackbar from 'soapbox/actions/snackbar';
import { useChatContext } from 'soapbox/contexts/chat-context';
import { useApi, useAppDispatch } from 'soapbox/hooks';
import { queryClient } from './client';
import type { IAccount } from './accounts';
export interface IChat {
id: string
unread: number
@ -24,7 +27,7 @@ export interface IChat {
updated_at: Date
accepted: boolean
discarded_at: null | string
account: any
account: IAccount
}
export interface IChatMessage {
@ -88,9 +91,10 @@ const useChatMessages = (chatId: string) => {
const useChats = () => {
const api = useApi();
const dispatch = useAppDispatch();
const getChats = async(pageParam?: any): Promise<{ result: IChat[], maxId: string, hasMore: boolean }> => {
const { data, headers } = await api.get('/api/v1/pleroma/chats', {
const { data, headers } = await api.get<IChat[]>('/api/v1/pleroma/chats', {
params: {
max_id: pageParam?.maxId,
},
@ -99,6 +103,9 @@ const useChats = () => {
const hasMore = !!headers.link;
const nextMaxId = data[data.length - 1]?.id;
// Set the relationships to these users in the redux store.
dispatch(fetchRelationships(data.map((item) => item.account.id)));
return {
result: data,
maxId: nextMaxId,

@ -5,34 +5,11 @@ import { importFetchedAccounts } from 'soapbox/actions/importer';
import { getLinks } from 'soapbox/api';
import { useApi, useAppDispatch } from 'soapbox/hooks';
type Account = {
acct: string
avatar: string
avatar_static: string
bot: boolean
created_at: string
discoverable: boolean
display_name: string
followers_count: number
following_count: number
group: boolean
header: string
header_static: string
id: string
last_status_at: string
location: string
locked: boolean
note: string
statuses_count: number
url: string
username: string
verified: boolean
website: string
}
import type { IAccount } from './accounts';
type Suggestion = {
source: 'staff'
account: Account
account: IAccount
}

Loading…
Cancel
Save