Add snooze icon to ChatList
This commit is contained in:
parent
8e35d1dd92
commit
4352d17217
6 changed files with 66 additions and 31 deletions
|
@ -1,17 +1,18 @@
|
|||
import React from 'react';
|
||||
|
||||
import RelativeTimestamp from 'soapbox/components/relative-timestamp';
|
||||
import { Avatar, HStack, Stack, Text } from 'soapbox/components/ui';
|
||||
import { Avatar, HStack, Icon, Stack, Text } from 'soapbox/components/ui';
|
||||
import VerificationBadge from 'soapbox/components/verification_badge';
|
||||
|
||||
import type { IChat } from 'soapbox/queries/chats';
|
||||
import type { IChat, IChatSilence } from 'soapbox/queries/chats';
|
||||
|
||||
interface IChatListItemInterface {
|
||||
chat: IChat,
|
||||
onClick: (chat: any) => void,
|
||||
chatSilence?: IChatSilence
|
||||
}
|
||||
|
||||
const ChatListItem: React.FC<IChatListItemInterface> = ({ chat, onClick }) => {
|
||||
const ChatListItem: React.FC<IChatListItemInterface> = ({ chat, chatSilence, onClick }) => {
|
||||
return (
|
||||
<button
|
||||
key={chat.id}
|
||||
|
@ -37,7 +38,7 @@ const ChatListItem: React.FC<IChatListItemInterface> = ({ chat, onClick }) => {
|
|||
weight='medium'
|
||||
theme='muted'
|
||||
truncate
|
||||
className='w-full'
|
||||
className='w-full truncate-child'
|
||||
data-testid='chat-last-message'
|
||||
dangerouslySetInnerHTML={{ __html: chat.last_message?.content }}
|
||||
/>
|
||||
|
@ -45,23 +46,29 @@ const ChatListItem: React.FC<IChatListItemInterface> = ({ chat, onClick }) => {
|
|||
</Stack>
|
||||
</HStack>
|
||||
|
||||
{chat.last_message && (
|
||||
<HStack alignItems='center' space={2}>
|
||||
{chat.last_message.unread && (
|
||||
<div
|
||||
className='w-2 h-2 rounded-full bg-secondary-500'
|
||||
data-testid='chat-unread-indicator'
|
||||
/>
|
||||
)}
|
||||
<HStack alignItems='center' space={2}>
|
||||
{chatSilence ? (
|
||||
<Icon src={require('@tabler/icons/bell-off.svg')} className='w-5 h-5 text-gray-600' />
|
||||
) : null}
|
||||
|
||||
<RelativeTimestamp
|
||||
timestamp={chat.last_message.created_at}
|
||||
align='right'
|
||||
size='xs'
|
||||
truncate
|
||||
/>
|
||||
</HStack>
|
||||
)}
|
||||
{chat.last_message && (
|
||||
<>
|
||||
{chat.last_message.unread && (
|
||||
<div
|
||||
className='w-2 h-2 rounded-full bg-secondary-500'
|
||||
data-testid='chat-unread-indicator'
|
||||
/>
|
||||
)}
|
||||
|
||||
<RelativeTimestamp
|
||||
timestamp={chat.last_message.created_at}
|
||||
align='right'
|
||||
size='xs'
|
||||
truncate
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</HStack>
|
||||
</HStack>
|
||||
</button>
|
||||
);
|
||||
|
|
|
@ -7,7 +7,7 @@ import PullToRefresh from 'soapbox/components/pull-to-refresh';
|
|||
import { Stack } from 'soapbox/components/ui';
|
||||
import PlaceholderChat from 'soapbox/features/placeholder/components/placeholder-chat';
|
||||
import { useAppDispatch } from 'soapbox/hooks';
|
||||
import { useChats } from 'soapbox/queries/chats';
|
||||
import { useChats, useChatSilences } from 'soapbox/queries/chats';
|
||||
|
||||
import ChatListItem from './chat-list-item';
|
||||
|
||||
|
@ -25,6 +25,8 @@ const ChatList: React.FC<IChatList> = ({ onClickChat, useWindowScroll = false, s
|
|||
|
||||
const { chatsQuery: { data: chats, isFetching, hasNextPage, fetchNextPage } } = useChats(searchValue);
|
||||
|
||||
const { data: chatSilences } = useChatSilences();
|
||||
|
||||
const [isNearBottom, setNearBottom] = useState<boolean>(false);
|
||||
const [isNearTop, setNearTop] = useState<boolean>(true);
|
||||
|
||||
|
@ -57,7 +59,10 @@ const ChatList: React.FC<IChatList> = ({ onClickChat, useWindowScroll = false, s
|
|||
useWindowScroll={useWindowScroll}
|
||||
data={chats}
|
||||
endReached={handleLoadMore}
|
||||
itemContent={(_index, chat) => <ChatListItem chat={chat} onClick={onClickChat} />}
|
||||
itemContent={(_index, chat) => {
|
||||
const chatSilence = chatSilences?.find((chatSilence) => String(chatSilence.target_account_id) === chat.account.id);
|
||||
return <ChatListItem chat={chat} onClick={onClickChat} chatSilence={chatSilence} />;
|
||||
}}
|
||||
components={{
|
||||
ScrollSeekPlaceholder: () => <PlaceholderChat />,
|
||||
// Footer: () => hasNextPage ? <Spinner withText={false} /> : null,
|
||||
|
|
|
@ -12,7 +12,7 @@ import { Avatar, Card, CardTitle, Divider, HStack, Icon, IconButton, Menu, MenuB
|
|||
import VerificationBadge from 'soapbox/components/verification_badge';
|
||||
import { useChatContext } from 'soapbox/contexts/chat-context';
|
||||
import { useAppDispatch } from 'soapbox/hooks';
|
||||
import { useChat, useChatSilences } from 'soapbox/queries/chats';
|
||||
import { useChat, useChatSilence } from 'soapbox/queries/chats';
|
||||
|
||||
import Chat from './chat';
|
||||
import ChatList from './chat-list';
|
||||
|
@ -36,8 +36,8 @@ const ChatPage = () => {
|
|||
const dispatch = useAppDispatch();
|
||||
const history = useHistory();
|
||||
|
||||
const { isSilenced, handleSilence } = useChatSilences();
|
||||
const { chat, setChat } = useChatContext();
|
||||
const { isSilenced, handleSilence } = useChatSilence(chat);
|
||||
const { deleteChat } = useChat(chat?.id as string);
|
||||
|
||||
const handleSuggestion = (accountId: string) => {
|
||||
|
|
|
@ -8,7 +8,7 @@ import List, { ListItem } from 'soapbox/components/list';
|
|||
import { Avatar, Divider, HStack, Icon, Stack, Text, Toggle } from 'soapbox/components/ui';
|
||||
import { useChatContext } from 'soapbox/contexts/chat-context';
|
||||
import { useAppDispatch } from 'soapbox/hooks';
|
||||
import { useChat, useChatSilences } from 'soapbox/queries/chats';
|
||||
import { useChat, useChatSilence } from 'soapbox/queries/chats';
|
||||
|
||||
import ChatPaneHeader from './chat-pane-header';
|
||||
|
||||
|
@ -29,9 +29,9 @@ const ChatSettings = () => {
|
|||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
|
||||
const { isSilenced, handleSilence } = useChatSilences();
|
||||
|
||||
const { chat, setEditing, toggleChatPane } = useChatContext();
|
||||
const { isSilenced, handleSilence } = useChatSilence(chat);
|
||||
|
||||
const { deleteChat } = useChat(chat?.id as string);
|
||||
|
||||
const closeSettings = () => setEditing(false);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { useInfiniteQuery, useMutation } from '@tanstack/react-query';
|
||||
import { useInfiniteQuery, useMutation, useQuery } from '@tanstack/react-query';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { fetchRelationships } from 'soapbox/actions/accounts';
|
||||
|
@ -43,6 +43,12 @@ export interface IChatMessage {
|
|||
pending?: boolean
|
||||
}
|
||||
|
||||
export interface IChatSilence {
|
||||
id: number
|
||||
account_id: number
|
||||
target_account_id: number
|
||||
}
|
||||
|
||||
const reverseOrder = (a: IChat, b: IChat): number => compareId(a.id, b.id);
|
||||
|
||||
const useChatMessages = (chatId: string) => {
|
||||
|
@ -178,9 +184,22 @@ const useChat = (chatId: string) => {
|
|||
|
||||
const useChatSilences = () => {
|
||||
const api = useApi();
|
||||
|
||||
const getChatSilences = async() => {
|
||||
const { data } = await api.get<IChatSilence[]>('/api/v1/pleroma/chats/silences');
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
return useQuery<IChatSilence[]>(['chatSilences'], getChatSilences, {
|
||||
placeholderData: [],
|
||||
});
|
||||
};
|
||||
|
||||
const useChatSilence = (chat: IChat | null) => {
|
||||
const api = useApi();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const { chat } = useChatContext();
|
||||
const [isSilenced, setSilenced] = useState<boolean>(false);
|
||||
|
||||
const getChatSilences = async() => {
|
||||
|
@ -235,9 +254,9 @@ const useChatSilences = () => {
|
|||
if (chat?.id) {
|
||||
fetchChatSilence();
|
||||
}
|
||||
}, [chat]);
|
||||
}, [chat?.id]);
|
||||
|
||||
return { isSilenced, handleSilence };
|
||||
};
|
||||
|
||||
export { useChat, useChats, useChatMessages, useChatSilences };
|
||||
export { useChat, useChats, useChatMessages, useChatSilences, useChatSilence };
|
||||
|
|
|
@ -87,6 +87,10 @@
|
|||
box-shadow: inset 0 0 0 1px rgb(255 255 255 / 10%);
|
||||
}
|
||||
|
||||
.truncate-child > * {
|
||||
@apply truncate;
|
||||
}
|
||||
|
||||
.d-screen {
|
||||
height: 100vh; // Backwards compatibility
|
||||
/* stylelint-disable-next-line unit-no-unknown */
|
||||
|
|
Loading…
Reference in a new issue