From a1385f87dcdbd3246523a88918f6a142d44b09d8 Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Sat, 29 Apr 2023 08:32:07 +0700 Subject: [PATCH] add members to channel and update note --- src/app/channel/components/blacklist.tsx | 2 +- src/app/channel/components/members.tsx | 39 ++++++++ src/app/channel/components/messageList.tsx | 27 ++++++ src/app/channel/components/metadata.tsx | 2 +- src/app/channel/components/miniMember.tsx | 20 ++++ src/app/channel/pages/index.page.tsx | 6 +- src/app/newsfeed/components/note/parent.tsx | 50 +++++----- .../newsfeed/components/note/placeholder.tsx | 2 - .../newsfeed/components/note/quoteRepost.tsx | 2 +- src/app/newsfeed/components/note/rootNote.tsx | 92 ++++++++++++------- src/stores/channel.tsx | 7 ++ 11 files changed, 182 insertions(+), 67 deletions(-) create mode 100644 src/app/channel/components/members.tsx create mode 100644 src/app/channel/components/miniMember.tsx diff --git a/src/app/channel/components/blacklist.tsx b/src/app/channel/components/blacklist.tsx index 030b6c3e..7b2c755e 100644 --- a/src/app/channel/components/blacklist.tsx +++ b/src/app/channel/components/blacklist.tsx @@ -10,7 +10,7 @@ export default function ChannelBlackList({ blacklist }: { blacklist: any }) { {({ open }) => ( <> diff --git a/src/app/channel/components/members.tsx b/src/app/channel/components/members.tsx new file mode 100644 index 00000000..dd24e8c0 --- /dev/null +++ b/src/app/channel/components/members.tsx @@ -0,0 +1,39 @@ +import MiniMember from '@lume/app/channel/components/miniMember'; +import { channelMembersAtom } from '@lume/stores/channel'; + +import { useAtomValue } from 'jotai'; + +export default function ChannelMembers() { + const membersAsSet = useAtomValue(channelMembersAtom); + const membersAsArray = [...membersAsSet]; + const miniMembersList = membersAsArray.slice(0, 4); + const totalMembers = + membersAsArray.length > 0 + ? '+' + + Intl.NumberFormat('en-US', { + notation: 'compact', + maximumFractionDigits: 1, + }).format(membersAsArray.length) + : 0; + + return ( +
+
+ {miniMembersList.map((member, index) => ( + + ))} + {totalMembers > 0 ? ( +
+ {totalMembers} +
+ ) : ( +
+ +
+ )} +
+
+ ); +} diff --git a/src/app/channel/components/messageList.tsx b/src/app/channel/components/messageList.tsx index a0a18e56..5c24a71a 100644 --- a/src/app/channel/components/messageList.tsx +++ b/src/app/channel/components/messageList.tsx @@ -1,11 +1,13 @@ import ChannelMessageItem from '@lume/app/channel/components/messages/item'; import { sortedChannelMessagesAtom } from '@lume/stores/channel'; +import { hoursAgo } from '@lume/utils/getDate'; import { useAtomValue } from 'jotai'; import { useCallback, useRef } from 'react'; import { Virtuoso } from 'react-virtuoso'; export default function ChannelMessageList() { + const now = useRef(new Date()); const virtuosoRef = useRef(null); const data = useAtomValue(sortedChannelMessagesAtom); @@ -29,6 +31,31 @@ export default function ChannelMessageList() { ref={virtuosoRef} data={data} itemContent={itemContent} + components={{ + Header: () => ( +
+ + ), + EmptyPlaceholder: () => ( +
+

Nothing to see here yet

+

Be the first to share a message in this channel.

+
+ ), + }} computeItemKey={computeItemKey} initialTopMostItemIndex={data.length - 1} alignToBottom={true} diff --git a/src/app/channel/components/metadata.tsx b/src/app/channel/components/metadata.tsx index 1a83ffc2..13721fa3 100644 --- a/src/app/channel/components/metadata.tsx +++ b/src/app/channel/components/metadata.tsx @@ -21,7 +21,7 @@ export default function ChannelMetadata({ id, pubkey }: { id: string; pubkey: st {id}
diff --git a/src/app/channel/components/miniMember.tsx b/src/app/channel/components/miniMember.tsx new file mode 100644 index 00000000..42dbf727 --- /dev/null +++ b/src/app/channel/components/miniMember.tsx @@ -0,0 +1,20 @@ +import { DEFAULT_AVATAR } from '@lume/stores/constants'; +import { useProfile } from '@lume/utils/hooks/useProfile'; + +export default function MiniMember({ pubkey }: { pubkey: string }) { + const { user, isError, isLoading } = useProfile(pubkey); + + return ( + <> + {isError || isLoading ? ( +
+ ) : ( + {user?.pubkey + )} + + ); +} diff --git a/src/app/channel/pages/index.page.tsx b/src/app/channel/pages/index.page.tsx index b40aac2d..5279e1c0 100644 --- a/src/app/channel/pages/index.page.tsx +++ b/src/app/channel/pages/index.page.tsx @@ -1,4 +1,5 @@ import ChannelBlackList from '@lume/app/channel/components/blacklist'; +import ChannelMembers from '@lume/app/channel/components/members'; import ChannelMessageForm from '@lume/app/channel/components/messages/form'; import ChannelMetadata from '@lume/app/channel/components/metadata'; import ChannelUpdateModal from '@lume/app/channel/components/updateModal'; @@ -54,7 +55,7 @@ export function Page() { { '#e': [key], kinds: [42], - since: dateToUnix(hoursAgo(72, now.current)), + since: dateToUnix(hoursAgo(24, now.current)), limit: 20, }, ], @@ -62,7 +63,7 @@ export function Page() { (event) => { const message: any = event; if (hided.includes(event.id)) { - message.push({ hide: true }); + message['hide'] = true; } if (!muted.includes(event.pubkey)) { setChannelMessages((prev) => [...prev, message]); @@ -89,6 +90,7 @@ export function Page() {
+ {!isLoading && !isError && account ? ( account.pubkey === channelPubkey && diff --git a/src/app/newsfeed/components/note/parent.tsx b/src/app/newsfeed/components/note/parent.tsx index 3947c673..466b3413 100644 --- a/src/app/newsfeed/components/note/parent.tsx +++ b/src/app/newsfeed/components/note/parent.tsx @@ -7,35 +7,29 @@ import { memo } from 'react'; import useSWRSubscription from 'swr/subscription'; export const NoteParent = memo(function NoteParent({ id }: { id: string }) { - const { data, error } = useSWRSubscription( - id - ? [ - { - ids: [id], - kinds: [1], - }, - ] - : null, - (key, { next }) => { - const pool = new RelayPool(READONLY_RELAYS); - const unsubscribe = pool.subscribe( - key, - READONLY_RELAYS, - (event: any) => { - next(null, event); - }, - undefined, - undefined, + const { data, error } = useSWRSubscription(id ? id : null, (key, { next }) => { + const pool = new RelayPool(READONLY_RELAYS); + const unsubscribe = pool.subscribe( + [ { - unsubscribeOnEose: true, - } - ); + ids: [key], + }, + ], + READONLY_RELAYS, + (event: any) => { + next(null, event); + }, + undefined, + undefined, + { + unsubscribeOnEose: true, + } + ); - return () => { - unsubscribe(); - }; - } - ); + return () => { + unsubscribe(); + }; + }); return (
@@ -48,8 +42,6 @@ export const NoteParent = memo(function NoteParent({ id }: { id: string }) {
- · -
diff --git a/src/app/newsfeed/components/note/placeholder.tsx b/src/app/newsfeed/components/note/placeholder.tsx index 17f7ee2a..072dd7bf 100644 --- a/src/app/newsfeed/components/note/placeholder.tsx +++ b/src/app/newsfeed/components/note/placeholder.tsx @@ -7,8 +7,6 @@ export const Placeholder = () => {
- · -
diff --git a/src/app/newsfeed/components/note/quoteRepost.tsx b/src/app/newsfeed/components/note/quoteRepost.tsx index cbc81590..80b5eb6e 100644 --- a/src/app/newsfeed/components/note/quoteRepost.tsx +++ b/src/app/newsfeed/components/note/quoteRepost.tsx @@ -13,7 +13,7 @@ export const NoteQuoteRepost = memo(function NoteQuoteRepost({ event }: { event:
- +
); }); diff --git a/src/app/newsfeed/components/note/rootNote.tsx b/src/app/newsfeed/components/note/rootNote.tsx index 87eb2d3f..e3f9c4cb 100644 --- a/src/app/newsfeed/components/note/rootNote.tsx +++ b/src/app/newsfeed/components/note/rootNote.tsx @@ -7,7 +7,33 @@ import { memo } from 'react'; import useSWRSubscription from 'swr/subscription'; import { navigate } from 'vite-plugin-ssr/client/router'; -export const RootNote = memo(function RootNote({ id }: { id: string }) { +export const RootNote = memo(function RootNote({ id, fallback }: { id: string; fallback?: any }) { + const parseFallback = fallback.length > 0 ? JSON.parse(fallback) : null; + + const { data, error } = useSWRSubscription(parseFallback ? null : id, (key, { next }) => { + const pool = new RelayPool(READONLY_RELAYS); + const unsubscribe = pool.subscribe( + [ + { + ids: [key], + }, + ], + READONLY_RELAYS, + (event: any) => { + next(null, event); + }, + undefined, + undefined, + { + unsubscribeOnEose: true, + } + ); + + return () => { + unsubscribe(); + }; + }); + const openThread = (e) => { const selection = window.getSelection(); if (selection.toString().length === 0) { @@ -17,41 +43,45 @@ export const RootNote = memo(function RootNote({ id }: { id: string }) { } }; - const { data, error } = useSWRSubscription( - id - ? [ - { - ids: [id], - kinds: [1], - }, - ] - : null, - (key, { next }) => { - const pool = new RelayPool(READONLY_RELAYS); - const unsubscribe = pool.subscribe( - key, - READONLY_RELAYS, - (event: any) => { - next(null, event); - }, - undefined, - undefined, - { - unsubscribeOnEose: true, - } - ); - - return () => { - unsubscribe(); - }; - } - ); + if (parseFallback) { + return ( +
openThread(e)} className="relative z-10 flex flex-col"> + +
+
+ {contentParser(parseFallback.content, parseFallback.tags)} +
+
+
e.stopPropagation()} className="mt-5 pl-[52px]">
+
+ ); + } return ( <> {error &&
failed to load
} {!data ? ( -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
) : (
openThread(e)} className="relative z-10 flex flex-col"> diff --git a/src/stores/channel.tsx b/src/stores/channel.tsx index 02e6a87b..56057e9b 100644 --- a/src/stores/channel.tsx +++ b/src/stores/channel.tsx @@ -11,5 +11,12 @@ export const sortedChannelMessagesAtom = atom((get) => { return messages.sort((x: { created_at: number }, y: { created_at: number }) => x.created_at - y.created_at); }); +// channel user list +export const channelMembersAtom = atom((get) => { + const messages = get(channelMessagesAtom); + const uniqueMembers = new Set(messages.map((m: { pubkey: string }) => m.pubkey)); + return uniqueMembers; +}); + // channel message content export const channelContentAtom = atomWithReset('');