import { commands } from "@/commands.gen"; import { cn, isValidRelayUrl, toLumeEvents } from "@/commons"; import { Spinner, User } from "@/components"; import { LumeWindow } from "@/system"; import type { LumeColumn, NostrEvent } from "@/types"; import { ArrowClockwise, ArrowRight, Plus } from "@phosphor-icons/react"; import * as ScrollArea from "@radix-ui/react-scroll-area"; import { useQuery } from "@tanstack/react-query"; import { createLazyFileRoute } from "@tanstack/react-router"; import { resolveResource } from "@tauri-apps/api/path"; import { message } from "@tauri-apps/plugin-dialog"; import { readTextFile } from "@tauri-apps/plugin-fs"; import { nanoid } from "nanoid"; import { memo, useCallback, useState, useTransition } from "react"; import { minidenticon } from "minidenticons"; export const Route = createLazyFileRoute("/columns/_layout/launchpad/$id")({ component: Screen, }); function Screen() { return ( ); } function Newsfeeds() { const { id } = Route.useParams(); const { isLoading, isError, error, data, refetch, isRefetching } = useQuery({ queryKey: ["newsfeeds", id], queryFn: async () => { const res = await commands.getAllNewsfeeds(id); if (res.status === "ok") { const data = toLumeEvents(res.data); return data; } else { throw new Error(res.error); } }, select: (data) => data.filter( (item) => item.tags.filter((tag) => tag[0] === "p")?.length > 0, ), refetchOnWindowFocus: false, }); const renderItem = useCallback( (item: NostrEvent) => { const users = item.tags.filter((tag) => tag[0] === "p"); const name = item.kind === 3 ? "Contacts" : item.tags.find((tag) => tag[0] === "title")?.[1] || "Unnamed"; const label = item.kind === 3 ? `newsfeed-${item.pubkey.slice(0, 5)}` : item.tags.find((tag) => tag[0] === "d")?.[1] || nanoid(); return (
{users.slice(0, 5).map((tag) => ( ))} {users.length > 5 ? (

+{users.length - 5}

) : null}
{name}
); }, [data], ); return (

Newsfeeds

{isLoading ? (
Loading...
) : isError ? (

{error?.message ?? "Error"}

) : !data?.length ? (

You don't have any groups yet.

) : ( data?.map((item) => renderItem(item)) )}
); } function Relayfeeds() { const { id } = Route.useParams(); const { isLoading, isError, error, data, refetch, isRefetching } = useQuery({ queryKey: ["relays", id], queryFn: async () => { const res = await commands.getRelayList(id); if (res.status === "ok") { const event: NostrEvent = JSON.parse(res.data); return event; } else { throw new Error(res.error); } }, refetchOnWindowFocus: false, }); return (

Relayfeeds

{isLoading ? (
Loading...
) : isError ? (

{error?.message ?? "Error"}

) : !data ? (

You don't have any relay list yet.

) : (
{data?.tags.map((tag) => tag[1]?.startsWith("wss://") ? (
{tag[1]}
) : null, )}
)}
); } function RelayForm() { const [url, setUrl] = useState(""); const [isPending, startTransition] = useTransition(); const submit = () => { startTransition(async () => { if (!isValidRelayUrl(url)) { await message("Relay URL is not valid", { kind: "error" }); return; } await LumeWindow.openColumn({ name: url, label: `relays_${url.replace(/[^\w\s]/gi, "")}`, url: `/columns/relays/${encodeURIComponent(url)}`, }); setUrl(""); }); }; return (
setUrl(e.currentTarget.value)} onKeyDown={(event) => { if (event.key === "Enter") submit(); }} value={url} disabled={isPending} placeholder="wss://..." spellCheck={false} className="flex-1 px-3 bg-neutral-100 border-transparent rounded-lg h-9 dark:bg-neutral-900 placeholder:text-neutral-600 focus:border-blue-500 focus:ring-0 dark:placeholder:text-neutral-400" />
); } function Interests() { const { id } = Route.useParams(); const { isLoading, isError, error, data, refetch, isRefetching } = useQuery({ queryKey: ["interests", id], queryFn: async () => { const res = await commands.getAllInterests(id); if (res.status === "ok") { const data = toLumeEvents(res.data); return data; } else { throw new Error(res.error); } }, select: (data) => data.filter( (item) => item.tags.filter((tag) => tag[0] === "t")?.length > 0, ), refetchOnWindowFocus: false, }); const renderItem = useCallback( (item: NostrEvent) => { const name = item.tags.find((tag) => tag[0] === "title")?.[1] || "Unnamed"; const label = item.tags.find((tag) => tag[0] === "label")?.[1] || nanoid(); return (
{item.tags .filter((tag) => tag[0] === "t") .map((tag) => (
{tag[1].includes("#") ? tag[1] : `#${tag[1]}`}
))}
{name}
); }, [data], ); return (

Interests

{isLoading ? (
Loading...
) : isError ? (

{error?.message ?? "Error"}

) : !data?.length ? (

You don't have any interests yet.

) : ( data?.map((item) => renderItem(item)) )}
); } function ContentDiscovery() { const { isLoading, isError, error, data } = useQuery({ queryKey: ["content-discovery"], queryFn: async () => { const res = await commands.getAllProviders(); if (res.status === "ok") { const events: NostrEvent[] = res.data.map((item) => JSON.parse(item)); return events; } else { throw new Error(res.error); } }, refetchOnWindowFocus: false, }); return (

Content Discovery

{isLoading ? (
Loading...
) : isError ? (

{error?.message ?? "Error"}

) : !data ? (

Empty.

) : (
{data?.map((item) => ( ))}
)}
); } const Provider = memo(function Provider({ event }: { event: NostrEvent }) { const { id } = Route.useParams(); const [isPending, startTransition] = useTransition(); const metadata: { [key: string]: string } = JSON.parse(event.content); const fallback = `data:image/svg+xml;utf8,${encodeURIComponent( minidenticon(event.id, 60, 50), )}`; const request = (name: string | undefined, provider: string) => { startTransition(async () => { // Ensure signer const signer = await commands.hasSigner(id); if (signer.status === "ok") { if (!signer.data) { const res = await commands.setSigner(id); if (res.status === "error") { await message(res.error, { kind: "error" }); return; } } // Send request event to provider const res = await commands.requestEventsFromProvider(provider); if (res.status === "ok") { // Open column await LumeWindow.openColumn({ label: `dvm_${provider.slice(0, 6)}`, name: name || "Content Discovery", account: id, url: `/columns/dvm/${provider}`, }); return; } else { await message(res.error, { kind: "error" }); return; } } else { await message(signer.error, { kind: "error" }); return; } }); }; return (
{event.id}
{metadata.name}

{metadata.about}

); }); function Core() { const { id } = Route.useParams(); const { data } = useQuery({ queryKey: ["core-columns"], queryFn: async () => { const systemPath = "resources/columns.json"; const resourcePath = await resolveResource(systemPath); const resourceFile = await readTextFile(resourcePath); const systemColumns: LumeColumn[] = JSON.parse(resourceFile); const columns = systemColumns.filter((col) => !col.default); return columns; }, refetchOnWindowFocus: false, }); return (

Core

Stories
Notification
{data?.map((column) => (
{column.name}
))}
); }