Add ability to delete message
This commit is contained in:
parent
7557445a3e
commit
1ed1f3fd2e
|
@ -1,3 +1,4 @@
|
||||||
|
import { useMutation } from '@tanstack/react-query';
|
||||||
import classNames from 'clsx';
|
import classNames from 'clsx';
|
||||||
import {
|
import {
|
||||||
Map as ImmutableMap,
|
Map as ImmutableMap,
|
||||||
|
@ -16,10 +17,12 @@ import { initReportById } from 'soapbox/actions/reports';
|
||||||
import { Avatar, HStack, IconButton, Spinner, Stack, Text } from 'soapbox/components/ui';
|
import { Avatar, HStack, IconButton, Spinner, Stack, Text } from 'soapbox/components/ui';
|
||||||
import DropdownMenuContainer from 'soapbox/containers/dropdown_menu_container';
|
import DropdownMenuContainer from 'soapbox/containers/dropdown_menu_container';
|
||||||
import emojify from 'soapbox/features/emoji/emoji';
|
import emojify from 'soapbox/features/emoji/emoji';
|
||||||
|
import PlaceholderChat from 'soapbox/features/placeholder/components/placeholder_chat';
|
||||||
import Bundle from 'soapbox/features/ui/components/bundle';
|
import Bundle from 'soapbox/features/ui/components/bundle';
|
||||||
import { MediaGallery } from 'soapbox/features/ui/util/async-components';
|
import { MediaGallery } from 'soapbox/features/ui/util/async-components';
|
||||||
import { useAppSelector, useAppDispatch, useRefEventHandler, useOwnAccount } from 'soapbox/hooks';
|
import { useAppSelector, useAppDispatch, useRefEventHandler, useOwnAccount } from 'soapbox/hooks';
|
||||||
import { IChat, IChatMessage, useChatMessages } from 'soapbox/queries/chats';
|
import { IChat, IChatMessage, useChat, useChatMessages } from 'soapbox/queries/chats';
|
||||||
|
import { queryClient } from 'soapbox/queries/client';
|
||||||
import { onlyEmoji } from 'soapbox/utils/rich_content';
|
import { onlyEmoji } from 'soapbox/utils/rich_content';
|
||||||
|
|
||||||
import type { Menu } from 'soapbox/components/dropdown_menu';
|
import type { Menu } from 'soapbox/components/dropdown_menu';
|
||||||
|
@ -80,10 +83,10 @@ const ChatMessageList: React.FC<IChatMessageList> = ({ chat, chatMessageIds, aut
|
||||||
const [initialLoad, setInitialLoad] = useState(true);
|
const [initialLoad, setInitialLoad] = useState(true);
|
||||||
const [scrollPosition, setScrollPosition] = useState(0);
|
const [scrollPosition, setScrollPosition] = useState(0);
|
||||||
|
|
||||||
const { data: chatMessages, isFetching, isFetched, fetchNextPage, isFetchingNextPage, isPlaceholderData } = useChatMessages(chat.id);
|
const { deleteChatMessage } = useChat(chat.id);
|
||||||
|
const { data: chatMessages, isLoading, isFetching, isFetched, fetchNextPage, isFetchingNextPage, isPlaceholderData } = useChatMessages(chat.id);
|
||||||
const formattedChatMessages = chatMessages || [];
|
const formattedChatMessages = chatMessages || [];
|
||||||
|
|
||||||
|
|
||||||
const me = useAppSelector(state => state.me);
|
const me = useAppSelector(state => state.me);
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,6 +97,12 @@ const ChatMessageList: React.FC<IChatMessageList> = ({ chat, chatMessageIds, aut
|
||||||
|
|
||||||
const initialCount = useMemo(() => formattedChatMessages.length, []);
|
const initialCount = useMemo(() => formattedChatMessages.length, []);
|
||||||
|
|
||||||
|
const handleDeleteMessage = useMutation((chatMessageId: string) => deleteChatMessage(chatMessageId), {
|
||||||
|
onSettled: () => {
|
||||||
|
queryClient.invalidateQueries(['chats', 'messages', chat.id]);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const scrollToBottom = () => {
|
const scrollToBottom = () => {
|
||||||
messagesEnd.current?.scrollIntoView(false);
|
messagesEnd.current?.scrollIntoView(false);
|
||||||
};
|
};
|
||||||
|
@ -224,12 +233,6 @@ const ChatMessageList: React.FC<IChatMessageList> = ({ chat, chatMessageIds, aut
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleDeleteMessage = (chatId: string, messageId: string) => {
|
|
||||||
return () => {
|
|
||||||
dispatch(deleteChatMessage(chatId, messageId));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleReportUser = (userId: string) => {
|
const handleReportUser = (userId: string) => {
|
||||||
return () => {
|
return () => {
|
||||||
dispatch(initReportById(userId));
|
dispatch(initReportById(userId));
|
||||||
|
@ -242,7 +245,7 @@ const ChatMessageList: React.FC<IChatMessageList> = ({ chat, chatMessageIds, aut
|
||||||
const menu: Menu = [
|
const menu: Menu = [
|
||||||
{
|
{
|
||||||
text: intl.formatMessage(messages.delete),
|
text: intl.formatMessage(messages.delete),
|
||||||
action: handleDeleteMessage(chatMessage.chat_id, chatMessage.id),
|
action: () => handleDeleteMessage.mutate(chatMessage.id),
|
||||||
icon: require('@tabler/icons/trash.svg'),
|
icon: require('@tabler/icons/trash.svg'),
|
||||||
destructive: true,
|
destructive: true,
|
||||||
},
|
},
|
||||||
|
@ -257,88 +260,88 @@ const ChatMessageList: React.FC<IChatMessageList> = ({ chat, chatMessageIds, aut
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack
|
<div key={chatMessage.id} className='group'>
|
||||||
key={chatMessage.id}
|
<Stack
|
||||||
space={1}
|
space={1}
|
||||||
className={classNames({
|
|
||||||
'group max-w-[85%]': true,
|
|
||||||
'ml-auto': isMyMessage,
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<HStack
|
|
||||||
alignItems='center'
|
|
||||||
justifyContent={isMyMessage ? 'end' : 'start'}
|
|
||||||
className={classNames({
|
|
||||||
'opacity-50': chatMessage.pending,
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
{isMyMessage ? (
|
|
||||||
// <IconButton
|
|
||||||
// src={require('@tabler/icons/dots.svg')}
|
|
||||||
// className='hidden group-hover:block text-gray-600 mr-2'
|
|
||||||
// iconClassName='w-5 h-5'
|
|
||||||
// />
|
|
||||||
<div className='hidden group-hover:block mr-2 text-gray-500'>
|
|
||||||
<DropdownMenuContainer
|
|
||||||
items={menu}
|
|
||||||
src={require('@tabler/icons/dots.svg')}
|
|
||||||
title={intl.formatMessage(messages.more)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
) : null}
|
|
||||||
|
|
||||||
<div
|
|
||||||
title={getFormattedTimestamp(chatMessage)}
|
|
||||||
className={
|
|
||||||
classNames({
|
|
||||||
'text-ellipsis break-words relative rounded-md p-2': true,
|
|
||||||
'bg-primary-500 text-white mr-2': isMyMessage,
|
|
||||||
'bg-gray-200 text-gray-900 order-2 ml-2': !isMyMessage,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
ref={setBubbleRef}
|
|
||||||
tabIndex={0}
|
|
||||||
>
|
|
||||||
{maybeRenderMedia(chatMessage)}
|
|
||||||
<Text size='sm' theme='inherit' dangerouslySetInnerHTML={{ __html: parseContent(chatMessage) }} />
|
|
||||||
<div className='chat-message__menu'>
|
|
||||||
<DropdownMenuContainer
|
|
||||||
items={menu}
|
|
||||||
src={require('@tabler/icons/dots.svg')}
|
|
||||||
title={intl.formatMessage(messages.more)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={classNames({ 'order-1': !isMyMessage })}>
|
|
||||||
<Avatar src={isMyMessage ? account?.avatar : chat.account.avatar} size={34} />
|
|
||||||
</div>
|
|
||||||
</HStack>
|
|
||||||
|
|
||||||
<HStack
|
|
||||||
alignItems='center'
|
|
||||||
space={2}
|
|
||||||
className={classNames({
|
className={classNames({
|
||||||
'ml-auto': isMyMessage,
|
'ml-auto': isMyMessage,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<Text
|
<HStack
|
||||||
theme='muted'
|
alignItems='center'
|
||||||
size='xs'
|
justifyContent={isMyMessage ? 'end' : 'start'}
|
||||||
className={classNames({
|
className={classNames({
|
||||||
'text-right': isMyMessage,
|
'opacity-50': chatMessage.pending,
|
||||||
'order-2': !isMyMessage,
|
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{intl.formatTime(chatMessage.created_at)}
|
{isMyMessage ? (
|
||||||
</Text>
|
<div className='hidden group-hover:block mr-2 text-gray-500'>
|
||||||
|
<DropdownMenuContainer
|
||||||
|
items={menu}
|
||||||
|
src={require('@tabler/icons/dots.svg')}
|
||||||
|
title={intl.formatMessage(messages.more)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
<div className={classNames({ 'order-1': !isMyMessage })}>
|
<HStack
|
||||||
<div className='w-[34px]' />
|
alignItems='center'
|
||||||
</div>
|
className='max-w-[85%]'
|
||||||
</HStack>
|
justifyContent={isMyMessage ? 'end' : 'start'}
|
||||||
</Stack>
|
>
|
||||||
|
<div
|
||||||
|
title={getFormattedTimestamp(chatMessage)}
|
||||||
|
className={
|
||||||
|
classNames({
|
||||||
|
'text-ellipsis break-words relative rounded-md p-2': true,
|
||||||
|
'bg-primary-500 text-white mr-2': isMyMessage,
|
||||||
|
'bg-gray-200 text-gray-900 order-2 ml-2': !isMyMessage,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
ref={setBubbleRef}
|
||||||
|
tabIndex={0}
|
||||||
|
>
|
||||||
|
{maybeRenderMedia(chatMessage)}
|
||||||
|
<Text size='sm' theme='inherit' dangerouslySetInnerHTML={{ __html: parseContent(chatMessage) }} />
|
||||||
|
<div className='chat-message__menu'>
|
||||||
|
<DropdownMenuContainer
|
||||||
|
items={menu}
|
||||||
|
src={require('@tabler/icons/dots.svg')}
|
||||||
|
title={intl.formatMessage(messages.more)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={classNames({ 'order-1': !isMyMessage })}>
|
||||||
|
<Avatar src={isMyMessage ? account?.avatar : chat.account.avatar} size={34} />
|
||||||
|
</div>
|
||||||
|
</HStack>
|
||||||
|
</HStack>
|
||||||
|
|
||||||
|
<HStack
|
||||||
|
alignItems='center'
|
||||||
|
space={2}
|
||||||
|
className={classNames({
|
||||||
|
'ml-auto': isMyMessage,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
theme='muted'
|
||||||
|
size='xs'
|
||||||
|
className={classNames({
|
||||||
|
'text-right': isMyMessage,
|
||||||
|
'order-2': !isMyMessage,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
{intl.formatTime(chatMessage.created_at)}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<div className={classNames({ 'order-1': !isMyMessage })}>
|
||||||
|
<div className='w-[34px]' />
|
||||||
|
</div>
|
||||||
|
</HStack>
|
||||||
|
</Stack>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -358,18 +361,18 @@ const ChatMessageList: React.FC<IChatMessageList> = ({ chat, chatMessageIds, aut
|
||||||
});
|
});
|
||||||
|
|
||||||
// Stick scrollbar to bottom.
|
// Stick scrollbar to bottom.
|
||||||
// useEffect(() => {
|
useEffect(() => {
|
||||||
// if (isNearBottom()) {
|
if (isNearBottom()) {
|
||||||
// scrollToBottom();
|
scrollToBottom();
|
||||||
// }
|
}
|
||||||
|
|
||||||
// // First load.
|
// First load.
|
||||||
// // if (chatMessages.count() !== initialCount) {
|
// if (chatMessages.count() !== initialCount) {
|
||||||
// // setInitialLoad(false);
|
// setInitialLoad(false);
|
||||||
// // setIsLoading(false);
|
// setIsLoading(false);
|
||||||
// // scrollToBottom();
|
// scrollToBottom();
|
||||||
// // }
|
// }
|
||||||
// }, [formattedChatMessages.length]);
|
}, [formattedChatMessages.length]);
|
||||||
|
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
// scrollToBottom();
|
// scrollToBottom();
|
||||||
|
@ -381,9 +384,7 @@ const ChatMessageList: React.FC<IChatMessageList> = ({ chat, chatMessageIds, aut
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Restore scroll bar position when loading old messages.
|
// Restore scroll bar position when loading old messages.
|
||||||
console.log('hii');
|
|
||||||
if (!initialLoad) {
|
if (!initialLoad) {
|
||||||
|
|
||||||
restoreScrollPosition();
|
restoreScrollPosition();
|
||||||
}
|
}
|
||||||
}, [formattedChatMessages.length, initialLoad]);
|
}, [formattedChatMessages.length, initialLoad]);
|
||||||
|
@ -398,26 +399,39 @@ const ChatMessageList: React.FC<IChatMessageList> = ({ chat, chatMessageIds, aut
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='h-full flex flex-col space-y-4 px-4 flex-grow overflow-y-scroll' onScroll={handleScroll} ref={node}> {/* style={{ height: autosize ? 'calc(100vh - 16rem)' : undefined }} */}
|
<div className='h-full flex flex-col px-4 flex-grow overflow-y-scroll' onScroll={handleScroll} ref={node}> {/* style={{ height: autosize ? 'calc(100vh - 16rem)' : undefined }} */}
|
||||||
{formattedChatMessages.reduce((acc: any, curr: any, idx: number) => {
|
<div className='flex-grow flex flex-col justify-end space-y-4'>
|
||||||
const lastMessage = formattedChatMessages[idx - 1];
|
{isLoading ? (
|
||||||
|
<>
|
||||||
|
<PlaceholderChat isMyMessage />
|
||||||
|
<PlaceholderChat />
|
||||||
|
<PlaceholderChat isMyMessage />
|
||||||
|
<PlaceholderChat isMyMessage />
|
||||||
|
<PlaceholderChat />
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
formattedChatMessages.reduce((acc: any, curr: any, idx: number) => {
|
||||||
|
const lastMessage = formattedChatMessages[idx - 1];
|
||||||
|
|
||||||
if (lastMessage) {
|
if (lastMessage) {
|
||||||
const key = `${curr.id}_divider`;
|
const key = `${curr.id}_divider`;
|
||||||
switch (timeChange(lastMessage, curr)) {
|
switch (timeChange(lastMessage, curr)) {
|
||||||
case 'today':
|
case 'today':
|
||||||
acc.push(renderDivider(key, intl.formatMessage(messages.today)));
|
acc.push(renderDivider(key, intl.formatMessage(messages.today)));
|
||||||
break;
|
break;
|
||||||
case 'date':
|
case 'date':
|
||||||
acc.push(renderDivider(key, intl.formatDate(new Date(curr.created_at), { weekday: 'short', hour: 'numeric', minute: '2-digit', month: 'short', day: 'numeric' })));
|
acc.push(renderDivider(key, intl.formatDate(new Date(curr.created_at), { weekday: 'short', hour: 'numeric', minute: '2-digit', month: 'short', day: 'numeric' })));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
acc.push(renderMessage(curr));
|
acc.push(renderMessage(curr));
|
||||||
return acc;
|
return acc;
|
||||||
}, [] as React.ReactNode[])}
|
}, [] as React.ReactNode[])
|
||||||
<div style={{ float: 'left', clear: 'both' }} ref={messagesEnd} />
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='float-left clear-both mt-4' style={{ float: 'left', clear: 'both' }} ref={messagesEnd} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,27 +1,11 @@
|
||||||
import React, { useEffect, useRef } from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
|
|
||||||
import {
|
import { Avatar, HStack, Icon, Stack, Text } from 'soapbox/components/ui';
|
||||||
closeChat,
|
|
||||||
toggleChat,
|
|
||||||
} from 'soapbox/actions/chats';
|
|
||||||
import HoverRefWrapper from 'soapbox/components/hover_ref_wrapper';
|
|
||||||
import IconButton from 'soapbox/components/icon_button';
|
|
||||||
import { Avatar, HStack, Counter, Icon, Stack, Text } from 'soapbox/components/ui';
|
|
||||||
import VerificationBadge from 'soapbox/components/verification_badge';
|
import VerificationBadge from 'soapbox/components/verification_badge';
|
||||||
import { useAppSelector, useAppDispatch } from 'soapbox/hooks';
|
|
||||||
import { IChat } from 'soapbox/queries/chats';
|
import { IChat } from 'soapbox/queries/chats';
|
||||||
import { makeGetChat } from 'soapbox/selectors';
|
|
||||||
import { getAcct } from 'soapbox/utils/accounts';
|
|
||||||
import { displayFqn as getDisplayFqn } from 'soapbox/utils/state';
|
|
||||||
|
|
||||||
import ChatBox from './chat-box';
|
import ChatBox from './chat-box';
|
||||||
import ChatPaneHeader from './chat-pane-header';
|
import ChatPaneHeader from './chat-pane-header';
|
||||||
import { Pane, WindowState } from './ui';
|
|
||||||
|
|
||||||
import type { Account as AccountEntity } from 'soapbox/types/entities';
|
|
||||||
|
|
||||||
const getChat = makeGetChat();
|
|
||||||
|
|
||||||
interface IChatWindow {
|
interface IChatWindow {
|
||||||
chat: IChat
|
chat: IChat
|
||||||
|
@ -67,23 +51,6 @@ const ChatWindow: React.FC<IChatWindow> = ({ chat, closeChat, closePane }) => {
|
||||||
<ChatBox chat={chat} onSetInputRef={() => null} />
|
<ChatBox chat={chat} onSetInputRef={() => null} />
|
||||||
</Stack>
|
</Stack>
|
||||||
</>
|
</>
|
||||||
// <Pane windowState={windowState} index={idx}>
|
|
||||||
// <HStack space={2} className='pane__header'>
|
|
||||||
// {unreadCount > 0 ? unreadIcon : avatar }
|
|
||||||
// <button className='pane__title' onClick={handleChatToggle(chat.id)}>
|
|
||||||
// @{getAcct(account, displayFqn)}
|
|
||||||
// </button>
|
|
||||||
// <div className='pane__close'>
|
|
||||||
// <IconButton src={require('@tabler/icons/x.svg')} title='Close chat' onClick={handleChatClose(chat.id)} />
|
|
||||||
// </div>
|
|
||||||
// </HStack>
|
|
||||||
// <div className='pane__content'>
|
|
||||||
// <ChatBox
|
|
||||||
// chatId={chat.id}
|
|
||||||
//
|
|
||||||
// />
|
|
||||||
// </div>
|
|
||||||
// </Pane>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,30 +1,69 @@
|
||||||
|
import classNames from 'classnames';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import { HStack, Stack, Text } from 'soapbox/components/ui';
|
||||||
|
|
||||||
import { randomIntFromInterval, generateText } from '../utils';
|
import { randomIntFromInterval, generateText } from '../utils';
|
||||||
|
|
||||||
import PlaceholderAvatar from './placeholder_avatar';
|
import PlaceholderAvatar from './placeholder_avatar';
|
||||||
import PlaceholderDisplayName from './placeholder_display_name';
|
import PlaceholderDisplayName from './placeholder_display_name';
|
||||||
|
|
||||||
/** Fake chat to display while data is loading. */
|
/** Fake chat to display while data is loading. */
|
||||||
const PlaceholderChat: React.FC = () => {
|
const PlaceholderChat = ({ isMyMessage = false }: { isMyMessage?: boolean }) => {
|
||||||
const messageLength = randomIntFromInterval(5, 75);
|
const messageLength = randomIntFromInterval(160, 220);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='chat-list-item chat-list-item--placeholder'>
|
<Stack
|
||||||
<div className='account'>
|
space={1}
|
||||||
<div className='account__wrapper'>
|
className={classNames({
|
||||||
<div className='account__display-name'>
|
'max-w-[85%] animate-pulse': true,
|
||||||
<div className='account__avatar-wrapper'>
|
'ml-auto': isMyMessage,
|
||||||
<PlaceholderAvatar size={36} />
|
})}
|
||||||
</div>
|
>
|
||||||
<PlaceholderDisplayName minLength={3} maxLength={25} />
|
<HStack
|
||||||
<span className='chat__last-message'>
|
alignItems='center'
|
||||||
{generateText(messageLength)}
|
justifyContent={isMyMessage ? 'end' : 'start'}
|
||||||
</span>
|
>
|
||||||
</div>
|
<div
|
||||||
|
className={
|
||||||
|
classNames({
|
||||||
|
'text-ellipsis break-words relative rounded-md p-2': true,
|
||||||
|
'mr-2': isMyMessage,
|
||||||
|
'order-2 ml-2': !isMyMessage,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div style={{ width: messageLength, height: 20 }} className='rounded-full bg-primary-50 dark:bg-primary-800' />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
<div className={classNames({ 'order-1': !isMyMessage })}>
|
||||||
|
<PlaceholderAvatar size={34} />
|
||||||
|
</div>
|
||||||
|
</HStack>
|
||||||
|
|
||||||
|
<HStack
|
||||||
|
alignItems='center'
|
||||||
|
space={2}
|
||||||
|
className={classNames({
|
||||||
|
'ml-auto': isMyMessage,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<Text
|
||||||
|
theme='muted'
|
||||||
|
size='xs'
|
||||||
|
className={classNames({
|
||||||
|
'text-right': isMyMessage,
|
||||||
|
'order-2': !isMyMessage,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<div style={{ width: 50, height: 12 }} className='rounded-full bg-primary-50 dark:bg-primary-800' />
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
<div className={classNames({ 'order-1': !isMyMessage })}>
|
||||||
|
<div className='w-[34px] ml-2' />
|
||||||
|
</div>
|
||||||
|
</HStack>
|
||||||
|
</Stack>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ const reverseOrder = (a: IChat, b: IChat): number => {
|
||||||
const useChatMessages = (chatId: string) => {
|
const useChatMessages = (chatId: string) => {
|
||||||
const api = useApi();
|
const api = useApi();
|
||||||
|
|
||||||
const getChatMessages = async (chatId: string, pageParam?: any): Promise<{ result: IChatMessage[], maxId: string, hasMore: boolean }> => {
|
const getChatMessages = async(chatId: string, pageParam?: any): Promise<{ result: IChatMessage[], maxId: string, hasMore: boolean }> => {
|
||||||
const { data, headers } = await api.get(`/api/v1/pleroma/chats/${chatId}/messages`, {
|
const { data, headers } = await api.get(`/api/v1/pleroma/chats/${chatId}/messages`, {
|
||||||
params: {
|
params: {
|
||||||
max_id: pageParam?.maxId,
|
max_id: pageParam?.maxId,
|
||||||
|
@ -74,7 +74,7 @@ const useChatMessages = (chatId: string) => {
|
||||||
const useChats = () => {
|
const useChats = () => {
|
||||||
const api = useApi();
|
const api = useApi();
|
||||||
|
|
||||||
const getChats = async () => {
|
const getChats = async() => {
|
||||||
const { data } = await api.get('/api/v1/pleroma/chats');
|
const { data } = await api.get('/api/v1/pleroma/chats');
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
@ -97,7 +97,9 @@ const useChat = (chatId: string) => {
|
||||||
return api.post<IChat>(`/api/v1/pleroma/chats/${chatId}/messages`, { content });
|
return api.post<IChat>(`/api/v1/pleroma/chats/${chatId}/messages`, { content });
|
||||||
};
|
};
|
||||||
|
|
||||||
return { createChatMessage, markChatAsRead };
|
const deleteChatMessage = (chatMessageId: string) => api.delete<IChat>(`/api/v1/pleroma/chats/${chatId}/messages/${chatMessageId}`);
|
||||||
|
|
||||||
|
return { createChatMessage, markChatAsRead, deleteChatMessage };
|
||||||
};
|
};
|
||||||
|
|
||||||
export { useChat, useChats, useChatMessages };
|
export { useChat, useChats, useChatMessages };
|
||||||
|
|
Loading…
Reference in New Issue