Compare commits

...

9 Commits

Author SHA1 Message Date
reya
10ca4e6ff4 chore: bump version 2024-05-17 15:32:14 +07:00
reya
b0f387d029 fix: wrong permissions for dialog 2024-05-17 15:31:35 +07:00
reya
1a8f750640 fix: profile is not show on edit screen 2024-05-17 14:45:17 +07:00
reya
25523229a2 fix: copy to clipboard is not working properly 2024-05-16 14:24:55 +07:00
雨宮蓮
47835ed857 feat: improve ui for multi-account (#188) 2024-05-16 14:13:07 +07:00
reya
d84647bc6b chore: bump version 2024-05-15 13:58:39 +07:00
reya
7724eccd72 feat: improve tauri commands 2024-05-15 13:58:03 +07:00
reya
8ea2335225 chore: update deps 2024-05-15 10:50:35 +07:00
reya
b60d4db0df feat: improve multi-account switching 2024-05-15 10:14:21 +07:00
32 changed files with 1536 additions and 1023 deletions

View File

@@ -22,42 +22,42 @@
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-switch": "^1.0.3",
"@radix-ui/react-tooltip": "^1.0.7",
"@tanstack/query-sync-storage-persister": "^5.32.0",
"@tanstack/react-query": "^5.32.0",
"@tanstack/react-query-persist-client": "^5.32.0",
"@tanstack/react-router": "1.29.2",
"i18next": "^23.11.3",
"@tanstack/query-sync-storage-persister": "^5.36.0",
"@tanstack/react-query": "^5.36.0",
"@tanstack/react-query-persist-client": "^5.36.0",
"@tanstack/react-router": "1.32.5",
"i18next": "^23.11.4",
"i18next-resources-to-backend": "^1.2.1",
"minidenticons": "^4.2.1",
"nanoid": "^5.0.7",
"nostr-tools": "^2.5.1",
"nostr-tools": "^2.5.2",
"react": "^18.3.1",
"react-currency-input-field": "^3.8.0",
"react-dom": "^18.3.1",
"react-hook-form": "^7.51.3",
"react-hook-form": "^7.51.4",
"react-hotkeys-hook": "^4.5.0",
"react-i18next": "^14.1.1",
"react-string-replace": "^1.1.1",
"slate": "^0.102.0",
"slate": "^0.103.0",
"slate-react": "^0.102.0",
"sonner": "^1.4.41",
"use-debounce": "^10.0.0",
"virtua": "^0.30.2"
"virtua": "^0.31.0"
},
"devDependencies": {
"@lume/tailwindcss": "workspace:^",
"@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^",
"@tanstack/router-devtools": "^1.31.3",
"@tanstack/router-vite-plugin": "^1.30.0",
"@types/react": "^18.3.1",
"@tanstack/router-devtools": "^1.32.5",
"@tanstack/router-vite-plugin": "^1.32.2",
"@types/react": "^18.3.2",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react-swc": "^3.6.0",
"autoprefixer": "^10.4.19",
"postcss": "^8.4.38",
"tailwindcss": "^3.4.3",
"typescript": "^5.4.5",
"vite": "^5.2.10",
"vite": "^5.2.11",
"vite-plugin-top-level-await": "^1.4.1",
"vite-tsconfig-paths": "^4.3.2"
}

View File

@@ -1,4 +1,4 @@
import { User } from "./user";
import { User } from "@/components/user";
import { getBitcoinDisplayValues } from "@lume/utils";
import { useRouteContext } from "@tanstack/react-router";
import { useEffect, useMemo, useState } from "react";

View File

@@ -5,7 +5,7 @@ import { invoke } from "@tauri-apps/api/core";
import { getCurrent } from "@tauri-apps/api/webviewWindow";
import { useEffect, useRef, useState } from "react";
export function Col({
export function Column({
column,
account,
isScroll,
@@ -17,68 +17,55 @@ export function Col({
isResize: boolean;
}) {
const container = useRef<HTMLDivElement>(null);
const [webview, setWebview] = useState<string | undefined>(undefined);
const webviewLabel = `column-${account}_${column.label}`;
const [isCreated, setIsCreated] = useState(false);
const repositionWebview = async () => {
if (webview && webview.length > 1) {
const newRect = container.current.getBoundingClientRect();
await invoke("reposition_column", {
label: webview,
x: newRect.x,
y: newRect.y,
});
}
const newRect = container.current.getBoundingClientRect();
await invoke("reposition_column", {
label: webviewLabel,
x: newRect.x,
y: newRect.y,
});
};
const resizeWebview = async () => {
if (webview && webview.length > 1) {
const newRect = container.current.getBoundingClientRect();
await invoke("resize_column", {
label: webview,
width: newRect.width,
height: newRect.height,
});
}
const newRect = container.current.getBoundingClientRect();
await invoke("resize_column", {
label: webviewLabel,
width: newRect.width,
height: newRect.height,
});
};
useEffect(() => {
resizeWebview();
if (isCreated) resizeWebview();
}, [isResize]);
useEffect(() => {
if (isScroll) repositionWebview();
if (isScroll && isCreated) repositionWebview();
}, [isScroll]);
useEffect(() => {
(async () => {
if (webview && webview.length > 1) return;
const rect = container.current.getBoundingClientRect();
const url = `${column.content}?account=${account}&label=${column.label}&name=${column.name}`;
const rect = container.current.getBoundingClientRect();
const windowLabel = `column-${column.label}`;
const url = `${column.content}?account=${account}&label=${column.label}&name=${column.name}`;
// create new webview
const label: string = await invoke("create_column", {
label: windowLabel,
x: rect.x,
y: rect.y,
width: rect.width,
height: rect.height,
url,
});
setWebview(label);
})();
// create new webview
invoke("create_column", {
label: webviewLabel,
x: rect.x,
y: rect.y,
width: rect.width,
height: rect.height,
url,
}).then(() => setIsCreated(true));
// close webview when unmounted
return () => {
if (webview && webview.length > 1) {
invoke("close_column", {
label: webview,
});
}
invoke("close_column", { label: webviewLabel });
};
}, [webview]);
}, [account]);
return (
<div className="h-full w-[440px] shrink-0 p-2">

View File

@@ -1,6 +1,6 @@
import { ThreadIcon } from "@lume/icons";
import type { Event } from "@lume/types";
import { Note } from "./note";
import { Note } from "@/components/note";
import { cn } from "@lume/utils";
import { useRouteContext } from "@tanstack/react-router";

View File

@@ -1,5 +1,5 @@
import type { Event } from "@lume/types";
import { Note } from "./note";
import { Note } from "@/components/note";
import { cn } from "@lume/utils";
export function Notification({

View File

@@ -1,6 +1,6 @@
import { QuoteIcon } from "@lume/icons";
import type { Event } from "@lume/types";
import { Note } from "./note";
import { Note } from "@/components/note";
import { cn } from "@lume/utils";
export function Quote({

View File

@@ -1,7 +1,7 @@
import type { Event } from "@lume/types";
import { Spinner } from "@lume/ui";
import { Note } from "./note";
import { User } from "./user";
import { Note } from "@/components/note";
import { User } from "@/components/user";
import { cn } from "@lume/utils";
import { useQuery } from "@tanstack/react-query";
import { useRouteContext } from "@tanstack/react-router";

View File

@@ -1,6 +1,6 @@
import type { Event } from "@lume/types";
import { cn } from "@lume/utils";
import { Note } from "./note";
import { Note } from "@/components/note";
export function TextNote({
event,

View File

@@ -1,4 +1,4 @@
import { Col } from "@/components/col";
import { Column } from "@/components/column";
import { Toolbar } from "@/components/toolbar";
import { ArrowLeftIcon, ArrowRightIcon } from "@lume/icons";
import type { EventColumns, LumeColumn } from "@lume/types";
@@ -13,20 +13,19 @@ import { useDebouncedCallback } from "use-debounce";
import { VList, type VListHandle } from "virtua";
export const Route = createFileRoute("/$account/home")({
beforeLoad: async ({ context }) => {
loader: async ({ context }) => {
try {
const ark = context.ark;
const resourcePath = await resolveResource(
"resources/system_columns.json",
);
const systemColumns: LumeColumn[] = JSON.parse(
await readTextFile(resourcePath),
);
const userColumns = await ark.get_columns();
const userColumns = await context.ark.get_columns();
if (userColumns.length > 0) {
return userColumns;
} else {
const systemPath = "resources/system_columns.json";
const resourcePath = await resolveResource(systemPath);
const resourceFile = await readTextFile(resourcePath);
const systemColumns: LumeColumn[] = JSON.parse(resourceFile);
return {
storedColumns: !userColumns.length ? systemColumns : userColumns,
};
return systemColumns;
}
} catch (e) {
console.error(String(e));
}
@@ -35,13 +34,14 @@ export const Route = createFileRoute("/$account/home")({
});
function Screen() {
const userSavedColumns = Route.useLoaderData();
const vlistRef = useRef<VListHandle>(null);
const { account } = Route.useParams();
const { ark, storedColumns } = Route.useRouteContext();
const { ark } = Route.useRouteContext();
const [selectedIndex, setSelectedIndex] = useState(-1);
const [columns, setColumns] = useState(storedColumns);
const [columns, setColumns] = useState([]);
const [isScroll, setIsScroll] = useState(false);
const [isResize, setIsResize] = useState(false);
@@ -114,6 +114,10 @@ function Screen() {
150,
);
useEffect(() => {
setColumns(userSavedColumns);
}, [userSavedColumns]);
useEffect(() => {
// save state
ark.set_columns(columns);
@@ -148,9 +152,10 @@ function Screen() {
onScroll={() => setIsScroll(true)}
onScrollEnd={() => setIsScroll(false)}
className="scrollbar-none h-full w-full overflow-x-auto focus:outline-none"
cache={null}
>
{columns.map((column) => (
<Col
<Column
key={column.label}
column={column}
account={account}

View File

@@ -1,4 +1,10 @@
import { BellIcon, ComposeFilledIcon, PlusIcon, SearchIcon } from "@lume/icons";
import {
BellIcon,
ComposeFilledIcon,
HorizontalDotsIcon,
PlusIcon,
SearchIcon,
} from "@lume/icons";
import { Event, Kind } from "@lume/types";
import { User } from "@/components/user";
import {
@@ -10,7 +16,9 @@ import {
import { Outlet, createFileRoute } from "@tanstack/react-router";
import { invoke } from "@tauri-apps/api/core";
import { getCurrent } from "@tauri-apps/api/window";
import { useEffect, useState } from "react";
import { useEffect, useMemo, useState } from "react";
import { toast } from "sonner";
import * as Popover from "@radix-ui/react-popover";
export const Route = createFileRoute("/$account")({
beforeLoad: async ({ context }) => {
@@ -39,8 +47,8 @@ function Screen() {
<Accounts />
<button
type="button"
onClick={() => navigate({ to: "/landing" })}
className="inline-flex size-8 items-center justify-center rounded-full bg-black/10 text-neutral-800 hover:bg-black/20 dark:bg-white/10 dark:text-neutral-200 dark:hover:bg-white/20"
onClick={() => navigate({ to: "/landing/" })}
className="inline-flex size-8 shrink-0 items-center justify-center rounded-full bg-black/10 text-neutral-800 hover:bg-black/20 dark:bg-white/10 dark:text-neutral-200 dark:hover:bg-white/20"
>
<PlusIcon className="size-5" />
</button>
@@ -73,43 +81,110 @@ function Screen() {
}
function Accounts() {
const navigate = Route.useNavigate();
const { ark, accounts } = Route.useRouteContext();
const { account } = Route.useParams();
const changeAccount = async (npub: string) => {
if (npub === account) return;
const [windowWidth, setWindowWidth] = useState<number>(null);
const navigate = Route.useNavigate();
const sortedList = useMemo(() => {
const list = accounts;
for (const [i, item] of list.entries()) {
if (item === account) {
list.splice(i, 1);
list.unshift(item);
}
}
return list;
}, [accounts]);
const changeAccount = async (npub: string) => {
if (npub === account) {
return await ark.open_profile(account);
}
// change current account and update signer
const select = await ark.load_selected_account(npub);
if (select) {
return navigate({ to: "/$account/home", params: { account: npub } });
} else {
toast.warning("Something wrong.");
}
};
const getWindowDimensions = () => {
const { innerWidth: width, innerHeight: height } = window;
return {
width,
height,
};
};
useEffect(() => {
function handleResize() {
setWindowWidth(getWindowDimensions().width);
}
if (!windowWidth) setWindowWidth(getWindowDimensions().width);
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
return (
<div data-tauri-drag-region className="flex items-center gap-3">
{accounts.map((user) => (
<button key={user} type="button" onClick={() => changeAccount(user)}>
<User.Provider pubkey={user}>
<User.Root
className={cn(
"rounded-full",
user === account
? "ring-1 ring-teal-500 ring-offset-2 ring-offset-neutral-200 dark:ring-offset-neutral-950"
: "",
)}
>
<User.Avatar
{sortedList
.slice(0, windowWidth > 500 ? account.length : 2)
.map((user) => (
<button key={user} type="button" onClick={() => changeAccount(user)}>
<User.Provider pubkey={user}>
<User.Root
className={cn(
"aspect-square h-auto rounded-full object-cover",
user === account ? "w-7" : "w-8",
"shrink-0 rounded-full transition-all ease-in-out duration-150 will-change-auto",
user === account
? "ring-1 ring-teal-500 ring-offset-2 ring-offset-neutral-200 dark:ring-offset-neutral-950"
: "",
)}
/>
</User.Root>
</User.Provider>
</button>
))}
>
<User.Avatar
className={cn(
"aspect-square h-auto rounded-full object-cover transition-all ease-in-out duration-150 will-change-auto",
user === account ? "w-7" : "w-8",
)}
/>
</User.Root>
</User.Provider>
</button>
))}
{accounts.length >= 3 && windowWidth <= 700 ? (
<Popover.Root>
<Popover.Trigger className="inline-flex size-8 shrink-0 items-center justify-center rounded-full bg-black/10 text-neutral-800 hover:bg-black/20 dark:bg-white/10 dark:text-neutral-200 dark:hover:bg-white/20">
<HorizontalDotsIcon className="size-5" />
</Popover.Trigger>
<Popover.Portal>
<Popover.Content className="flex h-11 select-none items-center justify-center rounded-md bg-neutral-950 p-1 text-sm text-neutral-50 will-change-[transform,opacity] data-[state=delayed-open]:data-[side=bottom]:animate-slideUpAndFade data-[state=delayed-open]:data-[side=left]:animate-slideRightAndFade data-[state=delayed-open]:data-[side=right]:animate-slideLeftAndFade data-[state=delayed-open]:data-[side=top]:animate-slideDownAndFade dark:bg-neutral-50 dark:text-neutral-950">
{sortedList.slice(2).map((user) => (
<button
key={user}
type="button"
onClick={() => changeAccount(user)}
className="size-9 inline-flex items-center justify-center hover:bg-white/10 rounded-md"
>
<User.Provider pubkey={user}>
<User.Root className="rounded-full ring-1 ring-white/10">
<User.Avatar className="size-7 aspect-square h-auto rounded-full object-cover" />
</User.Root>
</User.Provider>
</button>
))}
<Popover.Arrow className="fill-neutral-950 dark:fill-neutral-50" />
</Popover.Content>
</Popover.Portal>
</Popover.Root>
) : null}
</div>
);
}

View File

@@ -25,6 +25,7 @@ import { MediaButton } from "./-components/media";
import { NsfwToggle } from "./-components/nsfw";
import { MentionButton } from "./-components/mention";
import { MentionNote } from "@/components/note/mentions/note";
import { toast } from "sonner";
type EditorSearch = {
reply_to: string;

View File

@@ -18,7 +18,7 @@ export const Route = createFileRoute("/")({
if (!accounts.length) {
throw redirect({
to: "/landing",
to: "/landing/",
replace: true,
});
}
@@ -68,7 +68,7 @@ function Screen() {
<h2 className="mb-1 text-2xl">{currentDate}</h2>
<h2 className="text-2xl font-semibold">Welcome back!</h2>
</div>
<div className="flex items-center justify-center gap-6">
<div className="flex flex-wrap px-3 items-center justify-center gap-6">
{loading ? (
<div className="inline-flex size-6 items-center justify-center">
<Spinner className="size-6 text-white" />
@@ -89,10 +89,10 @@ function Screen() {
</User.Provider>
</button>
))}
<Link to="/landing">
<Link to="/landing/">
<div className="flex h-36 w-32 flex-col items-center justify-center gap-4 rounded-2xl p-2 text-white hover:bg-white/10 dark:hover:bg-black/10">
<div className="flex size-20 items-center justify-center rounded-full bg-white/20 dark:bg-black/20">
<PlusIcon className="size-5" />
<PlusIcon className="size-8" />
</div>
<p className="text-lg font-medium leading-tight">Add</p>
</div>

View File

@@ -19,7 +19,7 @@ export const Route = createFileRoute("/settings/user")({
function Screen() {
const { ark, profile } = Route.useRouteContext();
const { register, handleSubmit } = useForm();
const { register, handleSubmit } = useForm({ defaultValues: profile });
const [loading, setLoading] = useState(false);
const [picture, setPicture] = useState<string>("");
@@ -28,8 +28,8 @@ function Screen() {
try {
setLoading(true);
const profile = { ...data, picture };
await ark.create_profile(profile);
const newProfile: Metadata = { ...profile, ...data, picture };
await ark.create_profile(newProfile);
setLoading(false);
} catch (e) {
@@ -87,7 +87,7 @@ function Screen() {
</label>
<input
name="display_name"
{...register("display_name", { required: true, minLength: 1 })}
{...register("display_name")}
spellCheck={false}
className="h-9 w-full rounded-lg border-neutral-300 bg-transparent px-3 placeholder:text-neutral-500 focus:border-blue-500 focus:ring focus:ring-blue-200 dark:border-neutral-700 dark:placeholder:text-neutral-400 dark:focus:ring-blue-800"
/>

View File

@@ -13,7 +13,7 @@
"@astrojs/check": "^0.5.10",
"@astrojs/tailwind": "^5.1.0",
"@fontsource/geist-mono": "^5.0.3",
"astro": "^4.7.0",
"astro": "^4.8.3",
"astro-seo-meta": "^4.1.1",
"astro-seo-schema": "^4.0.2",
"schema-dts": "^1.1.2",

View File

@@ -20,17 +20,17 @@
"node": ">=18"
},
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.7",
"@tauri-apps/plugin-autostart": "2.0.0-beta.2",
"@tauri-apps/plugin-clipboard-manager": "2.1.0-beta.0",
"@tauri-apps/plugin-dialog": "2.0.0-beta.2",
"@tauri-apps/plugin-fs": "2.0.0-beta.2",
"@tauri-apps/plugin-http": "2.0.0-beta.2",
"@tauri-apps/plugin-notification": "2.0.0-beta.2",
"@tauri-apps/plugin-os": "2.0.0-beta.2",
"@tauri-apps/plugin-process": "2.0.0-beta.2",
"@tauri-apps/plugin-shell": "2.0.0-beta.2",
"@tauri-apps/plugin-updater": "2.0.0-beta.2",
"@tauri-apps/plugin-upload": "2.0.0-beta.3"
"@tauri-apps/api": "^2.0.0-beta.7",
"@tauri-apps/plugin-autostart": "2.0.0-beta.3",
"@tauri-apps/plugin-clipboard-manager": "2.1.0-beta.1",
"@tauri-apps/plugin-dialog": "2.0.0-beta.3",
"@tauri-apps/plugin-fs": "2.0.0-beta.3",
"@tauri-apps/plugin-http": "2.0.0-beta.3",
"@tauri-apps/plugin-notification": "2.0.0-beta.3",
"@tauri-apps/plugin-os": "2.0.0-beta.3",
"@tauri-apps/plugin-process": "2.0.0-beta.3",
"@tauri-apps/plugin-shell": "2.0.0-beta.4",
"@tauri-apps/plugin-updater": "2.0.0-beta.3",
"@tauri-apps/plugin-upload": "2.0.0-beta.4"
}
}

View File

@@ -5,13 +5,13 @@
"main": "./src/index.ts",
"dependencies": {
"@lume/utils": "workspace:^",
"@tanstack/react-query": "^5.32.0",
"@tanstack/react-query": "^5.36.0",
"react": "^18.3.1"
},
"devDependencies": {
"@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^",
"@types/react": "^18.3.1",
"@types/react": "^18.3.2",
"typescript": "^5.4.5"
}
}

View File

@@ -207,12 +207,10 @@ export class Ark {
global?: boolean,
) {
try {
let until: string = undefined;
const until: string = asOf && asOf > 0 ? asOf.toString() : undefined;
const isGlobal = global ?? false;
const seens = new Set<string>();
if (asOf && asOf > 0) until = asOf.toString();
const seenIds = new Set<string>();
const nostrEvents: Event[] = await invoke("get_events", {
limit,
until,
@@ -220,39 +218,31 @@ export class Ark {
global: isGlobal,
});
// remove duplicate event
for (const event of nostrEvents) {
if (event.kind === Kind.Repost) {
const repostId = event.tags.find((tag) => tag[0] === "e")?.[1];
seenIds.add(repostId);
const events = nostrEvents.filter((event) => {
const eTags = event.tags.filter((el) => el[0] === "e");
const ids = eTags.map((item) => item[1]);
const isDup = ids.some((id) => seens.has(id));
// Add found ids to seen list
for (const id of ids) {
seens.add(id);
}
const eventIds = event.tags
.filter((el) => el[0] === "e")
?.map((item) => item[1]);
// Filter NSFW event
if (this.settings?.nsfw) {
const wTags = event.tags.filter((t) => t[0] === "content-warning");
const isLewd = wTags.length > 0;
if (eventIds?.length) {
for (const id of eventIds) {
seenIds.add(id);
}
return !isDup && !isLewd;
}
}
const events = nostrEvents
.filter((event) => !seenIds.has(event.id))
.sort((a, b) => b.created_at - a.created_at);
if (this.settings?.nsfw) {
return events.filter(
(event) =>
event.tags.filter((event) => event[0] === "content-warning")
.length > 0,
);
}
// Filter duplicate event
return !isDup;
});
return events;
} catch (e) {
console.info(String(e));
console.error("[get_events] failed", String(e));
return [];
}
}

View File

@@ -8,7 +8,7 @@
},
"devDependencies": {
"@lume/tsconfig": "workspace:*",
"@types/react": "^18.3.1",
"@types/react": "^18.3.2",
"typescript": "^5.4.5"
}
}

View File

@@ -4,7 +4,7 @@
"private": true,
"main": "./src/index.ts",
"dependencies": {
"@getalby/sdk": "^3.5.0",
"@getalby/sdk": "^3.5.1",
"@lume/ark": "workspace:^",
"@lume/icons": "workspace:^",
"@lume/utils": "workspace:^",
@@ -17,11 +17,11 @@
"@radix-ui/react-hover-card": "^1.0.7",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-tooltip": "^1.0.7",
"@tanstack/react-query": "^5.32.0",
"@tanstack/react-router": "^1.31.3",
"framer-motion": "^11.1.7",
"@tanstack/react-query": "^5.36.0",
"@tanstack/react-router": "^1.32.5",
"framer-motion": "^11.2.0",
"get-urls": "^12.1.0",
"media-chrome": "^3.2.1",
"media-chrome": "^3.2.2",
"minidenticons": "^4.2.1",
"nanoid": "^5.0.7",
"qrcode.react": "^3.1.0",
@@ -29,24 +29,24 @@
"react": "^18.3.1",
"react-currency-input-field": "^3.8.0",
"react-dom": "^18.3.1",
"react-hook-form": "^7.51.3",
"react-hook-form": "^7.51.4",
"react-hotkeys-hook": "^4.5.0",
"react-i18next": "^14.1.1",
"react-snap-carousel": "^0.4.0",
"react-string-replace": "^1.1.1",
"slate": "^0.102.0",
"slate": "^0.103.0",
"slate-react": "^0.102.0",
"sonner": "^1.4.41",
"string-strip-html": "^13.4.8",
"uqr": "^0.1.2",
"use-debounce": "^10.0.0",
"virtua": "^0.30.2"
"virtua": "^0.31.0"
},
"devDependencies": {
"@lume/tailwindcss": "workspace:^",
"@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^",
"@types/react": "^18.3.1",
"@types/react": "^18.3.2",
"tailwindcss": "^3.4.3",
"typescript": "^5.4.5"
}

View File

@@ -8,21 +8,21 @@
"access": "public"
},
"dependencies": {
"@tanstack/react-query": "^5.32.0",
"@tanstack/react-query": "^5.36.0",
"bitcoin-units": "^1.0.0",
"clsx": "^2.1.1",
"dayjs": "^1.11.11",
"light-bolt11-decoder": "^3.1.1",
"nostr-tools": "^2.5.1",
"nostr-tools": "^2.5.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"slate": "^0.102.0",
"slate": "^0.103.0",
"slate-react": "^0.102.0"
},
"devDependencies": {
"@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^",
"@types/react": "^18.3.1",
"@types/react": "^18.3.2",
"@types/react-dom": "^18.3.0",
"tailwind-merge": "^2.3.0",
"typescript": "^5.4.5"

1680
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

220
src-tauri/Cargo.lock generated
View File

@@ -170,7 +170,7 @@ checksum = "9fb4009533e8ff8f1450a5bcbc30f4242a1d34442221f72314bea1f5dc9c7f89"
dependencies = [
"clipboard-win",
"core-graphics",
"image",
"image 0.25.1",
"log",
"objc2",
"objc2-app-kit",
@@ -221,12 +221,11 @@ dependencies = [
[[package]]
name = "async-channel"
version = "2.3.0"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f2776ead772134d55b62dd45e59a79e21612d85d0af729b8b7d3967d601a62a"
checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a"
dependencies = [
"concurrent-queue",
"event-listener 5.3.0",
"event-listener-strategy 0.5.2",
"futures-core",
"pin-project-lite",
@@ -556,6 +555,12 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "bit_field"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
[[package]]
name = "bitcoin"
version = "0.31.2"
@@ -704,9 +709,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]]
name = "bytemuck"
version = "1.15.0"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15"
checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5"
[[package]]
name = "byteorder"
@@ -771,9 +776,9 @@ dependencies = [
[[package]]
name = "camino"
version = "1.1.6"
version = "1.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c"
checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239"
dependencies = [
"serde",
]
@@ -945,7 +950,7 @@ dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim 0.11.1",
"strsim",
]
[[package]]
@@ -993,6 +998,12 @@ dependencies = [
"objc",
]
[[package]]
name = "color_quant"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "colorchoice"
version = "1.0.1"
@@ -1097,12 +1108,37 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-deque"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d"
dependencies = [
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "crypto-common"
version = "0.1.6"
@@ -1183,9 +1219,9 @@ dependencies = [
[[package]]
name = "darling"
version = "0.20.8"
version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391"
checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1"
dependencies = [
"darling_core",
"darling_macro",
@@ -1193,23 +1229,23 @@ dependencies = [
[[package]]
name = "darling_core"
version = "0.20.8"
version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f"
checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim 0.10.0",
"strsim",
"syn 2.0.63",
]
[[package]]
name = "darling_macro"
version = "0.20.8"
version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f"
checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178"
dependencies = [
"darling_core",
"quote",
@@ -1572,6 +1608,22 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "exr"
version = "1.72.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4"
dependencies = [
"bit_field",
"flume",
"half",
"lebe",
"miniz_oxide",
"rayon-core",
"smallvec",
"zune-inflate",
]
[[package]]
name = "fallible-iterator"
version = "0.3.0"
@@ -1650,6 +1702,15 @@ dependencies = [
"miniz_oxide",
]
[[package]]
name = "flume"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181"
dependencies = [
"spin",
]
[[package]]
name = "fnv"
version = "1.0.7"
@@ -1999,6 +2060,16 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "gif"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2"
dependencies = [
"color_quant",
"weezl",
]
[[package]]
name = "gimli"
version = "0.28.1"
@@ -2184,6 +2255,16 @@ dependencies = [
"tracing",
]
[[package]]
name = "half"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888"
dependencies = [
"cfg-if",
"crunchy",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
@@ -2235,9 +2316,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "hex-conservative"
version = "0.1.1"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30ed443af458ccb6d81c1e7e661545f94d3176752fb1df2f543b902a1e0f51e2"
checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20"
[[package]]
name = "hex_lit"
@@ -2459,6 +2540,24 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "image"
version = "0.24.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d"
dependencies = [
"bytemuck",
"byteorder",
"color_quant",
"exr",
"gif",
"jpeg-decoder",
"num-traits",
"png",
"qoi",
"tiff",
]
[[package]]
name = "image"
version = "0.25.1"
@@ -2638,6 +2737,9 @@ name = "jpeg-decoder"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0"
dependencies = [
"rayon",
]
[[package]]
name = "js-sys"
@@ -2703,6 +2805,12 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lebe"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
[[package]]
name = "libappindicator"
version = "0.9.0"
@@ -3038,9 +3146,9 @@ dependencies = [
[[package]]
name = "muda"
version = "0.13.2"
version = "0.13.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6fde56ead0971b4caae4aa0f19502e49d1fac2af9d0c60068e2d235e26ce709"
checksum = "1717c136c99673f55640c14125a0349a5cd7fee6efcfb0adbfe4c289e3b3f7f2"
dependencies = [
"cocoa",
"crossbeam-channel",
@@ -4076,6 +4184,15 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "qoi"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001"
dependencies = [
"bytemuck",
]
[[package]]
name = "quick-xml"
version = "0.31.0"
@@ -4187,6 +4304,26 @@ version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8cc3bcbdb1ddfc11e700e62968e6b4cc9c75bb466464ad28fb61c5b2c964418b"
[[package]]
name = "rayon"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa"
dependencies = [
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2"
dependencies = [
"crossbeam-deque",
"crossbeam-utils",
]
[[package]]
name = "read-progress-stream"
version = "1.0.0"
@@ -4459,9 +4596,9 @@ dependencies = [
[[package]]
name = "rustversion"
version = "1.0.16"
version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "092474d1a01ea8278f69e6a358998405fae5b8b963ddaeb2b0b04a128bf1dfb0"
checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
[[package]]
name = "ryu"
@@ -4646,18 +4783,18 @@ checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73"
[[package]]
name = "serde"
version = "1.0.201"
version = "1.0.202"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c"
checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.201"
version = "1.0.202"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865"
checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838"
dependencies = [
"proc-macro2",
"quote",
@@ -4666,9 +4803,9 @@ dependencies = [
[[package]]
name = "serde_derive_internals"
version = "0.29.0"
version = "0.29.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "330f01ce65a3a5fe59a60c82f3c9a024b573b8a6e875bd233fe5f934e71d54e3"
checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711"
dependencies = [
"proc-macro2",
"quote",
@@ -4700,9 +4837,9 @@ dependencies = [
[[package]]
name = "serde_spanned"
version = "0.6.5"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0"
dependencies = [
"serde",
]
@@ -4931,6 +5068,9 @@ name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
dependencies = [
"lock_api",
]
[[package]]
name = "stable_deref_trait"
@@ -4979,12 +5119,6 @@ dependencies = [
"quote",
]
[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "strsim"
version = "0.11.1"
@@ -5308,11 +5442,12 @@ dependencies = [
[[package]]
name = "tauri-plugin-clipboard-manager"
version = "2.0.0-beta.2"
version = "2.1.0-beta.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8cf4b7fde295126b30b8279aa2addedda7689027a6a7fc4cdf9bea43a86ad84"
checksum = "56e8b139799d4d39d15e4c1a61dd5d86e4ac154e6324f9dd1032c7a354cde6c1"
dependencies = [
"arboard",
"image 0.24.9",
"log",
"serde",
"serde_json",
@@ -7145,6 +7280,15 @@ dependencies = [
"pkg-config",
]
[[package]]
name = "zune-inflate"
version = "0.2.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02"
dependencies = [
"simd-adler32",
]
[[package]]
name = "zvariant"
version = "3.15.1"

View File

@@ -23,7 +23,7 @@ tauri = { version = "2.0.0-beta", features = [
"protocol-asset",
] }
tauri-plugin-cli = "2.0.0-beta"
tauri-plugin-clipboard-manager = "2.0.0-beta"
tauri-plugin-clipboard-manager = "2.1.0-beta"
tauri-plugin-dialog = "2.0.0-beta"
tauri-plugin-fs = "2.0.0-beta"
tauri-plugin-http = "2.0.0-beta"

View File

@@ -36,14 +36,14 @@
"window:allow-create",
"window:allow-close",
"window:allow-set-focus",
"clipboard-manager:allow-write",
"clipboard-manager:allow-read",
"clipboard-manager:allow-write-text",
"clipboard-manager:allow-read-text",
"webview:allow-create-webview-window",
"webview:allow-create-webview",
"webview:allow-set-webview-size",
"webview:allow-set-webview-position",
"webview:allow-webview-close",
"dialog:default",
"dialog:allow-open",
"dialog:allow-ask",
"dialog:allow-message",
"process:allow-restart",

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"desktop-capability":{"identifier":"desktop-capability","description":"Capability for the desktop","local":true,"windows":["main","splash","settings","search","nwc","activity","zap-*","event-*","user-*","editor-*","column-*"],"permissions":["path:default","event:default","window:default","app:default","resources:default","menu:default","tray:default","notification:allow-is-permission-granted","notification:allow-request-permission","notification:default","os:allow-locale","os:allow-platform","updater:default","updater:allow-check","updater:allow-download-and-install","window:allow-start-dragging","window:allow-create","window:allow-close","window:allow-set-focus","clipboard-manager:allow-write","clipboard-manager:allow-read","webview:allow-create-webview-window","webview:allow-create-webview","webview:allow-set-webview-size","webview:allow-set-webview-position","webview:allow-webview-close","dialog:default","dialog:allow-ask","dialog:allow-message","fs:allow-read-file","shell:allow-open",{"identifier":"http:default","allow":[{"url":"http://**/"},{"url":"https://**/"}]},{"identifier":"fs:allow-read-text-file","allow":[{"path":"$RESOURCE/locales/*"},{"path":"$RESOURCE/resources/*"}]}],"platforms":["linux","macOS","windows"]}}
{"desktop-capability":{"identifier":"desktop-capability","description":"Capability for the desktop","local":true,"windows":["main","splash","settings","search","nwc","activity","zap-*","event-*","user-*","editor-*","column-*"],"permissions":["path:default","event:default","window:default","app:default","resources:default","menu:default","tray:default","notification:allow-is-permission-granted","notification:allow-request-permission","notification:default","os:allow-locale","os:allow-platform","updater:default","updater:allow-check","updater:allow-download-and-install","window:allow-start-dragging","window:allow-create","window:allow-close","window:allow-set-focus","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","webview:allow-create-webview-window","webview:allow-create-webview","webview:allow-set-webview-size","webview:allow-set-webview-position","webview:allow-webview-close","dialog:allow-open","dialog:allow-ask","dialog:allow-message","process:allow-restart","fs:allow-read-file","shell:allow-open",{"identifier":"http:default","allow":[{"url":"http://**/"},{"url":"https://**/"}]},{"identifier":"fs:allow-read-text-file","allow":[{"path":"$RESOURCE/locales/*"},{"path":"$RESOURCE/resources/*"}]}],"platforms":["linux","macOS","windows"]}}

View File

@@ -2621,31 +2621,87 @@
]
},
{
"description": "clipboard-manager:allow-read -> Enables the read command without any pre-configured scope.",
"description": "clipboard-manager:allow-clear -> Enables the clear command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:allow-read"
"clipboard-manager:allow-clear"
]
},
{
"description": "clipboard-manager:allow-write -> Enables the write command without any pre-configured scope.",
"description": "clipboard-manager:allow-read-image -> Enables the read_image command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:allow-write"
"clipboard-manager:allow-read-image"
]
},
{
"description": "clipboard-manager:deny-read -> Denies the read command without any pre-configured scope.",
"description": "clipboard-manager:allow-read-text -> Enables the read_text command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-read"
"clipboard-manager:allow-read-text"
]
},
{
"description": "clipboard-manager:deny-write -> Denies the write command without any pre-configured scope.",
"description": "clipboard-manager:allow-write-html -> Enables the write_html command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-write"
"clipboard-manager:allow-write-html"
]
},
{
"description": "clipboard-manager:allow-write-image -> Enables the write_image command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:allow-write-image"
]
},
{
"description": "clipboard-manager:allow-write-text -> Enables the write_text command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:allow-write-text"
]
},
{
"description": "clipboard-manager:deny-clear -> Denies the clear command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-clear"
]
},
{
"description": "clipboard-manager:deny-read-image -> Denies the read_image command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-read-image"
]
},
{
"description": "clipboard-manager:deny-read-text -> Denies the read_text command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-read-text"
]
},
{
"description": "clipboard-manager:deny-write-html -> Denies the write_html command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-write-html"
]
},
{
"description": "clipboard-manager:deny-write-image -> Denies the write_image command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-write-image"
]
},
{
"description": "clipboard-manager:deny-write-text -> Denies the write_text command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-write-text"
]
},
{

View File

@@ -2621,31 +2621,87 @@
]
},
{
"description": "clipboard-manager:allow-read -> Enables the read command without any pre-configured scope.",
"description": "clipboard-manager:allow-clear -> Enables the clear command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:allow-read"
"clipboard-manager:allow-clear"
]
},
{
"description": "clipboard-manager:allow-write -> Enables the write command without any pre-configured scope.",
"description": "clipboard-manager:allow-read-image -> Enables the read_image command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:allow-write"
"clipboard-manager:allow-read-image"
]
},
{
"description": "clipboard-manager:deny-read -> Denies the read command without any pre-configured scope.",
"description": "clipboard-manager:allow-read-text -> Enables the read_text command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-read"
"clipboard-manager:allow-read-text"
]
},
{
"description": "clipboard-manager:deny-write -> Denies the write command without any pre-configured scope.",
"description": "clipboard-manager:allow-write-html -> Enables the write_html command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-write"
"clipboard-manager:allow-write-html"
]
},
{
"description": "clipboard-manager:allow-write-image -> Enables the write_image command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:allow-write-image"
]
},
{
"description": "clipboard-manager:allow-write-text -> Enables the write_text command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:allow-write-text"
]
},
{
"description": "clipboard-manager:deny-clear -> Denies the clear command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-clear"
]
},
{
"description": "clipboard-manager:deny-read-image -> Denies the read_image command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-read-image"
]
},
{
"description": "clipboard-manager:deny-read-text -> Denies the read_text command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-read-text"
]
},
{
"description": "clipboard-manager:deny-write-html -> Denies the write_html command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-write-html"
]
},
{
"description": "clipboard-manager:deny-write-image -> Denies the write_image command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-write-image"
]
},
{
"description": "clipboard-manager:deny-write-text -> Denies the write_text command without any pre-configured scope.",
"type": "string",
"enum": [
"clipboard-manager:deny-write-text"
]
},
{

View File

@@ -9,7 +9,15 @@ pub async fn get_event(id: &str, state: State<'_, Nostr>) -> Result<String, Stri
let event_id: Option<EventId> = match Nip19::from_bech32(id) {
Ok(val) => match val {
Nip19::EventId(id) => Some(id),
Nip19::Event(event) => Some(event.event_id),
Nip19::Event(event) => {
let relays = event.relays;
for relay in relays.into_iter() {
let url = Url::from_str(&relay).unwrap();
let _ = client.add_relay(url.clone()).await.unwrap_or_default();
client.connect_relay(url).await.unwrap_or_default();
}
Some(event.event_id)
}
_ => None,
},
Err(_) => match EventId::from_hex(id) {
@@ -18,23 +26,25 @@ pub async fn get_event(id: &str, state: State<'_, Nostr>) -> Result<String, Stri
},
};
if let Some(id) = event_id {
let filter = Filter::new().id(id);
match event_id {
Some(id) => {
let filter = Filter::new().id(id);
if let Ok(events) = &client
.get_events_of(vec![filter], Some(Duration::from_secs(10)))
.await
{
if let Some(event) = events.first() {
Ok(event.as_json())
} else {
Err("Event not found with current relay list".into())
match &client
.get_events_of(vec![filter], Some(Duration::from_secs(10)))
.await
{
Ok(events) => {
if let Some(event) = events.first() {
Ok(event.as_json())
} else {
Err("Cannot found this event with current relay list".into())
}
}
Err(err) => Err(err.to_string()),
}
} else {
Err("Event not found with current relay list".into())
}
} else {
Err("EventId is not valid".into())
None => Err("Event ID is not valid.".into()),
}
}
@@ -213,8 +223,6 @@ pub async fn search(
limit: usize,
state: State<'_, Nostr>,
) -> Result<Vec<Event>, String> {
println!("search: {}", content);
let client = &state.client;
let filter = Filter::new()
.kinds(vec![Kind::TextNote, Kind::Metadata])

View File

@@ -206,15 +206,12 @@ pub async fn load_selected_account(npub: &str, state: State<'_, Nostr>) -> Resul
// Add relay to relay pool
let _ = client
.add_relay_with_opts(relay_url, opts)
.add_relay_with_opts(relay_url.clone(), opts)
.await
.unwrap_or_default();
// Connect relay
client
.connect_relay(item.0.to_string())
.await
.unwrap_or_default();
client.connect_relay(relay_url).await.unwrap_or_default();
}
}
}
@@ -251,14 +248,10 @@ pub fn to_npub(hex: &str) -> Result<String, ()> {
Ok(npub.to_bech32().unwrap())
}
#[tauri::command(async)]
#[tauri::command]
pub async fn verify_nip05(key: &str, nip05: &str) -> Result<bool, ()> {
let public_key = PublicKey::from_str(key).unwrap();
let status = nip05::verify(public_key, nip05, None).await;
if status.is_ok() {
Ok(true)
} else {
Ok(false)
}
Ok(status.is_ok())
}

View File

@@ -104,8 +104,6 @@ pub async fn friend_to_friend(npub: &str, state: State<'_, Nostr>) -> Result<boo
}
}
println!("contact list: {}", contact_list.len());
match client.set_contact_list(contact_list).await {
Ok(_) => Ok(true),
Err(err) => Err(err.to_string()),
@@ -306,10 +304,7 @@ pub async fn set_nstore(
let builder = EventBuilder::new(Kind::ApplicationSpecificData, encrypted, vec![tag]);
match client.send_event_builder(builder).await {
Ok(event_id) => {
println!("set nstore: {}", event_id);
Ok(event_id)
}
Ok(event_id) => Ok(event_id),
Err(err) => Err(err.to_string()),
}
}
@@ -322,38 +317,29 @@ pub async fn get_nstore(key: &str, state: State<'_, Nostr>) -> Result<String, St
let client = &state.client;
if let Ok(signer) = client.signer().await {
let public_key = signer.public_key().await;
let public_key = signer.public_key().await.unwrap();
let filter = Filter::new()
.author(public_key)
.kind(Kind::ApplicationSpecificData)
.identifier(key)
.limit(1);
if let Ok(author) = public_key {
let filter = Filter::new()
.author(author)
.kind(Kind::ApplicationSpecificData)
.identifier(key)
.limit(1);
let query = client
.get_events_of(vec![filter], Some(Duration::from_secs(10)))
.await;
if let Ok(events) = query {
match client
.get_events_of(vec![filter], Some(Duration::from_secs(5)))
.await
{
Ok(events) => {
if let Some(event) = events.first() {
println!("get nstore key: {} - received: {}", key, event.id);
let content = event.content();
match signer.nip44_decrypt(author, content).await {
match signer.nip44_decrypt(public_key, content).await {
Ok(decrypted) => Ok(decrypted),
Err(_) => Err(event.content.to_string()),
}
} else {
println!("get nstore key: {}", key);
Err("Value not found".into())
}
} else {
Err("Query nstore event failed".into())
}
} else {
Err("Something is wrong".into())
Err(err) => Err(err.to_string()),
}
} else {
Err("Signer is required".into())

View File

@@ -1,7 +1,7 @@
{
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
"productName": "Lume",
"version": "4.0.1",
"version": "4.0.3",
"identifier": "nu.lume.Lume",
"build": {
"beforeBuildCommand": "pnpm desktop:build",