From 2403231ac4ee9f456bea15f3e2eff6c577ef6097 Mon Sep 17 00:00:00 2001 From: reya Date: Tue, 27 Feb 2024 13:42:59 +0700 Subject: [PATCH] feat: add user screen --- apps/desktop2/package.json | 1 - apps/desktop2/src/routes/editor/index.tsx | 2 +- .../src/routes/users/$pubkey.lazy.tsx | 41 ++++++++++- .../routes/users/-components/eventList.tsx | 71 +++++++++++++++++++ packages/ark/src/ark.ts | 17 +++++ packages/ui/src/note/menu.tsx | 31 ++++---- pnpm-lock.yaml | 7 -- src-tauri/src/main.rs | 1 + src-tauri/src/nostr/event.rs | 33 +++++++++ 9 files changed, 173 insertions(+), 31 deletions(-) create mode 100644 apps/desktop2/src/routes/users/-components/eventList.tsx diff --git a/apps/desktop2/package.json b/apps/desktop2/package.json index 9ea30b95..60d244e7 100644 --- a/apps/desktop2/package.json +++ b/apps/desktop2/package.json @@ -21,7 +21,6 @@ "@tanstack/react-router": "^1.16.6", "i18next": "^23.10.0", "i18next-resources-to-backend": "^1.2.0", - "idb-keyval": "^6.2.1", "nostr-tools": "^2.3.1", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/apps/desktop2/src/routes/editor/index.tsx b/apps/desktop2/src/routes/editor/index.tsx index e400168f..7552355c 100644 --- a/apps/desktop2/src/routes/editor/index.tsx +++ b/apps/desktop2/src/routes/editor/index.tsx @@ -222,7 +222,7 @@ function Screen() {
{reply_to && !quote ? ( -
+

Reply to:

diff --git a/apps/desktop2/src/routes/users/$pubkey.lazy.tsx b/apps/desktop2/src/routes/users/$pubkey.lazy.tsx index 061cd42d..628b7b10 100644 --- a/apps/desktop2/src/routes/users/$pubkey.lazy.tsx +++ b/apps/desktop2/src/routes/users/$pubkey.lazy.tsx @@ -1,11 +1,46 @@ import { createLazyFileRoute } from "@tanstack/react-router"; +import { WindowVirtualizer } from "virtua"; +import { User } from "@lume/ui"; +import { EventList } from "./-components/eventList"; export const Route = createLazyFileRoute("/users/$pubkey")({ - component: User, + component: Screen, }); -function User() { +function Screen() { const { pubkey } = Route.useParams(); - return
{pubkey}
; + return ( + +
+
+
+
+
+ + + +
+ +
+
+ + +
+ +
+ +
+
+
+
+

Notes

+ +
+
+
+
+
+ + ); } diff --git a/apps/desktop2/src/routes/users/-components/eventList.tsx b/apps/desktop2/src/routes/users/-components/eventList.tsx new file mode 100644 index 00000000..f3012179 --- /dev/null +++ b/apps/desktop2/src/routes/users/-components/eventList.tsx @@ -0,0 +1,71 @@ +import { RepostNote } from "@/routes/$account/home/-components/repost"; +import { TextNote } from "@/routes/$account/home/-components/text"; +import { useArk } from "@lume/ark"; +import { ArrowRightCircleIcon, LoaderIcon } from "@lume/icons"; +import { Event, Kind } from "@lume/types"; +import { EmptyFeed } from "@lume/ui"; +import { FETCH_LIMIT } from "@lume/utils"; +import { useInfiniteQuery } from "@tanstack/react-query"; + +export function EventList({ id }: { id: string }) { + const ark = useArk(); + const { data, hasNextPage, isLoading, isFetchingNextPage, fetchNextPage } = + useInfiniteQuery({ + queryKey: ["events", id], + initialPageParam: 0, + queryFn: async ({ pageParam }: { pageParam: number }) => { + const events = await ark.get_events_from(id, FETCH_LIMIT, pageParam); + return events; + }, + getNextPageParam: (lastPage) => { + const lastEvent = lastPage?.at(-1); + if (!lastEvent) return; + return lastEvent.created_at - 1; + }, + select: (data) => data?.pages.flatMap((page) => page), + refetchOnWindowFocus: false, + }); + + const renderItem = (event: Event) => { + if (!event) return; + switch (event.kind) { + case Kind.Repost: + return ; + default: + return ; + } + }; + + return ( +
+ {isLoading ? ( +
+ +
+ ) : !data.length ? ( + + ) : ( + data.map((item) => renderItem(item)) + )} +
+ {hasNextPage ? ( + + ) : null} +
+
+ ); +} diff --git a/packages/ark/src/ark.ts b/packages/ark/src/ark.ts index 70cd79f4..b6c592ed 100644 --- a/packages/ark/src/ark.ts +++ b/packages/ark/src/ark.ts @@ -99,6 +99,23 @@ export class Ark { } } + public async get_events_from(id: string, limit: number, asOf?: number) { + try { + let until: string = undefined; + if (asOf && asOf > 0) until = asOf.toString(); + + const nostrEvents: Event[] = await invoke("get_events_from", { + id, + limit, + until, + }); + + return nostrEvents.sort((a, b) => b.created_at - a.created_at); + } catch { + return []; + } + } + public async get_events( type: "local" | "global", limit: number, diff --git a/packages/ui/src/note/menu.tsx b/packages/ui/src/note/menu.tsx index 261cb4aa..6b5febc3 100644 --- a/packages/ui/src/note/menu.tsx +++ b/packages/ui/src/note/menu.tsx @@ -40,12 +40,12 @@ export function NoteMenu() { - + @@ -53,7 +53,8 @@ export function NoteMenu() { @@ -62,7 +63,7 @@ export function NoteMenu() { @@ -71,33 +72,25 @@ export function NoteMenu() { - ark.open_profile(event.pubkey)} + className="inline-flex h-9 items-center gap-2 rounded-lg px-3 text-sm font-medium text-white hover:bg-neutral-900 focus:outline-none dark:text-black dark:hover:bg-neutral-100" > {t("note.menu.viewAuthor")} - - - - - + diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 84ccc0bb..6738c8a0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -96,9 +96,6 @@ importers: i18next-resources-to-backend: specifier: ^1.2.0 version: 1.2.0 - idb-keyval: - specifier: ^6.2.1 - version: 6.2.1 nostr-tools: specifier: ^2.3.1 version: 2.3.1(typescript@5.3.3) @@ -4579,10 +4576,6 @@ packages: '@babel/runtime': 7.23.9 dev: false - /idb-keyval@6.2.1: - resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==} - dev: false - /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} dev: false diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 7f26ab5b..39e28285 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -107,6 +107,7 @@ fn main() { nostr::metadata::set_settings, nostr::metadata::get_settings, nostr::event::get_event, + nostr::event::get_events_from, nostr::event::get_local_events, nostr::event::get_global_events, nostr::event::get_event_thread, diff --git a/src-tauri/src/nostr/event.rs b/src-tauri/src/nostr/event.rs index 1ce905bc..6913b8f4 100644 --- a/src-tauri/src/nostr/event.rs +++ b/src-tauri/src/nostr/event.rs @@ -38,6 +38,39 @@ pub async fn get_event(id: &str, state: State<'_, Nostr>) -> Result, + state: State<'_, Nostr>, +) -> Result, String> { + let client = &state.client; + let f_until = match until { + Some(until) => Timestamp::from_str(until).unwrap(), + None => Timestamp::now(), + }; + + if let Ok(author) = PublicKey::from_str(id) { + let filter = Filter::new() + .kinds(vec![Kind::TextNote, Kind::Repost]) + .authors(vec![author]) + .limit(limit) + .until(f_until); + + if let Ok(events) = client + .get_events_of(vec![filter], Some(Duration::from_secs(10))) + .await + { + Ok(events) + } else { + Err("Get text event failed".into()) + } + } else { + Err("Parse author failed".into()) + } +} + #[tauri::command] pub async fn get_local_events( limit: usize,