diff --git a/apps/desktop2/src/routes/bootstrap-relays.tsx b/apps/desktop2/src/routes/bootstrap-relays.tsx new file mode 100644 index 00000000..1655b8aa --- /dev/null +++ b/apps/desktop2/src/routes/bootstrap-relays.tsx @@ -0,0 +1,132 @@ +import { CancelIcon, PlusIcon } from "@lume/icons"; +import { NostrQuery } from "@lume/system"; +import { Relay } from "@lume/types"; +import { Spinner } from "@lume/ui"; +import { createFileRoute } from "@tanstack/react-router"; +import { useEffect, useState } from "react"; +import { useForm } from "react-hook-form"; +import { toast } from "sonner"; + +export const Route = createFileRoute("/bootstrap-relays")({ + loader: async () => { + const bootstrapRelays = await NostrQuery.getBootstrapRelays(); + return bootstrapRelays; + }, + component: Screen, +}); + +function Screen() { + const bootstrapRelays = Route.useLoaderData(); + const { register, reset, handleSubmit } = useForm(); + + const [relays, setRelays] = useState([]); + const [isLoading, setIsLoading] = useState(false); + + const removeRelay = (url: string) => { + setRelays((prev) => prev.filter((relay) => relay.url !== url)); + }; + + const onSubmit = async (data: { url: string; purpose: string }) => { + try { + const relay: Relay = { url: data.url, purpose: data.purpose }; + setRelays((prev) => [...prev, relay]); + reset(); + } catch (e) { + toast.error(String(e)); + } + }; + + const save = async () => { + try { + setIsLoading(true); + await NostrQuery.saveBootstrapRelays(relays); + } catch (e) { + setIsLoading(false); + toast.error(String(e)); + } + }; + + useEffect(() => { + setRelays(bootstrapRelays); + }, [bootstrapRelays]); + + return ( +
+
+
+

Customize Bootstrap Relays

+
+
+ {relays.map((relay) => ( +
+
+ {relay.url} +
+
+ {relay.purpose?.length ? ( + + ) : null} + +
+
+ ))} +
+
+
+ + +
+ +
+
+
+ +
+
+ ); +} diff --git a/apps/desktop2/src/routes/index.tsx b/apps/desktop2/src/routes/index.tsx index d7f8ef0a..62ec4408 100644 --- a/apps/desktop2/src/routes/index.tsx +++ b/apps/desktop2/src/routes/index.tsx @@ -1,4 +1,4 @@ -import { PlusIcon } from "@lume/icons"; +import { PlusIcon, RelayIcon } from "@lume/icons"; import { Spinner } from "@lume/ui"; import { User } from "@/components/user"; import { checkForAppUpdates } from "@lume/utils"; @@ -59,46 +59,57 @@ function Screen() { return (
-
+
-

+

{currentDate}

Welcome back!

-
- {loading ? ( -
- -
- ) : ( - <> - {context.accounts.map((account) => ( - - ))} - -
-
- -
-

Add

+
+
+ {loading ? ( +
+ +
+ ) : ( + <> + {context.accounts.map((account) => ( + + ))} + +
+
+
- - - )} +

Add

+
+ + + )} +
+
+
+ + + Bootstrap Relays +
diff --git a/apps/desktop2/src/routes/settings/relay.tsx b/apps/desktop2/src/routes/settings/relay.tsx index 865224e0..b0f638e3 100644 --- a/apps/desktop2/src/routes/settings/relay.tsx +++ b/apps/desktop2/src/routes/settings/relay.tsx @@ -1,7 +1,7 @@ import { CancelIcon, PlusIcon } from "@lume/icons"; import { NostrQuery } from "@lume/system"; import { createFileRoute } from "@tanstack/react-router"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import { toast } from "sonner"; @@ -15,22 +15,32 @@ export const Route = createFileRoute("/settings/relay")({ function Screen() { const relayList = Route.useLoaderData(); - const [relays, setRelays] = useState(relayList.connected); - const { register, reset, handleSubmit } = useForm(); + const [relays, setRelays] = useState([]); + const [isLoading, setIsLoading] = useState(false); + const onSubmit = async (data: { url: string }) => { try { + setIsLoading(true); + const add = await NostrQuery.connectRelay(data.url); + if (add) { setRelays((prev) => [...prev, data.url]); + setIsLoading(false); reset(); } } catch (e) { + setIsLoading(false); toast.error(String(e)); } }; + useEffect(() => { + setRelays(relayList.connected); + }, [relayList]); + return (
@@ -79,6 +89,7 @@ function Screen() { />