From 0518389f5010bab5e1550ccba442b8974cd359fc Mon Sep 17 00:00:00 2001 From: reya Date: Sun, 27 Oct 2024 15:57:32 +0700 Subject: [PATCH] update --- src-tauri/Cargo.lock | 4 +- src-tauri/Cargo.toml | 5 +- src-tauri/src/commands/metadata.rs | 31 ++- src-tauri/src/commands/window.rs | 39 ++-- src-tauri/src/main.rs | 82 ++++---- src/commands.gen.ts | 20 +- src/components/column.tsx | 67 ++---- src/routes.gen.ts | 102 ++++----- ...-group.lazy.tsx => $id.set-group.lazy.tsx} | 11 +- src/routes/$id.set-group.tsx | 14 ++ ...est.lazy.tsx => $id.set-interest.lazy.tsx} | 11 +- src/routes/$id.set-interest.tsx | 3 + src/routes/_app/index.lazy.tsx | 31 ++- .../columns/_layout/launchpad.$id.lazy.tsx | 197 ++++++++---------- src/routes/set-group.tsx | 23 -- src/routes/set-interest.tsx | 13 -- src/system/window.ts | 2 +- 17 files changed, 306 insertions(+), 349 deletions(-) rename src/routes/{set-group.lazy.tsx => $id.set-group.lazy.tsx} (96%) create mode 100644 src/routes/$id.set-group.tsx rename src/routes/{set-interest.lazy.tsx => $id.set-interest.lazy.tsx} (96%) create mode 100644 src/routes/$id.set-interest.tsx delete mode 100644 src/routes/set-group.tsx delete mode 100644 src/routes/set-interest.tsx diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 954a1767..e32c17b5 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -3081,7 +3081,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -7223,7 +7223,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 1f68de35..0afe083f 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -11,11 +11,10 @@ rust-version = "1.70" tauri-build = { version = "2.0.0", features = [] } [dependencies] -tauri = { version = "2.0.0", features = [ +tauri = { version = "2.0.0", features = [ "protocol-asset", "unstable", "tray-icon", - "macos-private-api", - "protocol-asset", + "macos-private-api" ] } tauri-plugin-window-state = "2.0.0" tauri-plugin-clipboard-manager = "2.0.0" diff --git a/src-tauri/src/commands/metadata.rs b/src-tauri/src/commands/metadata.rs index 3ad752b9..3ce5773f 100644 --- a/src-tauri/src/commands/metadata.rs +++ b/src-tauri/src/commands/metadata.rs @@ -281,18 +281,33 @@ pub async fn get_group(id: String, state: State<'_, Nostr>) -> Result) -> Result, String> { +pub async fn get_all_newsfeeds( + id: String, + state: State<'_, Nostr>, +) -> Result, String> { let client = &state.client; let public_key = PublicKey::parse(&id).map_err(|e| e.to_string())?; - let filter = Filter::new().kind(Kind::FollowSet).author(public_key); - match client - .fetch_events(vec![filter], Some(Duration::from_secs(3))) + let groups = Filter::new().kind(Kind::FollowSet).author(public_key); + let contacts = Filter::new() + .kind(Kind::ContactList) + .author(public_key) + .limit(1); + + let remote_events = client + .fetch_events(vec![groups], Some(Duration::from_secs(3))) .await - { - Ok(events) => Ok(process_event(client, events, false).await), - Err(e) => Err(e.to_string()), - } + .map_err(|e| e.to_string())?; + + let contact_events = client + .fetch_events(vec![contacts], Some(Duration::from_secs(3))) + .await + .map_err(|e| e.to_string())?; + + let events = remote_events.merge(contact_events); + let alt_events = process_event(client, events, false).await; + + Ok(alt_events) } #[tauri::command] diff --git a/src-tauri/src/commands/window.rs b/src-tauri/src/commands/window.rs index 6dbd5d1f..dd15b40d 100644 --- a/src-tauri/src/commands/window.rs +++ b/src-tauri/src/commands/window.rs @@ -47,7 +47,17 @@ pub async fn create_column( main_window: Window, ) -> Result { match app_handle.get_webview(&column.label) { - Some(_) => Ok(column.label), + Some(webview) => { + if let Err(e) = webview.set_size(LogicalSize::new(column.width, column.height)) { + return Err(e.to_string()); + } + + if let Err(e) = webview.set_position(LogicalPosition::new(column.x, column.y)) { + return Err(e.to_string()); + } + + Ok(column.label) + } None => { let path = PathBuf::from(column.url); let webview_url = WebviewUrl::App(path); @@ -145,28 +155,15 @@ pub async fn close_column(label: String, app_handle: tauri::AppHandle) -> Result #[tauri::command] #[specta::specta] -pub async fn update_column( - label: String, - width: f32, - height: f32, - x: f32, - y: f32, - app_handle: tauri::AppHandle, -) -> Result<(), String> { - match app_handle.get_webview(&label) { - Some(webview) => { - if let Err(e) = webview.set_size(LogicalSize::new(width, height)) { - return Err(e.to_string()); - } +pub async fn close_all_columns(app_handle: tauri::AppHandle) -> Result<(), String> { + let mut webviews = app_handle.webviews(); + webviews.remove("main"); - if let Err(e) = webview.set_position(LogicalPosition::new(x, y)) { - return Err(e.to_string()); - } - - Ok(()) - } - None => Err("Cannot update, column not found.".into()), + for webview in webviews.values() { + webview.close().unwrap() } + + Ok(()) } #[tauri::command] diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 35c85067..f8ccb2e0 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -97,7 +97,7 @@ fn main() { get_all_profiles, set_group, get_group, - get_all_groups, + get_all_newsfeeds, set_interest, get_interest, get_all_interests, @@ -129,9 +129,9 @@ fn main() { event_to_bech32, user_to_bech32, create_column, - update_column, reload_column, close_column, + close_all_columns, open_window, ]); @@ -288,48 +288,46 @@ fn main() { let _ = client .handle_notifications(|notification| async { - #[allow(clippy::collapsible_match)] - if let RelayPoolNotification::Message { message, .. } = notification { - if let RelayMessage::Event { - event, - subscription_id, - } = message - { - // Handle events from notification subscription - if subscription_id == notification_id { - // Send native notification - if allow_notification { - let author = client - .database() - .profile(event.pubkey) - .await - .unwrap_or_else(|_| { - DatabaseProfile::new(event.pubkey, Metadata::new()) - }); + if let RelayPoolNotification::Event { + event, + subscription_id, + .. + } = notification + { + // Handle events from notification subscription + if subscription_id == notification_id { + // Send native notification + if allow_notification { + let author = client + .database() + .profile(event.pubkey) + .await + .unwrap_or_else(|_| { + DatabaseProfile::new(event.pubkey, Metadata::new()) + }); - send_event_notification( - &event, - author.metadata(), - &handle_clone, - ); - } - } else if event.kind != Kind::RelayList { - let payload = RichEvent { - raw: event.as_json(), - parsed: if event.kind == Kind::TextNote { - Some(parse_event(&event.content).await) - } else { - None - }, - }; + send_event_notification( + &event, + author.metadata(), + &handle_clone, + ); + } + } else if event.kind != Kind::RelayList { + let payload = RichEvent { + raw: event.as_json(), + parsed: if event.kind == Kind::TextNote { + Some(parse_event(&event.content).await) + } else { + None + }, + }; - if let Err(e) = handle_clone.emit_to( - EventTarget::labeled(subscription_id.to_string()), - "event", - payload, - ) { - println!("Emitter error: {}", e) - } + if let Err(e) = handle_clone.emit_to( + EventTarget::labeled(subscription_id.to_string()), + "event", + payload, + ) { + println!("Emitter error: {}", e) } } } diff --git a/src/commands.gen.ts b/src/commands.gen.ts index 5c8d26ce..5da3edda 100644 --- a/src/commands.gen.ts +++ b/src/commands.gen.ts @@ -200,9 +200,9 @@ async getGroup(id: string) : Promise> { else return { status: "error", error: e as any }; } }, -async getAllGroups(id: string) : Promise> { +async getAllNewsfeeds(id: string) : Promise> { try { - return { status: "ok", data: await TAURI_INVOKE("get_all_groups", { id }) }; + return { status: "ok", data: await TAURI_INVOKE("get_all_newsfeeds", { id }) }; } catch (e) { if(e instanceof Error) throw e; else return { status: "error", error: e as any }; @@ -456,14 +456,6 @@ async createColumn(column: Column) : Promise> { else return { status: "error", error: e as any }; } }, -async updateColumn(label: string, width: number, height: number, x: number, y: number) : Promise> { - try { - return { status: "ok", data: await TAURI_INVOKE("update_column", { label, width, height, x, y }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, async reloadColumn(label: string) : Promise> { try { return { status: "ok", data: await TAURI_INVOKE("reload_column", { label }) }; @@ -480,6 +472,14 @@ async closeColumn(label: string) : Promise> { else return { status: "error", error: e as any }; } }, +async closeAllColumns() : Promise> { + try { + return { status: "ok", data: await TAURI_INVOKE("close_all_columns") }; +} catch (e) { + if(e instanceof Error) throw e; + else return { status: "error", error: e as any }; +} +}, async openWindow(window: NewWindow) : Promise> { try { return { status: "ok", data: await TAURI_INVOKE("open_window", { window }) }; diff --git a/src/components/column.tsx b/src/components/column.tsx index bd6a77d6..0b353ab3 100644 --- a/src/components/column.tsx +++ b/src/components/column.tsx @@ -4,67 +4,32 @@ import type { LumeColumn } from "@/types"; import { CaretDown, Check } from "@phosphor-icons/react"; import { Menu, MenuItem, PredefinedMenuItem } from "@tauri-apps/api/menu"; import { getCurrentWindow } from "@tauri-apps/api/window"; -import { useCallback, useEffect, useLayoutEffect, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import { User } from "./user"; export function Column({ column }: { column: LumeColumn }) { const [rect, ref] = useRect(); - const [_error, setError] = useState(""); + const [error, setError] = useState(""); useEffect(() => { (async () => { if (rect) { - const res = await commands.updateColumn( - column.label, - rect.width, - rect.height, - rect.x, - rect.y, - ); + const res = await commands.createColumn({ + label: column.label, + x: rect.x, + y: rect.y, + width: rect.width, + height: rect.height, + url: `${column.url}?label=${column.label}&name=${column.name}`, + }); - if (res.status === "ok") { - console.log("webview is updated: ", column.label); - } else { - console.log("webview error: ", res.error); + if (res.status === "error") { + setError(res.error); } } })(); }, [rect]); - useLayoutEffect(() => { - console.log(column.label); - if (ref.current) { - const initialRect = ref.current.getBoundingClientRect(); - - commands - .createColumn({ - label: column.label, - x: initialRect.x, - y: initialRect.y, - width: initialRect.width, - height: initialRect.height, - url: `${column.url}?label=${column.label}&name=${column.name}`, - }) - .then((res) => { - if (res.status === "ok") { - console.log("webview is created: ", column.label); - } else { - setError(res.error); - } - }); - - return () => { - commands.closeColumn(column.label).then((res) => { - if (res.status === "ok") { - console.log("webview is closed: ", column.label); - } else { - console.log("webview error: ", res.error); - } - }); - }; - } - }, []); - return (
@@ -73,7 +38,13 @@ export function Column({ column }: { column: LumeColumn }) { name={column.name} account={column.account} /> -
+
+
+
+ {error?.length ? error : null} +
+
+
); diff --git a/src/routes.gen.ts b/src/routes.gen.ts index 17e5e314..680fa697 100644 --- a/src/routes.gen.ts +++ b/src/routes.gen.ts @@ -13,14 +13,14 @@ import { createFileRoute } from '@tanstack/react-router' // Import Routes import { Route as rootRoute } from './routes/__root' -import { Route as SetInterestImport } from './routes/set-interest' -import { Route as SetGroupImport } from './routes/set-group' import { Route as BootstrapRelaysImport } from './routes/bootstrap-relays' import { Route as AppImport } from './routes/_app' import { Route as NewPostIndexImport } from './routes/new-post/index' import { Route as AppIndexImport } from './routes/_app/index' import { Route as ZapIdImport } from './routes/zap.$id' import { Route as ColumnsLayoutImport } from './routes/columns/_layout' +import { Route as IdSetInterestImport } from './routes/$id.set-interest' +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 SettingsIdProfileImport } from './routes/settings.$id/profile' @@ -79,16 +79,6 @@ const NewLazyRoute = NewLazyImport.update({ getParentRoute: () => rootRoute, } as any).lazy(() => import('./routes/new.lazy').then((d) => d.Route)) -const SetInterestRoute = SetInterestImport.update({ - path: '/set-interest', - getParentRoute: () => rootRoute, -} as any).lazy(() => import('./routes/set-interest.lazy').then((d) => d.Route)) - -const SetGroupRoute = SetGroupImport.update({ - path: '/set-group', - getParentRoute: () => rootRoute, -} as any).lazy(() => import('./routes/set-group.lazy').then((d) => d.Route)) - const BootstrapRelaysRoute = BootstrapRelaysImport.update({ path: '/bootstrap-relays', getParentRoute: () => rootRoute, @@ -149,6 +139,18 @@ const ColumnsLayoutRoute = ColumnsLayoutImport.update({ getParentRoute: () => ColumnsRoute, } as any) +const IdSetInterestRoute = IdSetInterestImport.update({ + path: '/$id/set-interest', + getParentRoute: () => rootRoute, +} as any).lazy(() => + import('./routes/$id.set-interest.lazy').then((d) => d.Route), +) + +const IdSetGroupRoute = IdSetGroupImport.update({ + path: '/$id/set-group', + getParentRoute: () => rootRoute, +} as any).lazy(() => import('./routes/$id.set-group.lazy').then((d) => d.Route)) + const ColumnsLayoutTrendingLazyRoute = ColumnsLayoutTrendingLazyImport.update({ path: '/trending', getParentRoute: () => ColumnsLayoutRoute, @@ -309,20 +311,6 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof BootstrapRelaysImport parentRoute: typeof rootRoute } - '/set-group': { - id: '/set-group' - path: '/set-group' - fullPath: '/set-group' - preLoaderRoute: typeof SetGroupImport - parentRoute: typeof rootRoute - } - '/set-interest': { - id: '/set-interest' - path: '/set-interest' - fullPath: '/set-interest' - preLoaderRoute: typeof SetInterestImport - parentRoute: typeof rootRoute - } '/new': { id: '/new' path: '/new' @@ -330,6 +318,20 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof NewLazyImport parentRoute: typeof rootRoute } + '/$id/set-group': { + id: '/$id/set-group' + path: '/$id/set-group' + fullPath: '/$id/set-group' + preLoaderRoute: typeof IdSetGroupImport + parentRoute: typeof rootRoute + } + '/$id/set-interest': { + id: '/$id/set-interest' + path: '/$id/set-interest' + fullPath: '/$id/set-interest' + preLoaderRoute: typeof IdSetInterestImport + parentRoute: typeof rootRoute + } '/columns': { id: '/columns' path: '/columns' @@ -636,9 +638,9 @@ const SettingsIdLazyRouteWithChildren = SettingsIdLazyRoute._addFileChildren( export interface FileRoutesByFullPath { '': typeof AppRouteWithChildren '/bootstrap-relays': typeof BootstrapRelaysRoute - '/set-group': typeof SetGroupRoute - '/set-interest': typeof SetInterestRoute '/new': typeof NewLazyRoute + '/$id/set-group': typeof IdSetGroupRoute + '/$id/set-interest': typeof IdSetInterestRoute '/columns': typeof ColumnsLayoutRouteWithChildren '/zap/$id': typeof ZapIdRoute '/new-account/connect': typeof NewAccountConnectLazyRoute @@ -671,9 +673,9 @@ export interface FileRoutesByFullPath { export interface FileRoutesByTo { '/bootstrap-relays': typeof BootstrapRelaysRoute - '/set-group': typeof SetGroupRoute - '/set-interest': typeof SetInterestRoute '/new': typeof NewLazyRoute + '/$id/set-group': typeof IdSetGroupRoute + '/$id/set-interest': typeof IdSetInterestRoute '/columns': typeof ColumnsLayoutRouteWithChildren '/zap/$id': typeof ZapIdRoute '/new-account/connect': typeof NewAccountConnectLazyRoute @@ -708,9 +710,9 @@ export interface FileRoutesById { __root__: typeof rootRoute '/_app': typeof AppRouteWithChildren '/bootstrap-relays': typeof BootstrapRelaysRoute - '/set-group': typeof SetGroupRoute - '/set-interest': typeof SetInterestRoute '/new': typeof NewLazyRoute + '/$id/set-group': typeof IdSetGroupRoute + '/$id/set-interest': typeof IdSetInterestRoute '/columns': typeof ColumnsRouteWithChildren '/columns/_layout': typeof ColumnsLayoutRouteWithChildren '/zap/$id': typeof ZapIdRoute @@ -747,9 +749,9 @@ export interface FileRouteTypes { fullPaths: | '' | '/bootstrap-relays' - | '/set-group' - | '/set-interest' | '/new' + | '/$id/set-group' + | '/$id/set-interest' | '/columns' | '/zap/$id' | '/new-account/connect' @@ -781,9 +783,9 @@ export interface FileRouteTypes { fileRoutesByTo: FileRoutesByTo to: | '/bootstrap-relays' - | '/set-group' - | '/set-interest' | '/new' + | '/$id/set-group' + | '/$id/set-interest' | '/columns' | '/zap/$id' | '/new-account/connect' @@ -816,9 +818,9 @@ export interface FileRouteTypes { | '__root__' | '/_app' | '/bootstrap-relays' - | '/set-group' - | '/set-interest' | '/new' + | '/$id/set-group' + | '/$id/set-interest' | '/columns' | '/columns/_layout' | '/zap/$id' @@ -854,9 +856,9 @@ export interface FileRouteTypes { export interface RootRouteChildren { AppRoute: typeof AppRouteWithChildren BootstrapRelaysRoute: typeof BootstrapRelaysRoute - SetGroupRoute: typeof SetGroupRoute - SetInterestRoute: typeof SetInterestRoute NewLazyRoute: typeof NewLazyRoute + IdSetGroupRoute: typeof IdSetGroupRoute + IdSetInterestRoute: typeof IdSetInterestRoute ColumnsRoute: typeof ColumnsRouteWithChildren ZapIdRoute: typeof ZapIdRoute NewAccountConnectLazyRoute: typeof NewAccountConnectLazyRoute @@ -869,9 +871,9 @@ export interface RootRouteChildren { const rootRouteChildren: RootRouteChildren = { AppRoute: AppRouteWithChildren, BootstrapRelaysRoute: BootstrapRelaysRoute, - SetGroupRoute: SetGroupRoute, - SetInterestRoute: SetInterestRoute, NewLazyRoute: NewLazyRoute, + IdSetGroupRoute: IdSetGroupRoute, + IdSetInterestRoute: IdSetInterestRoute, ColumnsRoute: ColumnsRouteWithChildren, ZapIdRoute: ZapIdRoute, NewAccountConnectLazyRoute: NewAccountConnectLazyRoute, @@ -895,9 +897,9 @@ export const routeTree = rootRoute "children": [ "/_app", "/bootstrap-relays", - "/set-group", - "/set-interest", "/new", + "/$id/set-group", + "/$id/set-interest", "/columns", "/zap/$id", "/new-account/connect", @@ -916,15 +918,15 @@ export const routeTree = rootRoute "/bootstrap-relays": { "filePath": "bootstrap-relays.tsx" }, - "/set-group": { - "filePath": "set-group.tsx" - }, - "/set-interest": { - "filePath": "set-interest.tsx" - }, "/new": { "filePath": "new.lazy.tsx" }, + "/$id/set-group": { + "filePath": "$id.set-group.tsx" + }, + "/$id/set-interest": { + "filePath": "$id.set-interest.tsx" + }, "/columns": { "filePath": "columns", "children": [ diff --git a/src/routes/set-group.lazy.tsx b/src/routes/$id.set-group.lazy.tsx similarity index 96% rename from src/routes/set-group.lazy.tsx rename to src/routes/$id.set-group.lazy.tsx index aec9c195..efc7c0f4 100644 --- a/src/routes/set-group.lazy.tsx +++ b/src/routes/$id.set-group.lazy.tsx @@ -8,13 +8,13 @@ import { getCurrentWindow } from "@tauri-apps/api/window"; import { message } from "@tauri-apps/plugin-dialog"; import { useState, useTransition } from "react"; -export const Route = createLazyFileRoute("/set-group")({ +export const Route = createLazyFileRoute("/$id/set-group")({ component: Screen, }); function Screen() { const contacts = Route.useLoaderData(); - const { account } = Route.useSearch(); + const { id } = Route.useParams(); const { queryClient } = Route.useRouteContext(); const [title, setTitle] = useState(""); @@ -40,11 +40,11 @@ function Screen() { const submit = () => { startTransition(async () => { - const signer = await commands.hasSigner(account); + const signer = await commands.hasSigner(id); if (signer.status === "ok") { if (!signer.data) { - const res = await commands.setSigner(account); + const res = await commands.setSigner(id); if (res.status === "error") { await message(res.error, { kind: "error" }); @@ -63,7 +63,7 @@ function Screen() { // Invalidate cache await queryClient.invalidateQueries({ - queryKey: ["mygroups", account], + queryKey: ["others", "newsfeeds", id], }); // Create column in the main window @@ -72,6 +72,7 @@ function Screen() { column: { label: res.data, name: title, + account: id, url: `/columns/groups/${res.data}`, }, }); diff --git a/src/routes/$id.set-group.tsx b/src/routes/$id.set-group.tsx new file mode 100644 index 00000000..9c534e58 --- /dev/null +++ b/src/routes/$id.set-group.tsx @@ -0,0 +1,14 @@ +import { commands } from "@/commands.gen"; +import { createFileRoute } from "@tanstack/react-router"; + +export const Route = createFileRoute("/$id/set-group")({ + loader: async ({ params }) => { + const res = await commands.getContactList(params.id); + + if (res.status === "ok") { + return res.data; + } else { + throw new Error(res.error); + } + }, +}); diff --git a/src/routes/set-interest.lazy.tsx b/src/routes/$id.set-interest.lazy.tsx similarity index 96% rename from src/routes/set-interest.lazy.tsx rename to src/routes/$id.set-interest.lazy.tsx index 36dbb3b2..ccf14619 100644 --- a/src/routes/set-interest.lazy.tsx +++ b/src/routes/$id.set-interest.lazy.tsx @@ -23,7 +23,7 @@ const TOPICS = [ }, ]; -export const Route = createLazyFileRoute("/set-interest")({ +export const Route = createLazyFileRoute("/$id/set-interest")({ component: Screen, }); @@ -33,7 +33,7 @@ function Screen() { const [hashtags, setHashtags] = useState([]); const [isPending, startTransition] = useTransition(); - const { account } = Route.useSearch(); + const { id } = Route.useParams(); const { queryClient } = Route.useRouteContext(); const toggleHashtag = (tag: string) => { @@ -52,11 +52,11 @@ function Screen() { const submit = () => { startTransition(async () => { - const signer = await commands.hasSigner(account); + const signer = await commands.hasSigner(id); if (signer.status === "ok") { if (!signer.data) { - const res = await commands.setSigner(account); + const res = await commands.setSigner(id); if (res.status === "error") { await message(res.error, { kind: "error" }); @@ -79,7 +79,7 @@ function Screen() { // Invalidate cache await queryClient.invalidateQueries({ - queryKey: ["myinterests", account], + queryKey: ["interests", id], }); // Create column in the main window @@ -88,6 +88,7 @@ function Screen() { column: { label: res.data, name: title, + account: id, url: `/columns/interests/${res.data}`, }, }); diff --git a/src/routes/$id.set-interest.tsx b/src/routes/$id.set-interest.tsx new file mode 100644 index 00000000..f02fcbc1 --- /dev/null +++ b/src/routes/$id.set-interest.tsx @@ -0,0 +1,3 @@ +import { createFileRoute } from "@tanstack/react-router"; + +export const Route = createFileRoute("/$id/set-interest")({}); diff --git a/src/routes/_app/index.lazy.tsx b/src/routes/_app/index.lazy.tsx index 4a667e81..442ea43d 100644 --- a/src/routes/_app/index.lazy.tsx +++ b/src/routes/_app/index.lazy.tsx @@ -4,11 +4,12 @@ import { Column, Spinner } from "@/components"; import { LumeWindow } from "@/system"; import type { ColumnEvent, LumeColumn, Metadata } from "@/types"; import { ArrowLeft, ArrowRight, Plus } from "@phosphor-icons/react"; -import { createLazyFileRoute } from "@tanstack/react-router"; +import { createLazyFileRoute, useRouter } from "@tanstack/react-router"; import { useStore } from "@tanstack/react-store"; import { listen } from "@tauri-apps/api/event"; import { Menu, MenuItem } from "@tauri-apps/api/menu"; import { getCurrentWindow } from "@tauri-apps/api/window"; +import { message } from "@tauri-apps/plugin-dialog"; import useEmblaCarousel from "embla-carousel-react"; import { type ReactNode, @@ -26,6 +27,7 @@ export const Route = createLazyFileRoute("/_app/")({ function Screen() { const initialAppColumns = Route.useLoaderData(); + const router = useRouter(); const columns = useStore(appColumns, (state) => state); const [emblaRef, emblaApi] = useEmblaCarousel({ @@ -45,6 +47,19 @@ function Screen() { getCurrentWindow().emit("scrolling", {}); }, []); + const remove = useCallback( + async (label: string) => { + const res = await commands.closeColumn(label); + + if (res.status === "ok") { + appColumns.setState((prev) => prev.filter((t) => t.label !== label)); + } else { + await message(res.error, { kind: "errror" }); + } + }, + [columns], + ); + const add = useDebouncedCallback((column: LumeColumn) => { const exist = columns.find((col) => col.label === column.label); @@ -57,10 +72,6 @@ function Screen() { } }, 150); - const remove = useDebouncedCallback((label: string) => { - appColumns.setState((prev) => prev.filter((t) => t.label !== label)); - }, 150); - const move = useDebouncedCallback( (label: string, direction: "left" | "right") => { const newCols = [...columns]; @@ -122,6 +133,16 @@ function Screen() { }; }, []); + useEffect(() => { + const unsubscribeFn = router.subscribe("onBeforeNavigate", async () => { + await commands.closeAllColumns(); + }); + + return () => { + unsubscribeFn(); + }; + }, []); + useEffect(() => { if (initialAppColumns) { appColumns.setState(() => initialAppColumns); diff --git a/src/routes/columns/_layout/launchpad.$id.lazy.tsx b/src/routes/columns/_layout/launchpad.$id.lazy.tsx index c1b03ffd..95aaa27f 100644 --- a/src/routes/columns/_layout/launchpad.$id.lazy.tsx +++ b/src/routes/columns/_layout/launchpad.$id.lazy.tsx @@ -3,7 +3,7 @@ import { cn, toLumeEvents } from "@/commons"; import { Spinner, User } from "@/components"; import { LumeWindow } from "@/system"; import type { LumeColumn, NostrEvent } from "@/types"; -import { ArrowClockwise, Plus } from "@phosphor-icons/react"; +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"; @@ -24,7 +24,7 @@ function Screen() { className="overflow-hidden size-full" > - + @@ -39,80 +39,12 @@ function Screen() { ); } -/* -function SyncProgress() { - const { id } = Route.useParams(); - const { queryClient } = Route.useRouteContext(); - - const [error, setError] = useState(""); - const [progress, setProgress] = useState(0); - - useEffect(() => { - (async () => { - if (progress >= 100) { - await queryClient.invalidateQueries(); - } - })(); - }, [progress]); - - useEffect(() => { - const channel = new Channel(); - - channel.onmessage = (message) => { - setProgress(message); - }; - - (async () => { - const res = await commands.syncAccount(id, channel); - - if (res.status === "error") { - setError(res.error); - } - })(); - }, []); - - return ( -
-
-
-
- - - - - {error ? error : "Syncing in Progress..."} - -
-
- - Learn more about Negentropy - -
-
- ); -} -*/ - -function Groups() { +function Newsfeeds() { const { id } = Route.useParams(); const { isLoading, isError, error, data, refetch, isRefetching } = useQuery({ - queryKey: ["others", "groups", id], + queryKey: ["others", "newsfeeds", id], queryFn: async () => { - const res = await commands.getAllGroups(id); + const res = await commands.getAllNewsfeeds(id); if (res.status === "ok") { const data = toLumeEvents(res.data); @@ -131,8 +63,14 @@ function Groups() { const renderItem = useCallback( (item: NostrEvent) => { const name = - item.tags.find((tag) => tag[0] === "title")?.[1] || "Unnamed"; - const label = item.tags.find((tag) => tag[0] === "d")?.[1] || nanoid(); + item.kind === 3 + ? "Contacts" + : item.tags.find((tag) => tag[0] === "title")?.[1] || "Unnamed"; + + const label = + item.kind === 3 + ? `newsfeed-${id.slice(0, 5)}` + : item.tags.find((tag) => tag[0] === "d")?.[1] || nanoid(); return (
-
- {item.tags - .filter((tag) => tag[0] === "p") - .map((tag) => ( -
- - - - - -
- ))} -
+ + +
+ {item.tags + .filter((tag) => tag[0] === "p") + .map((tag) => ( +
+ + + + + +
+ ))} +
+
+ + + + +
@@ -170,10 +123,14 @@ function Groups() { LumeWindow.openColumn({ label, name, - url: `/columns/groups/${item.id}`, + account: id, + url: + item.kind === 3 + ? `/columns/newsfeed/${id}` + : `/columns/groups/${item.id}`, }) } - className="h-6 w-16 inline-flex items-center justify-center gap-1 text-xs font-semibold rounded-full bg-blue-600 hover:bg-blue-500 text-white" + className="h-6 w-16 inline-flex items-center justify-center gap-1 text-xs font-semibold rounded-full bg-neutral-100 group-hover:bg-blue-600 dark:group-hover:bg-blue-400 group-hover:text-white" > Add @@ -188,7 +145,7 @@ function Groups() { return (
-

Groups

+

Newsfeeds

); @@ -266,15 +227,30 @@ function Interests() { className="group flex flex-col rounded-xl overflow-hidden bg-white dark:bg-neutral-800/50 shadow-lg shadow-primary dark:ring-1 dark:ring-neutral-800" >
-
- {item.tags - .filter((tag) => tag[0] === "t") - .map((tag) => ( -
- {tag[1]} -
- ))} -
+ + +
+ {item.tags + .filter((tag) => tag[0] === "t") + .map((tag) => ( +
+ {tag[1].includes("#") ? tag[1] : `#${tag[1]}`} +
+ ))} +
+
+ + + + +
@@ -292,10 +268,11 @@ function Interests() { LumeWindow.openColumn({ label, name, + account: id, url: `/columns/interests/${item.id}`, }) } - className="h-6 w-16 inline-flex items-center justify-center gap-1 text-xs font-semibold rounded-full bg-blue-600 hover:bg-blue-500 text-white" + className="h-6 w-16 inline-flex items-center justify-center gap-1 text-xs font-semibold rounded-full bg-neutral-100 group-hover:bg-blue-600 dark:group-hover:bg-blue-400 group-hover:text-white" > Add @@ -325,7 +302,7 @@ function Interests() {
); @@ -380,16 +361,6 @@ function Core() {
-
-
Newsfeed
- -
Stories