From 8751ba26ebf7b7761b9e237f2bf3453623dd1018 Mon Sep 17 00:00:00 2001 From: polwex Date: Mon, 6 Oct 2025 10:13:39 +0700 Subject: added frontend WS connection for demonstration purposes --- gui/src/pages/Settings.tsx | 255 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 gui/src/pages/Settings.tsx (limited to 'gui/src/pages/Settings.tsx') diff --git a/gui/src/pages/Settings.tsx b/gui/src/pages/Settings.tsx new file mode 100644 index 0000000..abf0022 --- /dev/null +++ b/gui/src/pages/Settings.tsx @@ -0,0 +1,255 @@ +import useLocalState from "@/state/state"; +import { useState } from "react"; +import toast from "react-hot-toast"; +import { ThemeSwitcher } from "@/styles/ThemeSwitcher"; +import Icon from "@/components/Icon"; +import "@/styles/Settings.css"; +import WebSocketWidget from "@/components/WsWidget"; + +function Settings() { + const { key, relays, api, addNotification } = useLocalState((s) => ({ + key: s.pubkey, + relays: s.relays, + api: s.api, + addNotification: s.addNotification, + })); + const [newRelay, setNewRelay] = useState(""); + const [isAddingRelay, setIsAddingRelay] = useState(false); + const [isCyclingKey, setIsCyclingKey] = useState(false); + + async function removeRelay(url: string) { + try { + await api?.deleteRelay(url); + toast.success("Relay removed"); + } catch (error) { + toast.error("Failed to remove relay"); + console.error("Remove relay error:", error); + } + } + + async function addNewRelay() { + if (!newRelay.trim()) { + toast.error("Please enter a relay URL"); + return; + } + + setIsAddingRelay(true); + try { + const valid = ["wss:", "ws:"]; + const url = new URL(newRelay); + if (!valid.includes(url.protocol)) { + toast.error("Invalid Relay URL - must use wss:// or ws://"); + return; + } + + await api?.addRelay(newRelay); + toast.success("Relay added"); + setNewRelay(""); + } catch (error) { + toast.error("Invalid relay URL or failed to add relay"); + console.error("Add relay error:", error); + } finally { + setIsAddingRelay(false); + } + } + + async function cycleKey() { + setIsCyclingKey(true); + try { + await api?.cycleKeys(); + toast.success("Key cycled successfully"); + } catch (error) { + toast.error("Failed to cycle key"); + console.error("Cycle key error:", error); + } finally { + setIsCyclingKey(false); + } + } + + const handleKeyPress = (e: React.KeyboardEvent) => { + if (e.key === "Enter") { + addNewRelay(); + } + }; + + return ( +
+
+

Settings

+

Manage your Nostrill configuration and preferences

+
+ +
+ + {/* Notifications Test Section - Remove in production */} +
+
+ +

Test Notifications

+
+
+
+
+ +

Generate test notifications to see how they work

+
+
+ +
+
+
+
+ + {/* Appearance Section */} +
+
+ +

Appearance

+
+
+
+
+ +

Choose your preferred color theme

+
+
+ +
+
+
+
+ + {/* Identity Section */} +
+
+ +

Identity

+
+
+
+
+ +

Your unique identifier on the Nostr network

+
+
+
+ {key || "No key generated"} + +
+
+
+
+
+ + {/* Nostr Relays Section */} +
+
+ +

Nostr Relays

+
+
+
+
+ +

Manage your Nostr relay connections

+
+
+
+ {Object.keys(relays).length === 0 ? ( +
+ +

No relays configured

+
+ ) : ( + Object.keys(relays).map((url) => ( +
+
+ {url} + Connected +
+ +
+ )) + )} + +
+
+ setNewRelay(e.target.value)} + onKeyPress={handleKeyPress} + placeholder="wss://relay.example.com" + className="relay-input" + /> + +
+
+
+
+
+
+
+
+
+ ); +} +export default Settings; -- cgit v1.2.3