From ed52105c02498630a15f95736f28676b9b60a8f9 Mon Sep 17 00:00:00 2001
From: reya
Date: Mon, 12 Feb 2024 20:04:45 +0700
Subject: [PATCH] wip: migrate to desktop2
---
apps/desktop2/package.json | 5 ++
apps/desktop2/src/app.tsx | 30 ++++---
apps/desktop2/src/routes/__root.tsx | 11 +++
apps/desktop2/src/routes/app.tsx | 20 +++++
apps/desktop2/src/routes/app/space.lazy.tsx | 13 +++
apps/desktop2/src/routes/index.tsx | 12 +--
apps/desktop2/src/tree.gen.ts | 21 +++++
packages/ark/src/ark.ts | 10 +--
packages/ark/src/components/user/cover.tsx | 9 +-
.../ark/src/components/user/followButton.tsx | 3 +
packages/ark/src/components/user/nip05.tsx | 2 +-
packages/ark/src/hooks/useRelayList.ts | 90 -------------------
packages/ui/package.json | 1 +
packages/ui/src/account/active.tsx | 16 ++--
packages/ui/src/navigation.tsx | 59 ++++--------
pnpm-lock.yaml | 35 +++++++-
src-tauri/src/main.rs | 10 ++-
src-tauri/tauri.conf.json | 2 +
18 files changed, 172 insertions(+), 177 deletions(-)
create mode 100644 apps/desktop2/src/routes/app.tsx
create mode 100644 apps/desktop2/src/routes/app/space.lazy.tsx
delete mode 100644 packages/ark/src/hooks/useRelayList.ts
diff --git a/apps/desktop2/package.json b/apps/desktop2/package.json
index 59d38dc0..b8147cb4 100644
--- a/apps/desktop2/package.json
+++ b/apps/desktop2/package.json
@@ -10,10 +10,15 @@
},
"dependencies": {
"@lume/ark": "workspace:^",
+ "@lume/icons": "workspace:^",
"@lume/storage": "workspace:^",
+ "@lume/ui": "workspace:^",
+ "@lume/utils": "workspace:^",
+ "@tanstack/react-query": "^5.18.1",
"@tanstack/react-router": "^1.16.0",
"i18next": "^23.8.2",
"i18next-resources-to-backend": "^1.2.0",
+ "jotai": "^2.6.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-i18next": "^14.0.2"
diff --git a/apps/desktop2/src/app.tsx b/apps/desktop2/src/app.tsx
index 50a735ae..a01c53d9 100644
--- a/apps/desktop2/src/app.tsx
+++ b/apps/desktop2/src/app.tsx
@@ -1,5 +1,6 @@
import { ArkProvider } from "@lume/ark";
import { StorageProvider } from "@lume/storage";
+import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { RouterProvider, createRouter } from "@tanstack/react-router";
import React, { StrictMode } from "react";
import ReactDOM from "react-dom/client";
@@ -10,30 +11,37 @@ import i18n from "./i18n";
// Import the generated route tree
import { routeTree } from "./tree.gen";
-// Create a new router instance
-const router = createRouter({ routeTree });
+const queryClient = new QueryClient();
+const router = createRouter({
+ routeTree,
+ context: {
+ queryClient,
+ },
+ defaultPreload: "intent",
+ defaultPreloadStaleTime: 0,
+});
-// Register the router instance for type safety
declare module "@tanstack/react-router" {
interface Register {
router: typeof router;
}
}
-// Render the app
// biome-ignore lint/style/noNonNullAssertion:
const rootElement = document.getElementById("root")!;
if (!rootElement.innerHTML) {
const root = ReactDOM.createRoot(rootElement);
root.render(
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
,
);
}
diff --git a/apps/desktop2/src/routes/__root.tsx b/apps/desktop2/src/routes/__root.tsx
index b88ac49e..680e8254 100644
--- a/apps/desktop2/src/routes/__root.tsx
+++ b/apps/desktop2/src/routes/__root.tsx
@@ -1,3 +1,4 @@
+import { LoaderIcon } from "@lume/icons";
import {
Outlet,
ScrollRestoration,
@@ -11,4 +12,14 @@ export const Route = createRootRoute({
>
),
+ pendingComponent: Pending,
+ wrapInSuspense: true,
});
+
+function Pending() {
+ return (
+
+
+
+ );
+}
diff --git a/apps/desktop2/src/routes/app.tsx b/apps/desktop2/src/routes/app.tsx
new file mode 100644
index 00000000..41e6c1c7
--- /dev/null
+++ b/apps/desktop2/src/routes/app.tsx
@@ -0,0 +1,20 @@
+import { Navigation } from "@lume/ui";
+import { Outlet, createFileRoute } from "@tanstack/react-router";
+
+export const Route = createFileRoute("/app")({
+ component: App,
+});
+
+function App() {
+ return (
+
+ );
+}
diff --git a/apps/desktop2/src/routes/app/space.lazy.tsx b/apps/desktop2/src/routes/app/space.lazy.tsx
new file mode 100644
index 00000000..a8a32bf2
--- /dev/null
+++ b/apps/desktop2/src/routes/app/space.lazy.tsx
@@ -0,0 +1,13 @@
+import { createLazyFileRoute } from "@tanstack/react-router";
+
+export const Route = createLazyFileRoute("/app/space")({
+ component: Space,
+});
+
+function Space() {
+ return (
+
+ );
+}
diff --git a/apps/desktop2/src/routes/index.tsx b/apps/desktop2/src/routes/index.tsx
index d3370bd6..1658326e 100644
--- a/apps/desktop2/src/routes/index.tsx
+++ b/apps/desktop2/src/routes/index.tsx
@@ -2,7 +2,6 @@ import { createFileRoute, redirect } from "@tanstack/react-router";
import { invoke } from "@tauri-apps/api/core";
export const Route = createFileRoute("/")({
- component: Index,
beforeLoad: async ({ location }) => {
const signer = await invoke("verify_signer");
if (!signer) {
@@ -13,13 +12,8 @@ export const Route = createFileRoute("/")({
},
});
}
+ throw redirect({
+ to: "/app/space",
+ });
},
});
-
-function Index() {
- return (
-
-
Welcome Home!
-
- );
-}
diff --git a/apps/desktop2/src/tree.gen.ts b/apps/desktop2/src/tree.gen.ts
index 4fa60d03..6d592000 100644
--- a/apps/desktop2/src/tree.gen.ts
+++ b/apps/desktop2/src/tree.gen.ts
@@ -13,6 +13,7 @@ import { createFileRoute } from '@tanstack/react-router'
// Import Routes
import { Route as rootRoute } from './routes/__root'
+import { Route as AppImport } from './routes/app'
import { Route as IndexImport } from './routes/index'
import { Route as LandingIndexImport } from './routes/landing/index'
@@ -20,9 +21,15 @@ import { Route as LandingIndexImport } from './routes/landing/index'
const AuthImportLazyImport = createFileRoute('/auth/import')()
const AuthCreateLazyImport = createFileRoute('/auth/create')()
+const AppSpaceLazyImport = createFileRoute('/app/space')()
// Create/Update Routes
+const AppRoute = AppImport.update({
+ path: '/app',
+ getParentRoute: () => rootRoute,
+} as any)
+
const IndexRoute = IndexImport.update({
path: '/',
getParentRoute: () => rootRoute,
@@ -43,6 +50,11 @@ const AuthCreateLazyRoute = AuthCreateLazyImport.update({
getParentRoute: () => rootRoute,
} as any).lazy(() => import('./routes/auth/create.lazy').then((d) => d.Route))
+const AppSpaceLazyRoute = AppSpaceLazyImport.update({
+ path: '/space',
+ getParentRoute: () => AppRoute,
+} as any).lazy(() => import('./routes/app/space.lazy').then((d) => d.Route))
+
// Populate the FileRoutesByPath interface
declare module '@tanstack/react-router' {
@@ -51,6 +63,14 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof IndexImport
parentRoute: typeof rootRoute
}
+ '/app': {
+ preLoaderRoute: typeof AppImport
+ parentRoute: typeof rootRoute
+ }
+ '/app/space': {
+ preLoaderRoute: typeof AppSpaceLazyImport
+ parentRoute: typeof AppImport
+ }
'/auth/create': {
preLoaderRoute: typeof AuthCreateLazyImport
parentRoute: typeof rootRoute
@@ -70,6 +90,7 @@ declare module '@tanstack/react-router' {
export const routeTree = rootRoute.addChildren([
IndexRoute,
+ AppRoute.addChildren([AppSpaceLazyRoute]),
AuthCreateLazyRoute,
AuthImportLazyRoute,
LandingIndexRoute,
diff --git a/packages/ark/src/ark.ts b/packages/ark/src/ark.ts
index 8ab44aa7..50b13001 100644
--- a/packages/ark/src/ark.ts
+++ b/packages/ark/src/ark.ts
@@ -54,7 +54,7 @@ export class Ark {
const event = JSON.parse(cmd) as Event;
return event;
} catch (e) {
- console.error(String(e));
+ return null;
}
}
@@ -66,7 +66,7 @@ export class Ark {
const cmd: Event[] = await invoke("get_text_events", { limit, until });
return cmd;
} catch (e) {
- console.error(String(e));
+ return [];
}
}
@@ -120,7 +120,7 @@ export class Ark {
const cmd: Event[] = await invoke("get_event_thread", { id });
return cmd;
} catch (e) {
- console.error(String(e));
+ return [];
}
}
@@ -165,8 +165,8 @@ export class Ark {
try {
const cmd: Metadata = await invoke("get_profile", { id });
return cmd;
- } catch (e) {
- console.error(String(e));
+ } catch {
+ return null;
}
}
diff --git a/packages/ark/src/components/user/cover.tsx b/packages/ark/src/components/user/cover.tsx
index f9e0ce0d..37199fc2 100644
--- a/packages/ark/src/components/user/cover.tsx
+++ b/packages/ark/src/components/user/cover.tsx
@@ -7,19 +7,14 @@ export function UserCover({ className }: { className?: string }) {
if (!user) {
return (
);
}
if (user && !user.profile.banner) {
return (
-
+
);
}
diff --git a/packages/ark/src/components/user/followButton.tsx b/packages/ark/src/components/user/followButton.tsx
index 2c5cfe68..082ac77b 100644
--- a/packages/ark/src/components/user/followButton.tsx
+++ b/packages/ark/src/components/user/followButton.tsx
@@ -2,11 +2,14 @@ import { LoaderIcon } from "@lume/icons";
import { cn } from "@lume/utils";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
+import { useArk } from "../../provider";
export function UserFollowButton({
target,
className,
}: { target: string; className?: string }) {
+ const ark = useArk();
+
const [t] = useTranslation();
const [loading, setLoading] = useState(false);
const [followed, setFollowed] = useState(false);
diff --git a/packages/ark/src/components/user/nip05.tsx b/packages/ark/src/components/user/nip05.tsx
index 924d9fb4..090a4eec 100644
--- a/packages/ark/src/components/user/nip05.tsx
+++ b/packages/ark/src/components/user/nip05.tsx
@@ -37,7 +37,7 @@ export function UserNip05({ className }: { className?: string }) {
: user?.profile.nip05}
{!isLoading && verified ? (
-
+
) : null}
);
diff --git a/packages/ark/src/hooks/useRelayList.ts b/packages/ark/src/hooks/useRelayList.ts
deleted file mode 100644
index 3ba660aa..00000000
--- a/packages/ark/src/hooks/useRelayList.ts
+++ /dev/null
@@ -1,90 +0,0 @@
-import { useMutation, useQueryClient } from "@tanstack/react-query";
-import { useArk } from "../provider";
-
-export function useRelaylist() {
- const ark = useArk();
- const queryClient = useQueryClient();
-
- const connectRelay = useMutation({
- mutationFn: async (
- relay: WebSocket["url"],
- purpose?: "read" | "write" | undefined,
- ) => {
- // Cancel any outgoing refetches
- await queryClient.cancelQueries({
- queryKey: ["relay-personal"],
- });
-
- const relayUrl = normalizeRelayUrl(relay);
-
- // Snapshot the previous value
- const prevRelays: NDKTag[] = queryClient.getQueryData(["relay-personal"]);
-
- // create new relay list if not exist
- if (!prevRelays) {
- await ark.createEvent({
- kind: NDKKind.RelayList,
- tags: [["r", relay, purpose ?? ""]],
- });
- }
-
- // add relay to exist list
- const index = prevRelays.findIndex((el) => el[1] === relay);
- if (index > -1) return;
-
- await ark.createEvent({
- kind: NDKKind.RelayList,
- tags: [...prevRelays, ["r", relayUrl, purpose ?? ""]],
- });
-
- // Optimistically update to the new value
- queryClient.setQueryData(["relay-personal"], (prev: NDKTag[]) => [
- ...prev,
- ["r", relayUrl, purpose ?? ""],
- ]);
-
- // Return a context object with the snapshotted value
- return { prevRelays };
- },
- onSettled: () => {
- queryClient.invalidateQueries({
- queryKey: ["relay-personal"],
- });
- },
- });
-
- const removeRelay = useMutation({
- mutationFn: async (relay: WebSocket["url"]) => {
- // Cancel any outgoing refetches
- await queryClient.cancelQueries({
- queryKey: ["relay-personal"],
- });
-
- // Snapshot the previous value
- const prevRelays: NDKTag[] = queryClient.getQueryData(["relay-personal"]);
-
- if (!prevRelays) return;
-
- const index = prevRelays.findIndex((el) => el[1] === relay);
- if (index > -1) prevRelays.splice(index, 1);
-
- await ark.createEvent({
- kind: NDKKind.RelayList,
- tags: prevRelays,
- });
-
- // Optimistically update to the new value
- queryClient.setQueryData(["relay-personal"], prevRelays);
-
- // Return a context object with the snapshotted value
- return { prevRelays };
- },
- onSettled: () => {
- queryClient.invalidateQueries({
- queryKey: ["relay-personal"],
- });
- },
- });
-
- return { connectRelay, removeRelay };
-}
diff --git a/packages/ui/package.json b/packages/ui/package.json
index 4ceee4af..a5f31295 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -18,6 +18,7 @@
"@radix-ui/react-hover-card": "^1.0.7",
"@radix-ui/react-popover": "^1.0.7",
"@tanstack/react-query": "^5.18.1",
+ "@tanstack/react-router": "^1.16.0",
"framer-motion": "^11.0.3",
"jotai": "^2.6.4",
"minidenticons": "^4.2.0",
diff --git a/packages/ui/src/account/active.tsx b/packages/ui/src/account/active.tsx
index 47aadc5f..e5cb60a2 100644
--- a/packages/ui/src/account/active.tsx
+++ b/packages/ui/src/account/active.tsx
@@ -15,13 +15,13 @@ export function ActiveAccount() {
const svgURI = useMemo(
() =>
`data:image/svg+xml;utf8,${encodeURIComponent(
- minidenticon(ark.account.pubkey, 90, 50),
+ minidenticon(ark.account.npub, 90, 50),
)}`,
[],
);
const { t } = useTranslation();
- const { user } = useProfile(ark.account.pubkey);
+ const { user } = useProfile(ark.account.npub);
return (
@@ -30,24 +30,24 @@ export function ActiveAccount() {
diff --git a/packages/ui/src/navigation.tsx b/packages/ui/src/navigation.tsx
index 5367ec80..4d6567ec 100644
--- a/packages/ui/src/navigation.tsx
+++ b/packages/ui/src/navigation.tsx
@@ -2,8 +2,6 @@ import {
ArrowUpSquareIcon,
BellFilledIcon,
BellIcon,
- DepotFilledIcon,
- DepotIcon,
HomeFilledIcon,
HomeIcon,
PlusIcon,
@@ -13,13 +11,13 @@ import {
SettingsIcon,
} from "@lume/icons";
import { cn, editorAtom, searchAtom } from "@lume/utils";
+import { Link } from "@tanstack/react-router";
import { confirm } from "@tauri-apps/plugin-dialog";
import { relaunch } from "@tauri-apps/plugin-process";
import { Update, check } from "@tauri-apps/plugin-updater";
import { useAtom } from "jotai";
import { useEffect, useState } from "react";
import { useHotkeys } from "react-hotkeys-hook";
-import { NavLink } from "react-router-dom";
import { ActiveAccount } from "./account/active";
import { UnreadActivity } from "./unread";
@@ -65,20 +63,19 @@ export function Navigation() {
type="button"
onClick={() => setIsEditorOpen((state) => !state)}
className={cn(
- "flex items-center justify-center h-auto w-full text-black aspect-square rounded-xl hover:text-white dark:text-white",
+ "flex items-center justify-center h-auto w-full aspect-square rounded-xl text-gray-normal",
isEditorOpen
- ? "bg-blue-500 text-white"
- : "bg-black/5 hover:bg-blue-500 dark:bg-white/5 dark:hover:bg-blue-500",
+ ? "bg-blue-solid text-white"
+ : "bg-gray-4 hover:bg-blue-solid dark:bg-graydark-4",
)}
>
-
+
-
{({ isActive }) => (
@@ -97,10 +94,9 @@ export function Navigation() {
)}
)}
-
-
+
{({ isActive }) => (
@@ -120,29 +116,7 @@ export function Navigation() {
)}
-
-
- {({ isActive }) => (
-
- {isActive ? (
-
- ) : (
-
- )}
-
- )}
-
+
@@ -152,10 +126,10 @@ export function Navigation() {
onClick={installNewUpdate}
className="relative inline-flex flex-col items-center justify-center"
>
-
+
Update
-
+
@@ -180,9 +154,8 @@ export function Navigation() {
)}
-
{({ isActive }) => (
@@ -201,7 +174,7 @@ export function Navigation() {
)}
)}
-
+
);
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index cbd8b2ac..f9300ee7 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -259,9 +259,21 @@ importers:
'@lume/ark':
specifier: workspace:^
version: link:../../packages/ark
+ '@lume/icons':
+ specifier: workspace:^
+ version: link:../../packages/icons
'@lume/storage':
specifier: workspace:^
version: link:../../packages/storage
+ '@lume/ui':
+ specifier: workspace:^
+ version: link:../../packages/ui
+ '@lume/utils':
+ specifier: workspace:^
+ version: link:../../packages/utils
+ '@tanstack/react-query':
+ specifier: ^5.18.1
+ version: 5.18.1(react@18.2.0)
'@tanstack/react-router':
specifier: ^1.16.0
version: 1.16.0(react-dom@18.2.0)(react@18.2.0)
@@ -271,6 +283,9 @@ importers:
i18next-resources-to-backend:
specifier: ^1.2.0
version: 1.2.0
+ jotai:
+ specifier: ^2.6.4
+ version: 2.6.4(@types/react@18.2.55)(react@18.2.0)
react:
specifier: ^18.2.0
version: 18.2.0
@@ -1157,6 +1172,9 @@ importers:
'@tanstack/react-query':
specifier: ^5.18.1
version: 5.18.1(react@18.2.0)
+ '@tanstack/react-router':
+ specifier: ^1.16.0
+ version: 1.16.0(react-dom@18.2.0)(react@18.2.0)
framer-motion:
specifier: ^11.0.3
version: 11.0.3(react-dom@18.2.0)(react@18.2.0)
@@ -3616,7 +3634,6 @@ packages:
'@types/prop-types': 15.7.11
'@types/scheduler': 0.16.8
csstype: 3.1.3
- dev: true
/@types/scheduler@0.16.8:
resolution: {integrity: sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==}
@@ -5099,6 +5116,22 @@ packages:
react: 18.2.0
dev: false
+ /jotai@2.6.4(@types/react@18.2.55)(react@18.2.0):
+ resolution: {integrity: sha512-RniwQPX4893YlNR1muOtyUGHYaTD1fhEN4qnOuZJSrDHj6xdEMrqlRSN/hCm2fshwk78ruecB/P2l+NCVWe6TQ==}
+ engines: {node: '>=12.20.0'}
+ peerDependencies:
+ '@types/react': '>=17.0.0'
+ react: '>=17.0.0'
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ react:
+ optional: true
+ dependencies:
+ '@types/react': 18.2.55
+ react: 18.2.0
+ dev: false
+
/js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index 9e109eb2..61f02eef 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -164,8 +164,14 @@ fn main() {
commands::folder::show_in_folder,
commands::opg::fetch_opg,
])
- .run(ctx)
- .expect("error while running tauri application");
+ .build(ctx)
+ .expect("error while running tauri application")
+ .run(|_app_handle, event| match event {
+ tauri::RunEvent::ExitRequested { api, .. } => {
+ api.prevent_exit();
+ }
+ _ => {}
+ });
}
fn get_nsec_paths(dir: &Path) -> Result, Box> {
diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json
index 29258ac0..cc8f307e 100644
--- a/src-tauri/tauri.conf.json
+++ b/src-tauri/tauri.conf.json
@@ -32,6 +32,8 @@
}
},
"trayIcon": {
+ "id": "lume-tray",
+ "tooltip": "Lume",
"iconPath": "icons/tray.png"
}
},