fix: settings
This commit is contained in:
@@ -1,12 +1,8 @@
|
|||||||
use nostr_sdk::prelude::*;
|
use nostr_sdk::prelude::*;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use specta::Type;
|
use specta::Type;
|
||||||
use std::{
|
use std::str::FromStr;
|
||||||
fs::OpenOptions,
|
use tauri::State;
|
||||||
io::{self, BufRead, Write},
|
|
||||||
str::FromStr,
|
|
||||||
};
|
|
||||||
use tauri::{path::BaseDirectory, Manager, State};
|
|
||||||
|
|
||||||
use crate::{Nostr, FETCH_LIMIT};
|
use crate::{Nostr, FETCH_LIMIT};
|
||||||
|
|
||||||
@@ -20,82 +16,17 @@ pub struct Relays {
|
|||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
#[specta::specta]
|
#[specta::specta]
|
||||||
pub async fn get_relays(id: String, state: State<'_, Nostr>) -> Result<Relays, String> {
|
pub async fn get_all_relays(state: State<'_, Nostr>) -> Result<Vec<String>, String> {
|
||||||
let client = &state.client;
|
let client = &state.client;
|
||||||
let public_key = PublicKey::from_str(&id).map_err(|e| e.to_string())?;
|
let relays = client.pool().all_relays().await;
|
||||||
|
let v: Vec<String> = relays.iter().map(|item| item.0.to_string()).collect();
|
||||||
|
|
||||||
let connected_relays = client
|
Ok(v)
|
||||||
.relays()
|
|
||||||
.await
|
|
||||||
.into_keys()
|
|
||||||
.map(|url| url.to_string())
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let filter = Filter::new()
|
|
||||||
.author(public_key)
|
|
||||||
.kind(Kind::RelayList)
|
|
||||||
.limit(1);
|
|
||||||
|
|
||||||
match client.database().query(vec![filter]).await {
|
|
||||||
Ok(events) => {
|
|
||||||
if let Some(event) = events.first() {
|
|
||||||
let nip65_list = nip65::extract_relay_list(event).collect::<Vec<_>>();
|
|
||||||
|
|
||||||
let read = nip65_list
|
|
||||||
.iter()
|
|
||||||
.filter_map(|(url, meta)| {
|
|
||||||
if let Some(RelayMetadata::Read) = meta {
|
|
||||||
Some(url.to_string())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let write = nip65_list
|
|
||||||
.iter()
|
|
||||||
.filter_map(|(url, meta)| {
|
|
||||||
if let Some(RelayMetadata::Write) = meta {
|
|
||||||
Some(url.to_string())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let both = nip65_list
|
|
||||||
.iter()
|
|
||||||
.filter_map(|(url, meta)| {
|
|
||||||
if meta.is_none() {
|
|
||||||
Some(url.to_string())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
Ok(Relays {
|
|
||||||
connected: connected_relays,
|
|
||||||
read: Some(read),
|
|
||||||
write: Some(write),
|
|
||||||
both: Some(both),
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Ok(Relays {
|
|
||||||
connected: connected_relays,
|
|
||||||
read: None,
|
|
||||||
write: None,
|
|
||||||
both: None,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => Err(e.to_string()),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
#[specta::specta]
|
#[specta::specta]
|
||||||
pub async fn get_all_relays(
|
pub async fn get_all_relay_lists(
|
||||||
until: Option<String>,
|
until: Option<String>,
|
||||||
state: State<'_, Nostr>,
|
state: State<'_, Nostr>,
|
||||||
) -> Result<Vec<String>, String> {
|
) -> Result<Vec<String>, String> {
|
||||||
@@ -149,36 +80,3 @@ pub async fn remove_relay(relay: String, state: State<'_, Nostr>) -> Result<(),
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
#[specta::specta]
|
|
||||||
pub fn get_bootstrap_relays(app: tauri::AppHandle) -> Result<Vec<String>, String> {
|
|
||||||
let relays_path = app
|
|
||||||
.path()
|
|
||||||
.resolve("resources/relays.txt", BaseDirectory::Resource)
|
|
||||||
.map_err(|e| e.to_string())?;
|
|
||||||
|
|
||||||
let file = std::fs::File::open(relays_path).map_err(|e| e.to_string())?;
|
|
||||||
let reader = io::BufReader::new(file);
|
|
||||||
|
|
||||||
reader
|
|
||||||
.lines()
|
|
||||||
.collect::<Result<Vec<String>, io::Error>>()
|
|
||||||
.map_err(|e| e.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
#[specta::specta]
|
|
||||||
pub fn set_bootstrap_relays(relays: String, app: tauri::AppHandle) -> Result<(), String> {
|
|
||||||
let relays_path = app
|
|
||||||
.path()
|
|
||||||
.resolve("resources/relays.txt", BaseDirectory::Resource)
|
|
||||||
.map_err(|e| e.to_string())?;
|
|
||||||
|
|
||||||
let mut file = OpenOptions::new()
|
|
||||||
.write(true)
|
|
||||||
.open(relays_path)
|
|
||||||
.map_err(|e| e.to_string())?;
|
|
||||||
|
|
||||||
file.write_all(relays.as_bytes()).map_err(|e| e.to_string())
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ use tauri::{
|
|||||||
};
|
};
|
||||||
use tauri_plugin_decorum::WebviewWindowExt;
|
use tauri_plugin_decorum::WebviewWindowExt;
|
||||||
use tauri_plugin_notification::{NotificationExt, PermissionState};
|
use tauri_plugin_notification::{NotificationExt, PermissionState};
|
||||||
|
use tauri_plugin_store::StoreExt;
|
||||||
use tauri_specta::{collect_commands, Builder};
|
use tauri_specta::{collect_commands, Builder};
|
||||||
use tokio::{sync::RwLock, time::sleep};
|
use tokio::{sync::RwLock, time::sleep};
|
||||||
|
|
||||||
@@ -42,7 +43,7 @@ pub struct Payload {
|
|||||||
id: String,
|
id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Deserialize, Type)]
|
#[derive(Debug, Clone, Serialize, Deserialize, Type)]
|
||||||
pub struct Settings {
|
pub struct Settings {
|
||||||
resize_service: bool,
|
resize_service: bool,
|
||||||
content_warning: bool,
|
content_warning: bool,
|
||||||
@@ -74,13 +75,11 @@ fn main() {
|
|||||||
tracing_subscriber::fmt::init();
|
tracing_subscriber::fmt::init();
|
||||||
|
|
||||||
let builder = Builder::<tauri::Wry>::new().commands(collect_commands![
|
let builder = Builder::<tauri::Wry>::new().commands(collect_commands![
|
||||||
get_relays,
|
|
||||||
get_all_relays,
|
get_all_relays,
|
||||||
|
get_all_relay_lists,
|
||||||
is_relay_connected,
|
is_relay_connected,
|
||||||
connect_relay,
|
connect_relay,
|
||||||
remove_relay,
|
remove_relay,
|
||||||
get_bootstrap_relays,
|
|
||||||
set_bootstrap_relays,
|
|
||||||
get_accounts,
|
get_accounts,
|
||||||
watch_account,
|
watch_account,
|
||||||
import_account,
|
import_account,
|
||||||
@@ -278,11 +277,29 @@ fn main() {
|
|||||||
client
|
client
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Load app settings
|
||||||
|
let store = app.store(".data")?;
|
||||||
|
|
||||||
|
// Parse app settings if exist
|
||||||
|
let settings = if let Some(data) = store.get("tanstack-query-[\"settings\"]") {
|
||||||
|
if let Some(str) = data.as_str() {
|
||||||
|
let v: Value = serde_json::from_str(str).unwrap();
|
||||||
|
let data = v["state"]["data"].clone();
|
||||||
|
let parse: Settings = serde_json::from_value(data).unwrap();
|
||||||
|
|
||||||
|
RwLock::new(parse)
|
||||||
|
} else {
|
||||||
|
RwLock::new(Settings::default())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
RwLock::new(Settings::default())
|
||||||
|
};
|
||||||
|
|
||||||
// Create global state
|
// Create global state
|
||||||
app.manage(Nostr {
|
app.manage(Nostr {
|
||||||
client,
|
client,
|
||||||
|
settings,
|
||||||
queue: RwLock::new(HashSet::new()),
|
queue: RwLock::new(HashSet::new()),
|
||||||
settings: RwLock::new(Settings::default()),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Listen for request metadata
|
// Listen for request metadata
|
||||||
|
|||||||
@@ -5,17 +5,17 @@
|
|||||||
|
|
||||||
|
|
||||||
export const commands = {
|
export const commands = {
|
||||||
async getRelays(id: string) : Promise<Result<Relays, string>> {
|
async getAllRelays() : Promise<Result<string[], string>> {
|
||||||
try {
|
try {
|
||||||
return { status: "ok", data: await TAURI_INVOKE("get_relays", { id }) };
|
return { status: "ok", data: await TAURI_INVOKE("get_all_relays") };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if(e instanceof Error) throw e;
|
if(e instanceof Error) throw e;
|
||||||
else return { status: "error", error: e as any };
|
else return { status: "error", error: e as any };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async getAllRelays(until: string | null) : Promise<Result<string[], string>> {
|
async getAllRelayLists(until: string | null) : Promise<Result<string[], string>> {
|
||||||
try {
|
try {
|
||||||
return { status: "ok", data: await TAURI_INVOKE("get_all_relays", { until }) };
|
return { status: "ok", data: await TAURI_INVOKE("get_all_relay_lists", { until }) };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if(e instanceof Error) throw e;
|
if(e instanceof Error) throw e;
|
||||||
else return { status: "error", error: e as any };
|
else return { status: "error", error: e as any };
|
||||||
@@ -45,22 +45,6 @@ async removeRelay(relay: string) : Promise<Result<null, string>> {
|
|||||||
else return { status: "error", error: e as any };
|
else return { status: "error", error: e as any };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async getBootstrapRelays() : Promise<Result<string[], string>> {
|
|
||||||
try {
|
|
||||||
return { status: "ok", data: await TAURI_INVOKE("get_bootstrap_relays") };
|
|
||||||
} catch (e) {
|
|
||||||
if(e instanceof Error) throw e;
|
|
||||||
else return { status: "error", error: e as any };
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async setBootstrapRelays(relays: string) : Promise<Result<null, string>> {
|
|
||||||
try {
|
|
||||||
return { status: "ok", data: await TAURI_INVOKE("set_bootstrap_relays", { relays }) };
|
|
||||||
} catch (e) {
|
|
||||||
if(e instanceof Error) throw e;
|
|
||||||
else return { status: "error", error: e as any };
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async getAccounts() : Promise<string[]> {
|
async getAccounts() : Promise<string[]> {
|
||||||
return await TAURI_INVOKE("get_accounts");
|
return await TAURI_INVOKE("get_accounts");
|
||||||
},
|
},
|
||||||
@@ -536,7 +520,6 @@ export type Column = { label: string; url: string; x: number; y: number; width:
|
|||||||
export type Mention = { pubkey: string; avatar: string; display_name: string; name: string }
|
export type Mention = { pubkey: string; avatar: string; display_name: string; name: string }
|
||||||
export type Meta = { content: string; images: string[]; events: string[]; mentions: string[]; hashtags: string[] }
|
export type Meta = { content: string; images: string[]; events: string[]; mentions: string[]; hashtags: string[] }
|
||||||
export type NewWindow = { label: string; title: string; url: string; width: number; height: number; maximizable: boolean; minimizable: boolean; hidden_title: boolean; closable: boolean }
|
export type NewWindow = { label: string; title: string; url: string; width: number; height: number; maximizable: boolean; minimizable: boolean; hidden_title: boolean; closable: boolean }
|
||||||
export type Relays = { connected: string[]; read: string[] | null; write: string[] | null; both: string[] | null }
|
|
||||||
export type RichEvent = { raw: string; parsed: Meta | null }
|
export type RichEvent = { raw: string; parsed: Meta | null }
|
||||||
export type Settings = { resize_service: boolean; content_warning: boolean; display_avatar: boolean; display_zap_button: boolean; display_repost_button: boolean; display_media: boolean }
|
export type Settings = { resize_service: boolean; content_warning: boolean; display_avatar: boolean; display_zap_button: boolean; display_repost_button: boolean; display_media: boolean }
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,12 @@ import { ZapIcon } from "@/components";
|
|||||||
import { settingsQueryOptions } from "@/routes/__root";
|
import { settingsQueryOptions } from "@/routes/__root";
|
||||||
import { LumeWindow } from "@/system";
|
import { LumeWindow } from "@/system";
|
||||||
import { useSuspenseQuery } from "@tanstack/react-query";
|
import { useSuspenseQuery } from "@tanstack/react-query";
|
||||||
import { useSearch } from "@tanstack/react-router";
|
|
||||||
import { useNoteContext } from "../provider";
|
import { useNoteContext } from "../provider";
|
||||||
|
|
||||||
export function NoteZap({
|
export function NoteZap({
|
||||||
label = false,
|
label = false,
|
||||||
smol = false,
|
smol = false,
|
||||||
}: { label?: boolean; smol?: boolean }) {
|
}: { label?: boolean; smol?: boolean }) {
|
||||||
const search = useSearch({ strict: false });
|
|
||||||
const settings = useSuspenseQuery(settingsQueryOptions);
|
const settings = useSuspenseQuery(settingsQueryOptions);
|
||||||
const event = useNoteContext();
|
const event = useNoteContext();
|
||||||
|
|
||||||
@@ -19,7 +17,7 @@ export function NoteZap({
|
|||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => LumeWindow.openZap(event.id, search.account)}
|
onClick={() => LumeWindow.openZap(event.id)}
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-7 rounded-full inline-flex items-center justify-center text-neutral-800 hover:bg-black/5 dark:hover:bg-white/5 dark:text-neutral-200 text-sm font-medium",
|
"h-7 rounded-full inline-flex items-center justify-center text-neutral-800 hover:bg-black/5 dark:hover:bg-white/5 dark:text-neutral-200 text-sm font-medium",
|
||||||
label ? "w-24 gap-1.5" : "w-14",
|
label ? "w-24 gap-1.5" : "w-14",
|
||||||
|
|||||||
@@ -1,23 +1,28 @@
|
|||||||
import { commands } from "@/commands.gen";
|
import { commands } from "@/commands.gen";
|
||||||
import { cn } from "@/commons";
|
import { cn, displayNpub } from "@/commons";
|
||||||
import { Spinner } from "@/components";
|
import { Spinner } from "@/components";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||||
import { useRouteContext } from "@tanstack/react-router";
|
|
||||||
import { message } from "@tauri-apps/plugin-dialog";
|
import { message } from "@tauri-apps/plugin-dialog";
|
||||||
import { useTransition } from "react";
|
import { useCallback, useTransition } from "react";
|
||||||
import { useUserContext } from "./provider";
|
import { useUserContext } from "./provider";
|
||||||
|
import type { Metadata } from "@/types";
|
||||||
|
import { MenuItem, Menu } from "@tauri-apps/api/menu";
|
||||||
|
|
||||||
export function UserButton({ className }: { className?: string }) {
|
export function UserButton({ className }: { className?: string }) {
|
||||||
const user = useUserContext();
|
const user = useUserContext();
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
const { queryClient } = useRouteContext({ strict: false });
|
|
||||||
const {
|
const {
|
||||||
isLoading,
|
isLoading,
|
||||||
isError,
|
isError,
|
||||||
data: isFollow,
|
data: isFollow,
|
||||||
} = useQuery({
|
} = useQuery({
|
||||||
queryKey: ["status", user.pubkey],
|
queryKey: ["status", user?.pubkey],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
|
if (!user) {
|
||||||
|
throw new Error("User not found");
|
||||||
|
}
|
||||||
|
|
||||||
const res = await commands.isContact(user.pubkey);
|
const res = await commands.isContact(user.pubkey);
|
||||||
|
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
@@ -27,28 +32,95 @@ export function UserButton({ className }: { className?: string }) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
refetchOnWindowFocus: false,
|
refetchOnWindowFocus: false,
|
||||||
|
refetchOnMount: false,
|
||||||
|
refetchOnReconnect: false,
|
||||||
|
retry: 2,
|
||||||
});
|
});
|
||||||
|
|
||||||
const [isPending, startTransition] = useTransition();
|
const [isPending, startTransition] = useTransition();
|
||||||
|
|
||||||
const toggleFollow = () => {
|
const showContextMenu = useCallback(async (e: React.MouseEvent) => {
|
||||||
startTransition(async () => {
|
e.preventDefault();
|
||||||
|
|
||||||
|
const accounts = await commands.getAccounts();
|
||||||
|
const list: Promise<MenuItem>[] = [];
|
||||||
|
|
||||||
|
for (const account of accounts) {
|
||||||
|
const res = await commands.getProfile(account);
|
||||||
|
let name = "unknown";
|
||||||
|
|
||||||
|
if (res.status === "ok") {
|
||||||
|
const profile: Metadata = JSON.parse(res.data);
|
||||||
|
name = profile.display_name ?? profile.name ?? "anon";
|
||||||
|
}
|
||||||
|
|
||||||
|
list.push(
|
||||||
|
MenuItem.new({
|
||||||
|
text: `Follow as ${name} (${displayNpub(account, 16)})`,
|
||||||
|
action: async () => submit(account),
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const items = await Promise.all(list);
|
||||||
|
const menu = await Menu.new({ items });
|
||||||
|
|
||||||
|
await menu.popup().catch((e) => console.error(e));
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const toggleFollow = useMutation({
|
||||||
|
mutationFn: async () => {
|
||||||
|
if (!user) return;
|
||||||
|
|
||||||
|
// Cancel any outgoing refetches
|
||||||
|
await queryClient.cancelQueries({ queryKey: ["status", user.pubkey] });
|
||||||
|
|
||||||
|
// Optimistically update to the new value
|
||||||
|
queryClient.setQueryData(
|
||||||
|
["status", user.pubkey],
|
||||||
|
(data: boolean) => !data,
|
||||||
|
);
|
||||||
|
|
||||||
const res = await commands.toggleContact(user.pubkey, null);
|
const res = await commands.toggleContact(user.pubkey, null);
|
||||||
|
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
queryClient.setQueryData(
|
|
||||||
["status", user.pubkey],
|
|
||||||
(prev: boolean) => !prev,
|
|
||||||
);
|
|
||||||
|
|
||||||
// invalidate cache
|
|
||||||
await queryClient.invalidateQueries({
|
|
||||||
queryKey: ["status", user.pubkey],
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
await message(res.error, { kind: "error" });
|
throw new Error(res.error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onError: () => {
|
||||||
|
queryClient.setQueryData(["status", user?.pubkey], false);
|
||||||
|
},
|
||||||
|
onSettled: async () => {
|
||||||
|
return await queryClient.invalidateQueries({
|
||||||
|
queryKey: ["status", user?.pubkey],
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const submit = (account: string) => {
|
||||||
|
startTransition(async () => {
|
||||||
|
if (!status) {
|
||||||
|
const signer = await commands.hasSigner(account);
|
||||||
|
|
||||||
|
if (signer.status === "ok") {
|
||||||
|
if (!signer.data) {
|
||||||
|
if (!signer.data) {
|
||||||
|
const res = await commands.setSigner(account);
|
||||||
|
|
||||||
|
if (res.status === "error") {
|
||||||
|
await message(res.error, { kind: "error" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleFollow.mutate();
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -57,8 +129,8 @@ export function UserButton({ className }: { className?: string }) {
|
|||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
disabled={isPending}
|
disabled={isPending || isLoading}
|
||||||
onClick={() => toggleFollow()}
|
onClick={(e) => showContextMenu(e)}
|
||||||
className={cn("w-max gap-1", className)}
|
className={cn("w-max gap-1", className)}
|
||||||
>
|
>
|
||||||
{isError ? "Error" : null}
|
{isError ? "Error" : null}
|
||||||
|
|||||||
@@ -17,13 +17,13 @@ import { Route as AppImport } from './routes/_app'
|
|||||||
import { Route as NewPostIndexImport } from './routes/new-post/index'
|
import { Route as NewPostIndexImport } from './routes/new-post/index'
|
||||||
import { Route as AppIndexImport } from './routes/_app/index'
|
import { Route as AppIndexImport } from './routes/_app/index'
|
||||||
import { Route as ZapIdImport } from './routes/zap.$id'
|
import { Route as ZapIdImport } from './routes/zap.$id'
|
||||||
|
import { Route as SettingsWalletImport } from './routes/settings/wallet'
|
||||||
|
import { Route as SettingsRelaysImport } from './routes/settings/relays'
|
||||||
|
import { Route as SettingsGeneralImport } from './routes/settings/general'
|
||||||
import { Route as ColumnsLayoutImport } from './routes/columns/_layout'
|
import { Route as ColumnsLayoutImport } from './routes/columns/_layout'
|
||||||
import { Route as IdSetProfileImport } from './routes/$id.set-profile'
|
import { Route as IdSetProfileImport } from './routes/$id.set-profile'
|
||||||
import { Route as IdSetInterestImport } from './routes/$id.set-interest'
|
import { Route as IdSetInterestImport } from './routes/$id.set-interest'
|
||||||
import { Route as IdSetGroupImport } from './routes/$id.set-group'
|
import { Route as IdSetGroupImport } from './routes/$id.set-group'
|
||||||
import { Route as SettingsIdWalletImport } from './routes/settings.$id/wallet'
|
|
||||||
import { Route as SettingsIdRelayImport } from './routes/settings.$id/relay'
|
|
||||||
import { Route as SettingsIdGeneralImport } from './routes/settings.$id/general'
|
|
||||||
import { Route as ColumnsLayoutGlobalImport } from './routes/columns/_layout/global'
|
import { Route as ColumnsLayoutGlobalImport } from './routes/columns/_layout/global'
|
||||||
import { Route as ColumnsLayoutCreateNewsfeedImport } from './routes/columns/_layout/create-newsfeed'
|
import { Route as ColumnsLayoutCreateNewsfeedImport } from './routes/columns/_layout/create-newsfeed'
|
||||||
import { Route as ColumnsLayoutStoriesIdImport } from './routes/columns/_layout/stories.$id'
|
import { Route as ColumnsLayoutStoriesIdImport } from './routes/columns/_layout/stories.$id'
|
||||||
@@ -37,8 +37,8 @@ import { Route as ColumnsLayoutCreateNewsfeedF2fImport } from './routes/columns/
|
|||||||
// Create Virtual Routes
|
// Create Virtual Routes
|
||||||
|
|
||||||
const ColumnsImport = createFileRoute('/columns')()
|
const ColumnsImport = createFileRoute('/columns')()
|
||||||
|
const SettingsLazyImport = createFileRoute('/settings')()
|
||||||
const NewLazyImport = createFileRoute('/new')()
|
const NewLazyImport = createFileRoute('/new')()
|
||||||
const SettingsIdLazyImport = createFileRoute('/settings/$id')()
|
|
||||||
const NewAccountWatchLazyImport = createFileRoute('/new-account/watch')()
|
const NewAccountWatchLazyImport = createFileRoute('/new-account/watch')()
|
||||||
const NewAccountImportLazyImport = createFileRoute('/new-account/import')()
|
const NewAccountImportLazyImport = createFileRoute('/new-account/import')()
|
||||||
const NewAccountConnectLazyImport = createFileRoute('/new-account/connect')()
|
const NewAccountConnectLazyImport = createFileRoute('/new-account/connect')()
|
||||||
@@ -84,6 +84,12 @@ const ColumnsRoute = ColumnsImport.update({
|
|||||||
getParentRoute: () => rootRoute,
|
getParentRoute: () => rootRoute,
|
||||||
} as any)
|
} as any)
|
||||||
|
|
||||||
|
const SettingsLazyRoute = SettingsLazyImport.update({
|
||||||
|
id: '/settings',
|
||||||
|
path: '/settings',
|
||||||
|
getParentRoute: () => rootRoute,
|
||||||
|
} as any).lazy(() => import('./routes/settings.lazy').then((d) => d.Route))
|
||||||
|
|
||||||
const NewLazyRoute = NewLazyImport.update({
|
const NewLazyRoute = NewLazyImport.update({
|
||||||
id: '/new',
|
id: '/new',
|
||||||
path: '/new',
|
path: '/new',
|
||||||
@@ -109,12 +115,6 @@ const AppIndexRoute = AppIndexImport.update({
|
|||||||
getParentRoute: () => AppRoute,
|
getParentRoute: () => AppRoute,
|
||||||
} as any).lazy(() => import('./routes/_app/index.lazy').then((d) => d.Route))
|
} as any).lazy(() => import('./routes/_app/index.lazy').then((d) => d.Route))
|
||||||
|
|
||||||
const SettingsIdLazyRoute = SettingsIdLazyImport.update({
|
|
||||||
id: '/settings/$id',
|
|
||||||
path: '/settings/$id',
|
|
||||||
getParentRoute: () => rootRoute,
|
|
||||||
} as any).lazy(() => import('./routes/settings.$id.lazy').then((d) => d.Route))
|
|
||||||
|
|
||||||
const NewAccountWatchLazyRoute = NewAccountWatchLazyImport.update({
|
const NewAccountWatchLazyRoute = NewAccountWatchLazyImport.update({
|
||||||
id: '/new-account/watch',
|
id: '/new-account/watch',
|
||||||
path: '/new-account/watch',
|
path: '/new-account/watch',
|
||||||
@@ -145,6 +145,30 @@ const ZapIdRoute = ZapIdImport.update({
|
|||||||
getParentRoute: () => rootRoute,
|
getParentRoute: () => rootRoute,
|
||||||
} as any).lazy(() => import('./routes/zap.$id.lazy').then((d) => d.Route))
|
} as any).lazy(() => import('./routes/zap.$id.lazy').then((d) => d.Route))
|
||||||
|
|
||||||
|
const SettingsWalletRoute = SettingsWalletImport.update({
|
||||||
|
id: '/wallet',
|
||||||
|
path: '/wallet',
|
||||||
|
getParentRoute: () => SettingsLazyRoute,
|
||||||
|
} as any).lazy(() =>
|
||||||
|
import('./routes/settings/wallet.lazy').then((d) => d.Route),
|
||||||
|
)
|
||||||
|
|
||||||
|
const SettingsRelaysRoute = SettingsRelaysImport.update({
|
||||||
|
id: '/relays',
|
||||||
|
path: '/relays',
|
||||||
|
getParentRoute: () => SettingsLazyRoute,
|
||||||
|
} as any).lazy(() =>
|
||||||
|
import('./routes/settings/relays.lazy').then((d) => d.Route),
|
||||||
|
)
|
||||||
|
|
||||||
|
const SettingsGeneralRoute = SettingsGeneralImport.update({
|
||||||
|
id: '/general',
|
||||||
|
path: '/general',
|
||||||
|
getParentRoute: () => SettingsLazyRoute,
|
||||||
|
} as any).lazy(() =>
|
||||||
|
import('./routes/settings/general.lazy').then((d) => d.Route),
|
||||||
|
)
|
||||||
|
|
||||||
const ColumnsLayoutRoute = ColumnsLayoutImport.update({
|
const ColumnsLayoutRoute = ColumnsLayoutImport.update({
|
||||||
id: '/_layout',
|
id: '/_layout',
|
||||||
getParentRoute: () => ColumnsRoute,
|
getParentRoute: () => ColumnsRoute,
|
||||||
@@ -230,30 +254,6 @@ const ColumnsLayoutDiscoverInterestsLazyRoute =
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
const SettingsIdWalletRoute = SettingsIdWalletImport.update({
|
|
||||||
id: '/wallet',
|
|
||||||
path: '/wallet',
|
|
||||||
getParentRoute: () => SettingsIdLazyRoute,
|
|
||||||
} as any).lazy(() =>
|
|
||||||
import('./routes/settings.$id/wallet.lazy').then((d) => d.Route),
|
|
||||||
)
|
|
||||||
|
|
||||||
const SettingsIdRelayRoute = SettingsIdRelayImport.update({
|
|
||||||
id: '/relay',
|
|
||||||
path: '/relay',
|
|
||||||
getParentRoute: () => SettingsIdLazyRoute,
|
|
||||||
} as any).lazy(() =>
|
|
||||||
import('./routes/settings.$id/relay.lazy').then((d) => d.Route),
|
|
||||||
)
|
|
||||||
|
|
||||||
const SettingsIdGeneralRoute = SettingsIdGeneralImport.update({
|
|
||||||
id: '/general',
|
|
||||||
path: '/general',
|
|
||||||
getParentRoute: () => SettingsIdLazyRoute,
|
|
||||||
} as any).lazy(() =>
|
|
||||||
import('./routes/settings.$id/general.lazy').then((d) => d.Route),
|
|
||||||
)
|
|
||||||
|
|
||||||
const ColumnsLayoutGlobalRoute = ColumnsLayoutGlobalImport.update({
|
const ColumnsLayoutGlobalRoute = ColumnsLayoutGlobalImport.update({
|
||||||
id: '/global',
|
id: '/global',
|
||||||
path: '/global',
|
path: '/global',
|
||||||
@@ -387,6 +387,13 @@ declare module '@tanstack/react-router' {
|
|||||||
preLoaderRoute: typeof NewLazyImport
|
preLoaderRoute: typeof NewLazyImport
|
||||||
parentRoute: typeof rootRoute
|
parentRoute: typeof rootRoute
|
||||||
}
|
}
|
||||||
|
'/settings': {
|
||||||
|
id: '/settings'
|
||||||
|
path: '/settings'
|
||||||
|
fullPath: '/settings'
|
||||||
|
preLoaderRoute: typeof SettingsLazyImport
|
||||||
|
parentRoute: typeof rootRoute
|
||||||
|
}
|
||||||
'/$id/set-group': {
|
'/$id/set-group': {
|
||||||
id: '/$id/set-group'
|
id: '/$id/set-group'
|
||||||
path: '/$id/set-group'
|
path: '/$id/set-group'
|
||||||
@@ -422,6 +429,27 @@ declare module '@tanstack/react-router' {
|
|||||||
preLoaderRoute: typeof ColumnsLayoutImport
|
preLoaderRoute: typeof ColumnsLayoutImport
|
||||||
parentRoute: typeof ColumnsRoute
|
parentRoute: typeof ColumnsRoute
|
||||||
}
|
}
|
||||||
|
'/settings/general': {
|
||||||
|
id: '/settings/general'
|
||||||
|
path: '/general'
|
||||||
|
fullPath: '/settings/general'
|
||||||
|
preLoaderRoute: typeof SettingsGeneralImport
|
||||||
|
parentRoute: typeof SettingsLazyImport
|
||||||
|
}
|
||||||
|
'/settings/relays': {
|
||||||
|
id: '/settings/relays'
|
||||||
|
path: '/relays'
|
||||||
|
fullPath: '/settings/relays'
|
||||||
|
preLoaderRoute: typeof SettingsRelaysImport
|
||||||
|
parentRoute: typeof SettingsLazyImport
|
||||||
|
}
|
||||||
|
'/settings/wallet': {
|
||||||
|
id: '/settings/wallet'
|
||||||
|
path: '/wallet'
|
||||||
|
fullPath: '/settings/wallet'
|
||||||
|
preLoaderRoute: typeof SettingsWalletImport
|
||||||
|
parentRoute: typeof SettingsLazyImport
|
||||||
|
}
|
||||||
'/zap/$id': {
|
'/zap/$id': {
|
||||||
id: '/zap/$id'
|
id: '/zap/$id'
|
||||||
path: '/zap/$id'
|
path: '/zap/$id'
|
||||||
@@ -450,13 +478,6 @@ declare module '@tanstack/react-router' {
|
|||||||
preLoaderRoute: typeof NewAccountWatchLazyImport
|
preLoaderRoute: typeof NewAccountWatchLazyImport
|
||||||
parentRoute: typeof rootRoute
|
parentRoute: typeof rootRoute
|
||||||
}
|
}
|
||||||
'/settings/$id': {
|
|
||||||
id: '/settings/$id'
|
|
||||||
path: '/settings/$id'
|
|
||||||
fullPath: '/settings/$id'
|
|
||||||
preLoaderRoute: typeof SettingsIdLazyImport
|
|
||||||
parentRoute: typeof rootRoute
|
|
||||||
}
|
|
||||||
'/_app/': {
|
'/_app/': {
|
||||||
id: '/_app/'
|
id: '/_app/'
|
||||||
path: '/'
|
path: '/'
|
||||||
@@ -485,27 +506,6 @@ declare module '@tanstack/react-router' {
|
|||||||
preLoaderRoute: typeof ColumnsLayoutGlobalImport
|
preLoaderRoute: typeof ColumnsLayoutGlobalImport
|
||||||
parentRoute: typeof ColumnsLayoutImport
|
parentRoute: typeof ColumnsLayoutImport
|
||||||
}
|
}
|
||||||
'/settings/$id/general': {
|
|
||||||
id: '/settings/$id/general'
|
|
||||||
path: '/general'
|
|
||||||
fullPath: '/settings/$id/general'
|
|
||||||
preLoaderRoute: typeof SettingsIdGeneralImport
|
|
||||||
parentRoute: typeof SettingsIdLazyImport
|
|
||||||
}
|
|
||||||
'/settings/$id/relay': {
|
|
||||||
id: '/settings/$id/relay'
|
|
||||||
path: '/relay'
|
|
||||||
fullPath: '/settings/$id/relay'
|
|
||||||
preLoaderRoute: typeof SettingsIdRelayImport
|
|
||||||
parentRoute: typeof SettingsIdLazyImport
|
|
||||||
}
|
|
||||||
'/settings/$id/wallet': {
|
|
||||||
id: '/settings/$id/wallet'
|
|
||||||
path: '/wallet'
|
|
||||||
fullPath: '/settings/$id/wallet'
|
|
||||||
preLoaderRoute: typeof SettingsIdWalletImport
|
|
||||||
parentRoute: typeof SettingsIdLazyImport
|
|
||||||
}
|
|
||||||
'/columns/_layout/discover-interests': {
|
'/columns/_layout/discover-interests': {
|
||||||
id: '/columns/_layout/discover-interests'
|
id: '/columns/_layout/discover-interests'
|
||||||
path: '/discover-interests'
|
path: '/discover-interests'
|
||||||
@@ -647,6 +647,22 @@ const AppRouteChildren: AppRouteChildren = {
|
|||||||
|
|
||||||
const AppRouteWithChildren = AppRoute._addFileChildren(AppRouteChildren)
|
const AppRouteWithChildren = AppRoute._addFileChildren(AppRouteChildren)
|
||||||
|
|
||||||
|
interface SettingsLazyRouteChildren {
|
||||||
|
SettingsGeneralRoute: typeof SettingsGeneralRoute
|
||||||
|
SettingsRelaysRoute: typeof SettingsRelaysRoute
|
||||||
|
SettingsWalletRoute: typeof SettingsWalletRoute
|
||||||
|
}
|
||||||
|
|
||||||
|
const SettingsLazyRouteChildren: SettingsLazyRouteChildren = {
|
||||||
|
SettingsGeneralRoute: SettingsGeneralRoute,
|
||||||
|
SettingsRelaysRoute: SettingsRelaysRoute,
|
||||||
|
SettingsWalletRoute: SettingsWalletRoute,
|
||||||
|
}
|
||||||
|
|
||||||
|
const SettingsLazyRouteWithChildren = SettingsLazyRoute._addFileChildren(
|
||||||
|
SettingsLazyRouteChildren,
|
||||||
|
)
|
||||||
|
|
||||||
interface ColumnsLayoutCreateNewsfeedRouteChildren {
|
interface ColumnsLayoutCreateNewsfeedRouteChildren {
|
||||||
ColumnsLayoutCreateNewsfeedF2fRoute: typeof ColumnsLayoutCreateNewsfeedF2fRoute
|
ColumnsLayoutCreateNewsfeedF2fRoute: typeof ColumnsLayoutCreateNewsfeedF2fRoute
|
||||||
ColumnsLayoutCreateNewsfeedUsersRoute: typeof ColumnsLayoutCreateNewsfeedUsersRoute
|
ColumnsLayoutCreateNewsfeedUsersRoute: typeof ColumnsLayoutCreateNewsfeedUsersRoute
|
||||||
@@ -724,41 +740,25 @@ const ColumnsRouteChildren: ColumnsRouteChildren = {
|
|||||||
const ColumnsRouteWithChildren =
|
const ColumnsRouteWithChildren =
|
||||||
ColumnsRoute._addFileChildren(ColumnsRouteChildren)
|
ColumnsRoute._addFileChildren(ColumnsRouteChildren)
|
||||||
|
|
||||||
interface SettingsIdLazyRouteChildren {
|
|
||||||
SettingsIdGeneralRoute: typeof SettingsIdGeneralRoute
|
|
||||||
SettingsIdRelayRoute: typeof SettingsIdRelayRoute
|
|
||||||
SettingsIdWalletRoute: typeof SettingsIdWalletRoute
|
|
||||||
}
|
|
||||||
|
|
||||||
const SettingsIdLazyRouteChildren: SettingsIdLazyRouteChildren = {
|
|
||||||
SettingsIdGeneralRoute: SettingsIdGeneralRoute,
|
|
||||||
SettingsIdRelayRoute: SettingsIdRelayRoute,
|
|
||||||
SettingsIdWalletRoute: SettingsIdWalletRoute,
|
|
||||||
}
|
|
||||||
|
|
||||||
const SettingsIdLazyRouteWithChildren = SettingsIdLazyRoute._addFileChildren(
|
|
||||||
SettingsIdLazyRouteChildren,
|
|
||||||
)
|
|
||||||
|
|
||||||
export interface FileRoutesByFullPath {
|
export interface FileRoutesByFullPath {
|
||||||
'': typeof AppRouteWithChildren
|
'': typeof AppRouteWithChildren
|
||||||
'/new': typeof NewLazyRoute
|
'/new': typeof NewLazyRoute
|
||||||
|
'/settings': typeof SettingsLazyRouteWithChildren
|
||||||
'/$id/set-group': typeof IdSetGroupRoute
|
'/$id/set-group': typeof IdSetGroupRoute
|
||||||
'/$id/set-interest': typeof IdSetInterestRoute
|
'/$id/set-interest': typeof IdSetInterestRoute
|
||||||
'/$id/set-profile': typeof IdSetProfileRoute
|
'/$id/set-profile': typeof IdSetProfileRoute
|
||||||
'/columns': typeof ColumnsLayoutRouteWithChildren
|
'/columns': typeof ColumnsLayoutRouteWithChildren
|
||||||
|
'/settings/general': typeof SettingsGeneralRoute
|
||||||
|
'/settings/relays': typeof SettingsRelaysRoute
|
||||||
|
'/settings/wallet': typeof SettingsWalletRoute
|
||||||
'/zap/$id': typeof ZapIdRoute
|
'/zap/$id': typeof ZapIdRoute
|
||||||
'/new-account/connect': typeof NewAccountConnectLazyRoute
|
'/new-account/connect': typeof NewAccountConnectLazyRoute
|
||||||
'/new-account/import': typeof NewAccountImportLazyRoute
|
'/new-account/import': typeof NewAccountImportLazyRoute
|
||||||
'/new-account/watch': typeof NewAccountWatchLazyRoute
|
'/new-account/watch': typeof NewAccountWatchLazyRoute
|
||||||
'/settings/$id': typeof SettingsIdLazyRouteWithChildren
|
|
||||||
'/': typeof AppIndexRoute
|
'/': typeof AppIndexRoute
|
||||||
'/new-post': typeof NewPostIndexRoute
|
'/new-post': typeof NewPostIndexRoute
|
||||||
'/columns/create-newsfeed': typeof ColumnsLayoutCreateNewsfeedRouteWithChildren
|
'/columns/create-newsfeed': typeof ColumnsLayoutCreateNewsfeedRouteWithChildren
|
||||||
'/columns/global': typeof ColumnsLayoutGlobalRoute
|
'/columns/global': typeof ColumnsLayoutGlobalRoute
|
||||||
'/settings/$id/general': typeof SettingsIdGeneralRoute
|
|
||||||
'/settings/$id/relay': typeof SettingsIdRelayRoute
|
|
||||||
'/settings/$id/wallet': typeof SettingsIdWalletRoute
|
|
||||||
'/columns/discover-interests': typeof ColumnsLayoutDiscoverInterestsLazyRoute
|
'/columns/discover-interests': typeof ColumnsLayoutDiscoverInterestsLazyRoute
|
||||||
'/columns/discover-newsfeeds': typeof ColumnsLayoutDiscoverNewsfeedsLazyRoute
|
'/columns/discover-newsfeeds': typeof ColumnsLayoutDiscoverNewsfeedsLazyRoute
|
||||||
'/columns/discover-relays': typeof ColumnsLayoutDiscoverRelaysLazyRoute
|
'/columns/discover-relays': typeof ColumnsLayoutDiscoverRelaysLazyRoute
|
||||||
@@ -781,22 +781,22 @@ export interface FileRoutesByFullPath {
|
|||||||
|
|
||||||
export interface FileRoutesByTo {
|
export interface FileRoutesByTo {
|
||||||
'/new': typeof NewLazyRoute
|
'/new': typeof NewLazyRoute
|
||||||
|
'/settings': typeof SettingsLazyRouteWithChildren
|
||||||
'/$id/set-group': typeof IdSetGroupRoute
|
'/$id/set-group': typeof IdSetGroupRoute
|
||||||
'/$id/set-interest': typeof IdSetInterestRoute
|
'/$id/set-interest': typeof IdSetInterestRoute
|
||||||
'/$id/set-profile': typeof IdSetProfileRoute
|
'/$id/set-profile': typeof IdSetProfileRoute
|
||||||
'/columns': typeof ColumnsLayoutRouteWithChildren
|
'/columns': typeof ColumnsLayoutRouteWithChildren
|
||||||
|
'/settings/general': typeof SettingsGeneralRoute
|
||||||
|
'/settings/relays': typeof SettingsRelaysRoute
|
||||||
|
'/settings/wallet': typeof SettingsWalletRoute
|
||||||
'/zap/$id': typeof ZapIdRoute
|
'/zap/$id': typeof ZapIdRoute
|
||||||
'/new-account/connect': typeof NewAccountConnectLazyRoute
|
'/new-account/connect': typeof NewAccountConnectLazyRoute
|
||||||
'/new-account/import': typeof NewAccountImportLazyRoute
|
'/new-account/import': typeof NewAccountImportLazyRoute
|
||||||
'/new-account/watch': typeof NewAccountWatchLazyRoute
|
'/new-account/watch': typeof NewAccountWatchLazyRoute
|
||||||
'/settings/$id': typeof SettingsIdLazyRouteWithChildren
|
|
||||||
'/': typeof AppIndexRoute
|
'/': typeof AppIndexRoute
|
||||||
'/new-post': typeof NewPostIndexRoute
|
'/new-post': typeof NewPostIndexRoute
|
||||||
'/columns/create-newsfeed': typeof ColumnsLayoutCreateNewsfeedRouteWithChildren
|
'/columns/create-newsfeed': typeof ColumnsLayoutCreateNewsfeedRouteWithChildren
|
||||||
'/columns/global': typeof ColumnsLayoutGlobalRoute
|
'/columns/global': typeof ColumnsLayoutGlobalRoute
|
||||||
'/settings/$id/general': typeof SettingsIdGeneralRoute
|
|
||||||
'/settings/$id/relay': typeof SettingsIdRelayRoute
|
|
||||||
'/settings/$id/wallet': typeof SettingsIdWalletRoute
|
|
||||||
'/columns/discover-interests': typeof ColumnsLayoutDiscoverInterestsLazyRoute
|
'/columns/discover-interests': typeof ColumnsLayoutDiscoverInterestsLazyRoute
|
||||||
'/columns/discover-newsfeeds': typeof ColumnsLayoutDiscoverNewsfeedsLazyRoute
|
'/columns/discover-newsfeeds': typeof ColumnsLayoutDiscoverNewsfeedsLazyRoute
|
||||||
'/columns/discover-relays': typeof ColumnsLayoutDiscoverRelaysLazyRoute
|
'/columns/discover-relays': typeof ColumnsLayoutDiscoverRelaysLazyRoute
|
||||||
@@ -821,23 +821,23 @@ export interface FileRoutesById {
|
|||||||
__root__: typeof rootRoute
|
__root__: typeof rootRoute
|
||||||
'/_app': typeof AppRouteWithChildren
|
'/_app': typeof AppRouteWithChildren
|
||||||
'/new': typeof NewLazyRoute
|
'/new': typeof NewLazyRoute
|
||||||
|
'/settings': typeof SettingsLazyRouteWithChildren
|
||||||
'/$id/set-group': typeof IdSetGroupRoute
|
'/$id/set-group': typeof IdSetGroupRoute
|
||||||
'/$id/set-interest': typeof IdSetInterestRoute
|
'/$id/set-interest': typeof IdSetInterestRoute
|
||||||
'/$id/set-profile': typeof IdSetProfileRoute
|
'/$id/set-profile': typeof IdSetProfileRoute
|
||||||
'/columns': typeof ColumnsRouteWithChildren
|
'/columns': typeof ColumnsRouteWithChildren
|
||||||
'/columns/_layout': typeof ColumnsLayoutRouteWithChildren
|
'/columns/_layout': typeof ColumnsLayoutRouteWithChildren
|
||||||
|
'/settings/general': typeof SettingsGeneralRoute
|
||||||
|
'/settings/relays': typeof SettingsRelaysRoute
|
||||||
|
'/settings/wallet': typeof SettingsWalletRoute
|
||||||
'/zap/$id': typeof ZapIdRoute
|
'/zap/$id': typeof ZapIdRoute
|
||||||
'/new-account/connect': typeof NewAccountConnectLazyRoute
|
'/new-account/connect': typeof NewAccountConnectLazyRoute
|
||||||
'/new-account/import': typeof NewAccountImportLazyRoute
|
'/new-account/import': typeof NewAccountImportLazyRoute
|
||||||
'/new-account/watch': typeof NewAccountWatchLazyRoute
|
'/new-account/watch': typeof NewAccountWatchLazyRoute
|
||||||
'/settings/$id': typeof SettingsIdLazyRouteWithChildren
|
|
||||||
'/_app/': typeof AppIndexRoute
|
'/_app/': typeof AppIndexRoute
|
||||||
'/new-post/': typeof NewPostIndexRoute
|
'/new-post/': typeof NewPostIndexRoute
|
||||||
'/columns/_layout/create-newsfeed': typeof ColumnsLayoutCreateNewsfeedRouteWithChildren
|
'/columns/_layout/create-newsfeed': typeof ColumnsLayoutCreateNewsfeedRouteWithChildren
|
||||||
'/columns/_layout/global': typeof ColumnsLayoutGlobalRoute
|
'/columns/_layout/global': typeof ColumnsLayoutGlobalRoute
|
||||||
'/settings/$id/general': typeof SettingsIdGeneralRoute
|
|
||||||
'/settings/$id/relay': typeof SettingsIdRelayRoute
|
|
||||||
'/settings/$id/wallet': typeof SettingsIdWalletRoute
|
|
||||||
'/columns/_layout/discover-interests': typeof ColumnsLayoutDiscoverInterestsLazyRoute
|
'/columns/_layout/discover-interests': typeof ColumnsLayoutDiscoverInterestsLazyRoute
|
||||||
'/columns/_layout/discover-newsfeeds': typeof ColumnsLayoutDiscoverNewsfeedsLazyRoute
|
'/columns/_layout/discover-newsfeeds': typeof ColumnsLayoutDiscoverNewsfeedsLazyRoute
|
||||||
'/columns/_layout/discover-relays': typeof ColumnsLayoutDiscoverRelaysLazyRoute
|
'/columns/_layout/discover-relays': typeof ColumnsLayoutDiscoverRelaysLazyRoute
|
||||||
@@ -863,22 +863,22 @@ export interface FileRouteTypes {
|
|||||||
fullPaths:
|
fullPaths:
|
||||||
| ''
|
| ''
|
||||||
| '/new'
|
| '/new'
|
||||||
|
| '/settings'
|
||||||
| '/$id/set-group'
|
| '/$id/set-group'
|
||||||
| '/$id/set-interest'
|
| '/$id/set-interest'
|
||||||
| '/$id/set-profile'
|
| '/$id/set-profile'
|
||||||
| '/columns'
|
| '/columns'
|
||||||
|
| '/settings/general'
|
||||||
|
| '/settings/relays'
|
||||||
|
| '/settings/wallet'
|
||||||
| '/zap/$id'
|
| '/zap/$id'
|
||||||
| '/new-account/connect'
|
| '/new-account/connect'
|
||||||
| '/new-account/import'
|
| '/new-account/import'
|
||||||
| '/new-account/watch'
|
| '/new-account/watch'
|
||||||
| '/settings/$id'
|
|
||||||
| '/'
|
| '/'
|
||||||
| '/new-post'
|
| '/new-post'
|
||||||
| '/columns/create-newsfeed'
|
| '/columns/create-newsfeed'
|
||||||
| '/columns/global'
|
| '/columns/global'
|
||||||
| '/settings/$id/general'
|
|
||||||
| '/settings/$id/relay'
|
|
||||||
| '/settings/$id/wallet'
|
|
||||||
| '/columns/discover-interests'
|
| '/columns/discover-interests'
|
||||||
| '/columns/discover-newsfeeds'
|
| '/columns/discover-newsfeeds'
|
||||||
| '/columns/discover-relays'
|
| '/columns/discover-relays'
|
||||||
@@ -900,22 +900,22 @@ export interface FileRouteTypes {
|
|||||||
fileRoutesByTo: FileRoutesByTo
|
fileRoutesByTo: FileRoutesByTo
|
||||||
to:
|
to:
|
||||||
| '/new'
|
| '/new'
|
||||||
|
| '/settings'
|
||||||
| '/$id/set-group'
|
| '/$id/set-group'
|
||||||
| '/$id/set-interest'
|
| '/$id/set-interest'
|
||||||
| '/$id/set-profile'
|
| '/$id/set-profile'
|
||||||
| '/columns'
|
| '/columns'
|
||||||
|
| '/settings/general'
|
||||||
|
| '/settings/relays'
|
||||||
|
| '/settings/wallet'
|
||||||
| '/zap/$id'
|
| '/zap/$id'
|
||||||
| '/new-account/connect'
|
| '/new-account/connect'
|
||||||
| '/new-account/import'
|
| '/new-account/import'
|
||||||
| '/new-account/watch'
|
| '/new-account/watch'
|
||||||
| '/settings/$id'
|
|
||||||
| '/'
|
| '/'
|
||||||
| '/new-post'
|
| '/new-post'
|
||||||
| '/columns/create-newsfeed'
|
| '/columns/create-newsfeed'
|
||||||
| '/columns/global'
|
| '/columns/global'
|
||||||
| '/settings/$id/general'
|
|
||||||
| '/settings/$id/relay'
|
|
||||||
| '/settings/$id/wallet'
|
|
||||||
| '/columns/discover-interests'
|
| '/columns/discover-interests'
|
||||||
| '/columns/discover-newsfeeds'
|
| '/columns/discover-newsfeeds'
|
||||||
| '/columns/discover-relays'
|
| '/columns/discover-relays'
|
||||||
@@ -938,23 +938,23 @@ export interface FileRouteTypes {
|
|||||||
| '__root__'
|
| '__root__'
|
||||||
| '/_app'
|
| '/_app'
|
||||||
| '/new'
|
| '/new'
|
||||||
|
| '/settings'
|
||||||
| '/$id/set-group'
|
| '/$id/set-group'
|
||||||
| '/$id/set-interest'
|
| '/$id/set-interest'
|
||||||
| '/$id/set-profile'
|
| '/$id/set-profile'
|
||||||
| '/columns'
|
| '/columns'
|
||||||
| '/columns/_layout'
|
| '/columns/_layout'
|
||||||
|
| '/settings/general'
|
||||||
|
| '/settings/relays'
|
||||||
|
| '/settings/wallet'
|
||||||
| '/zap/$id'
|
| '/zap/$id'
|
||||||
| '/new-account/connect'
|
| '/new-account/connect'
|
||||||
| '/new-account/import'
|
| '/new-account/import'
|
||||||
| '/new-account/watch'
|
| '/new-account/watch'
|
||||||
| '/settings/$id'
|
|
||||||
| '/_app/'
|
| '/_app/'
|
||||||
| '/new-post/'
|
| '/new-post/'
|
||||||
| '/columns/_layout/create-newsfeed'
|
| '/columns/_layout/create-newsfeed'
|
||||||
| '/columns/_layout/global'
|
| '/columns/_layout/global'
|
||||||
| '/settings/$id/general'
|
|
||||||
| '/settings/$id/relay'
|
|
||||||
| '/settings/$id/wallet'
|
|
||||||
| '/columns/_layout/discover-interests'
|
| '/columns/_layout/discover-interests'
|
||||||
| '/columns/_layout/discover-newsfeeds'
|
| '/columns/_layout/discover-newsfeeds'
|
||||||
| '/columns/_layout/discover-relays'
|
| '/columns/_layout/discover-relays'
|
||||||
@@ -979,6 +979,7 @@ export interface FileRouteTypes {
|
|||||||
export interface RootRouteChildren {
|
export interface RootRouteChildren {
|
||||||
AppRoute: typeof AppRouteWithChildren
|
AppRoute: typeof AppRouteWithChildren
|
||||||
NewLazyRoute: typeof NewLazyRoute
|
NewLazyRoute: typeof NewLazyRoute
|
||||||
|
SettingsLazyRoute: typeof SettingsLazyRouteWithChildren
|
||||||
IdSetGroupRoute: typeof IdSetGroupRoute
|
IdSetGroupRoute: typeof IdSetGroupRoute
|
||||||
IdSetInterestRoute: typeof IdSetInterestRoute
|
IdSetInterestRoute: typeof IdSetInterestRoute
|
||||||
IdSetProfileRoute: typeof IdSetProfileRoute
|
IdSetProfileRoute: typeof IdSetProfileRoute
|
||||||
@@ -987,13 +988,13 @@ export interface RootRouteChildren {
|
|||||||
NewAccountConnectLazyRoute: typeof NewAccountConnectLazyRoute
|
NewAccountConnectLazyRoute: typeof NewAccountConnectLazyRoute
|
||||||
NewAccountImportLazyRoute: typeof NewAccountImportLazyRoute
|
NewAccountImportLazyRoute: typeof NewAccountImportLazyRoute
|
||||||
NewAccountWatchLazyRoute: typeof NewAccountWatchLazyRoute
|
NewAccountWatchLazyRoute: typeof NewAccountWatchLazyRoute
|
||||||
SettingsIdLazyRoute: typeof SettingsIdLazyRouteWithChildren
|
|
||||||
NewPostIndexRoute: typeof NewPostIndexRoute
|
NewPostIndexRoute: typeof NewPostIndexRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
const rootRouteChildren: RootRouteChildren = {
|
const rootRouteChildren: RootRouteChildren = {
|
||||||
AppRoute: AppRouteWithChildren,
|
AppRoute: AppRouteWithChildren,
|
||||||
NewLazyRoute: NewLazyRoute,
|
NewLazyRoute: NewLazyRoute,
|
||||||
|
SettingsLazyRoute: SettingsLazyRouteWithChildren,
|
||||||
IdSetGroupRoute: IdSetGroupRoute,
|
IdSetGroupRoute: IdSetGroupRoute,
|
||||||
IdSetInterestRoute: IdSetInterestRoute,
|
IdSetInterestRoute: IdSetInterestRoute,
|
||||||
IdSetProfileRoute: IdSetProfileRoute,
|
IdSetProfileRoute: IdSetProfileRoute,
|
||||||
@@ -1002,7 +1003,6 @@ const rootRouteChildren: RootRouteChildren = {
|
|||||||
NewAccountConnectLazyRoute: NewAccountConnectLazyRoute,
|
NewAccountConnectLazyRoute: NewAccountConnectLazyRoute,
|
||||||
NewAccountImportLazyRoute: NewAccountImportLazyRoute,
|
NewAccountImportLazyRoute: NewAccountImportLazyRoute,
|
||||||
NewAccountWatchLazyRoute: NewAccountWatchLazyRoute,
|
NewAccountWatchLazyRoute: NewAccountWatchLazyRoute,
|
||||||
SettingsIdLazyRoute: SettingsIdLazyRouteWithChildren,
|
|
||||||
NewPostIndexRoute: NewPostIndexRoute,
|
NewPostIndexRoute: NewPostIndexRoute,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1020,6 +1020,7 @@ export const routeTree = rootRoute
|
|||||||
"children": [
|
"children": [
|
||||||
"/_app",
|
"/_app",
|
||||||
"/new",
|
"/new",
|
||||||
|
"/settings",
|
||||||
"/$id/set-group",
|
"/$id/set-group",
|
||||||
"/$id/set-interest",
|
"/$id/set-interest",
|
||||||
"/$id/set-profile",
|
"/$id/set-profile",
|
||||||
@@ -1028,7 +1029,6 @@ export const routeTree = rootRoute
|
|||||||
"/new-account/connect",
|
"/new-account/connect",
|
||||||
"/new-account/import",
|
"/new-account/import",
|
||||||
"/new-account/watch",
|
"/new-account/watch",
|
||||||
"/settings/$id",
|
|
||||||
"/new-post/"
|
"/new-post/"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -1041,6 +1041,14 @@ export const routeTree = rootRoute
|
|||||||
"/new": {
|
"/new": {
|
||||||
"filePath": "new.lazy.tsx"
|
"filePath": "new.lazy.tsx"
|
||||||
},
|
},
|
||||||
|
"/settings": {
|
||||||
|
"filePath": "settings.lazy.tsx",
|
||||||
|
"children": [
|
||||||
|
"/settings/general",
|
||||||
|
"/settings/relays",
|
||||||
|
"/settings/wallet"
|
||||||
|
]
|
||||||
|
},
|
||||||
"/$id/set-group": {
|
"/$id/set-group": {
|
||||||
"filePath": "$id.set-group.tsx"
|
"filePath": "$id.set-group.tsx"
|
||||||
},
|
},
|
||||||
@@ -1080,6 +1088,18 @@ export const routeTree = rootRoute
|
|||||||
"/columns/_layout/users/$id"
|
"/columns/_layout/users/$id"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"/settings/general": {
|
||||||
|
"filePath": "settings/general.tsx",
|
||||||
|
"parent": "/settings"
|
||||||
|
},
|
||||||
|
"/settings/relays": {
|
||||||
|
"filePath": "settings/relays.tsx",
|
||||||
|
"parent": "/settings"
|
||||||
|
},
|
||||||
|
"/settings/wallet": {
|
||||||
|
"filePath": "settings/wallet.tsx",
|
||||||
|
"parent": "/settings"
|
||||||
|
},
|
||||||
"/zap/$id": {
|
"/zap/$id": {
|
||||||
"filePath": "zap.$id.tsx"
|
"filePath": "zap.$id.tsx"
|
||||||
},
|
},
|
||||||
@@ -1092,14 +1112,6 @@ export const routeTree = rootRoute
|
|||||||
"/new-account/watch": {
|
"/new-account/watch": {
|
||||||
"filePath": "new-account/watch.lazy.tsx"
|
"filePath": "new-account/watch.lazy.tsx"
|
||||||
},
|
},
|
||||||
"/settings/$id": {
|
|
||||||
"filePath": "settings.$id.lazy.tsx",
|
|
||||||
"children": [
|
|
||||||
"/settings/$id/general",
|
|
||||||
"/settings/$id/relay",
|
|
||||||
"/settings/$id/wallet"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"/_app/": {
|
"/_app/": {
|
||||||
"filePath": "_app/index.tsx",
|
"filePath": "_app/index.tsx",
|
||||||
"parent": "/_app"
|
"parent": "/_app"
|
||||||
@@ -1119,18 +1131,6 @@ export const routeTree = rootRoute
|
|||||||
"filePath": "columns/_layout/global.tsx",
|
"filePath": "columns/_layout/global.tsx",
|
||||||
"parent": "/columns/_layout"
|
"parent": "/columns/_layout"
|
||||||
},
|
},
|
||||||
"/settings/$id/general": {
|
|
||||||
"filePath": "settings.$id/general.tsx",
|
|
||||||
"parent": "/settings/$id"
|
|
||||||
},
|
|
||||||
"/settings/$id/relay": {
|
|
||||||
"filePath": "settings.$id/relay.tsx",
|
|
||||||
"parent": "/settings/$id"
|
|
||||||
},
|
|
||||||
"/settings/$id/wallet": {
|
|
||||||
"filePath": "settings.$id/wallet.tsx",
|
|
||||||
"parent": "/settings/$id"
|
|
||||||
},
|
|
||||||
"/columns/_layout/discover-interests": {
|
"/columns/_layout/discover-interests": {
|
||||||
"filePath": "columns/_layout/discover-interests.lazy.tsx",
|
"filePath": "columns/_layout/discover-interests.lazy.tsx",
|
||||||
"parent": "/columns/_layout"
|
"parent": "/columns/_layout"
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ function Account({ pubkey }: { pubkey: string }) {
|
|||||||
PredefinedMenuItem.new({ item: "Separator" }),
|
PredefinedMenuItem.new({ item: "Separator" }),
|
||||||
MenuItem.new({
|
MenuItem.new({
|
||||||
text: "Settings",
|
text: "Settings",
|
||||||
action: () => LumeWindow.openSettings(pubkey),
|
action: () => LumeWindow.openSettings(),
|
||||||
}),
|
}),
|
||||||
PredefinedMenuItem.new({ item: "Separator" }),
|
PredefinedMenuItem.new({ item: "Separator" }),
|
||||||
MenuItem.new({
|
MenuItem.new({
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ function Screen() {
|
|||||||
initialPageParam: 0,
|
initialPageParam: 0,
|
||||||
queryFn: async ({ pageParam }: { pageParam: number }) => {
|
queryFn: async ({ pageParam }: { pageParam: number }) => {
|
||||||
const until = pageParam > 0 ? pageParam.toString() : null;
|
const until = pageParam > 0 ? pageParam.toString() : null;
|
||||||
const res = await commands.getAllRelays(until);
|
const res = await commands.getAllRelayLists(until);
|
||||||
|
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
const data: NostrEvent[] = res.data.map((item) => JSON.parse(item));
|
const data: NostrEvent[] = res.data.map((item) => JSON.parse(item));
|
||||||
|
|||||||
@@ -1,114 +0,0 @@
|
|||||||
import { cn } from "@/commons";
|
|
||||||
import { CurrencyBtc, GearSix, HardDrives, User } from "@phosphor-icons/react";
|
|
||||||
import * as ScrollArea from "@radix-ui/react-scroll-area";
|
|
||||||
import { Link } from "@tanstack/react-router";
|
|
||||||
import { Outlet, createLazyFileRoute } from "@tanstack/react-router";
|
|
||||||
|
|
||||||
export const Route = createLazyFileRoute("/settings/$id")({
|
|
||||||
component: Screen,
|
|
||||||
});
|
|
||||||
|
|
||||||
function Screen() {
|
|
||||||
const { id } = Route.useParams();
|
|
||||||
const { platform } = Route.useRouteContext();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="flex size-full">
|
|
||||||
<div
|
|
||||||
data-tauri-drag-region
|
|
||||||
className={cn(
|
|
||||||
"w-[200px] shrink-0 flex flex-col gap-1 border-r border-black/10 dark:border-white/10 p-2",
|
|
||||||
platform === "macos" ? "pt-11" : "",
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<div className="h-8 px-1.5">
|
|
||||||
<h1 className="text-lg font-semibold">Settings</h1>
|
|
||||||
</div>
|
|
||||||
<Link to="/settings/$id/general" params={{ id }}>
|
|
||||||
{({ isActive }) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
"h-9 w-full inline-flex items-center gap-1.5 rounded-lg p-2",
|
|
||||||
isActive
|
|
||||||
? "bg-black/10 hover:bg-black/20 dark:bg-white/10 text-neutral-900 dark:text-neutral-100 dark:hover:bg-bg-white/20"
|
|
||||||
: "text-neutral-700 hover:bg-black/10 dark:text-neutral-300 dark:hover:bg-white/10",
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<GearSix className="size-5 shrink-0" />
|
|
||||||
<p className="text-sm font-medium">General</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Link>
|
|
||||||
<Link to="/settings/$id/profile" params={{ id }}>
|
|
||||||
{({ isActive }) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
"h-9 w-full inline-flex items-center gap-1.5 rounded-lg p-2",
|
|
||||||
isActive
|
|
||||||
? "bg-black/10 hover:bg-black/20 dark:bg-white/10 text-neutral-900 dark:text-neutral-100 dark:hover:bg-bg-white/20"
|
|
||||||
: "text-neutral-700 hover:bg-black/10 dark:text-neutral-300 dark:hover:bg-white/10",
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<User className="size-5 shrink-0" />
|
|
||||||
<p className="text-sm font-medium">Profile</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Link>
|
|
||||||
<Link to="/settings/$id/relay" params={{ id }}>
|
|
||||||
{({ isActive }) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
"h-9 w-full inline-flex items-center gap-1.5 rounded-lg p-2",
|
|
||||||
isActive
|
|
||||||
? "bg-black/10 hover:bg-black/20 dark:bg-white/10 text-neutral-900 dark:text-neutral-100 dark:hover:bg-bg-white/20"
|
|
||||||
: "text-neutral-700 hover:bg-black/10 dark:text-neutral-300 dark:hover:bg-white/10",
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<HardDrives className="size-5 shrink-0" />
|
|
||||||
<p className="text-sm font-medium">Relay</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Link>
|
|
||||||
<Link to="/settings/$id/wallet" params={{ id }}>
|
|
||||||
{({ isActive }) => {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={cn(
|
|
||||||
"h-9 w-full inline-flex items-center gap-1.5 rounded-lg p-2",
|
|
||||||
isActive
|
|
||||||
? "bg-black/10 hover:bg-black/20 dark:bg-white/10 text-neutral-900 dark:text-neutral-100 dark:hover:bg-bg-white/20"
|
|
||||||
: "text-neutral-700 hover:bg-black/10 dark:text-neutral-300 dark:hover:bg-white/10",
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
<CurrencyBtc className="size-5 shrink-0" />
|
|
||||||
<p className="text-sm font-medium">Wallet</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
<ScrollArea.Root
|
|
||||||
type={"scroll"}
|
|
||||||
scrollHideDelay={300}
|
|
||||||
className="flex-1 overflow-hidden size-full"
|
|
||||||
>
|
|
||||||
<ScrollArea.Viewport className="relative h-full pt-12">
|
|
||||||
<Outlet />
|
|
||||||
</ScrollArea.Viewport>
|
|
||||||
<ScrollArea.Scrollbar
|
|
||||||
className="flex select-none touch-none p-0.5 duration-[160ms] ease-out data-[orientation=vertical]:w-2"
|
|
||||||
orientation="vertical"
|
|
||||||
>
|
|
||||||
<ScrollArea.Thumb className="flex-1 bg-black/10 dark:bg-white/10 rounded-full relative before:content-[''] before:absolute before:top-1/2 before:left-1/2 before:-translate-x-1/2 before:-translate-y-1/2 before:w-full before:h-full before:min-w-[44px] before:min-h-[44px]" />
|
|
||||||
</ScrollArea.Scrollbar>
|
|
||||||
<ScrollArea.Corner className="bg-transparent" />
|
|
||||||
</ScrollArea.Root>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
import { createFileRoute } from "@tanstack/react-router";
|
|
||||||
|
|
||||||
export const Route = createFileRoute("/settings/$id/general")();
|
|
||||||
@@ -1,156 +0,0 @@
|
|||||||
import { commands } from "@/commands.gen";
|
|
||||||
import { Plus, X } from "@phosphor-icons/react";
|
|
||||||
import { createLazyFileRoute } from "@tanstack/react-router";
|
|
||||||
import { message } from "@tauri-apps/plugin-dialog";
|
|
||||||
import { useEffect, useState, useTransition } from "react";
|
|
||||||
|
|
||||||
export const Route = createLazyFileRoute("/settings/$id/relay")({
|
|
||||||
component: Screen,
|
|
||||||
});
|
|
||||||
|
|
||||||
function Screen() {
|
|
||||||
const { relayList } = Route.useRouteContext();
|
|
||||||
|
|
||||||
const [relays, setRelays] = useState<string[]>([]);
|
|
||||||
const [newRelay, setNewRelay] = useState<string>("");
|
|
||||||
const [isPending, startTransition] = useTransition();
|
|
||||||
|
|
||||||
const removeRelay = async (relay: string) => {
|
|
||||||
const res = await commands.removeRelay(relay);
|
|
||||||
|
|
||||||
if (res.status === "ok") {
|
|
||||||
return res.data;
|
|
||||||
} else {
|
|
||||||
throw new Error(res.error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const addNewRelay = () => {
|
|
||||||
startTransition(async () => {
|
|
||||||
try {
|
|
||||||
let url = newRelay;
|
|
||||||
|
|
||||||
if (!url.startsWith("wss://")) {
|
|
||||||
url = `wss://${url}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const relay = new URL(url);
|
|
||||||
const res = await commands.connectRelay(relay.toString());
|
|
||||||
|
|
||||||
if (res.status === "ok") {
|
|
||||||
setRelays((prev) => [...prev, newRelay]);
|
|
||||||
setNewRelay("");
|
|
||||||
} else {
|
|
||||||
await message(res.error, { title: "Relay", kind: "error" });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
await message("URL is not valid.", { kind: "error" });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setRelays(relayList.connected);
|
|
||||||
}, [relayList]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="w-full px-3 pb-3">
|
|
||||||
<div className="flex flex-col gap-6">
|
|
||||||
<div className="flex flex-col gap-2">
|
|
||||||
<h2 className="text-sm font-semibold text-neutral-700 dark:text-neutral-300">
|
|
||||||
Connected Relays
|
|
||||||
</h2>
|
|
||||||
<div className="flex flex-col px-3 divide-y divide-black/10 dark:divide-white/10 bg-black/5 dark:bg-white/5 rounded-xl">
|
|
||||||
{relays.map((relay) => (
|
|
||||||
<div
|
|
||||||
key={relay}
|
|
||||||
className="flex items-center justify-between h-11"
|
|
||||||
>
|
|
||||||
<div className="inline-flex items-center gap-2 text-sm font-medium">
|
|
||||||
<span className="relative flex size-2">
|
|
||||||
<span className="absolute inline-flex w-full h-full bg-teal-400 rounded-full opacity-75 animate-ping" />
|
|
||||||
<span className="relative inline-flex bg-teal-500 rounded-full size-2" />
|
|
||||||
</span>
|
|
||||||
{relay}
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => removeRelay(relay)}
|
|
||||||
className="inline-flex items-center justify-center rounded-md size-7 hover:bg-black/10 dark:hover:bg-white/10"
|
|
||||||
>
|
|
||||||
<X className="size-4" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
<div className="flex items-center h-14">
|
|
||||||
<div className="flex items-center w-full gap-2 mb-0">
|
|
||||||
<input
|
|
||||||
value={newRelay}
|
|
||||||
onChange={(e) => setNewRelay(e.target.value)}
|
|
||||||
name="url"
|
|
||||||
placeholder="wss://..."
|
|
||||||
disabled={isPending}
|
|
||||||
spellCheck={false}
|
|
||||||
className="flex-1 px-3 bg-transparent rounded-lg h-9 border-neutral-300 placeholder:text-neutral-500 focus:border-blue-500 focus:ring-0 dark:border-neutral-700 dark:placeholder:text-neutral-400"
|
|
||||||
/>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
disabled={isPending}
|
|
||||||
onClick={() => addNewRelay()}
|
|
||||||
className="inline-flex items-center justify-center w-16 px-2 text-sm font-medium text-white rounded-lg shrink-0 h-9 bg-black/20 dark:bg-white/20 hover:bg-blue-500 disabled:opacity-50"
|
|
||||||
>
|
|
||||||
<Plus className="size-5" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col gap-2">
|
|
||||||
<h2 className="text-sm font-semibold text-neutral-700 dark:text-neutral-300">
|
|
||||||
User Relays (NIP-65)
|
|
||||||
</h2>
|
|
||||||
<div className="flex flex-col px-3 py-2 bg-black/5 dark:bg-white/5 rounded-xl">
|
|
||||||
<p className="text-sm text-yellow-500">
|
|
||||||
Lume will automatically connect to the user's relay list, but the
|
|
||||||
manager function (like adding, removing, changing relay purpose)
|
|
||||||
is not yet available.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col px-3 divide-y divide-black/10 dark:divide-white/10 bg-black/5 dark:bg-white/5 rounded-xl">
|
|
||||||
{relayList.read?.map((relay) => (
|
|
||||||
<div
|
|
||||||
key={relay}
|
|
||||||
className="flex items-center justify-between h-11"
|
|
||||||
>
|
|
||||||
<div className="text-sm font-medium">{relay}</div>
|
|
||||||
<div className="text-xs font-semibold">READ</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
{relayList.write?.map((relay) => (
|
|
||||||
<div
|
|
||||||
key={relay}
|
|
||||||
className="flex items-center justify-between h-11"
|
|
||||||
>
|
|
||||||
<div className="text-sm font-medium">{relay}</div>
|
|
||||||
<div className="text-xs font-semibold">WRITE</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
{relayList.both?.map((relay) => (
|
|
||||||
<div
|
|
||||||
key={relay}
|
|
||||||
className="flex items-center justify-between h-11"
|
|
||||||
>
|
|
||||||
<div className="text-sm font-medium">{relay}</div>
|
|
||||||
<div className="text-xs font-semibold">READ + WRITE</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
96
src/routes/settings.lazy.tsx
Normal file
96
src/routes/settings.lazy.tsx
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
import { cn } from '@/commons'
|
||||||
|
import { CurrencyBtc, GearSix, HardDrives } from '@phosphor-icons/react'
|
||||||
|
import * as ScrollArea from '@radix-ui/react-scroll-area'
|
||||||
|
import { Link } from '@tanstack/react-router'
|
||||||
|
import { Outlet, createLazyFileRoute } from '@tanstack/react-router'
|
||||||
|
|
||||||
|
export const Route = createLazyFileRoute('/settings')({
|
||||||
|
component: Screen,
|
||||||
|
})
|
||||||
|
|
||||||
|
function Screen() {
|
||||||
|
const { platform } = Route.useRouteContext()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex size-full">
|
||||||
|
<div
|
||||||
|
data-tauri-drag-region
|
||||||
|
className={cn(
|
||||||
|
'w-[200px] shrink-0 flex flex-col gap-1 border-r border-black/10 dark:border-white/10 p-2',
|
||||||
|
platform === 'macos' ? 'pt-11' : '',
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="h-8 px-1.5">
|
||||||
|
<h1 className="text-lg font-semibold">Settings</h1>
|
||||||
|
</div>
|
||||||
|
<Link to="/settings/general">
|
||||||
|
{({ isActive }) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
'h-9 w-full inline-flex items-center gap-1.5 rounded-lg p-2',
|
||||||
|
isActive
|
||||||
|
? 'bg-black/10 hover:bg-black/20 dark:bg-white/10 text-neutral-900 dark:text-neutral-100 dark:hover:bg-bg-white/20'
|
||||||
|
: 'text-neutral-700 hover:bg-black/10 dark:text-neutral-300 dark:hover:bg-white/10',
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<GearSix className="size-5 shrink-0" />
|
||||||
|
<p className="text-sm font-medium">General</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</Link>
|
||||||
|
<Link to="/settings/relays">
|
||||||
|
{({ isActive }) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
'h-9 w-full inline-flex items-center gap-1.5 rounded-lg p-2',
|
||||||
|
isActive
|
||||||
|
? 'bg-black/10 hover:bg-black/20 dark:bg-white/10 text-neutral-900 dark:text-neutral-100 dark:hover:bg-bg-white/20'
|
||||||
|
: 'text-neutral-700 hover:bg-black/10 dark:text-neutral-300 dark:hover:bg-white/10',
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<HardDrives className="size-5 shrink-0" />
|
||||||
|
<p className="text-sm font-medium">Relays</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</Link>
|
||||||
|
<Link to="/settings/wallet">
|
||||||
|
{({ isActive }) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
'h-9 w-full inline-flex items-center gap-1.5 rounded-lg p-2',
|
||||||
|
isActive
|
||||||
|
? 'bg-black/10 hover:bg-black/20 dark:bg-white/10 text-neutral-900 dark:text-neutral-100 dark:hover:bg-bg-white/20'
|
||||||
|
: 'text-neutral-700 hover:bg-black/10 dark:text-neutral-300 dark:hover:bg-white/10',
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<CurrencyBtc className="size-5 shrink-0" />
|
||||||
|
<p className="text-sm font-medium">Wallet</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
<ScrollArea.Root
|
||||||
|
type={'scroll'}
|
||||||
|
scrollHideDelay={300}
|
||||||
|
className="flex-1 overflow-hidden size-full"
|
||||||
|
>
|
||||||
|
<ScrollArea.Viewport className="relative h-full pt-12">
|
||||||
|
<Outlet />
|
||||||
|
</ScrollArea.Viewport>
|
||||||
|
<ScrollArea.Scrollbar
|
||||||
|
className="flex select-none touch-none p-0.5 duration-[160ms] ease-out data-[orientation=vertical]:w-2"
|
||||||
|
orientation="vertical"
|
||||||
|
>
|
||||||
|
<ScrollArea.Thumb className="flex-1 bg-black/10 dark:bg-white/10 rounded-full relative before:content-[''] before:absolute before:top-1/2 before:left-1/2 before:-translate-x-1/2 before:-translate-y-1/2 before:w-full before:h-full before:min-w-[44px] before:min-h-[44px]" />
|
||||||
|
</ScrollArea.Scrollbar>
|
||||||
|
<ScrollArea.Corner className="bg-transparent" />
|
||||||
|
</ScrollArea.Root>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ import { settingsQueryOptions } from "../__root";
|
|||||||
|
|
||||||
type Theme = "auto" | "light" | "dark";
|
type Theme = "auto" | "light" | "dark";
|
||||||
|
|
||||||
export const Route = createLazyFileRoute("/settings/$id/general")({
|
export const Route = createLazyFileRoute("/settings/general")({
|
||||||
component: Screen,
|
component: Screen,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -46,6 +46,7 @@ function Screen() {
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
await message(res.error, { kind: "error" });
|
await message(res.error, { kind: "error" });
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
3
src/routes/settings/general.tsx
Normal file
3
src/routes/settings/general.tsx
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import { createFileRoute } from "@tanstack/react-router";
|
||||||
|
|
||||||
|
export const Route = createFileRoute("/settings/general")();
|
||||||
107
src/routes/settings/relays.lazy.tsx
Normal file
107
src/routes/settings/relays.lazy.tsx
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
import { commands } from "@/commands.gen";
|
||||||
|
import { isValidRelayUrl } from "@/commons";
|
||||||
|
import { Plus, X } from "@phosphor-icons/react";
|
||||||
|
import { createLazyFileRoute } from "@tanstack/react-router";
|
||||||
|
import { message } from "@tauri-apps/plugin-dialog";
|
||||||
|
import { useEffect, useState, useTransition } from "react";
|
||||||
|
|
||||||
|
export const Route = createLazyFileRoute("/settings/relays")({
|
||||||
|
component: Screen,
|
||||||
|
});
|
||||||
|
|
||||||
|
function Screen() {
|
||||||
|
const { allRelays } = Route.useRouteContext();
|
||||||
|
|
||||||
|
const [relays, setRelays] = useState<string[]>([]);
|
||||||
|
const [newRelay, setNewRelay] = useState<string>("");
|
||||||
|
const [isPending, startTransition] = useTransition();
|
||||||
|
|
||||||
|
const removeRelay = async (relay: string) => {
|
||||||
|
const res = await commands.removeRelay(relay);
|
||||||
|
|
||||||
|
if (res.status === "ok") {
|
||||||
|
return res.data;
|
||||||
|
} else {
|
||||||
|
throw new Error(res.error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const addNewRelay = () => {
|
||||||
|
startTransition(async () => {
|
||||||
|
if (!isValidRelayUrl(newRelay)) {
|
||||||
|
await message("Relay URL is not valid", { kind: "error" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await commands.connectRelay(newRelay);
|
||||||
|
|
||||||
|
if (res.status === "ok") {
|
||||||
|
setRelays((prev) => [...prev, newRelay]);
|
||||||
|
setNewRelay("");
|
||||||
|
} else {
|
||||||
|
await message(res.error, { title: "Relay", kind: "error" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (allRelays) setRelays(allRelays);
|
||||||
|
}, [allRelays]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-full px-3 pb-3">
|
||||||
|
<div className="flex flex-col gap-6">
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<h2 className="text-sm font-semibold text-neutral-700 dark:text-neutral-300">
|
||||||
|
Connected Relays
|
||||||
|
</h2>
|
||||||
|
<div className="flex flex-col px-3 divide-y divide-black/10 dark:divide-white/10 bg-black/5 dark:bg-white/5 rounded-xl">
|
||||||
|
<div className="flex items-center h-14">
|
||||||
|
<div className="flex items-center w-full gap-2 mb-0">
|
||||||
|
<input
|
||||||
|
value={newRelay}
|
||||||
|
onChange={(e) => setNewRelay(e.target.value)}
|
||||||
|
name="url"
|
||||||
|
placeholder="wss://..."
|
||||||
|
disabled={isPending}
|
||||||
|
spellCheck={false}
|
||||||
|
className="flex-1 px-3 bg-transparent rounded-lg h-9 border-neutral-400/50 placeholder:text-neutral-500 focus:border-blue-500 focus:ring-0 dark:border-neutral-800/50 dark:placeholder:text-neutral-400"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
disabled={isPending}
|
||||||
|
onClick={() => addNewRelay()}
|
||||||
|
className="inline-flex items-center justify-center w-16 px-2 text-sm font-medium text-white rounded-lg shrink-0 h-9 bg-black/20 dark:bg-white/20 hover:bg-blue-500 disabled:opacity-50"
|
||||||
|
>
|
||||||
|
<Plus className="size-5" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{relays.map((relay) => (
|
||||||
|
<div
|
||||||
|
key={relay}
|
||||||
|
className="flex items-center justify-between h-11"
|
||||||
|
>
|
||||||
|
<div className="inline-flex items-center gap-2 text-sm font-medium truncate">
|
||||||
|
<span className="relative flex size-2">
|
||||||
|
<span className="absolute inline-flex w-full h-full bg-teal-400 rounded-full opacity-75 animate-ping" />
|
||||||
|
<span className="relative inline-flex bg-teal-500 rounded-full size-2" />
|
||||||
|
</span>
|
||||||
|
<span className="truncate">{relay}</span>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => removeRelay(relay)}
|
||||||
|
className="inline-flex items-center justify-center rounded-md size-7 text-neutral-500 hover:bg-black/5 dark:hover:bg-white/5"
|
||||||
|
>
|
||||||
|
<X className="size-4" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
import { commands } from "@/commands.gen";
|
import { commands } from "@/commands.gen";
|
||||||
import { createFileRoute } from "@tanstack/react-router";
|
import { createFileRoute } from "@tanstack/react-router";
|
||||||
|
|
||||||
export const Route = createFileRoute("/settings/$id/relay")({
|
export const Route = createFileRoute("/settings/relays")({
|
||||||
beforeLoad: async ({ params }) => {
|
beforeLoad: async () => {
|
||||||
const res = await commands.getRelays(params.id);
|
const res = await commands.getAllRelays();
|
||||||
|
|
||||||
if (res.status === "ok") {
|
if (res.status === "ok") {
|
||||||
return { relayList: res.data };
|
return { allRelays: res.data };
|
||||||
} else {
|
} else {
|
||||||
throw new Error(res.error);
|
throw new Error(res.error);
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ import { Button } from "@getalby/bitcoin-connect-react";
|
|||||||
import { createLazyFileRoute } from "@tanstack/react-router";
|
import { createLazyFileRoute } from "@tanstack/react-router";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
export const Route = createLazyFileRoute("/settings/$id/wallet")({
|
export const Route = createLazyFileRoute("/settings/wallet")({
|
||||||
component: Screen,
|
component: Screen,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { init } from "@getalby/bitcoin-connect-react";
|
import { init } from "@getalby/bitcoin-connect-react";
|
||||||
import { createFileRoute } from "@tanstack/react-router";
|
import { createFileRoute } from "@tanstack/react-router";
|
||||||
|
|
||||||
export const Route = createFileRoute("/settings/$id/wallet")({
|
export const Route = createFileRoute("/settings/wallet")({
|
||||||
beforeLoad: async () => {
|
beforeLoad: async () => {
|
||||||
init({
|
init({
|
||||||
appName: "Lume",
|
appName: "Lume",
|
||||||
@@ -121,7 +121,7 @@ export const LumeWindow = {
|
|||||||
throw new Error(query.error);
|
throw new Error(query.error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
openZap: async (id: string, account?: string) => {
|
openZap: async (id: string) => {
|
||||||
const wallet = await commands.loadWallet();
|
const wallet = await commands.loadWallet();
|
||||||
|
|
||||||
if (wallet.status === "ok") {
|
if (wallet.status === "ok") {
|
||||||
@@ -136,16 +136,14 @@ export const LumeWindow = {
|
|||||||
hidden_title: true,
|
hidden_title: true,
|
||||||
closable: true,
|
closable: true,
|
||||||
});
|
});
|
||||||
} else if (account) {
|
} else {
|
||||||
await LumeWindow.openSettings(account, "wallet");
|
await LumeWindow.openSettings("wallet");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
openSettings: async (account: string, path?: string) => {
|
openSettings: async (path?: string) => {
|
||||||
const query = await commands.openWindow({
|
const query = await commands.openWindow({
|
||||||
label: "settings",
|
label: "settings",
|
||||||
url: path
|
url: path ? `/settings/${path}` : "/settings/general",
|
||||||
? `/settings/${account}/${path}`
|
|
||||||
: `/settings/${account}/general`,
|
|
||||||
title: "Settings",
|
title: "Settings",
|
||||||
width: 700,
|
width: 700,
|
||||||
height: 500,
|
height: 500,
|
||||||
|
|||||||
Reference in New Issue
Block a user