Improve loading previous messages (#68)

This commit is contained in:
Szymon Szlachtowicz 2021-10-13 14:02:32 +02:00 committed by GitHub
parent 7bb7f059b8
commit 85932c1dd2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 26 additions and 4 deletions

View File

@ -32,6 +32,7 @@ export function Chat({ theme, community, fetchMetadata }: ChatProps) {
notifications, notifications,
clearNotifications, clearNotifications,
loadNextDay, loadNextDay,
loadingMessages,
} = useMessenger( } = useMessenger(
activeChannel.name, activeChannel.name,
channels.map((channel) => channel.name) channels.map((channel) => channel.name)
@ -68,6 +69,7 @@ export function Chat({ theme, community, fetchMetadata }: ChatProps) {
loadNextDay={() => loadNextDay(activeChannel.name)} loadNextDay={() => loadNextDay(activeChannel.name)}
onCommunityClick={showModal} onCommunityClick={showModal}
fetchMetadata={fetchMetadata} fetchMetadata={fetchMetadata}
loadingMessages={loadingMessages}
/> />
{showMembers && !narrow && ( {showMembers && !narrow && (
<Members community={community} setShowChannels={setShowChannels} /> <Members community={community} setShowChannels={setShowChannels} />

View File

@ -35,6 +35,7 @@ interface ChatBodyProps {
loadNextDay: () => void; loadNextDay: () => void;
onCommunityClick: () => void; onCommunityClick: () => void;
fetchMetadata?: (url: string) => Promise<Metadata | undefined>; fetchMetadata?: (url: string) => Promise<Metadata | undefined>;
loadingMessages: boolean;
} }
export function ChatBody({ export function ChatBody({
@ -53,6 +54,7 @@ export function ChatBody({
loadNextDay, loadNextDay,
onCommunityClick, onCommunityClick,
fetchMetadata, fetchMetadata,
loadingMessages,
}: ChatBodyProps) { }: ChatBodyProps) {
const narrow = useNarrow(); const narrow = useNarrow();
const [showChannelsList, setShowChannelsList] = useState(false); const [showChannelsList, setShowChannelsList] = useState(false);
@ -112,6 +114,7 @@ export function ChatBody({
messages={messages} messages={messages}
loadNextDay={loadNextDay} loadNextDay={loadNextDay}
fetchMetadata={fetchMetadata} fetchMetadata={fetchMetadata}
loadingMessages={loadingMessages}
/> />
) : ( ) : (
<LoadingSkeleton /> <LoadingSkeleton />

View File

@ -15,12 +15,14 @@ type ChatMessagesProps = {
messages: ChatMessage[]; messages: ChatMessage[];
loadNextDay: () => void; loadNextDay: () => void;
fetchMetadata?: (url: string) => Promise<Metadata | undefined>; fetchMetadata?: (url: string) => Promise<Metadata | undefined>;
loadingMessages: boolean;
}; };
export function ChatMessages({ export function ChatMessages({
messages, messages,
loadNextDay, loadNextDay,
fetchMetadata, fetchMetadata,
loadingMessages,
}: ChatMessagesProps) { }: ChatMessagesProps) {
const [scrollOnBot, setScrollOnBot] = useState(true); const [scrollOnBot, setScrollOnBot] = useState(true);
const ref = useRef<HTMLHeadingElement>(null); const ref = useRef<HTMLHeadingElement>(null);
@ -31,6 +33,12 @@ export function ChatMessages({
} }
}, [messages, messages.length, scrollOnBot]); }, [messages, messages.length, scrollOnBot]);
useEffect(() => {
if ((ref?.current?.clientHeight ?? 0) < (ref?.current?.scrollHeight ?? 0)) {
loadNextDay();
}
}, [messages, messages.length]);
useEffect(() => { useEffect(() => {
const setScroll = () => { const setScroll = () => {
if (ref && ref.current) { if (ref && ref.current) {
@ -63,9 +71,11 @@ export function ChatMessages({
image={image} image={image}
/> />
<LinkModal isVisible={!!link} onClose={() => setLink("")} link={link} /> <LinkModal isVisible={!!link} onClose={() => setLink("")} link={link} />
<LoadingWrapper> {loadingMessages && (
<LoadingIcon className="message" /> <LoadingWrapper>
</LoadingWrapper> <LoadingIcon className="message" />
</LoadingWrapper>
)}
{messages.map((message, idx) => { {messages.map((message, idx) => {
return ( return (
<MessageOuterWrapper key={message.date.getTime()}> <MessageOuterWrapper key={message.date.getTime()}>

View File

@ -46,6 +46,7 @@ export function useMessenger(chatId: string, chatIdList: string[]) {
[chatId: string]: Date; [chatId: string]: Date;
}>({}); }>({});
const [lastMessage, setLastMessage] = useState(new Date()); const [lastMessage, setLastMessage] = useState(new Date());
const [loadingMessages, setLoadingMessages] = useState(false);
useEffect(() => { useEffect(() => {
if (lastLoadTime.current?.[chatId]) { if (lastLoadTime.current?.[chatId]) {
@ -112,6 +113,7 @@ export function useMessenger(chatId: string, chatIdList: string[]) {
if (timeDiff < 30) { if (timeDiff < 30) {
if (!loadingPreviousMessages.current[id]) { if (!loadingPreviousMessages.current[id]) {
loadingPreviousMessages.current[id] = true; loadingPreviousMessages.current[id] = true;
setLoadingMessages(true);
const amountOfMessages = await messenger.retrievePreviousMessages( const amountOfMessages = await messenger.retrievePreviousMessages(
id, id,
startTime, startTime,
@ -122,6 +124,7 @@ export function useMessenger(chatId: string, chatIdList: string[]) {
setLastMessage(startTime); setLastMessage(startTime);
} }
loadingPreviousMessages.current[id] = false; loadingPreviousMessages.current[id] = false;
setLoadingMessages(false);
if (amountOfMessages === 0) { if (amountOfMessages === 0) {
loadNextDay(id); loadNextDay(id);
} }
@ -186,7 +189,6 @@ export function useMessenger(chatId: string, chatIdList: string[]) {
const sendMessage = useCallback( const sendMessage = useCallback(
async (messageText?: string, image?: Uint8Array) => { async (messageText?: string, image?: Uint8Array) => {
// TODO: A message can either contain text or media, not both.
if (messageText) { if (messageText) {
await messenger?.sendMessage(chatId, { await messenger?.sendMessage(chatId, {
text: messageText, text: messageText,
@ -209,6 +211,10 @@ export function useMessenger(chatId: string, chatIdList: string[]) {
[messages, chatId] [messages, chatId]
); );
useEffect(() => {
setLoadingMessages(loadingPreviousMessages.current[chatId]);
}, [chatId]);
return { return {
messenger, messenger,
messages: activeMessages, messages: activeMessages,
@ -217,5 +223,6 @@ export function useMessenger(chatId: string, chatIdList: string[]) {
clearNotifications, clearNotifications,
loadNextDay, loadNextDay,
lastMessage, lastMessage,
loadingMessages,
}; };
} }