Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
921cf871ee | ||
|
|
d5b1593aca | ||
|
|
6676b4e2a4 | ||
|
|
5f30ddcfca | ||
|
|
41d0de539d | ||
|
|
e254ee3203 | ||
|
|
6d42360549 | ||
|
|
70c5143445 | ||
|
|
41b66b18f5 | ||
|
|
dda0720ed4 |
+16
-16
@@ -9,8 +9,8 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lume/system": "workspace:^",
|
|
||||||
"@lume/icons": "workspace:^",
|
"@lume/icons": "workspace:^",
|
||||||
|
"@lume/system": "workspace:^",
|
||||||
"@lume/ui": "workspace:^",
|
"@lume/ui": "workspace:^",
|
||||||
"@lume/utils": "workspace:^",
|
"@lume/utils": "workspace:^",
|
||||||
"@radix-ui/react-avatar": "^1.0.4",
|
"@radix-ui/react-avatar": "^1.0.4",
|
||||||
@@ -22,42 +22,42 @@
|
|||||||
"@radix-ui/react-popover": "^1.0.7",
|
"@radix-ui/react-popover": "^1.0.7",
|
||||||
"@radix-ui/react-switch": "^1.0.3",
|
"@radix-ui/react-switch": "^1.0.3",
|
||||||
"@radix-ui/react-tooltip": "^1.0.7",
|
"@radix-ui/react-tooltip": "^1.0.7",
|
||||||
"@tanstack/query-sync-storage-persister": "^5.36.0",
|
"@tanstack/query-sync-storage-persister": "^5.40.0",
|
||||||
"@tanstack/react-query": "^5.36.0",
|
"@tanstack/react-query": "^5.40.0",
|
||||||
"@tanstack/react-query-persist-client": "^5.36.0",
|
"@tanstack/react-query-persist-client": "^5.40.0",
|
||||||
"@tanstack/react-router": "1.32.5",
|
"@tanstack/react-router": "^1.34.5",
|
||||||
"i18next": "^23.11.4",
|
"i18next": "^23.11.5",
|
||||||
"i18next-resources-to-backend": "^1.2.1",
|
"i18next-resources-to-backend": "^1.2.1",
|
||||||
"minidenticons": "^4.2.1",
|
"minidenticons": "^4.2.1",
|
||||||
"nanoid": "^5.0.7",
|
"nanoid": "^5.0.7",
|
||||||
"nostr-tools": "^2.5.2",
|
"nostr-tools": "^2.6.0",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-currency-input-field": "^3.8.0",
|
"react-currency-input-field": "^3.8.0",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-hook-form": "^7.51.4",
|
"react-hook-form": "^7.51.5",
|
||||||
"react-hotkeys-hook": "^4.5.0",
|
"react-hotkeys-hook": "^4.5.0",
|
||||||
"react-i18next": "^14.1.1",
|
"react-i18next": "^14.1.2",
|
||||||
"react-string-replace": "^1.1.1",
|
"react-string-replace": "^1.1.1",
|
||||||
"slate": "^0.103.0",
|
"slate": "^0.103.0",
|
||||||
"slate-react": "^0.102.0",
|
"slate-react": "^0.104.0",
|
||||||
"sonner": "^1.4.41",
|
"sonner": "^1.4.41",
|
||||||
"use-debounce": "^10.0.0",
|
"use-debounce": "^10.0.1",
|
||||||
"virtua": "^0.31.0"
|
"virtua": "^0.31.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@lume/tailwindcss": "workspace:^",
|
"@lume/tailwindcss": "workspace:^",
|
||||||
"@lume/tsconfig": "workspace:^",
|
"@lume/tsconfig": "workspace:^",
|
||||||
"@lume/types": "workspace:^",
|
"@lume/types": "workspace:^",
|
||||||
"@tanstack/router-devtools": "^1.32.5",
|
"@tanstack/router-devtools": "^1.34.5",
|
||||||
"@tanstack/router-vite-plugin": "^1.32.2",
|
"@tanstack/router-vite-plugin": "^1.34.1",
|
||||||
"@types/react": "^18.3.2",
|
"@types/react": "^18.3.3",
|
||||||
"@types/react-dom": "^18.3.0",
|
"@types/react-dom": "^18.3.0",
|
||||||
"@vitejs/plugin-react-swc": "^3.6.0",
|
"@vitejs/plugin-react-swc": "^3.7.0",
|
||||||
"autoprefixer": "^10.4.19",
|
"autoprefixer": "^10.4.19",
|
||||||
"postcss": "^8.4.38",
|
"postcss": "^8.4.38",
|
||||||
"tailwindcss": "^3.4.3",
|
"tailwindcss": "^3.4.3",
|
||||||
"typescript": "^5.4.5",
|
"typescript": "^5.4.5",
|
||||||
"vite": "^5.2.11",
|
"vite": "^5.2.12",
|
||||||
"vite-plugin-top-level-await": "^1.4.1",
|
"vite-plugin-top-level-await": "^1.4.1",
|
||||||
"vite-tsconfig-paths": "^4.3.2"
|
"vite-tsconfig-paths": "^4.3.2"
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 171 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 201 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 170 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 104 KiB |
+1
-1
@@ -9,7 +9,7 @@ import { useState } from "react";
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
|
||||||
export const Route = createFileRoute("/auth/new/$account/backup")({
|
export const Route = createFileRoute("/auth/$account/backup")({
|
||||||
component: Screen,
|
component: Screen,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
import { LaurelIcon } from "@lume/icons";
|
import { LaurelIcon } from "@lume/icons";
|
||||||
import { NostrQuery } from "@lume/system";
|
import { NostrAccount, NostrQuery } from "@lume/system";
|
||||||
import { Spinner } from "@lume/ui";
|
import { Spinner } from "@lume/ui";
|
||||||
import * as Switch from "@radix-ui/react-switch";
|
import * as Switch from "@radix-ui/react-switch";
|
||||||
import { createFileRoute } from "@tanstack/react-router";
|
import { createFileRoute } from "@tanstack/react-router";
|
||||||
import { requestPermission } from "@tauri-apps/plugin-notification";
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
@@ -18,28 +17,14 @@ export const Route = createFileRoute("/auth/$account/settings")({
|
|||||||
});
|
});
|
||||||
|
|
||||||
function Screen() {
|
function Screen() {
|
||||||
const navigate = Route.useNavigate();
|
|
||||||
const { account } = Route.useParams();
|
|
||||||
const { settings } = Route.useRouteContext();
|
const { settings } = Route.useRouteContext();
|
||||||
|
const { account } = Route.useParams();
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const [newSettings, setNewSettings] = useState(settings);
|
const [newSettings, setNewSettings] = useState(settings);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
const toggleNofitication = async () => {
|
const navigate = Route.useNavigate();
|
||||||
await requestPermission();
|
|
||||||
setNewSettings((prev) => ({
|
|
||||||
...prev,
|
|
||||||
notification: !newSettings.notification,
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
const toggleAutoUpdate = () => {
|
|
||||||
setNewSettings((prev) => ({
|
|
||||||
...prev,
|
|
||||||
autoUpdate: !newSettings.autoUpdate,
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
const toggleEnhancedPrivacy = () => {
|
const toggleEnhancedPrivacy = () => {
|
||||||
setNewSettings((prev) => ({
|
setNewSettings((prev) => ({
|
||||||
@@ -69,11 +54,13 @@ function Screen() {
|
|||||||
|
|
||||||
// publish settings
|
// publish settings
|
||||||
const eventId = await NostrQuery.setSettings(newSettings);
|
const eventId = await NostrQuery.setSettings(newSettings);
|
||||||
|
const allAccounts = await NostrAccount.getAccounts();
|
||||||
|
|
||||||
if (eventId) {
|
if (eventId) {
|
||||||
return navigate({
|
return navigate({
|
||||||
to: "/$account/home",
|
to: "/$account/home",
|
||||||
params: { account },
|
params: { account },
|
||||||
|
search: { accounts: [...new Set([account, ...allAccounts])] },
|
||||||
replace: true,
|
replace: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -100,22 +87,6 @@ function Screen() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-5">
|
<div className="flex flex-col gap-5">
|
||||||
<div className="flex flex-col gap-3">
|
<div className="flex flex-col gap-3">
|
||||||
<div className="flex w-full items-start justify-between gap-4 rounded-lg bg-neutral-100 px-5 py-4 dark:bg-white/10">
|
|
||||||
<div className="flex-1">
|
|
||||||
<h3 className="font-semibold">Push Notification</h3>
|
|
||||||
<p className="text-sm text-neutral-700 dark:text-neutral-300">
|
|
||||||
Enabling push notifications will allow you to receive
|
|
||||||
notifications from Lume.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<Switch.Root
|
|
||||||
checked={newSettings.notification}
|
|
||||||
onClick={() => toggleNofitication()}
|
|
||||||
className="relative mt-1 h-7 w-12 shrink-0 cursor-default rounded-full bg-neutral-200 outline-none data-[state=checked]:bg-blue-500 dark:bg-white/20"
|
|
||||||
>
|
|
||||||
<Switch.Thumb className="block size-6 translate-x-0.5 rounded-full bg-white transition-transform duration-100 will-change-transform data-[state=checked]:translate-x-[19px]" />
|
|
||||||
</Switch.Root>
|
|
||||||
</div>
|
|
||||||
<div className="flex w-full items-start justify-between gap-4 rounded-lg bg-neutral-100 px-5 py-4 dark:bg-white/10">
|
<div className="flex w-full items-start justify-between gap-4 rounded-lg bg-neutral-100 px-5 py-4 dark:bg-white/10">
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<h3 className="font-semibold">Enhanced Privacy</h3>
|
<h3 className="font-semibold">Enhanced Privacy</h3>
|
||||||
@@ -132,21 +103,6 @@ function Screen() {
|
|||||||
<Switch.Thumb className="block size-6 translate-x-0.5 rounded-full bg-white transition-transform duration-100 will-change-transform data-[state=checked]:translate-x-[19px]" />
|
<Switch.Thumb className="block size-6 translate-x-0.5 rounded-full bg-white transition-transform duration-100 will-change-transform data-[state=checked]:translate-x-[19px]" />
|
||||||
</Switch.Root>
|
</Switch.Root>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex w-full items-start justify-between gap-4 rounded-lg bg-neutral-100 px-5 py-4 dark:bg-white/10">
|
|
||||||
<div className="flex-1">
|
|
||||||
<h3 className="font-semibold">Auto Update</h3>
|
|
||||||
<p className="text-sm text-neutral-700 dark:text-neutral-300">
|
|
||||||
Automatically download and install new version.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<Switch.Root
|
|
||||||
checked={newSettings.autoUpdate}
|
|
||||||
onClick={() => toggleAutoUpdate()}
|
|
||||||
className="relative mt-1 h-7 w-12 shrink-0 cursor-default rounded-full bg-neutral-200 outline-none data-[state=checked]:bg-blue-500 dark:bg-white/20"
|
|
||||||
>
|
|
||||||
<Switch.Thumb className="block size-6 translate-x-0.5 rounded-full bg-white transition-transform duration-100 will-change-transform data-[state=checked]:translate-x-[19px]" />
|
|
||||||
</Switch.Root>
|
|
||||||
</div>
|
|
||||||
<div className="flex w-full items-start justify-between gap-4 rounded-lg bg-neutral-100 px-5 py-4 dark:bg-white/10">
|
<div className="flex w-full items-start justify-between gap-4 rounded-lg bg-neutral-100 px-5 py-4 dark:bg-white/10">
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<h3 className="font-semibold">Zap</h3>
|
<h3 className="font-semibold">Zap</h3>
|
||||||
@@ -186,7 +142,7 @@ function Screen() {
|
|||||||
disabled={loading}
|
disabled={loading}
|
||||||
className="mb-1 inline-flex h-11 w-full shrink-0 items-center justify-center rounded-lg bg-blue-500 font-semibold text-white hover:bg-blue-600 disabled:opacity-50"
|
className="mb-1 inline-flex h-11 w-full shrink-0 items-center justify-center rounded-lg bg-blue-500 font-semibold text-white hover:bg-blue-600 disabled:opacity-50"
|
||||||
>
|
>
|
||||||
{t("global.continue")}
|
{loading ? <Spinner /> : t("global.continue")}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ function Screen() {
|
|||||||
|
|
||||||
if (eventId) {
|
if (eventId) {
|
||||||
navigate({
|
navigate({
|
||||||
to: "/auth/new/$account/backup",
|
to: "/auth/$account/backup",
|
||||||
params: { account: account.npub },
|
params: { account: account.npub },
|
||||||
replace: true,
|
replace: true,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ function Screen() {
|
|||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
const npub = await NostrAccount.connectRemoteAccount(uri);
|
const remoteAccount = await NostrAccount.connectRemoteAccount(uri);
|
||||||
|
|
||||||
if (npub) {
|
if (remoteAccount?.length) {
|
||||||
navigate({
|
return navigate({
|
||||||
to: "/auth/$account/settings",
|
to: "/auth/$account/settings",
|
||||||
params: { account: npub },
|
params: { account: remoteAccount },
|
||||||
replace: true,
|
replace: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ function Screen() {
|
|||||||
className="h-auto w-full aspect-square rounded-lg shadow-md transform"
|
className="h-auto w-full aspect-square rounded-lg shadow-md transform"
|
||||||
controls
|
controls
|
||||||
muted
|
muted
|
||||||
|
preload="none"
|
||||||
|
poster="/poster_1.jpeg"
|
||||||
>
|
>
|
||||||
<source
|
<source
|
||||||
src="https://video.nostr.build/692f71e2be47ecfc29edcbdaa198cc5979bfb9c900f05d78682895dd546d8d4f.mp4"
|
src="https://video.nostr.build/692f71e2be47ecfc29edcbdaa198cc5979bfb9c900f05d78682895dd546d8d4f.mp4"
|
||||||
@@ -55,6 +57,8 @@ function Screen() {
|
|||||||
className="h-auto w-full aspect-square rounded-lg shadow-md transform"
|
className="h-auto w-full aspect-square rounded-lg shadow-md transform"
|
||||||
controls
|
controls
|
||||||
muted
|
muted
|
||||||
|
preload="none"
|
||||||
|
poster="/poster_2.jpeg"
|
||||||
>
|
>
|
||||||
<source
|
<source
|
||||||
src="https://video.nostr.build/d33962520506d86acfb4b55a7b265821e10ae637f5ec830a173b7e6092b16ec8.mp4"
|
src="https://video.nostr.build/d33962520506d86acfb4b55a7b265821e10ae637f5ec830a173b7e6092b16ec8.mp4"
|
||||||
@@ -76,6 +80,8 @@ function Screen() {
|
|||||||
className="h-auto w-full aspect-square rounded-lg shadow-md transform"
|
className="h-auto w-full aspect-square rounded-lg shadow-md transform"
|
||||||
controls
|
controls
|
||||||
muted
|
muted
|
||||||
|
preload="none"
|
||||||
|
poster="/poster_3.jpeg"
|
||||||
>
|
>
|
||||||
<source
|
<source
|
||||||
src="https://video.nostr.build/927abbfde2097e470ac751181b1db456b7e4b9149550408efff1a966a7ffb9a8.mp4"
|
src="https://video.nostr.build/927abbfde2097e470ac751181b1db456b7e4b9149550408efff1a966a7ffb9a8.mp4"
|
||||||
@@ -97,6 +103,8 @@ function Screen() {
|
|||||||
className="h-auto w-full rounded-lg shadow-md transform"
|
className="h-auto w-full rounded-lg shadow-md transform"
|
||||||
controls
|
controls
|
||||||
muted
|
muted
|
||||||
|
preload="none"
|
||||||
|
poster="/poster_4.jpeg"
|
||||||
>
|
>
|
||||||
<source
|
<source
|
||||||
src="https://video.nostr.build/513de4824b6abaf7e9698c1dad2f68096574356848c0c200bc8cb8074df29410.mp4"
|
src="https://video.nostr.build/513de4824b6abaf7e9698c1dad2f68096574356848c0c200bc8cb8074df29410.mp4"
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
"@astrojs/check": "^0.5.10",
|
"@astrojs/check": "^0.5.10",
|
||||||
"@astrojs/tailwind": "^5.1.0",
|
"@astrojs/tailwind": "^5.1.0",
|
||||||
"@fontsource/alice": "^5.0.13",
|
"@fontsource/alice": "^5.0.13",
|
||||||
"astro": "^4.8.3",
|
"astro": "^4.9.2",
|
||||||
"astro-seo-meta": "^4.1.1",
|
"astro-seo-meta": "^4.1.1",
|
||||||
"astro-seo-schema": "^4.0.2",
|
"astro-seo-schema": "^4.0.2",
|
||||||
"schema-dts": "^1.1.2",
|
"schema-dts": "^1.1.2",
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@
|
|||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tauri-apps/api": "^2.0.0-beta.7",
|
"@tauri-apps/api": "2.0.0-beta.13",
|
||||||
"@tauri-apps/plugin-autostart": "2.0.0-beta.3",
|
"@tauri-apps/plugin-autostart": "2.0.0-beta.3",
|
||||||
"@tauri-apps/plugin-clipboard-manager": "2.1.0-beta.1",
|
"@tauri-apps/plugin-clipboard-manager": "2.1.0-beta.1",
|
||||||
"@tauri-apps/plugin-dialog": "2.0.0-beta.3",
|
"@tauri-apps/plugin-dialog": "2.0.0-beta.3",
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@lume/tsconfig": "workspace:*",
|
"@lume/tsconfig": "workspace:*",
|
||||||
"@types/react": "^18.3.2",
|
"@types/react": "^18.3.3",
|
||||||
"typescript": "^5.4.5"
|
"typescript": "^5.4.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,13 +5,13 @@
|
|||||||
"main": "./src/index.ts",
|
"main": "./src/index.ts",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@lume/utils": "workspace:^",
|
"@lume/utils": "workspace:^",
|
||||||
"@tanstack/react-query": "^5.36.0",
|
"@tanstack/react-query": "^5.40.0",
|
||||||
"react": "^18.3.1"
|
"react": "^18.3.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@lume/tsconfig": "workspace:^",
|
"@lume/tsconfig": "workspace:^",
|
||||||
"@lume/types": "workspace:^",
|
"@lume/types": "workspace:^",
|
||||||
"@types/react": "^18.3.2",
|
"@types/react": "^18.3.3",
|
||||||
"typescript": "^5.4.5"
|
"typescript": "^5.4.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Metadata } from "@lume/types";
|
import { Metadata } from "@lume/types";
|
||||||
import { commands } from "./commands";
|
import { Result, commands } from "./commands";
|
||||||
|
|
||||||
export class NostrAccount {
|
export class NostrAccount {
|
||||||
static async getAccounts() {
|
static async getAccounts() {
|
||||||
@@ -13,7 +13,14 @@ export class NostrAccount {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static async loadAccount(npub: string) {
|
static async loadAccount(npub: string) {
|
||||||
const query = await commands.loadAccount(npub);
|
const bunker: string = localStorage.getItem(`${npub}_bunker`);
|
||||||
|
let query: Result<boolean, string>;
|
||||||
|
|
||||||
|
if (bunker?.length && bunker?.startsWith("bunker://")) {
|
||||||
|
query = await commands.loadAccount(npub, bunker);
|
||||||
|
} else {
|
||||||
|
query = await commands.loadAccount(npub, null);
|
||||||
|
}
|
||||||
|
|
||||||
if (query.status === "ok") {
|
if (query.status === "ok") {
|
||||||
return query.data;
|
return query.data;
|
||||||
@@ -62,20 +69,20 @@ export class NostrAccount {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static async connectRemoteAccount(uri: string) {
|
static async connectRemoteAccount(uri: string) {
|
||||||
const remoteKey = uri.replace("bunker://", "").split("?")[0];
|
const connect = await commands.connectRemoteAccount(uri);
|
||||||
const npub = await commands.toNpub(remoteKey);
|
|
||||||
|
|
||||||
if (npub.status === "ok") {
|
|
||||||
const connect = await commands.nostrConnect(npub.data, uri);
|
|
||||||
|
|
||||||
if (connect.status === "ok") {
|
if (connect.status === "ok") {
|
||||||
return connect.data;
|
const npub = connect.data;
|
||||||
|
const parsed = new URL(uri);
|
||||||
|
parsed.searchParams.delete("secret");
|
||||||
|
|
||||||
|
// save connection string
|
||||||
|
localStorage.setItem(`${npub}_bunker`, parsed.toString());
|
||||||
|
|
||||||
|
return npub;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(connect.error);
|
throw new Error(connect.error);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
throw new Error(npub.error);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async setContactList(pubkeys: string[]) {
|
static async setContactList(pubkeys: string[]) {
|
||||||
|
|||||||
+62
-256
@@ -11,10 +11,7 @@ export const commands = {
|
|||||||
},
|
},
|
||||||
async connectRelay(relay: string) : Promise<Result<boolean, null>> {
|
async connectRelay(relay: string) : Promise<Result<boolean, null>> {
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("connect_relay", { relay }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("connect_relay", { relay }),
|
|
||||||
};
|
|
||||||
} 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 };
|
||||||
@@ -22,10 +19,7 @@ export const commands = {
|
|||||||
},
|
},
|
||||||
async removeRelay(relay: string) : Promise<Result<boolean, null>> {
|
async removeRelay(relay: string) : Promise<Result<boolean, null>> {
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("remove_relay", { relay }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("remove_relay", { relay }),
|
|
||||||
};
|
|
||||||
} 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 };
|
||||||
@@ -47,118 +41,65 @@ export const commands = {
|
|||||||
else return { status: "error", error: e as any };
|
else return { status: "error", error: e as any };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async saveAccount(
|
async saveAccount(nsec: string, password: string) : Promise<Result<string, string>> {
|
||||||
nsec: string,
|
|
||||||
password: string,
|
|
||||||
): Promise<Result<string, string>> {
|
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("save_account", { nsec, password }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("save_account", { nsec, password }),
|
|
||||||
};
|
|
||||||
} 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 getEncryptedKey(
|
async getEncryptedKey(npub: string, password: string) : Promise<Result<string, string>> {
|
||||||
npub: string,
|
|
||||||
password: string,
|
|
||||||
): Promise<Result<string, string>> {
|
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("get_encrypted_key", { npub, password }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("get_encrypted_key", { npub, password }),
|
|
||||||
};
|
|
||||||
} 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 nostrConnect(
|
async connectRemoteAccount(uri: string) : Promise<Result<string, string>> {
|
||||||
npub: string,
|
|
||||||
uri: string,
|
|
||||||
): Promise<Result<string, string>> {
|
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("connect_remote_account", { uri }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("nostr_connect", { npub, uri }),
|
|
||||||
};
|
|
||||||
} 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 loadAccount(npub: string): Promise<Result<boolean, string>> {
|
async loadAccount(npub: string, bunker: string | null) : Promise<Result<boolean, string>> {
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("load_account", { npub, bunker }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("load_account", { npub }),
|
|
||||||
};
|
|
||||||
} 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 eventToBech32(
|
async eventToBech32(id: string, relays: string[]) : Promise<Result<string, null>> {
|
||||||
id: string,
|
|
||||||
relays: string[],
|
|
||||||
): Promise<Result<string, null>> {
|
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("event_to_bech32", { id, relays }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("event_to_bech32", { id, 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 userToBech32(
|
async userToBech32(key: string, relays: string[]) : Promise<Result<string, null>> {
|
||||||
key: string,
|
|
||||||
relays: string[],
|
|
||||||
): Promise<Result<string, null>> {
|
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("user_to_bech32", { key, relays }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("user_to_bech32", { key, 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 toNpub(hex: string): Promise<Result<string, null>> {
|
async verifyNip05(key: string, nip05: string) : Promise<Result<boolean, string>> {
|
||||||
try {
|
try {
|
||||||
return { status: "ok", data: await TAURI_INVOKE("to_npub", { hex }) };
|
return { status: "ok", data: await TAURI_INVOKE("verify_nip05", { key, nip05 }) };
|
||||||
} 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 verifyNip05(
|
async getActivities(account: string, kind: string) : Promise<Result<string[], string>> {
|
||||||
key: string,
|
|
||||||
nip05: string,
|
|
||||||
): Promise<Result<boolean, string>> {
|
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("get_activities", { account, kind }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("verify_nip05", { key, nip05 }),
|
|
||||||
};
|
|
||||||
} catch (e) {
|
|
||||||
if (e instanceof Error) throw e;
|
|
||||||
else return { status: "error", error: e as any };
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async getActivities(
|
|
||||||
account: string,
|
|
||||||
kind: string,
|
|
||||||
): Promise<Result<string[], string>> {
|
|
||||||
try {
|
|
||||||
return {
|
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("get_activities", { account, kind }),
|
|
||||||
};
|
|
||||||
} 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 };
|
||||||
@@ -166,10 +107,7 @@ export const commands = {
|
|||||||
},
|
},
|
||||||
async getCurrentUserProfile() : Promise<Result<string, string>> {
|
async getCurrentUserProfile() : Promise<Result<string, string>> {
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("get_current_user_profile") };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("get_current_user_profile"),
|
|
||||||
};
|
|
||||||
} 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 };
|
||||||
@@ -193,53 +131,23 @@ export const commands = {
|
|||||||
},
|
},
|
||||||
async setContactList(pubkeys: string[]) : Promise<Result<boolean, string>> {
|
async setContactList(pubkeys: string[]) : Promise<Result<boolean, string>> {
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("set_contact_list", { pubkeys }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("set_contact_list", { pubkeys }),
|
|
||||||
};
|
|
||||||
} 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 createProfile(
|
async createProfile(name: string, displayName: string, about: string, picture: string, banner: string, nip05: string, lud16: string, website: string) : Promise<Result<string, string>> {
|
||||||
name: string,
|
|
||||||
displayName: string,
|
|
||||||
about: string,
|
|
||||||
picture: string,
|
|
||||||
banner: string,
|
|
||||||
nip05: string,
|
|
||||||
lud16: string,
|
|
||||||
website: string,
|
|
||||||
): Promise<Result<string, string>> {
|
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("create_profile", { name, displayName, about, picture, banner, nip05, lud16, website }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("create_profile", {
|
|
||||||
name,
|
|
||||||
displayName,
|
|
||||||
about,
|
|
||||||
picture,
|
|
||||||
banner,
|
|
||||||
nip05,
|
|
||||||
lud16,
|
|
||||||
website,
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
} 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 follow(
|
async follow(id: string, alias: string | null) : Promise<Result<string, string>> {
|
||||||
id: string,
|
|
||||||
alias: string | null,
|
|
||||||
): Promise<Result<string, string>> {
|
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("follow", { id, alias }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("follow", { id, alias }),
|
|
||||||
};
|
|
||||||
} 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 };
|
||||||
@@ -261,15 +169,9 @@ export const commands = {
|
|||||||
else return { status: "error", error: e as any };
|
else return { status: "error", error: e as any };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async setNstore(
|
async setNstore(key: string, content: string) : Promise<Result<string, string>> {
|
||||||
key: string,
|
|
||||||
content: string,
|
|
||||||
): Promise<Result<string, string>> {
|
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("set_nstore", { key, content }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("set_nstore", { key, content }),
|
|
||||||
};
|
|
||||||
} 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 };
|
||||||
@@ -299,31 +201,17 @@ export const commands = {
|
|||||||
else return { status: "error", error: e as any };
|
else return { status: "error", error: e as any };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async zapProfile(
|
async zapProfile(id: string, amount: string, message: string) : Promise<Result<boolean, string>> {
|
||||||
id: string,
|
|
||||||
amount: string,
|
|
||||||
message: string,
|
|
||||||
): Promise<Result<boolean, string>> {
|
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("zap_profile", { id, amount, message }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("zap_profile", { id, amount, message }),
|
|
||||||
};
|
|
||||||
} 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 zapEvent(
|
async zapEvent(id: string, amount: string, message: string) : Promise<Result<boolean, string>> {
|
||||||
id: string,
|
|
||||||
amount: string,
|
|
||||||
message: string,
|
|
||||||
): Promise<Result<boolean, string>> {
|
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("zap_event", { id, amount, message }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("zap_event", { id, amount, message }),
|
|
||||||
};
|
|
||||||
} 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 };
|
||||||
@@ -331,10 +219,7 @@ export const commands = {
|
|||||||
},
|
},
|
||||||
async friendToFriend(npub: string) : Promise<Result<boolean, string>> {
|
async friendToFriend(npub: string) : Promise<Result<boolean, string>> {
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("friend_to_friend", { npub }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("friend_to_friend", { npub }),
|
|
||||||
};
|
|
||||||
} 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 };
|
||||||
@@ -356,70 +241,41 @@ export const commands = {
|
|||||||
else return { status: "error", error: e as any };
|
else return { status: "error", error: e as any };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async getEventsBy(
|
async getEventsBy(publicKey: string, asOf: string | null) : Promise<Result<string[], string>> {
|
||||||
publicKey: string,
|
|
||||||
asOf: string | null,
|
|
||||||
): Promise<Result<string[], string>> {
|
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("get_events_by", { publicKey, asOf }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("get_events_by", { publicKey, asOf }),
|
|
||||||
};
|
|
||||||
} 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 getLocalEvents(
|
async getLocalEvents(pubkeys: string[], until: string | null) : Promise<Result<string[], string>> {
|
||||||
pubkeys: string[],
|
|
||||||
until: string | null,
|
|
||||||
): Promise<Result<string[], string>> {
|
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("get_local_events", { pubkeys, until }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("get_local_events", { pubkeys, 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 };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async getGlobalEvents(
|
async getGlobalEvents(until: string | null) : Promise<Result<string[], string>> {
|
||||||
until: string | null,
|
|
||||||
): Promise<Result<string[], string>> {
|
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("get_global_events", { until }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("get_global_events", { 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 };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async getHashtagEvents(
|
async getHashtagEvents(hashtags: string[], until: string | null) : Promise<Result<string[], string>> {
|
||||||
hashtags: string[],
|
|
||||||
until: string | null,
|
|
||||||
): Promise<Result<string[], string>> {
|
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("get_hashtag_events", { hashtags, until }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("get_hashtag_events", { hashtags, 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 };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async publish(
|
async publish(content: string, tags: string[][]) : Promise<Result<string, string>> {
|
||||||
content: string,
|
|
||||||
tags: string[][],
|
|
||||||
): Promise<Result<string, string>> {
|
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("publish", { content, tags }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("publish", { content, tags }),
|
|
||||||
};
|
|
||||||
} 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 };
|
||||||
@@ -436,26 +292,9 @@ export const commands = {
|
|||||||
async showInFolder(path: string) : Promise<void> {
|
async showInFolder(path: string) : Promise<void> {
|
||||||
await TAURI_INVOKE("show_in_folder", { path });
|
await TAURI_INVOKE("show_in_folder", { path });
|
||||||
},
|
},
|
||||||
async createColumn(
|
async createColumn(label: string, x: number, y: number, width: number, height: number, url: string) : Promise<Result<string, string>> {
|
||||||
label: string,
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
width: number,
|
|
||||||
height: number,
|
|
||||||
url: string,
|
|
||||||
): Promise<Result<string, string>> {
|
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("create_column", { label, x, y, width, height, url }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("create_column", {
|
|
||||||
label,
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
url,
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
} 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 };
|
||||||
@@ -463,63 +302,31 @@ export const commands = {
|
|||||||
},
|
},
|
||||||
async closeColumn(label: string) : Promise<Result<boolean, null>> {
|
async closeColumn(label: string) : Promise<Result<boolean, null>> {
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("close_column", { label }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("close_column", { label }),
|
|
||||||
};
|
|
||||||
} 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 repositionColumn(
|
async repositionColumn(label: string, x: number, y: number) : Promise<Result<null, string>> {
|
||||||
label: string,
|
|
||||||
x: number,
|
|
||||||
y: number,
|
|
||||||
): Promise<Result<null, string>> {
|
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("reposition_column", { label, x, y }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("reposition_column", { label, x, y }),
|
|
||||||
};
|
|
||||||
} 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 resizeColumn(
|
async resizeColumn(label: string, width: number, height: number) : Promise<Result<null, string>> {
|
||||||
label: string,
|
|
||||||
width: number,
|
|
||||||
height: number,
|
|
||||||
): Promise<Result<null, string>> {
|
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("resize_column", { label, width, height }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("resize_column", { label, width, height }),
|
|
||||||
};
|
|
||||||
} 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 openWindow(
|
async openWindow(label: string, title: string, url: string, width: number, height: number) : Promise<Result<null, string>> {
|
||||||
label: string,
|
|
||||||
title: string,
|
|
||||||
url: string,
|
|
||||||
width: number,
|
|
||||||
height: number,
|
|
||||||
): Promise<Result<null, string>> {
|
|
||||||
try {
|
try {
|
||||||
return {
|
return { status: "ok", data: await TAURI_INVOKE("open_window", { label, title, url, width, height }) };
|
||||||
status: "ok",
|
|
||||||
data: await TAURI_INVOKE("open_window", {
|
|
||||||
label,
|
|
||||||
title,
|
|
||||||
url,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
} 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 };
|
||||||
@@ -527,18 +334,15 @@ export const commands = {
|
|||||||
},
|
},
|
||||||
async setBadge(count: number) : Promise<void> {
|
async setBadge(count: number) : Promise<void> {
|
||||||
await TAURI_INVOKE("set_badge", { count });
|
await TAURI_INVOKE("set_badge", { count });
|
||||||
},
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** user-defined types **/
|
/** user-defined types **/
|
||||||
|
|
||||||
export type Account = { npub: string; nsec: string };
|
export type Account = { npub: string; nsec: string }
|
||||||
export type Relays = {
|
export type Relays = { connected: string[]; read: string[] | null; write: string[] | null; both: string[] | null }
|
||||||
connected: string[];
|
|
||||||
read: string[] | null;
|
|
||||||
write: string[] | null;
|
|
||||||
both: string[] | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** tauri-specta globals **/
|
/** tauri-specta globals **/
|
||||||
|
|
||||||
@@ -548,10 +352,10 @@ import { type WebviewWindow as __WebviewWindow__ } from "@tauri-apps/api/webview
|
|||||||
|
|
||||||
type __EventObj__<T> = {
|
type __EventObj__<T> = {
|
||||||
listen: (
|
listen: (
|
||||||
cb: TAURI_API_EVENT.EventCallback<T>,
|
cb: TAURI_API_EVENT.EventCallback<T>
|
||||||
) => ReturnType<typeof TAURI_API_EVENT.listen<T>>;
|
) => ReturnType<typeof TAURI_API_EVENT.listen<T>>;
|
||||||
once: (
|
once: (
|
||||||
cb: TAURI_API_EVENT.EventCallback<T>,
|
cb: TAURI_API_EVENT.EventCallback<T>
|
||||||
) => ReturnType<typeof TAURI_API_EVENT.once<T>>;
|
) => ReturnType<typeof TAURI_API_EVENT.once<T>>;
|
||||||
emit: T extends null
|
emit: T extends null
|
||||||
? (payload?: T) => ReturnType<typeof TAURI_API_EVENT.emit>
|
? (payload?: T) => ReturnType<typeof TAURI_API_EVENT.emit>
|
||||||
@@ -563,7 +367,7 @@ export type Result<T, E> =
|
|||||||
| { status: "error"; error: E };
|
| { status: "error"; error: E };
|
||||||
|
|
||||||
function __makeEvents__<T extends Record<string, any>>(
|
function __makeEvents__<T extends Record<string, any>>(
|
||||||
mappings: Record<keyof T, string>,
|
mappings: Record<keyof T, string>
|
||||||
) {
|
) {
|
||||||
return new Proxy(
|
return new Proxy(
|
||||||
{} as unknown as {
|
{} as unknown as {
|
||||||
@@ -593,6 +397,8 @@ function __makeEvents__<T extends Record<string, any>>(
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -236,31 +236,28 @@ export class NostrQuery {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static async getColumns() {
|
static async getColumns() {
|
||||||
|
const systemPath = "resources/system_columns.json";
|
||||||
|
const resourcePath = await resolveResource(systemPath);
|
||||||
|
const resourceFile = await readTextFile(resourcePath);
|
||||||
|
const systemColumns: LumeColumn[] = JSON.parse(resourceFile);
|
||||||
const query = await commands.getNstore(NSTORE_KEYS.columns);
|
const query = await commands.getNstore(NSTORE_KEYS.columns);
|
||||||
|
|
||||||
if (query.status === "ok") {
|
if (query.status === "ok") {
|
||||||
const columns: LumeColumn[] = query.data ? JSON.parse(query.data) : [];
|
const columns: LumeColumn[] = query.data ? JSON.parse(query.data) : [];
|
||||||
|
|
||||||
if (columns.length < 1) {
|
if (columns.length < 1) {
|
||||||
const systemPath = "resources/system_columns.json";
|
|
||||||
const resourcePath = await resolveResource(systemPath);
|
|
||||||
const resourceFile = await readTextFile(resourcePath);
|
|
||||||
const systemColumns: LumeColumn[] = JSON.parse(resourceFile);
|
|
||||||
|
|
||||||
return systemColumns;
|
return systemColumns;
|
||||||
}
|
}
|
||||||
|
|
||||||
return columns;
|
return columns;
|
||||||
} else {
|
} else {
|
||||||
return [];
|
return systemColumns;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static async setColumns(columns: LumeColumn[]) {
|
static async setColumns(columns: LumeColumn[]) {
|
||||||
const query = await commands.setNstore(
|
const content = JSON.stringify(columns);
|
||||||
NSTORE_KEYS.columns,
|
const query = await commands.setNstore(NSTORE_KEYS.columns, content);
|
||||||
JSON.stringify(columns),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (query.status === "ok") {
|
if (query.status === "ok") {
|
||||||
return query.data;
|
return query.data;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
"@lume/tailwindcss": "workspace:^",
|
"@lume/tailwindcss": "workspace:^",
|
||||||
"@lume/tsconfig": "workspace:^",
|
"@lume/tsconfig": "workspace:^",
|
||||||
"@lume/types": "workspace:^",
|
"@lume/types": "workspace:^",
|
||||||
"@types/react": "^18.3.2",
|
"@types/react": "^18.3.3",
|
||||||
"tailwindcss": "^3.4.3",
|
"tailwindcss": "^3.4.3",
|
||||||
"typescript": "^5.4.5"
|
"typescript": "^5.4.5"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,21 +8,21 @@
|
|||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tanstack/react-query": "^5.36.0",
|
"@tanstack/react-query": "^5.40.0",
|
||||||
"bitcoin-units": "^1.0.0",
|
"bitcoin-units": "^1.0.0",
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"dayjs": "^1.11.11",
|
"dayjs": "^1.11.11",
|
||||||
"light-bolt11-decoder": "^3.1.1",
|
"light-bolt11-decoder": "^3.1.1",
|
||||||
"nostr-tools": "^2.5.2",
|
"nostr-tools": "^2.6.0",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"slate": "^0.103.0",
|
"slate": "^0.103.0",
|
||||||
"slate-react": "^0.102.0"
|
"slate-react": "^0.104.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@lume/tsconfig": "workspace:^",
|
"@lume/tsconfig": "workspace:^",
|
||||||
"@lume/types": "workspace:^",
|
"@lume/types": "workspace:^",
|
||||||
"@types/react": "^18.3.2",
|
"@types/react": "^18.3.3",
|
||||||
"@types/react-dom": "^18.3.0",
|
"@types/react-dom": "^18.3.0",
|
||||||
"tailwind-merge": "^2.3.0",
|
"tailwind-merge": "^2.3.0",
|
||||||
"typescript": "^5.4.5"
|
"typescript": "^5.4.5"
|
||||||
|
|||||||
Generated
+871
-851
File diff suppressed because it is too large
Load Diff
@@ -34,11 +34,10 @@ fn main() {
|
|||||||
nostr::keys::create_account,
|
nostr::keys::create_account,
|
||||||
nostr::keys::save_account,
|
nostr::keys::save_account,
|
||||||
nostr::keys::get_encrypted_key,
|
nostr::keys::get_encrypted_key,
|
||||||
nostr::keys::nostr_connect,
|
nostr::keys::connect_remote_account,
|
||||||
nostr::keys::load_account,
|
nostr::keys::load_account,
|
||||||
nostr::keys::event_to_bech32,
|
nostr::keys::event_to_bech32,
|
||||||
nostr::keys::user_to_bech32,
|
nostr::keys::user_to_bech32,
|
||||||
nostr::keys::to_npub,
|
|
||||||
nostr::keys::verify_nip05,
|
nostr::keys::verify_nip05,
|
||||||
nostr::metadata::get_activities,
|
nostr::metadata::get_activities,
|
||||||
nostr::metadata::get_current_user_profile,
|
nostr::metadata::get_current_user_profile,
|
||||||
|
|||||||
+31
-54
@@ -102,39 +102,36 @@ pub async fn save_account(
|
|||||||
#[specta::specta]
|
#[specta::specta]
|
||||||
pub async fn load_account(
|
pub async fn load_account(
|
||||||
npub: &str,
|
npub: &str,
|
||||||
|
bunker: Option<&str>,
|
||||||
state: State<'_, Nostr>,
|
state: State<'_, Nostr>,
|
||||||
app: tauri::AppHandle,
|
app: tauri::AppHandle,
|
||||||
) -> Result<bool, String> {
|
) -> Result<bool, String> {
|
||||||
let client = &state.client;
|
let client = &state.client;
|
||||||
let keyring = Entry::new(npub, "nostr_secret").unwrap();
|
let keyring = Entry::new(npub, "nostr_secret").unwrap();
|
||||||
|
|
||||||
match keyring.get_password() {
|
if let Ok(password) = keyring.get_password() {
|
||||||
Ok(password) => {
|
match bunker {
|
||||||
if password.starts_with("bunker://") {
|
Some(uri) => {
|
||||||
let local_keyring = Entry::new(npub, "bunker_local_account").unwrap();
|
let app_keys = Keys::parse(password).expect("Secret Key is modified, please check again.");
|
||||||
|
|
||||||
match local_keyring.get_password() {
|
match NostrConnectURI::parse(uri) {
|
||||||
Ok(local_password) => {
|
Ok(bunker_uri) => {
|
||||||
let secret_key = SecretKey::from_bech32(local_password).unwrap();
|
match Nip46Signer::new(bunker_uri, app_keys, Duration::from_secs(30), None).await {
|
||||||
let app_keys = Keys::new(secret_key);
|
Ok(signer) => client.set_signer(Some(signer.into())).await,
|
||||||
let bunker_uri = NostrConnectURI::parse(password).unwrap();
|
Err(err) => return Err(err.to_string()),
|
||||||
let signer = Nip46Signer::new(bunker_uri, app_keys, Duration::from_secs(60), None)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// Update signer
|
|
||||||
client.set_signer(Some(signer.into())).await;
|
|
||||||
}
|
}
|
||||||
Err(_) => todo!(),
|
|
||||||
}
|
}
|
||||||
} else {
|
Err(err) => return Err(err.to_string()),
|
||||||
let secret_key = SecretKey::from_bech32(password).expect("Get secret key failed");
|
}
|
||||||
let keys = Keys::new(secret_key);
|
}
|
||||||
|
None => {
|
||||||
|
let keys = Keys::parse(password).expect("Secret Key is modified, please check again.");
|
||||||
let signer = NostrSigner::Keys(keys);
|
let signer = NostrSigner::Keys(keys);
|
||||||
|
|
||||||
// Update signer
|
// Update signer
|
||||||
client.set_signer(Some(signer)).await;
|
client.set_signer(Some(signer)).await;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Verify signer
|
// Verify signer
|
||||||
let signer = client.signer().await.unwrap();
|
let signer = client.signer().await.unwrap();
|
||||||
@@ -147,11 +144,10 @@ pub async fn load_account(
|
|||||||
|
|
||||||
// Connect to user's relay (NIP-65)
|
// Connect to user's relay (NIP-65)
|
||||||
// #TODO: Let rust-nostr handle it
|
// #TODO: Let rust-nostr handle it
|
||||||
match client
|
if let Ok(events) = client
|
||||||
.get_events_of(vec![filter], Some(Duration::from_secs(10)))
|
.get_events_of(vec![filter], Some(Duration::from_secs(10)))
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(events) => {
|
|
||||||
if let Some(event) = events.first() {
|
if let Some(event) = events.first() {
|
||||||
let relay_list = nip65::extract_relay_list(event);
|
let relay_list = nip65::extract_relay_list(event);
|
||||||
for item in relay_list.into_iter() {
|
for item in relay_list.into_iter() {
|
||||||
@@ -179,8 +175,6 @@ pub async fn load_account(
|
|||||||
client.connect_relay(relay_url).await.unwrap_or_default();
|
client.connect_relay(relay_url).await.unwrap_or_default();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Err(_) => todo!(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Run notification service
|
// Run notification service
|
||||||
@@ -218,42 +212,34 @@ pub async fn load_account(
|
|||||||
});
|
});
|
||||||
|
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
} else {
|
||||||
Err(err) => Err(err.to_string()),
|
Err("Key not found.".into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
#[specta::specta]
|
#[specta::specta]
|
||||||
pub async fn nostr_connect(
|
pub async fn connect_remote_account(uri: &str, state: State<'_, Nostr>) -> Result<String, String> {
|
||||||
npub: &str,
|
|
||||||
uri: &str,
|
|
||||||
state: State<'_, Nostr>,
|
|
||||||
) -> Result<String, String> {
|
|
||||||
let client = &state.client;
|
let client = &state.client;
|
||||||
let local_key = Keys::generate();
|
|
||||||
|
|
||||||
match NostrConnectURI::parse(uri) {
|
match NostrConnectURI::parse(uri) {
|
||||||
Ok(bunker_uri) => {
|
Ok(bunker_uri) => {
|
||||||
match Nip46Signer::new(
|
let app_keys = Keys::generate();
|
||||||
bunker_uri,
|
let app_secret = app_keys.secret_key().unwrap().to_string();
|
||||||
local_key.clone(),
|
|
||||||
Duration::from_secs(120),
|
// Get remote user
|
||||||
None,
|
let remote_user = bunker_uri.signer_public_key().unwrap();
|
||||||
)
|
let remote_npub = remote_user.to_bech32().unwrap();
|
||||||
.await
|
|
||||||
{
|
match Nip46Signer::new(bunker_uri, app_keys, Duration::from_secs(120), None).await {
|
||||||
Ok(signer) => {
|
Ok(signer) => {
|
||||||
let local_secret = local_key.secret_key().unwrap().to_bech32().unwrap();
|
let keyring = Entry::new(&remote_npub, "nostr_secret").unwrap();
|
||||||
let secret_keyring = Entry::new(&npub, "nostr_secret").unwrap();
|
let _ = keyring.set_password(&app_secret);
|
||||||
let account_keyring = Entry::new(&npub, "bunker_local_account").unwrap();
|
|
||||||
let _ = secret_keyring.set_password(uri);
|
|
||||||
let _ = account_keyring.set_password(&local_secret);
|
|
||||||
|
|
||||||
// Update signer
|
// Update signer
|
||||||
let _ = client.set_signer(Some(signer.into())).await;
|
let _ = client.set_signer(Some(signer.into())).await;
|
||||||
|
|
||||||
Ok(npub.into())
|
Ok(remote_npub.into())
|
||||||
}
|
}
|
||||||
Err(err) => Err(err.to_string()),
|
Err(err) => Err(err.to_string()),
|
||||||
}
|
}
|
||||||
@@ -299,15 +285,6 @@ pub fn user_to_bech32(key: &str, relays: Vec<String>) -> Result<String, ()> {
|
|||||||
Ok(profile.to_bech32().unwrap())
|
Ok(profile.to_bech32().unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
#[specta::specta]
|
|
||||||
pub fn to_npub(hex: &str) -> Result<String, ()> {
|
|
||||||
let public_key = PublicKey::from_str(hex).unwrap();
|
|
||||||
let npub = Nip19::Pubkey(public_key);
|
|
||||||
|
|
||||||
Ok(npub.to_bech32().unwrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
#[specta::specta]
|
#[specta::specta]
|
||||||
pub async fn verify_nip05(key: &str, nip05: &str) -> Result<bool, String> {
|
pub async fn verify_nip05(key: &str, nip05: &str) -> Result<bool, String> {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
|
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
|
||||||
"productName": "Lume",
|
"productName": "Lume",
|
||||||
"version": "4.0.6",
|
"version": "4.0.8",
|
||||||
"identifier": "nu.lume.Lume",
|
"identifier": "nu.lume.Lume",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeBuildCommand": "pnpm desktop:build",
|
"beforeBuildCommand": "pnpm desktop:build",
|
||||||
|
|||||||
Reference in New Issue
Block a user