mirror of
https://github.com/luminous-devs/lume.git
synced 2024-09-19 11:43:30 +00:00
updated chat list
This commit is contained in:
parent
7d5f9d90c4
commit
8db5d5f87d
@ -1,29 +1,57 @@
|
|||||||
|
import { ChatListItem } from '@components/chats/chatListItem';
|
||||||
import { ImageWithFallback } from '@components/imageWithFallback';
|
import { ImageWithFallback } from '@components/imageWithFallback';
|
||||||
|
import { RelayContext } from '@components/relaysProvider';
|
||||||
|
|
||||||
import { activeAccountAtom } from '@stores/account';
|
import { activeAccountAtom } from '@stores/account';
|
||||||
import { DEFAULT_AVATAR } from '@stores/constants';
|
import { DEFAULT_AVATAR } from '@stores/constants';
|
||||||
|
|
||||||
import { useAtomValue } from 'jotai';
|
import { useAtomValue } from 'jotai';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
|
import { useContext, useEffect, useState } from 'react';
|
||||||
|
|
||||||
export default function ChatList() {
|
export default function ChatList() {
|
||||||
|
const [pool, relays]: any = useContext(RelayContext);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const activeAccount: any = useAtomValue(activeAccountAtom);
|
const activeAccount: any = useAtomValue(activeAccountAtom);
|
||||||
const accountProfile = JSON.parse(activeAccount.metadata);
|
const accountProfile = JSON.parse(activeAccount.metadata);
|
||||||
|
|
||||||
const openChats = () => {
|
const [list, setList] = useState(new Set());
|
||||||
router.push({
|
|
||||||
|
const openSelfChat = () => {
|
||||||
|
router.replace({
|
||||||
pathname: '/chats/[pubkey]',
|
pathname: '/chats/[pubkey]',
|
||||||
query: { pubkey: activeAccount.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 (
|
return (
|
||||||
<div className="flex flex-col gap-px">
|
<div className="flex flex-col gap-px">
|
||||||
<div
|
<div
|
||||||
onClick={() => openChats()}
|
onClick={() => openSelfChat()}
|
||||||
className="inline-flex items-center gap-2 rounded-md px-2.5 py-2 hover:bg-zinc-900"
|
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">
|
<div className="relative h-5 w-5 shrink overflow-hidden rounded bg-white">
|
||||||
<ImageWithFallback
|
<ImageWithFallback
|
||||||
@ -39,6 +67,9 @@ export default function ChatList() {
|
|||||||
</h5>
|
</h5>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{[...list].map((item: string, index) => (
|
||||||
|
<ChatListItem key={index} pubkey={item} />
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
41
src/components/chats/chatListItem.tsx
Normal file
41
src/components/chats/chatListItem.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
};
|
@ -1,4 +1,4 @@
|
|||||||
import { Message } from '@components/chats/message';
|
import MessageListItem from '@components/chats/messageListItem';
|
||||||
|
|
||||||
import { useCallback, useRef } from 'react';
|
import { useCallback, useRef } from 'react';
|
||||||
import { Virtuoso } from 'react-virtuoso';
|
import { Virtuoso } from 'react-virtuoso';
|
||||||
@ -10,7 +10,7 @@ export const MessageList = ({ data }: { data: any }) => {
|
|||||||
(index: string | number) => {
|
(index: string | number) => {
|
||||||
const activeAccount = JSON.parse(localStorage.getItem('activeAccount'));
|
const activeAccount = JSON.parse(localStorage.getItem('activeAccount'));
|
||||||
return (
|
return (
|
||||||
<Message
|
<MessageListItem
|
||||||
data={data[index]}
|
data={data[index]}
|
||||||
activeAccountPubkey={activeAccount.pubkey}
|
activeAccountPubkey={activeAccount.pubkey}
|
||||||
activeAccountPrivkey={activeAccount.privkey}
|
activeAccountPrivkey={activeAccount.privkey}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { MessageUser } from '@components/chats/user';
|
import { MessageUser } from '@components/chats/user';
|
||||||
|
|
||||||
import { nip04 } from 'nostr-tools';
|
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,
|
data,
|
||||||
activeAccountPubkey,
|
activeAccountPubkey,
|
||||||
activeAccountPrivkey,
|
activeAccountPrivkey,
|
||||||
@ -47,3 +47,5 @@ export const Message = ({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export default memo(MessageListItem);
|
@ -2,6 +2,7 @@ import RelayProvider from '@components/relaysProvider';
|
|||||||
|
|
||||||
import type { NextPage } from 'next';
|
import type { NextPage } from 'next';
|
||||||
import type { AppProps } from 'next/app';
|
import type { AppProps } from 'next/app';
|
||||||
|
import { useRouter } from 'next/router';
|
||||||
import { ReactElement, ReactNode } from 'react';
|
import { ReactElement, ReactNode } from 'react';
|
||||||
|
|
||||||
import '../App.css';
|
import '../App.css';
|
||||||
@ -16,8 +17,9 @@ type AppPropsWithLayout = AppProps & {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default function MyApp({ Component, pageProps }: AppPropsWithLayout) {
|
export default function MyApp({ Component, pageProps }: AppPropsWithLayout) {
|
||||||
|
const router = useRouter();
|
||||||
// Use the layout defined at the page level, if available
|
// Use the layout defined at the page level, if available
|
||||||
const getLayout = Component.getLayout ?? ((page) => page);
|
const getLayout = Component.getLayout ?? ((page) => page);
|
||||||
|
|
||||||
return <RelayProvider>{getLayout(<Component {...pageProps} />)}</RelayProvider>;
|
return <RelayProvider>{getLayout(<Component key={router.asPath} {...pageProps} />)}</RelayProvider>;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user