migrated channel messages to jotai state (same as chat)

This commit is contained in:
Ren Amamiya 2023-04-16 17:31:31 +07:00
parent 00e28529dd
commit a573f9e4eb
3 changed files with 33 additions and 8 deletions

View File

@ -4,17 +4,19 @@ import { ChannelMessages } from '@components/channels/messages/index';
import FormChannelMessage from '@components/form/channelMessage'; import FormChannelMessage from '@components/form/channelMessage';
import { RelayContext } from '@components/relaysProvider'; import { RelayContext } from '@components/relaysProvider';
import { channelReplyAtom } from '@stores/channel'; import { channelMessagesAtom, channelReplyAtom } from '@stores/channel';
import useLocalStorage from '@rehooks/local-storage'; import useLocalStorage from '@rehooks/local-storage';
import { useSetAtom } from 'jotai';
import { useResetAtom } from 'jotai/utils'; import { useResetAtom } from 'jotai/utils';
import { useContext, useEffect, useRef, useState } from 'react'; import { Suspense, useContext, useEffect, useRef } from 'react';
export default function Page({ params }: { params: { id: string } }) { export default function Page({ params }: { params: { id: string } }) {
const [pool, relays]: any = useContext(RelayContext); const [pool, relays]: any = useContext(RelayContext);
const [messages, setMessages] = useState([]);
const [activeAccount]: any = useLocalStorage('activeAccount', {}); const [activeAccount]: any = useLocalStorage('activeAccount', {});
const setChannelMessages = useSetAtom(channelMessagesAtom);
const resetChannelMessages = useResetAtom(channelMessagesAtom);
const resetChannelReply = useResetAtom(channelReplyAtom); const resetChannelReply = useResetAtom(channelReplyAtom);
const muted = useRef(new Set()); const muted = useRef(new Set());
@ -23,6 +25,8 @@ export default function Page({ params }: { params: { id: string } }) {
useEffect(() => { useEffect(() => {
// reset channel reply // reset channel reply
resetChannelReply(); resetChannelReply();
// reset channel messages
resetChannelMessages();
// subscribe event // subscribe event
const unsubscribe = pool.subscribe( const unsubscribe = pool.subscribe(
[ [
@ -49,7 +53,7 @@ export default function Page({ params }: { params: { id: string } }) {
} else if (hided.current.has(event.id)) { } else if (hided.current.has(event.id)) {
console.log('hided'); console.log('hided');
} else { } else {
setMessages((messages) => [event, ...messages]); setChannelMessages((messages) => [event, ...messages]);
} }
} }
} }
@ -58,11 +62,13 @@ export default function Page({ params }: { params: { id: string } }) {
return () => { return () => {
unsubscribe(); unsubscribe();
}; };
}, [pool, relays, activeAccount.pubkey, params.id, resetChannelReply]); }, [pool, relays, activeAccount.pubkey, params.id, setChannelMessages, resetChannelReply, resetChannelMessages]);
return ( return (
<div className="flex h-full w-full flex-col justify-between"> <div className="flex h-full w-full flex-col justify-between">
<ChannelMessages data={messages.sort((a, b) => a.created_at - b.created_at)} /> <Suspense fallback={<>Loading...</>}>
<ChannelMessages />
</Suspense>
<div className="shrink-0 p-3"> <div className="shrink-0 p-3">
<FormChannelMessage eventId={params.id} /> <FormChannelMessage eventId={params.id} />
</div> </div>

View File

@ -1,11 +1,17 @@
import ChannelMessageItem from '@components/channels/messages/item'; import ChannelMessageItem from '@components/channels/messages/item';
import { Placeholder } from '@components/note/placeholder';
import { sortedChannelMessagesAtom } from '@stores/channel';
import { useAtomValue } from 'jotai';
import { useCallback, useRef } from 'react'; import { useCallback, useRef } from 'react';
import { Virtuoso } from 'react-virtuoso'; import { Virtuoso } from 'react-virtuoso';
export const ChannelMessages = ({ data }: { data: any }) => { export const ChannelMessages = () => {
const virtuosoRef = useRef(null); const virtuosoRef = useRef(null);
const data = useAtomValue(sortedChannelMessagesAtom);
const itemContent: any = useCallback( const itemContent: any = useCallback(
(index: string | number) => { (index: string | number) => {
return <ChannelMessageItem data={data[index]} />; return <ChannelMessageItem data={data[index]} />;
@ -25,6 +31,7 @@ export const ChannelMessages = ({ data }: { data: any }) => {
<Virtuoso <Virtuoso
ref={virtuosoRef} ref={virtuosoRef}
data={data} data={data}
components={COMPONENTS}
itemContent={itemContent} itemContent={itemContent}
computeItemKey={computeItemKey} computeItemKey={computeItemKey}
initialTopMostItemIndex={data.length - 1} initialTopMostItemIndex={data.length - 1}
@ -37,3 +44,8 @@ export const ChannelMessages = ({ data }: { data: any }) => {
</div> </div>
); );
}; };
const COMPONENTS = {
EmptyPlaceholder: () => <Placeholder />,
ScrollSeekPlaceholder: () => <Placeholder />,
};

View File

@ -1,4 +1,11 @@
import { atom } from 'jotai';
import { atomWithReset } from 'jotai/utils'; import { atomWithReset } from 'jotai/utils';
// channel reply id // channel reply id
export const channelReplyAtom = atomWithReset({ id: null, pubkey: null, content: null }); export const channelReplyAtom = atomWithReset({ id: null, pubkey: null, content: null });
// channel messages
export const channelMessagesAtom = atomWithReset([]);
export const sortedChannelMessagesAtom = atom((get) => {
const messages = get(channelMessagesAtom);
return messages.sort((x: { created_at: number }, y: { created_at: number }) => x.created_at - y.created_at);
});