refactor note component & add support for kind 30023

This commit is contained in:
Ren Amamiya
2023-08-23 09:48:22 +07:00
parent 0912948b31
commit c97c685149
32 changed files with 714 additions and 593 deletions

View File

@@ -36,7 +36,7 @@ export function AddWidgetButton() {
const setArticleWidget = () => {
setWidget(db, {
kind: WidgetKinds.article,
title: 'Blogs',
title: 'Articles',
content: '',
});
};

View File

@@ -1,24 +1,21 @@
import { NDKEvent } from '@nostr-dev-kit/ndk';
import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk';
import { useQuery } from '@tanstack/react-query';
import { useVirtualizer } from '@tanstack/react-virtual';
import { useCallback, useRef } from 'react';
import { useNDK } from '@libs/ndk/provider';
import { NoteKind_1, NoteSkeleton, Repost } from '@shared/notes';
import { NoteKindUnsupport } from '@shared/notes/kinds/unsupport';
import { ArticleNote, NoteSkeleton, NoteWrapper } from '@shared/notes';
import { TitleBar } from '@shared/titleBar';
import { nHoursAgo } from '@utils/date';
import { Widget } from '@utils/types';
export function ArticleWidget({ params }: { params: Widget }) {
const { ndk } = useNDK();
const { status, data } = useQuery(['article-widget', params.content], async () => {
const events = await ndk.fetchEvents({
kinds: [30023],
'#t': [params.content],
since: nHoursAgo(48),
kinds: [NDKKind.Article],
limit: 100,
});
return [...events] as unknown as NDKEvent[];
});
@@ -38,41 +35,20 @@ export function ArticleWidget({ params }: { params: Widget }) {
const event: NDKEvent = data[index];
if (!event) return;
switch (event.kind) {
case 1:
return (
<div key={event.id} data-index={index} ref={virtualizer.measureElement}>
<NoteKind_1 event={event} skipMetadata={false} />
</div>
);
case 6:
return (
<div
key={event.id + index}
data-index={index}
ref={virtualizer.measureElement}
>
<Repost key={event.id} event={event} />
</div>
);
default:
return (
<div
key={event.id + index}
data-index={index}
ref={virtualizer.measureElement}
>
<NoteKindUnsupport key={event.id} event={event} />
</div>
);
}
return (
<div key={event.id} data-index={index} ref={virtualizer.measureElement}>
<NoteWrapper event={event}>
<ArticleNote event={event} />
</NoteWrapper>
</div>
);
},
[data]
);
return (
<div className="relative w-[400px] shrink-0 bg-white/10">
<TitleBar id={params.id} title={params.title + ' in 24 hours ago'} />
<TitleBar id={params.id} title={params.title} />
<div ref={parentRef} className="scrollbar-hide h-full overflow-y-auto pb-20">
{status === 'loading' ? (
<div className="px-3 py-1.5">
@@ -85,7 +61,7 @@ export function ArticleWidget({ params }: { params: Widget }) {
<div className="rounded-xl bg-white/10 px-3 py-6">
<div className="flex flex-col items-center gap-4">
<p className="text-center text-sm font-medium text-white">
No new postrs about this hashtag in 24 hours ago
There have been no new articles in the last 24 hours.
</p>
</div>
</div>

View File

@@ -1,4 +1,4 @@
import { NDKEvent } from '@nostr-dev-kit/ndk';
import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk';
import { useInfiniteQuery } from '@tanstack/react-query';
import { useVirtualizer } from '@tanstack/react-virtual';
import { useCallback, useMemo, useRef } from 'react';
@@ -6,8 +6,14 @@ import { useCallback, useMemo, useRef } from 'react';
import { useStorage } from '@libs/storage/provider';
import { ArrowRightCircleIcon, LoaderIcon } from '@shared/icons';
import { NoteKind_1, NoteKind_1063, NoteThread, Repost } from '@shared/notes';
import { NoteKindUnsupport } from '@shared/notes/kinds/unsupport';
import {
ArticleNote,
FileNote,
NoteWrapper,
Repost,
TextNote,
UnknownNote,
} from '@shared/notes';
import { NoteSkeleton } from '@shared/notes/skeleton';
import { TitleBar } from '@shared/titleBar';
@@ -45,36 +51,20 @@ export function FeedWidget({ params }: { params: Widget }) {
if (!dbEvent) return;
const event: NDKEvent = JSON.parse(dbEvent.event as string);
switch (event.kind) {
case 1: {
if (dbEvent.root_id || dbEvent.reply_id) {
return (
<div
key={(dbEvent.root_id || dbEvent.reply_id) + dbEvent.id + index}
data-index={index}
ref={virtualizer.measureElement}
>
<NoteThread
event={event}
root={dbEvent.root_id}
reply={dbEvent.reply_id}
/>
</div>
);
} else {
return (
<div
key={dbEvent.id + index}
data-index={index}
ref={virtualizer.measureElement}
>
<NoteKind_1 event={event} skipMetadata={false} />
</div>
);
}
}
case 6:
case NDKKind.Text:
return (
<div
key={dbEvent.id + index}
data-index={index}
ref={virtualizer.measureElement}
>
<NoteWrapper event={event} root={dbEvent.root_id} reply={dbEvent.reply_id}>
<TextNote event={event} />
</NoteWrapper>
</div>
);
case NDKKind.Repost:
return (
<div
key={dbEvent.id + index}
@@ -91,7 +81,21 @@ export function FeedWidget({ params }: { params: Widget }) {
data-index={index}
ref={virtualizer.measureElement}
>
<NoteKind_1063 key={dbEvent.id} event={event} />
<NoteWrapper event={event}>
<FileNote event={event} />
</NoteWrapper>
</div>
);
case NDKKind.Article:
return (
<div
key={dbEvent.id + index}
data-index={index}
ref={virtualizer.measureElement}
>
<NoteWrapper event={event}>
<ArticleNote event={event} />
</NoteWrapper>
</div>
);
default:
@@ -101,7 +105,9 @@ export function FeedWidget({ params }: { params: Widget }) {
data-index={index}
ref={virtualizer.measureElement}
>
<NoteKindUnsupport key={dbEvent.id} event={event} />
<NoteWrapper event={event}>
<UnknownNote event={event} />
</NoteWrapper>
</div>
);
}
@@ -124,7 +130,7 @@ export function FeedWidget({ params }: { params: Widget }) {
<div className="bbg-white/10 rounded-xl px-3 py-6">
<div className="flex flex-col items-center gap-4">
<p className="text-center text-sm text-white">
Not found any postrs from last 48 hours
There have been no new postrs.
</p>
</div>
</div>

View File

@@ -1,12 +1,19 @@
import { NDKEvent } from '@nostr-dev-kit/ndk';
import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk';
import { useQuery } from '@tanstack/react-query';
import { useVirtualizer } from '@tanstack/react-virtual';
import { useCallback, useRef } from 'react';
import { useNDK } from '@libs/ndk/provider';
import { NoteKind_1, NoteSkeleton, Repost } from '@shared/notes';
import { NoteKindUnsupport } from '@shared/notes/kinds/unsupport';
import {
ArticleNote,
FileNote,
NoteSkeleton,
NoteWrapper,
Repost,
TextNote,
UnknownNote,
} from '@shared/notes';
import { TitleBar } from '@shared/titleBar';
import { nHoursAgo } from '@utils/date';
@@ -16,7 +23,6 @@ export function HashtagWidget({ params }: { params: Widget }) {
const { ndk } = useNDK();
const { status, data } = useQuery(['hashtag-widget', params.content], async () => {
const events = await ndk.fetchEvents({
kinds: [1],
'#t': [params.content],
since: nHoursAgo(24),
});
@@ -39,13 +45,19 @@ export function HashtagWidget({ params }: { params: Widget }) {
if (!event) return;
switch (event.kind) {
case 1:
case NDKKind.Text:
return (
<div key={event.id} data-index={index} ref={virtualizer.measureElement}>
<NoteKind_1 event={event} skipMetadata={false} />
<div
key={event.id + index}
data-index={index}
ref={virtualizer.measureElement}
>
<NoteWrapper event={event}>
<TextNote event={event} />
</NoteWrapper>
</div>
);
case 6:
case NDKKind.Repost:
return (
<div
key={event.id + index}
@@ -55,6 +67,30 @@ export function HashtagWidget({ params }: { params: Widget }) {
<Repost key={event.id} event={event} />
</div>
);
case 1063:
return (
<div
key={event.id + index}
data-index={index}
ref={virtualizer.measureElement}
>
<NoteWrapper event={event}>
<FileNote event={event} />
</NoteWrapper>
</div>
);
case NDKKind.Article:
return (
<div
key={event.id + index}
data-index={index}
ref={virtualizer.measureElement}
>
<NoteWrapper event={event}>
<ArticleNote event={event} />
</NoteWrapper>
</div>
);
default:
return (
<div
@@ -62,7 +98,9 @@ export function HashtagWidget({ params }: { params: Widget }) {
data-index={index}
ref={virtualizer.measureElement}
>
<NoteKindUnsupport key={event.id} event={event} />
<NoteWrapper event={event}>
<UnknownNote event={event} />
</NoteWrapper>
</div>
);
}
@@ -85,7 +123,7 @@ export function HashtagWidget({ params }: { params: Widget }) {
<div className="rounded-xl bg-white/10 px-3 py-6">
<div className="flex flex-col items-center gap-4">
<p className="text-center text-sm font-medium text-white">
No new postrs about this hashtag in 24 hours ago
There have been no new postrs with this hashtag in the last 24 hours.
</p>
</div>
</div>

View File

@@ -1,15 +1,20 @@
import { NDKEvent, NDKFilter } from '@nostr-dev-kit/ndk';
import { NDKEvent, NDKFilter, NDKKind } from '@nostr-dev-kit/ndk';
import { useInfiniteQuery } from '@tanstack/react-query';
import { useVirtualizer } from '@tanstack/react-virtual';
import { destr } from 'destr';
import { useCallback, useEffect, useMemo, useRef } from 'react';
import { Link } from 'react-router-dom';
import { useStorage } from '@libs/storage/provider';
import { ArrowRightCircleIcon, LoaderIcon } from '@shared/icons';
import { NoteKind_1, NoteKind_1063, NoteThread, Repost } from '@shared/notes';
import { NoteKindUnsupport } from '@shared/notes/kinds/unsupport';
import {
ArticleNote,
FileNote,
NoteWrapper,
Repost,
TextNote,
UnknownNote,
} from '@shared/notes';
import { NoteSkeleton } from '@shared/notes/skeleton';
import { TitleBar } from '@shared/titleBar';
@@ -23,7 +28,7 @@ export function NetworkWidget() {
useInfiniteQuery({
queryKey: ['network-widget'],
queryFn: async ({ pageParam = 0 }) => {
return await db.getAllEvents(20, pageParam);
return await db.getAllEvents(30, pageParam);
},
getNextPageParam: (lastPage) => lastPage.nextCursor,
refetchOnWindowFocus: false,
@@ -51,36 +56,20 @@ export function NetworkWidget() {
if (!dbEvent) return;
const event: NDKEvent = JSON.parse(dbEvent.event as string);
switch (event.kind) {
case 1: {
if (dbEvent.root_id || dbEvent.reply_id) {
return (
<div
key={(dbEvent.root_id || dbEvent.reply_id) + dbEvent.id + index}
data-index={index}
ref={virtualizer.measureElement}
>
<NoteThread
event={event}
root={dbEvent.root_id}
reply={dbEvent.reply_id}
/>
</div>
);
} else {
return (
<div
key={dbEvent.id + index}
data-index={index}
ref={virtualizer.measureElement}
>
<NoteKind_1 event={event} skipMetadata={false} />
</div>
);
}
}
case 6:
case NDKKind.Text:
return (
<div
key={dbEvent.id + index}
data-index={index}
ref={virtualizer.measureElement}
>
<NoteWrapper event={event} root={dbEvent.root_id} reply={dbEvent.reply_id}>
<TextNote event={event} />
</NoteWrapper>
</div>
);
case NDKKind.Repost:
return (
<div
key={dbEvent.id + index}
@@ -97,7 +86,21 @@ export function NetworkWidget() {
data-index={index}
ref={virtualizer.measureElement}
>
<NoteKind_1063 key={dbEvent.id} event={event} />
<NoteWrapper event={event}>
<FileNote event={event} />
</NoteWrapper>
</div>
);
case NDKKind.Article:
return (
<div
key={dbEvent.id + index}
data-index={index}
ref={virtualizer.measureElement}
>
<NoteWrapper event={event}>
<ArticleNote event={event} />
</NoteWrapper>
</div>
);
default:
@@ -107,7 +110,9 @@ export function NetworkWidget() {
data-index={index}
ref={virtualizer.measureElement}
>
<NoteKindUnsupport key={dbEvent.id} event={event} />
<NoteWrapper event={event}>
<UnknownNote event={event} />
</NoteWrapper>
</div>
);
}
@@ -168,12 +173,6 @@ export function NetworkWidget() {
<br />
Follow more people to have more fun.
</p>
<Link
to="/trending"
className="inline-flex w-max rounded bg-fuchsia-500 px-2.5 py-1.5 text-sm hover:bg-fuchsia-600"
>
Trending users
</Link>
</div>
</div>
</div>

View File

@@ -1,11 +1,17 @@
import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk';
import { useCallback } from 'react';
import { useStorage } from '@libs/storage/provider';
import {
ArticleNote,
FileNote,
NoteActions,
NoteContent,
NoteReplyForm,
NoteStats,
TextNote,
ThreadUser,
UnknownNote,
} from '@shared/notes';
import { RepliesList } from '@shared/notes/replies/list';
import { NoteSkeleton } from '@shared/notes/skeleton';
@@ -18,6 +24,22 @@ export function ThreadBlock({ params }: { params: Widget }) {
const { db } = useStorage();
const { status, data } = useEvent(params.content);
const renderKind = useCallback(
(event: NDKEvent) => {
switch (event.kind) {
case NDKKind.Text:
return <TextNote event={event} />;
case NDKKind.Article:
return <ArticleNote event={event} />;
case 1063:
return <FileNote event={event} />;
default:
return <UnknownNote event={event} />;
}
},
[data]
);
return (
<div className="scrollbar-hide h-full w-[400px] shrink-0 overflow-y-auto bg-white/10">
<TitleBar id={params.id} title={params.title} />
@@ -31,18 +53,10 @@ export function ThreadBlock({ params }: { params: Widget }) {
) : (
<div className="h-min w-full px-3 pt-1.5">
<div className="rounded-xl bg-white/10 px-3 pt-3">
<ThreadUser pubkey={data.event.pubkey} time={data.event.created_at} />
<div className="mt-2">
<NoteContent content={data.richContent} />
</div>
<div>
<NoteActions
id={params.content}
pubkey={data.event.pubkey}
noOpenThread={true}
/>
<NoteStats id={params.content} />
</div>
<ThreadUser pubkey={data.pubkey} time={data.created_at} />
<div className="mt-2">{renderKind(data)}</div>
<NoteActions id={params.content} pubkey={data.pubkey} noOpenThread={true} />
<NoteStats id={params.content} />
</div>
</div>
)}

View File

@@ -1,8 +1,7 @@
import { NDKEvent } from '@nostr-dev-kit/ndk';
import { useQuery } from '@tanstack/react-query';
import { NoteKind_1 } from '@shared/notes';
import { NoteSkeleton } from '@shared/notes/skeleton';
import { NoteSkeleton, NoteWrapper, TextNote } from '@shared/notes';
import { TitleBar } from '@shared/titleBar';
import { Widget } from '@utils/types';
@@ -52,7 +51,9 @@ export function TrendingNotesWidget({ params }: { params: Widget }) {
) : (
<div className="relative flex w-full flex-col">
{data.map((item) => (
<NoteKind_1 key={item.event.id} event={item.event} skipMetadata={true} />
<NoteWrapper key={item.event.id} event={item.event}>
<TextNote event={item.event} />
</NoteWrapper>
))}
</div>
)}

View File

@@ -1,12 +1,19 @@
import { NDKEvent } from '@nostr-dev-kit/ndk';
import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk';
import { useQuery } from '@tanstack/react-query';
import { useVirtualizer } from '@tanstack/react-virtual';
import { useCallback, useRef } from 'react';
import { useNDK } from '@libs/ndk/provider';
import { NoteKind_1, NoteSkeleton, Repost } from '@shared/notes';
import { NoteKindUnsupport } from '@shared/notes/kinds/unsupport';
import {
ArticleNote,
FileNote,
NoteSkeleton,
NoteWrapper,
Repost,
TextNote,
UnknownNote,
} from '@shared/notes';
import { TitleBar } from '@shared/titleBar';
import { UserProfile } from '@shared/userProfile';
@@ -49,13 +56,19 @@ export function UserWidget({ params }: { params: Widget }) {
if (!event) return;
switch (event.kind) {
case 1:
case NDKKind.Text:
return (
<div key={event.id} data-index={index} ref={virtualizer.measureElement}>
<NoteKind_1 event={event} skipMetadata={false} />
<div
key={event.id + index}
data-index={index}
ref={virtualizer.measureElement}
>
<NoteWrapper event={event}>
<TextNote event={event} />
</NoteWrapper>
</div>
);
case 6:
case NDKKind.Repost:
return (
<div
key={event.id + index}
@@ -65,6 +78,30 @@ export function UserWidget({ params }: { params: Widget }) {
<Repost key={event.id} event={event} />
</div>
);
case 1063:
return (
<div
key={event.id + index}
data-index={index}
ref={virtualizer.measureElement}
>
<NoteWrapper event={event}>
<FileNote event={event} />
</NoteWrapper>
</div>
);
case NDKKind.Article:
return (
<div
key={event.id + index}
data-index={index}
ref={virtualizer.measureElement}
>
<NoteWrapper event={event}>
<ArticleNote event={event} />
</NoteWrapper>
</div>
);
default:
return (
<div
@@ -72,7 +109,9 @@ export function UserWidget({ params }: { params: Widget }) {
data-index={index}
ref={virtualizer.measureElement}
>
<NoteKindUnsupport key={event.id} event={event} />
<NoteWrapper event={event}>
<UnknownNote event={event} />
</NoteWrapper>
</div>
);
}

View File

@@ -3,6 +3,7 @@ import { useCallback, useEffect } from 'react';
import { AddWidgetButton } from '@app/space/components/button';
import { FeedWidgetForm } from '@app/space/components/forms/feed';
import { HashTagWidgetForm } from '@app/space/components/forms/hashtag';
import { ArticleWidget } from '@app/space/components/widgets/article';
import { FeedWidget } from '@app/space/components/widgets/feed';
import { HashtagWidget } from '@app/space/components/widgets/hashtag';
import { NetworkWidget } from '@app/space/components/widgets/network';
@@ -45,6 +46,8 @@ export function SpaceScreen() {
return <TrendingNotesWidget key={widget.id} params={widget} />;
case WidgetKinds.network:
return <NetworkWidget key={widget.id} />;
case WidgetKinds.article:
return <ArticleWidget key={widget.id} params={widget} />;
case WidgetKinds.xhashtag:
return <HashTagWidgetForm key={widget.id} params={widget} />;
case WidgetKinds.xfeed: