updated chat list

This commit is contained in:
Ren Amamiya 2023-04-07 09:16:31 +07:00
parent 7d5f9d90c4
commit 8db5d5f87d
5 changed files with 85 additions and 9 deletions

View File

@ -1,29 +1,57 @@
import { ChatListItem } from '@components/chats/chatListItem';
import { ImageWithFallback } from '@components/imageWithFallback';
import { RelayContext } from '@components/relaysProvider';
import { activeAccountAtom } from '@stores/account';
import { DEFAULT_AVATAR } from '@stores/constants';
import { useAtomValue } from 'jotai';
import { useRouter } from 'next/router';
import { useContext, useEffect, useState } from 'react';
export default function ChatList() {
const [pool, relays]: any = useContext(RelayContext);
const router = useRouter();
const activeAccount: any = useAtomValue(activeAccountAtom);
const accountProfile = JSON.parse(activeAccount.metadata);
const openChats = () => {
router.push({
const [list, setList] = useState(new Set());
const openSelfChat = () => {
router.replace({
pathname: '/chats/[pubkey]',
query: { pubkey: activeAccount.pubkey },
});
};
useEffect(() => {
const unsubscribe = pool.subscribe(
[
{
kinds: [4],
'#p': [activeAccount.pubkey],
since: 0,
},
],
relays,
(event: any) => {
if (event.pubkey !== activeAccount.pubkey) {
setList((list) => new Set(list).add(event.pubkey));
}
}
);
return () => {
unsubscribe;
};
}, [pool, relays, activeAccount.pubkey]);
return (
<div className="flex flex-col gap-px">
<div
onClick={() => openChats()}
className="inline-flex items-center gap-2 rounded-md px-2.5 py-2 hover:bg-zinc-900"
onClick={() => openSelfChat()}
className="inline-flex items-center gap-2 rounded-md px-2.5 py-1.5 hover:bg-zinc-900"
>
<div className="relative h-5 w-5 shrink overflow-hidden rounded bg-white">
<ImageWithFallback
@ -39,6 +67,9 @@ export default function ChatList() {
</h5>
</div>
</div>
{[...list].map((item: string, index) => (
<ChatListItem key={index} pubkey={item} />
))}
</div>
);
}

View File

@ -0,0 +1,41 @@
import { ImageWithFallback } from '@components/imageWithFallback';
import { DEFAULT_AVATAR } from '@stores/constants';
import { useMetadata } from '@utils/metadata';
import { truncate } from '@utils/truncate';
import { useRouter } from 'next/router';
export const ChatListItem = ({ pubkey }: { pubkey: string }) => {
const router = useRouter();
const profile = useMetadata(pubkey);
const openChat = () => {
router.replace({
pathname: '/chats/[pubkey]',
query: { pubkey: pubkey },
});
};
return (
<div
onClick={() => openChat()}
className="inline-flex items-center gap-2 rounded-md px-2.5 py-1.5 hover:bg-zinc-900"
>
<div className="relative h-5 w-5 shrink overflow-hidden rounded bg-white">
<ImageWithFallback
src={profile?.picture || DEFAULT_AVATAR}
alt={pubkey}
fill={true}
className="rounded object-cover"
/>
</div>
<div>
<h5 className="text-sm font-medium text-zinc-400">
{profile?.display_name || profile?.name || truncate(pubkey, 16, ' .... ')}
</h5>
</div>
</div>
);
};

View File

@ -1,4 +1,4 @@
import { Message } from '@components/chats/message';
import MessageListItem from '@components/chats/messageListItem';
import { useCallback, useRef } from 'react';
import { Virtuoso } from 'react-virtuoso';
@ -10,7 +10,7 @@ export const MessageList = ({ data }: { data: any }) => {
(index: string | number) => {
const activeAccount = JSON.parse(localStorage.getItem('activeAccount'));
return (
<Message
<MessageListItem
data={data[index]}
activeAccountPubkey={activeAccount.pubkey}
activeAccountPrivkey={activeAccount.privkey}

View File

@ -1,9 +1,9 @@
import { MessageUser } from '@components/chats/user';
import { nip04 } from 'nostr-tools';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { memo, useCallback, useEffect, useMemo, useState } from 'react';
export const Message = ({
const MessageListItem = ({
data,
activeAccountPubkey,
activeAccountPrivkey,
@ -47,3 +47,5 @@ export const Message = ({
</div>
);
};
export default memo(MessageListItem);

View File

@ -2,6 +2,7 @@ import RelayProvider from '@components/relaysProvider';
import type { NextPage } from 'next';
import type { AppProps } from 'next/app';
import { useRouter } from 'next/router';
import { ReactElement, ReactNode } from 'react';
import '../App.css';
@ -16,8 +17,9 @@ type AppPropsWithLayout = AppProps & {
};
export default function MyApp({ Component, pageProps }: AppPropsWithLayout) {
const router = useRouter();
// Use the layout defined at the page level, if available
const getLayout = Component.getLayout ?? ((page) => page);
return <RelayProvider>{getLayout(<Component {...pageProps} />)}</RelayProvider>;
return <RelayProvider>{getLayout(<Component key={router.asPath} {...pageProps} />)}</RelayProvider>;
}