Add ability to accept chat

alex-chats
Justin 2 years ago
parent 1ed1f3fd2e
commit 8492cc59e2

@ -0,0 +1,24 @@
import React, { createContext, useContext, useState } from 'react';
import type { IChat } from 'soapbox/queries/chats';
const ChatContext = createContext<any>({
chat: null,
});
const ChatProvider: React.FC = ({ children }) => {
const [chat, setChat] = useState<IChat>();
return (
<ChatContext.Provider value={{ chat, setChat }}>{children}</ChatContext.Provider>
);
};
interface IChatContext {
chat: IChat | null
setChat: React.Dispatch<React.SetStateAction<IChat | null>>
}
const useChatContext = (): IChatContext => useContext(ChatContext);
export { ChatContext, ChatProvider, useChatContext };

@ -8,7 +8,7 @@ import {
markChatRead,
} from 'soapbox/actions/chats';
import { uploadMedia } from 'soapbox/actions/media';
import { HStack, Icon, IconButton, Input, Stack, Textarea } from 'soapbox/components/ui';
import { Avatar, Button, HStack, Icon, IconButton, Input, Stack, Text, Textarea } from 'soapbox/components/ui';
import UploadProgress from 'soapbox/components/upload-progress';
import UploadButton from 'soapbox/features/compose/components/upload_button';
import { useAppSelector, useAppDispatch, useOwnAccount } from 'soapbox/hooks';
@ -41,7 +41,7 @@ const ChatBox: React.FC<IChatBox> = ({ chat, onSetInputRef, autosize }) => {
const chatMessageIds = useAppSelector(state => state.chat_message_lists.get(chat.id, ImmutableOrderedSet<string>()));
const account = useOwnAccount();
const { createChatMessage, markChatAsRead } = useChat(chat.id);
const { createChatMessage, markChatAsRead, acceptChat } = useChat(chat.id);
const [content, setContent] = useState<string>('');
const [attachment, setAttachment] = useState<any>(undefined);
@ -51,6 +51,8 @@ const ChatBox: React.FC<IChatBox> = ({ chat, onSetInputRef, autosize }) => {
const inputElem = useRef<HTMLTextAreaElement | null>(null);
const needsAcceptance = !chat.accepted && chat.created_by_account !== account?.id;
const isSubmitDisabled = content.length === 0 && !attachment;
// TODO: needs last_read_id param
@ -216,8 +218,37 @@ const ChatBox: React.FC<IChatBox> = ({ chat, onSetInputRef, autosize }) => {
return (
<Stack className='overflow-hidden flex flex-grow' onMouseOver={handleMouseOver}>
<div className='flex-grow h-full overflow-hidden'>
<ChatMessageList chatMessageIds={chatMessageIds} chat={chat} autosize />
<div className='flex-grow h-full overflow-hidden flex justify-center'>
{needsAcceptance ? (
<Stack justifyContent='center' alignItems='center' space={5} className='w-3/4 mx-auto'>
<Stack alignItems='center' space={2}>
<Avatar src={chat.account.avatar_static} size={75} />
<Text size='lg' align='center'>
<Text tag='span' weight='semibold'>@{chat.account.acct}</Text>
{' '}
<Text tag='span'>wants to start a chat with you</Text>
</Text>
</Stack>
<Stack space={2} className='w-full'>
<Button
theme='primary'
block
onClick={() => acceptChat.mutate()}
disabled={acceptChat.isLoading}
>
Accept
</Button>
<HStack alignItems='center' space={2} className='w-full'>
<Button theme='accent' block>Leave chat</Button>
<Button theme='secondary' block>Report</Button>
</HStack>
</Stack>
</Stack>
) : (
<ChatMessageList chatMessageIds={chatMessageIds} chat={chat} autosize />
)}
</div>
<div className='mt-auto p-4 shadow-3xl'>

@ -275,7 +275,7 @@ const ChatMessageList: React.FC<IChatMessageList> = ({ chat, chatMessageIds, aut
})}
>
{isMyMessage ? (
<div className='hidden group-hover:block mr-2 text-gray-500'>
<div className='hidden focus:block group-hover:block mr-2 text-gray-500'>
<DropdownMenuContainer
items={menu}
src={require('@tabler/icons/dots.svg')}

@ -13,6 +13,7 @@ import snackbar from 'soapbox/actions/snackbar';
import AccountSearch from 'soapbox/components/account_search';
import { Avatar, Button, Counter, HStack, Icon, IconButton, Input, Spinner, Stack, Text } from 'soapbox/components/ui';
import VerificationBadge from 'soapbox/components/verification_badge';
import { ChatProvider, useChatContext } from 'soapbox/contexts/chat-context';
import AudioToggle from 'soapbox/features/chats/components/audio-toggle';
import PlaceholderAccount from 'soapbox/features/placeholder/components/placeholder_account';
import { useAppDispatch, useAppSelector, useDebounce, useSettings } from 'soapbox/hooks';
@ -47,12 +48,13 @@ const makeNormalizeChatPanes = () => createSelector([
const normalizeChatPanes = makeNormalizeChatPanes();
const ChatPanes = () => {
const ChatPane = () => {
const intl = useIntl();
const dispatch = useAppDispatch();
const debounce = useDebounce;
const [chat, setChat] = useState<IChat | null>();
const { chat, setChat } = useChatContext();
const [value, setValue] = useState<string>();
const debouncedValue = debounce(value as string, 300);
@ -210,4 +212,4 @@ const ChatPanes = () => {
);
};
export default ChatPanes;
export default ChatPane;

@ -0,0 +1,15 @@
import React from 'react';
import { ChatProvider } from 'soapbox/contexts/chat-context';
import ChatPane from './chat-pane';
const ChatWidget = () => {
return (
<ChatProvider>
<ChatPane />
</ChatProvider>
);
};
export default ChatWidget;

@ -89,7 +89,7 @@ import {
MfaForm,
ChatIndex,
ChatRoom,
ChatPanes,
ChatWidget,
ServerInfo,
Dashboard,
ModerationLog,
@ -680,7 +680,7 @@ const UI: React.FC = ({ children }) => {
</BundleContainer>
)}
{me && features.chats && !mobile && (
<BundleContainer fetchComponent={ChatPanes}>
<BundleContainer fetchComponent={ChatWidget}>
{Component => <Component />}
</BundleContainer>
)}

@ -318,8 +318,8 @@ export function ChatRoom() {
return import(/* webpackChunkName: "features/chats/chat_room" */'../../chats/chat-room');
}
export function ChatPanes() {
return import(/* webpackChunkName: "features/chats/components/chat_panes" */'../../chats/components/chat-panes');
export function ChatWidget() {
return import(/* webpackChunkName: "features/chats/components/chat-widget" */'../../chats/components/chat-widget');
}
export function ServerInfo() {

@ -1,11 +1,14 @@
import { useInfiniteQuery, useQuery } from '@tanstack/react-query';
import { useInfiniteQuery, useMutation, useQuery } from '@tanstack/react-query';
import { useChatContext } from 'soapbox/contexts/chat-context';
import { useApi } from 'soapbox/hooks';
import { queryClient } from './client';
export interface IChat {
id: string
unread: number
created_by_account: number
created_by_account: string
last_message: null | string
created_at: Date
updated_at: Date
@ -90,6 +93,7 @@ const useChats = () => {
const useChat = (chatId: string) => {
const api = useApi();
const { setChat } = useChatContext();
const markChatAsRead = () => api.post<IChat>(`/api/v1/pleroma/chats/${chatId}/read`);
@ -99,7 +103,15 @@ const useChat = (chatId: string) => {
const deleteChatMessage = (chatMessageId: string) => api.delete<IChat>(`/api/v1/pleroma/chats/${chatId}/messages/${chatMessageId}`);
return { createChatMessage, markChatAsRead, deleteChatMessage };
const acceptChat = useMutation(() => api.post<IChat>(`/api/v1/pleroma/chats/${chatId}/accept`), {
onSuccess(response) {
setChat(response.data);
queryClient.invalidateQueries(['chats', 'messages', chatId]);
queryClient.invalidateQueries(['chats']);
},
});
return { createChatMessage, markChatAsRead, deleteChatMessage, acceptChat };
};
export { useChat, useChats, useChatMessages };

Loading…
Cancel
Save