2023-03-17 19:56:59 +00:00
|
|
|
import React, { Suspense } from 'react';
|
2023-03-08 21:30:11 +00:00
|
|
|
import styled from '@emotion/styled';
|
|
|
|
import slugify from 'slugify';
|
|
|
|
import { useEffect } from 'react';
|
|
|
|
import { useParams } from 'react-router-dom';
|
|
|
|
import { Loader } from '@mantine/core';
|
|
|
|
|
|
|
|
import { useAppContext } from '../../context';
|
|
|
|
import { backend } from '../../backend';
|
|
|
|
import { Page } from '../page';
|
|
|
|
|
2023-03-17 19:56:59 +00:00
|
|
|
const Message = React.lazy(() => import(/* webpackChunkName: "message" */ '../message'));
|
|
|
|
|
2023-03-08 21:30:11 +00:00
|
|
|
const Messages = styled.div`
|
|
|
|
max-height: 100%;
|
|
|
|
flex-grow: 1;
|
|
|
|
overflow-y: scroll;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
`;
|
|
|
|
|
|
|
|
const EmptyMessage = styled.div`
|
|
|
|
flex-grow: 1;
|
|
|
|
padding-bottom: 5vh;
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
justify-content: center;
|
|
|
|
align-items: center;
|
|
|
|
font-family: "Work Sans", sans-serif;
|
|
|
|
line-height: 1.7;
|
|
|
|
gap: 1rem;
|
|
|
|
`;
|
|
|
|
|
|
|
|
export default function ChatPage(props: any) {
|
|
|
|
const { id } = useParams();
|
|
|
|
const context = useAppContext();
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (props.share || !context.currentChat.chatLoadedAt) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const shouldScroll = (Date.now() - context.currentChat.chatLoadedAt) > 5000;
|
|
|
|
|
|
|
|
if (!shouldScroll) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const container = document.querySelector('#messages') as HTMLElement;
|
|
|
|
const messages = document.querySelectorAll('#messages .message');
|
|
|
|
|
|
|
|
if (messages.length) {
|
|
|
|
const latest = messages[messages.length - 1] as HTMLElement;
|
|
|
|
const offset = Math.max(0, latest.offsetTop - 100);
|
|
|
|
setTimeout(() => {
|
|
|
|
container?.scrollTo({ top: offset, behavior: 'smooth' });
|
|
|
|
}, 500);
|
|
|
|
}
|
2023-03-09 19:50:57 +00:00
|
|
|
}, [context.currentChat?.chatLoadedAt, context.currentChat?.messagesToDisplay.length, props.share]);
|
2023-03-08 21:30:11 +00:00
|
|
|
|
|
|
|
const messagesToDisplay = context.currentChat.messagesToDisplay;
|
|
|
|
|
|
|
|
const shouldShowChat = id && context.currentChat.chat && !!messagesToDisplay.length;
|
|
|
|
|
|
|
|
return <Page id={id || 'landing'}
|
|
|
|
headerProps={{
|
|
|
|
share: context.isShare,
|
|
|
|
canShare: messagesToDisplay.length > 1,
|
|
|
|
title: (id && messagesToDisplay.length) ? context.currentChat.chat?.title : null,
|
|
|
|
onShare: async () => {
|
|
|
|
if (context.currentChat.chat) {
|
2023-03-09 19:50:57 +00:00
|
|
|
const id = await backend.current?.shareChat(context.currentChat.chat);
|
2023-03-08 21:30:11 +00:00
|
|
|
if (id) {
|
|
|
|
const slug = context.currentChat.chat.title
|
|
|
|
? '/' + slugify(context.currentChat.chat.title.toLocaleLowerCase())
|
|
|
|
: '';
|
|
|
|
const url = window.location.origin + '/s/' + id + slug;
|
|
|
|
navigator.share?.({
|
|
|
|
title: context.currentChat.chat.title || undefined,
|
|
|
|
url,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
}}>
|
2023-03-17 19:56:59 +00:00
|
|
|
<Suspense fallback={<Messages id="messages">
|
|
|
|
<EmptyMessage>
|
2023-03-08 21:30:11 +00:00
|
|
|
<Loader variant="dots" />
|
2023-03-17 19:56:59 +00:00
|
|
|
</EmptyMessage>
|
|
|
|
</Messages>}>
|
|
|
|
<Messages id="messages">
|
|
|
|
{shouldShowChat && (
|
|
|
|
<div style={{ paddingBottom: '4.5rem' }}>
|
|
|
|
{messagesToDisplay.map((message) => (
|
|
|
|
<Message key={message.id}
|
|
|
|
message={message}
|
|
|
|
share={props.share}
|
|
|
|
last={context.currentChat.chat!.messages.leafs.some(n => n.id === message.id)} />
|
|
|
|
))}
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
{!shouldShowChat && <EmptyMessage>
|
|
|
|
<Loader variant="dots" />
|
|
|
|
</EmptyMessage>}
|
|
|
|
</Messages>
|
|
|
|
</Suspense>
|
2023-03-08 21:30:11 +00:00
|
|
|
</Page>;
|
|
|
|
}
|