+
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,