Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d84647bc6b | ||
|
|
7724eccd72 | ||
|
|
8ea2335225 | ||
|
|
b60d4db0df |
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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">
|
||||
@@ -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";
|
||||
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -11,6 +11,7 @@ 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 { toast } from "sonner";
|
||||
|
||||
export const Route = createFileRoute("/$account")({
|
||||
beforeLoad: async ({ context }) => {
|
||||
@@ -78,12 +79,17 @@ function Accounts() {
|
||||
const { account } = Route.useParams();
|
||||
|
||||
const changeAccount = async (npub: string) => {
|
||||
if (npub === account) return;
|
||||
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.");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -94,7 +100,7 @@ function Accounts() {
|
||||
<User.Provider pubkey={user}>
|
||||
<User.Root
|
||||
className={cn(
|
||||
"rounded-full",
|
||||
"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"
|
||||
: "",
|
||||
@@ -102,7 +108,7 @@ function Accounts() {
|
||||
>
|
||||
<User.Avatar
|
||||
className={cn(
|
||||
"aspect-square h-auto rounded-full object-cover",
|
||||
"aspect-square h-auto rounded-full object-cover transition-all ease-in-out duration-150 will-change-auto",
|
||||
user === account ? "w-7" : "w-8",
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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",
|
||||
|
||||
24
package.json
24
package.json
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 [];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@lume/tsconfig": "workspace:*",
|
||||
"@types/react": "^18.3.1",
|
||||
"@types/react": "^18.3.2",
|
||||
"typescript": "^5.4.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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
1680
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
20
src-tauri/Cargo.lock
generated
20
src-tauri/Cargo.lock
generated
@@ -704,9 +704,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 +771,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",
|
||||
]
|
||||
@@ -2235,9 +2235,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"
|
||||
@@ -3038,9 +3038,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "muda"
|
||||
version = "0.13.2"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6fde56ead0971b4caae4aa0f19502e49d1fac2af9d0c60068e2d235e26ce709"
|
||||
checksum = "80540ed8e87ad7c2a4890cde4ba1232d8d775394853f02e84ed18603a94a0a00"
|
||||
dependencies = [
|
||||
"cocoa",
|
||||
"crossbeam-channel",
|
||||
@@ -4459,9 +4459,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"
|
||||
|
||||
@@ -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","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","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"]}}
|
||||
@@ -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])
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
|
||||
"productName": "Lume",
|
||||
"version": "4.0.1",
|
||||
"version": "4.0.2",
|
||||
"identifier": "nu.lume.Lume",
|
||||
"build": {
|
||||
"beforeBuildCommand": "pnpm desktop:build",
|
||||
|
||||
Reference in New Issue
Block a user