Compare commits

..
14 Commits
Author SHA1 Message Date
reya a5255fa503 chore: bump version 2024-07-31 12:51:41 +07:00
reya 954a17b541 fix: build on linux 2024-07-31 12:51:17 +07:00
reya a55b31b0e6 feat: add keyring support for linux and windows 2024-07-31 10:59:54 +07:00
reya bdf3ffd7bf fix: tray panel is missing 2024-07-19 13:58:32 +07:00
reya 07ce253f5b fix: child webview is not reposition after scroll 2024-07-19 13:10:29 +07:00
reya f3db010c74 chore: update tauri config 2024-07-19 10:01:20 +07:00
reya dcf2791fe5 fix: build 2024-07-19 09:28:03 +07:00
reya 8fcf3551d8 chore: bump version 2024-07-19 08:33:46 +07:00
reya 2d987849d8 feat: use native border in macos 2024-07-19 08:33:16 +07:00
reya 3b99926f3b feat: adapt latest changes in tauri v2 2024-07-19 08:25:36 +07:00
reya 113d69a4df chore: update deps 2024-07-18 18:57:28 +07:00
reya 5d12ba7216 fix: some screen too large 2024-07-03 14:36:54 +07:00
reya 72b59020b4 fix: build on linux and windows 2024-07-03 14:09:07 +07:00
XIAO YUandGitHub 4c323b9daa chore: Refactor code to use HashSet for account search results (#222) 2024-07-03 07:33:16 +07:00
53 changed files with 3729 additions and 3701 deletions
+4 -4
View File
@@ -18,10 +18,10 @@ jobs:
args: "--target x86_64-apple-darwin"
- platform: "macos-latest" # for Intel based macs.
args: "--target universal-apple-darwin"
#- platform: 'ubuntu-22.04'
# args: ''
#- platform: 'windows-latest'
# args: '--target x86_64-pc-windows-msvc'
- platform: 'ubuntu-22.04'
args: ''
- platform: 'windows-latest'
args: '--target x86_64-pc-windows-msvc'
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v4
+13 -14
View File
@@ -21,20 +21,20 @@
"@radix-ui/react-switch": "^1.1.0",
"@radix-ui/react-tabs": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.2",
"@tanstack/query-persist-client-core": "^5.49.1",
"@tanstack/react-query": "^5.49.2",
"@tanstack/react-router": "^1.43.3",
"embla-carousel-react": "^8.1.5",
"i18next": "^23.11.5",
"@tanstack/query-persist-client-core": "^5.51.9",
"@tanstack/react-query": "^5.51.9",
"@tanstack/react-router": "^1.45.4",
"embla-carousel-react": "^8.1.6",
"i18next": "^23.12.1",
"i18next-resources-to-backend": "^1.2.1",
"minidenticons": "^4.2.1",
"nanoid": "^5.0.7",
"nostr-tools": "^2.7.0",
"nostr-tools": "^2.7.1",
"react": "^18.3.1",
"react-currency-input-field": "^3.8.0",
"react-dom": "^18.3.1",
"react-hook-form": "^7.52.0",
"react-i18next": "^14.1.2",
"react-hook-form": "^7.52.1",
"react-i18next": "^14.1.3",
"react-string-replace": "^1.1.1",
"slate": "^0.103.0",
"slate-react": "^0.105.0",
@@ -45,17 +45,16 @@
"@lume/tailwindcss": "workspace:^",
"@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^",
"@tanstack/router-devtools": "^1.43.3",
"@tanstack/router-vite-plugin": "^1.43.1",
"@tanstack/router-devtools": "^1.45.4",
"@tanstack/router-vite-plugin": "^1.45.3",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react-swc": "^3.7.0",
"autoprefixer": "^10.4.19",
"postcss": "^8.4.39",
"tailwindcss": "^3.4.4",
"typescript": "^5.5.2",
"vite": "^5.3.2",
"vite-plugin-top-level-await": "^1.4.1",
"tailwindcss": "^3.4.6",
"typescript": "^5.5.3",
"vite": "^5.3.4",
"vite-tsconfig-paths": "^4.3.2"
}
}
+8 -5
View File
@@ -3,7 +3,7 @@ import type { LumeColumn } from "@lume/types";
import { invoke } from "@tauri-apps/api/core";
import { listen } from "@tauri-apps/api/event";
import { Menu, MenuItem, PredefinedMenuItem } from "@tauri-apps/api/menu";
import { getCurrent } from "@tauri-apps/api/webviewWindow";
import { getCurrentWindow } from "@tauri-apps/api/window";
import { memo, useCallback, useEffect, useRef, useState } from "react";
type WindowEvent = {
@@ -106,7 +106,7 @@ function Header({
const [isChanged, setIsChanged] = useState(false);
const saveNewTitle = async () => {
const mainWindow = getCurrent();
const mainWindow = getCurrentWindow();
await mainWindow.emit("columns", { type: "set_title", label, title });
// update search params
@@ -135,7 +135,7 @@ function Header({
MenuItem.new({
text: "Move left",
action: async () => {
await getCurrent().emit("columns", {
await getCurrentWindow().emit("columns", {
type: "move",
label,
direction: "left",
@@ -145,7 +145,7 @@ function Header({
MenuItem.new({
text: "Move right",
action: async () => {
await getCurrent().emit("columns", {
await getCurrentWindow().emit("columns", {
type: "move",
label,
direction: "right",
@@ -156,7 +156,10 @@ function Header({
MenuItem.new({
text: "Close",
action: async () => {
await getCurrent().emit("columns", { type: "remove", label });
await getCurrentWindow().emit("columns", {
type: "remove",
label,
});
},
}),
]);
+8 -8
View File
@@ -5,7 +5,7 @@ import { NostrQuery } from "@lume/system";
import type { ColumnEvent, LumeColumn } from "@lume/types";
import { createFileRoute } from "@tanstack/react-router";
import { listen } from "@tauri-apps/api/event";
import { getCurrent } from "@tauri-apps/api/window";
import { getCurrentWindow } from "@tauri-apps/api/window";
import useEmblaCarousel from "embla-carousel-react";
import { nanoid } from "nanoid";
import { useCallback, useEffect, useState } from "react";
@@ -30,23 +30,23 @@ function Screen() {
});
const scrollPrev = useCallback(() => {
if (emblaApi) emblaApi.scrollPrev(true);
if (emblaApi) emblaApi.scrollPrev();
}, [emblaApi]);
const scrollNext = useCallback(() => {
if (emblaApi) emblaApi.scrollNext(true);
if (emblaApi) emblaApi.scrollNext();
}, [emblaApi]);
const emitScrollEvent = useCallback(() => {
getCurrent().emit("child_webview", { scroll: true });
getCurrentWindow().emit("child_webview", { scroll: true });
}, []);
const emitResizeEvent = useCallback(() => {
getCurrent().emit("child_webview", { resize: true, direction: "x" });
getCurrentWindow().emit("child_webview", { resize: true, direction: "x" });
}, []);
const openLumeStore = useCallback(async () => {
await getCurrent().emit("columns", {
await getCurrentWindow().emit("columns", {
type: "add",
column: {
label: "store",
@@ -101,10 +101,10 @@ function Screen() {
switch (event.code) {
case "ArrowLeft":
if (emblaApi) emblaApi.scrollPrev(true);
if (emblaApi) emblaApi.scrollPrev();
break;
case "ArrowRight":
if (emblaApi) emblaApi.scrollNext(true);
if (emblaApi) emblaApi.scrollNext();
break;
default:
break;
+3 -3
View File
@@ -9,7 +9,7 @@ import { LumeWindow, NostrAccount, NostrQuery } from "@lume/system";
import { cn } from "@lume/utils";
import { Outlet, createFileRoute } from "@tanstack/react-router";
import { Menu, MenuItem, PredefinedMenuItem } from "@tauri-apps/api/menu";
import { getCurrent } from "@tauri-apps/api/window";
import { getCurrentWindow } from "@tauri-apps/api/window";
import { message } from "@tauri-apps/plugin-dialog";
import { memo, useCallback, useState } from "react";
@@ -30,7 +30,7 @@ function Screen() {
const { settings, platform } = Route.useRouteContext();
const openLumeStore = async () => {
await getCurrent().emit("columns", {
await getCurrentWindow().emit("columns", {
type: "add",
column: {
label: "store",
@@ -137,7 +137,7 @@ const Accounts = memo(function Accounts() {
if (select) {
// Reset current columns
await getCurrent().emit("columns", { type: "reset" });
await getCurrentWindow().emit("columns", { type: "reset" });
// Redirect to new account
return navigate({
-1
View File
@@ -11,7 +11,6 @@ interface RouterContext {
export const Route = createRootRouteWithContext<RouterContext>()({
component: () => <Outlet />,
pendingComponent: Pending,
wrapInSuspense: true,
});
function Pending() {
+3 -3
View File
@@ -1,4 +1,4 @@
import { Box, Container } from "@lume/ui";
import { Container } from "@lume/ui";
import { Outlet, createLazyFileRoute } from "@tanstack/react-router";
export const Route = createLazyFileRoute("/auth")({
@@ -8,9 +8,9 @@ export const Route = createLazyFileRoute("/auth")({
function Screen() {
return (
<Container withDrag>
<Box className="px-3 pt-3">
<div className="max-w-sm mx-auto size-full">
<Outlet />
</Box>
</div>
</Container>
);
}
@@ -55,12 +55,13 @@ function Screen() {
};
return (
<div className="flex flex-col items-center justify-center w-full h-full gap-6 px-5 mx-auto xl:max-w-xl">
<div className="flex flex-col items-center justify-center size-full gap-4">
<div className="text-center">
<h3 className="text-xl font-semibold">Let's set up your profile.</h3>
</div>
<div>
<div className="relative rounded-full size-24 bg-gradient-to-tr from-orange-100 via-red-50 to-blue-200">
<form onSubmit={handleSubmit(onSubmit)} className="w-full mb-0">
<div className="flex flex-col gap-3 w-full p-3 overflow-hidden bg-white rounded-xl shadow-primary dark:bg-white/10 dark:ring-1 ring-white/15">
<div className="self-center relative rounded-full size-20 bg-neutral-200 dark:bg-white/70 my-3">
{picture ? (
<img
src={picture}
@@ -77,11 +78,6 @@ function Screen() {
<PlusIcon className="size-8" />
</AvatarUploader>
</div>
</div>
<form
onSubmit={handleSubmit(onSubmit)}
className="flex flex-col w-full gap-3"
>
<div className="flex flex-col gap-1">
<label htmlFor="display_name" className="font-medium">
Display Name *
@@ -129,9 +125,11 @@ function Screen() {
className="px-3 border-transparent rounded-lg h-11 bg-neutral-100 placeholder:text-neutral-500 focus:border-blue-500 focus:ring-0 dark:bg-white/10 dark:placeholder:text-neutral-400"
/>
</div>
</div>
<button
type="submit"
className="inline-flex items-center justify-center w-full mt-3 font-semibold text-white bg-blue-500 rounded-lg h-11 shrink-0 hover:bg-blue-600 disabled:opacity-50"
disabled={loading}
className="inline-flex items-center justify-center w-full h-9 mt-4 text-sm font-semibold text-white bg-blue-500 rounded-lg shrink-0 hover:bg-blue-600 disabled:opacity-50"
>
{loading ? <Spinner /> : "Continue"}
</button>
@@ -38,11 +38,12 @@ function Screen() {
};
return (
<div className="flex flex-col items-center justify-center w-full h-full gap-6 px-5 mx-auto xl:max-w-xl">
<div className="flex flex-col items-center justify-center size-full gap-4">
<div className="text-center">
<h3 className="text-xl font-semibold">Continue with Private Key</h3>
</div>
<div className="flex flex-col w-full gap-3">
<div className="flex flex-col w-full">
<div className="flex flex-col gap-3 w-full p-3 overflow-hidden bg-white rounded-xl shadow-primary dark:bg-white/10 dark:ring-1 ring-white/15">
<div className="flex flex-col gap-1">
<label
htmlFor="key"
@@ -74,11 +75,12 @@ function Screen() {
className="px-3 border-transparent rounded-lg h-11 bg-neutral-100 placeholder:text-neutral-600 focus:border-blue-500 focus:ring-0 dark:bg-white/10 dark:placeholder:text-neutral-400"
/>
</div>
</div>
<button
type="button"
onClick={() => submit()}
disabled={loading}
className="inline-flex items-center justify-center w-full mt-3 font-semibold text-white bg-blue-500 rounded-lg h-11 shrink-0 hover:bg-blue-600 disabled:opacity-50"
className="inline-flex items-center justify-center w-full h-9 mt-4 text-sm font-semibold text-white bg-blue-500 rounded-lg shrink-0 hover:bg-blue-600 disabled:opacity-50"
>
{loading ? <Spinner /> : "Login"}
</button>
@@ -37,12 +37,12 @@ function Screen() {
};
return (
<div className="flex flex-col items-center justify-center w-full h-full gap-6 px-5 mx-auto xl:max-w-xl">
<div className="flex flex-col items-center justify-center size-full gap-4">
<div className="text-center">
<h3 className="text-xl font-semibold">Continue with Nostr Connect</h3>
</div>
<div className="flex flex-col w-full gap-3">
<div className="flex flex-col gap-1">
<div className="flex flex-col w-full">
<div className="flex flex-col gap-1 w-full p-3 overflow-hidden bg-white rounded-xl shadow-primary dark:bg-white/10 dark:ring-1 ring-white/15">
<label
htmlFor="uri"
className="font-medium text-neutral-900 dark:text-neutral-100"
@@ -63,7 +63,7 @@ function Screen() {
type="button"
onClick={() => submit()}
disabled={loading}
className="inline-flex items-center justify-center w-full mt-3 font-semibold text-white bg-blue-500 rounded-lg h-11 shrink-0 hover:bg-blue-600 disabled:opacity-50"
className="inline-flex items-center justify-center w-full h-9 mt-4 text-sm font-semibold text-white bg-blue-500 rounded-lg shrink-0 hover:bg-blue-600 disabled:opacity-50"
>
{loading ? <Spinner /> : "Login"}
</button>
@@ -65,9 +65,9 @@ function Screen() {
data-tauri-drag-region
className="absolute top-0 left-0 h-14 w-full"
/>
<div className="flex items-end justify-center flex-1 w-full px-4 pb-10">
<div className="flex items-end justify-center flex-1 w-full px-4 pb-4">
<div className="text-center">
<h2 className="text-2xl font-semibold">Customize Bootstrap Relays</h2>
<h2 className="text-xl font-semibold">Customize Bootstrap Relays</h2>
</div>
</div>
<div className="flex flex-col items-center flex-1 w-full">
@@ -3,7 +3,7 @@ import { NostrQuery } from "@lume/system";
import { Spinner } from "@lume/ui";
import { insertImage, isImagePath } from "@lume/utils";
import type { UnlistenFn } from "@tauri-apps/api/event";
import { getCurrent } from "@tauri-apps/api/window";
import { getCurrentWindow } from "@tauri-apps/api/window";
import { message } from "@tauri-apps/plugin-dialog";
import { useEffect, useState } from "react";
import { useSlateStatic } from "slate-react";
@@ -32,7 +32,7 @@ export function MediaButton() {
let unlisten: UnlistenFn = undefined;
async function listenFileDrop() {
const window = getCurrent();
const window = getCurrentWindow();
if (!unlisten) {
unlisten = await window.listen("tauri://file-drop", async (event) => {
// @ts-ignore, lfg !!!
+8 -5
View File
@@ -3,7 +3,7 @@ import { LumeEvent, NostrQuery } from "@lume/system";
import type { Meta } from "@lume/types";
import * as ScrollArea from "@radix-ui/react-scroll-area";
import { createFileRoute } from "@tanstack/react-router";
import { getCurrent } from "@tauri-apps/api/window";
import { getCurrentWindow } from "@tauri-apps/api/window";
import { useEffect, useRef, useState } from "react";
import { Virtualizer } from "virtua";
import NoteParent from "./-components/parent";
@@ -83,14 +83,17 @@ function ReplyList() {
const [replies, setReplies] = useState<LumeEvent[]>([]);
useEffect(() => {
const unlistenEvent = getCurrent().listen<Payload>("new_reply", (data) => {
const unlistenEvent = getCurrentWindow().listen<Payload>(
"new_reply",
(data) => {
const event = LumeEvent.from(data.payload.raw, data.payload.parsed);
setReplies((prev) => [event, ...prev]);
});
},
);
const unlistenWindow = getCurrent().onCloseRequested(async () => {
const unlistenWindow = getCurrentWindow().onCloseRequested(async () => {
await event.unlistenEventReply();
await getCurrent().destroy();
await getCurrentWindow().destroy();
});
return () => {
+2 -2
View File
@@ -10,7 +10,7 @@ import * as ScrollArea from "@radix-ui/react-scroll-area";
import { type InfiniteData, useInfiniteQuery } from "@tanstack/react-query";
import { createFileRoute, redirect } from "@tanstack/react-router";
import { listen } from "@tauri-apps/api/event";
import { getCurrent } from "@tauri-apps/api/window";
import { getCurrentWindow } from "@tauri-apps/api/window";
import { useCallback, useEffect, useRef, useState } from "react";
import { Virtualizer } from "virtua";
@@ -195,7 +195,7 @@ function Listerner() {
};
useEffect(() => {
const unlisten = getCurrent().listen<Payload>("new_event", (data) => {
const unlisten = getCurrentWindow().listen<Payload>("new_event", (data) => {
const event = LumeEvent.from(data.payload.raw, data.payload.parsed);
setEvents((prev) => [event, ...prev]);
});
+6 -2
View File
@@ -15,12 +15,15 @@ import { useQuery } from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import { invoke } from "@tauri-apps/api/core";
import { Menu, MenuItem, PredefinedMenuItem } from "@tauri-apps/api/menu";
import { getCurrent } from "@tauri-apps/api/window";
import { getCurrentWindow } from "@tauri-apps/api/window";
import { open } from "@tauri-apps/plugin-shell";
import { type ReactNode, useCallback, useEffect, useRef } from "react";
import { Virtualizer } from "virtua";
export const Route = createFileRoute("/panel/$account")({
beforeLoad: async ({ context }) => {
console.log(context);
},
component: Screen,
});
@@ -30,6 +33,7 @@ function Screen() {
const { isLoading, data } = useQuery({
queryKey: ["notification", account],
queryFn: async () => {
console.log(queryClient);
const events = await NostrQuery.getNotifications();
return events;
},
@@ -110,7 +114,7 @@ function Screen() {
}, []);
useEffect(() => {
const unlisten = getCurrent().listen("notification", async (data) => {
const unlisten = getCurrentWindow().listen("notification", async (data) => {
const event: LumeEvent = JSON.parse(data.payload as string);
await queryClient.setQueryData(
["notification", account],
@@ -1,7 +1,7 @@
import { Button, init } from "@getalby/bitcoin-connect-react";
import { NostrAccount } from "@lume/system";
import { createFileRoute } from "@tanstack/react-router";
import { getCurrent } from "@tauri-apps/api/webviewWindow";
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow";
export const Route = createFileRoute("/settings/bitcoin-connect")({
beforeLoad: () => {
@@ -17,7 +17,7 @@ export const Route = createFileRoute("/settings/bitcoin-connect")({
function Screen() {
const setNwcUri = async (uri: string) => {
const cmd = await NostrAccount.setWallet(uri);
if (cmd) getCurrent().close();
if (cmd) getCurrentWebviewWindow().close();
};
return (
+2 -2
View File
@@ -3,7 +3,7 @@ import type { LumeColumn } from "@lume/types";
import * as ScrollArea from "@radix-ui/react-scroll-area";
import { createFileRoute } from "@tanstack/react-router";
import { resolveResource } from "@tauri-apps/api/path";
import { getCurrent } from "@tauri-apps/api/window";
import { getCurrentWindow } from "@tauri-apps/api/window";
import { readTextFile } from "@tauri-apps/plugin-fs";
export const Route = createFileRoute("/store")({
@@ -24,7 +24,7 @@ function Screen() {
const { officialColumns } = Route.useRouteContext();
const install = async (column: LumeColumn) => {
const mainWindow = getCurrent();
const mainWindow = getCurrentWindow();
await mainWindow.emit("columns", { type: "add", column });
};
+2 -2
View File
@@ -1,7 +1,7 @@
import { User } from "@/components/user";
import { NostrQuery } from "@lume/system";
import { createFileRoute } from "@tanstack/react-router";
import { getCurrent } from "@tauri-apps/api/webviewWindow";
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow";
import { message } from "@tauri-apps/plugin-dialog";
import { useState } from "react";
import CurrencyInput from "react-currency-input-field";
@@ -35,7 +35,7 @@ function Screen() {
if (val) {
setIsCompleted(true);
// close current window
await getCurrent().close();
await getCurrentWebviewWindow().close();
}
} catch (e) {
setIsLoading(false);
+1 -10
View File
@@ -1,19 +1,10 @@
import { TanStackRouterVite } from "@tanstack/router-vite-plugin";
import react from "@vitejs/plugin-react-swc";
import { defineConfig } from "vite";
import topLevelAwait from "vite-plugin-top-level-await";
import viteTsconfigPaths from "vite-tsconfig-paths";
export default defineConfig({
plugins: [
react(),
viteTsconfigPaths(),
topLevelAwait({
promiseExportName: "__tla",
promiseImportName: (i) => `__tla_${i}`,
}),
TanStackRouterVite(),
],
plugins: [react(), viteTsconfigPaths(), TanStackRouterVite()],
build: {
outDir: "../../dist",
},
+3 -3
View File
@@ -13,12 +13,12 @@
"@astrojs/check": "^0.5.10",
"@astrojs/tailwind": "^5.1.0",
"@fontsource/alice": "^5.0.13",
"astro": "^4.11.3",
"astro": "^4.11.6",
"astro-seo-meta": "^4.1.1",
"astro-seo-schema": "^4.0.2",
"schema-dts": "^1.1.2",
"tailwindcss": "^3.4.4",
"typescript": "^5.5.2"
"tailwindcss": "^3.4.6",
"typescript": "^5.5.3"
},
"devDependencies": {
"@tailwindcss/typography": "^0.5.13"
+4 -1
View File
@@ -4,7 +4,10 @@
"enabled": true
},
"files": {
"ignore": ["apps/desktop2/src/router.gen.ts"]
"ignore": [
"apps/desktop2/src/router.gen.ts",
"packages/system/src/commands.ts"
]
},
"linter": {
"enabled": true,
+12 -12
View File
@@ -12,7 +12,7 @@
},
"devDependencies": {
"@biomejs/biome": "^1.8.3",
"@tauri-apps/cli": "2.0.0-beta.20",
"@tauri-apps/cli": "2.0.0-beta.22",
"turbo": "^1.13.4"
},
"packageManager": "pnpm@8.9.0",
@@ -20,16 +20,16 @@
"node": ">=18"
},
"dependencies": {
"@tauri-apps/api": "2.0.0-beta.13",
"@tauri-apps/plugin-clipboard-manager": "2.1.0-beta.3",
"@tauri-apps/plugin-dialog": "2.0.0-beta.5",
"@tauri-apps/plugin-fs": "2.0.0-beta.5",
"@tauri-apps/plugin-http": "2.0.0-beta.5",
"@tauri-apps/plugin-os": "github:tauri-apps/tauri-plugin-os#v2",
"@tauri-apps/plugin-process": "2.0.0-beta.5",
"@tauri-apps/plugin-shell": "2.0.0-beta.6",
"@tauri-apps/plugin-updater": "2.0.0-beta.5",
"@tauri-apps/plugin-upload": "2.0.0-beta.6",
"@tauri-apps/plugin-window-state": "2.0.0-beta.6"
"@tauri-apps/api": "2.0.0-beta.15",
"@tauri-apps/plugin-clipboard-manager": "2.1.0-beta.5",
"@tauri-apps/plugin-dialog": "2.0.0-beta.7",
"@tauri-apps/plugin-fs": "2.0.0-beta.7",
"@tauri-apps/plugin-http": "2.0.0-beta.8",
"@tauri-apps/plugin-os": "2.0.0-beta.7",
"@tauri-apps/plugin-process": "2.0.0-beta.7",
"@tauri-apps/plugin-shell": "2.0.0-beta.8",
"@tauri-apps/plugin-updater": "2.0.0-beta.7",
"@tauri-apps/plugin-upload": "2.0.0-beta.8",
"@tauri-apps/plugin-window-state": "2.0.0-beta.8"
}
}
+1 -1
View File
@@ -9,6 +9,6 @@
"devDependencies": {
"@lume/tsconfig": "workspace:*",
"@types/react": "^18.3.3",
"typescript": "^5.5.2"
"typescript": "^5.5.3"
}
}
+4 -4
View File
@@ -5,15 +5,15 @@
"main": "./src/index.ts",
"dependencies": {
"@lume/utils": "workspace:^",
"@tanstack/query-persist-client-core": "^5.49.1",
"@tanstack/react-query": "^5.49.2",
"nostr-tools": "^2.7.0",
"@tanstack/query-persist-client-core": "^5.51.9",
"@tanstack/react-query": "^5.51.9",
"nostr-tools": "^2.7.1",
"react": "^18.3.1"
},
"devDependencies": {
"@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^",
"@types/react": "^18.3.3",
"typescript": "^5.5.2"
"typescript": "^5.5.3"
}
}
+1 -6
View File
@@ -4,12 +4,7 @@ import { type Result, commands } from "./commands";
export const NostrAccount = {
getAccounts: async () => {
const query = await commands.getAccounts();
if (query.status === "ok") {
return query.data;
} else {
return [];
}
return query;
},
loadAccount: async (npub: string) => {
const bunker: string = localStorage.getItem(`${npub}_bunker`);
+2 -7
View File
@@ -44,13 +44,8 @@ try {
else return { status: "error", error: e as any };
}
},
async getAccounts() : Promise<Result<string[], string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("get_accounts") };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
async getAccounts() : Promise<string[]> {
return await TAURI_INVOKE("get_accounts");
},
async createAccount() : Promise<Result<Account, string>> {
try {
+3 -3
View File
@@ -1,6 +1,6 @@
import type { LumeColumn, Metadata, NostrEvent, Relay } from "@lume/types";
import { resolveResource } from "@tauri-apps/api/path";
import { getCurrent } from "@tauri-apps/api/window";
import { getCurrentWindow } from "@tauri-apps/api/window";
import { open } from "@tauri-apps/plugin-dialog";
import { readFile, readTextFile } from "@tauri-apps/plugin-fs";
import { relaunch } from "@tauri-apps/plugin-process";
@@ -201,7 +201,7 @@ export const NostrQuery = {
}
},
listenLocalEvent: async () => {
const label = getCurrent().label;
const label = getCurrentWindow().label;
const query = await commands.listenLocalEvent(label);
if (query.status === "ok") {
@@ -394,7 +394,7 @@ export const NostrQuery = {
}
},
unlisten: async (id?: string) => {
const label = id ? id : getCurrent().label;
const label = id ? id : getCurrentWindow().label;
const query = await commands.unlisten(label);
if (query.status === "ok") {
+1 -1
View File
@@ -15,7 +15,7 @@
"@tailwindcss/typography": "^0.5.13",
"tailwind-gradient-mask-image": "^1.2.0",
"tailwind-scrollbar": "^3.1.0",
"tailwindcss": "^3.4.4",
"tailwindcss": "^3.4.6",
"tailwindcss-content-visibility": "^0.2.0"
}
}
+1 -1
View File
@@ -9,6 +9,6 @@
"access": "public"
},
"devDependencies": {
"typescript": "^5.5.2"
"typescript": "^5.5.3"
}
}
+2 -2
View File
@@ -15,7 +15,7 @@
"@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^",
"@types/react": "^18.3.3",
"tailwindcss": "^3.4.4",
"typescript": "^5.5.2"
"tailwindcss": "^3.4.6",
"typescript": "^5.5.3"
}
}
+3 -3
View File
@@ -12,7 +12,7 @@
"clsx": "^2.1.1",
"dayjs": "^1.11.11",
"light-bolt11-decoder": "^3.1.1",
"nostr-tools": "^2.7.0",
"nostr-tools": "^2.7.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"slate": "^0.103.0",
@@ -23,7 +23,7 @@
"@lume/types": "workspace:^",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"tailwind-merge": "^2.3.0",
"typescript": "^5.5.2"
"tailwind-merge": "^2.4.0",
"typescript": "^5.5.3"
}
}
+836 -927
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -1 +0,0 @@
tab_spaces=2
+273 -219
View File
File diff suppressed because it is too large Load Diff
+10 -5
View File
@@ -11,7 +11,7 @@ rust-version = "1.70"
tauri-build = { version = "2.0.0-beta", features = [] }
[dependencies]
nostr-sdk = { version = "0.32", features = ["sqlite"] }
nostr-sdk = { version = "0.33", features = ["sqlite"] }
tokio = { version = "1", features = ["full"] }
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
@@ -33,19 +33,23 @@ tauri-plugin-process = { git = "https://github.com/tauri-apps/plugins-workspace"
tauri-plugin-shell = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
tauri-plugin-updater = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
tauri-plugin-upload = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v2" }
tauri-specta = { git = "https://github.com/reyamir/tauri-specta", features = [
tauri-specta = { git = "https://github.com/reyamir/tauri-specta", branch = "feat/tauri-v2", features = [
"typescript",
] }
tauri-plugin-theme = "0.4.1"
tauri-plugin-decorum = "0.1.0"
tauri-plugin-decorum = { git = "https://github.com/reyamir/tauri-plugin-decorum", branch = "feat/tauri-v2" }
specta = "^2.0.0-rc.12"
keyring = "2"
keyring-search = "0.2.0"
reqwest = "0.12.4"
url = "2.5.0"
futures = "0.3.30"
linkify = "0.10.0"
regex = "1.10.4"
keyring = { version = "3", features = [
"apple-native",
"windows-native",
"sync-secret-service",
] }
keyring-search = "1.2.0"
[target.'cfg(target_os = "macos")'.dependencies]
cocoa = "0.25.0"
@@ -53,6 +57,7 @@ objc = "0.2.7"
rand = "0.8.5"
monitor = { git = "https://github.com/ahkohd/tauri-toolkit", branch = "v2" }
tauri-nspanel = { git = "https://github.com/ahkohd/tauri-nspanel", branch = "v2" }
border = { git = "https://github.com/ahkohd/tauri-toolkit", branch = "v2" }
[profile.release]
codegen-units = 1
File diff suppressed because one or more lines are too long
+14
View File
@@ -6738,6 +6738,13 @@
"window:allow-set-title"
]
},
{
"description": "window:allow-set-title-bar-style -> Enables the set_title_bar_style command without any pre-configured scope.",
"type": "string",
"enum": [
"window:allow-set-title-bar-style"
]
},
{
"description": "window:allow-set-visible-on-all-workspaces -> Enables the set_visible_on_all_workspaces command without any pre-configured scope.",
"type": "string",
@@ -7179,6 +7186,13 @@
"window:deny-set-title"
]
},
{
"description": "window:deny-set-title-bar-style -> Denies the set_title_bar_style command without any pre-configured scope.",
"type": "string",
"enum": [
"window:deny-set-title-bar-style"
]
},
{
"description": "window:deny-set-visible-on-all-workspaces -> Denies the set_visible_on_all_workspaces command without any pre-configured scope.",
"type": "string",
+14
View File
@@ -6738,6 +6738,13 @@
"window:allow-set-title"
]
},
{
"description": "window:allow-set-title-bar-style -> Enables the set_title_bar_style command without any pre-configured scope.",
"type": "string",
"enum": [
"window:allow-set-title-bar-style"
]
},
{
"description": "window:allow-set-visible-on-all-workspaces -> Enables the set_visible_on_all_workspaces command without any pre-configured scope.",
"type": "string",
@@ -7179,6 +7186,13 @@
"window:deny-set-title"
]
},
{
"description": "window:deny-set-title-bar-style -> Denies the set_title_bar_style command without any pre-configured scope.",
"type": "string",
"enum": [
"window:deny-set-title-bar-style"
]
},
{
"description": "window:deny-set-visible-on-all-workspaces -> Denies the set_visible_on_all_workspaces command without any pre-configured scope.",
"type": "string",
+2 -5
View File
@@ -1,6 +1,6 @@
use std::ffi::CString;
use tauri::{AppHandle, Manager, WebviewWindow};
use tauri::{AppHandle, Emitter, Listener, Manager, WebviewWindow};
use tauri_nspanel::{
block::ConcreteBlock,
cocoa::{
@@ -27,12 +27,9 @@ pub fn swizzle_to_menubar_panel(app_handle: &tauri::AppHandle) {
let handle = app_handle.clone();
panel_delegate.set_listener(Box::new(move |delegate_name: String| {
match delegate_name.as_str() {
"window_did_resign_key" => {
if delegate_name.as_str() == "window_did_resign_key" {
let _ = handle.emit("menubar_panel_did_resign_key", ());
}
_ => (),
}
}));
panel.set_level(NSMainMenuWindowLevel + 1);
+2
View File
@@ -1,3 +1,5 @@
#[cfg(target_os = "macos")]
pub mod fns;
#[cfg(target_os = "macos")]
pub mod tray;
pub mod window;
+33 -13
View File
@@ -1,16 +1,21 @@
use std::path::PathBuf;
use std::str::FromStr;
#[cfg(target_os = "macos")]
use border::WebviewWindowExt as BorderWebviewWindowExt;
#[cfg(target_os = "macos")]
use cocoa::{appkit::NSApp, base::nil, foundation::NSString};
use serde::{Deserialize, Serialize};
use specta::Type;
#[cfg(not(target_os = "linux"))]
use tauri::utils::config::WindowEffectsConfig;
#[cfg(not(target_os = "linux"))]
use tauri::window::Effect;
#[cfg(target_os = "macos")]
use tauri::TitleBarStyle;
use tauri::WebviewWindowBuilder;
use tauri::{LogicalPosition, LogicalSize, Manager, State, WebviewUrl};
#[cfg(not(target_os = "linux"))]
use tauri_plugin_decorum::WebviewWindowExt;
use url::Url;
@@ -177,6 +182,7 @@ pub fn open_window(window: Window, app_handle: tauri::AppHandle) -> Result<(), S
.title_bar_style(TitleBarStyle::Overlay)
.minimizable(window.minimizable)
.maximizable(window.maximizable)
.transparent(true)
.effects(WindowEffectsConfig {
state: None,
effects: vec![Effect::UnderWindowBackground],
@@ -187,10 +193,16 @@ pub fn open_window(window: Window, app_handle: tauri::AppHandle) -> Result<(), S
.unwrap();
#[cfg(target_os = "windows")]
let window = WebviewWindowBuilder::new(&app_handle, label, WebviewUrl::App(PathBuf::from(url)))
.title(title)
.min_inner_size(width, height)
.inner_size(width, height)
let window = WebviewWindowBuilder::new(
&app_handle,
&window.label,
WebviewUrl::App(PathBuf::from(window.url)),
)
.title(&window.title)
.min_inner_size(window.width, window.height)
.inner_size(window.width, window.height)
.minimizable(window.minimizable)
.maximizable(window.maximizable)
.effects(WindowEffectsConfig {
state: None,
effects: vec![Effect::Mica],
@@ -201,19 +213,26 @@ pub fn open_window(window: Window, app_handle: tauri::AppHandle) -> Result<(), S
.unwrap();
#[cfg(target_os = "linux")]
let window = WebviewWindowBuilder::new(&app_handle, label, WebviewUrl::App(PathBuf::from(url)))
.title(title)
.min_inner_size(width, height)
.inner_size(width, height)
let window = WebviewWindowBuilder::new(
&app_handle,
&window.label,
WebviewUrl::App(PathBuf::from(window.url)),
)
.title(&window.title)
.min_inner_size(window.width, window.height)
.inner_size(window.width, window.height)
.minimizable(window.minimizable)
.maximizable(window.maximizable)
.build()
.unwrap();
// Set decoration
#[cfg(not(target_os = "linux"))]
window.create_overlay_titlebar().unwrap();
// Make main window transparent
// Restore native border
#[cfg(target_os = "macos")]
window.make_transparent().unwrap();
window.add_border(None);
}
Ok(())
@@ -230,14 +249,15 @@ pub fn open_main_window(app: tauri::AppHandle) {
let _ = window.set_focus();
};
} else {
let window = WebviewWindowBuilder::from_config(&app, app.config().app.windows.first().unwrap())
let window =
WebviewWindowBuilder::from_config(&app, app.config().app.windows.first().unwrap())
.unwrap()
.build()
.unwrap();
// Make main window transparent
// Restore native border
#[cfg(target_os = "macos")]
window.make_transparent().unwrap();
window.add_border(None);
}
}
+35 -20
View File
@@ -9,6 +9,8 @@ extern crate cocoa;
#[macro_use]
extern crate objc;
#[cfg(target_os = "macos")]
use border::WebviewWindowExt as BorderWebviewWindowExt;
use nostr_sdk::prelude::*;
use serde::{Deserialize, Serialize};
use specta::Type;
@@ -20,6 +22,7 @@ use std::{
str::FromStr,
};
use tauri::{path::BaseDirectory, Manager};
#[cfg(not(target_os = "linux"))]
use tauri_plugin_decorum::WebviewWindowExt;
pub mod commands;
@@ -137,22 +140,45 @@ fn main() {
builder.build().unwrap()
};
tauri::Builder::default()
#[cfg(target_os = "macos")]
let builder = tauri::Builder::default().plugin(tauri_nspanel::init());
#[cfg(not(target_os = "macos"))]
let builder = tauri::Builder::default();
builder
.setup(|app| {
#[cfg(target_os = "macos")]
app.handle().plugin(tauri_nspanel::init()).unwrap();
#[cfg(not(target_os = "linux"))]
let main_window = app.get_webview_window("main").unwrap();
// Set custom decoration for Windows
#[cfg(target_os = "windows")]
main_window.create_overlay_titlebar().unwrap();
// Make main window transparent
// Restore native border
#[cfg(target_os = "macos")]
main_window.make_transparent().unwrap();
main_window.add_border(None);
// Set a custom inset to the traffic lights
#[cfg(target_os = "macos")]
main_window.set_traffic_lights_inset(8.0, 16.0).unwrap();
#[cfg(target_os = "macos")]
let win = main_window.clone();
#[cfg(target_os = "macos")]
main_window.on_window_event(move |event| {
if let tauri::WindowEvent::ThemeChanged(_) = event {
win.set_traffic_lights_inset(8.0, 16.0).unwrap();
}
if let tauri::WindowEvent::Resized(_) = event {
win.set_traffic_lights_inset(8.0, 16.0).unwrap();
}
});
// Create data folder if not exist
let home_dir = app.path().home_dir().unwrap();
let _ = fs::create_dir_all(home_dir.join("Lume/"));
@@ -186,7 +212,10 @@ fn main() {
if let Some((relay, option)) = line.split_once(',') {
match RelayMetadata::from_str(option) {
Ok(meta) => {
println!("connecting to bootstrap relay...: {} - {}", relay, meta);
println!(
"connecting to bootstrap relay...: {} - {}",
relay, meta
);
let opts = if meta == RelayMetadata::Read {
RelayOptions::new().read(true).write(false)
} else {
@@ -216,7 +245,6 @@ fn main() {
Ok(())
})
.plugin(tauri_nspanel::init())
.plugin(tauri_plugin_theme::init(ctx.config_mut()))
.plugin(tauri_plugin_decorum::init())
.plugin(tauri_plugin_clipboard_manager::init())
@@ -229,20 +257,7 @@ fn main() {
.plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_upload::init())
.plugin(tauri_plugin_updater::Builder::new().build())
.plugin(
tauri_plugin_window_state::Builder::new()
.with_denylist(&["panel"])
.build(),
)
.invoke_handler(invoke_handler)
.build(ctx)
.expect("error while running tauri application")
.run(|_, event| {
if let tauri::RunEvent::ExitRequested { api, .. } = event {
// Hide app icon on macOS
// let _ = app.set_activation_policy(tauri::ActivationPolicy::Accessory);
// Keep API running
api.prevent_exit();
}
});
.run(ctx)
.expect("error while running tauri application");
}
+4 -3
View File
@@ -192,7 +192,7 @@ pub async fn listen_event_reply(id: &str, state: State<'_, Nostr>) -> Result<(),
.since(Timestamp::now());
// Subscribe
client.subscribe_with_id(sub_id, vec![filter], None).await;
let _ = client.subscribe_with_id(sub_id, vec![filter], None).await;
Ok(())
}
@@ -308,7 +308,7 @@ pub async fn listen_local_event(label: &str, state: State<'_, Nostr>) -> Result<
.since(Timestamp::now());
// Subscribe
client.subscribe_with_id(sub_id, vec![filter], None).await;
let _ = client.subscribe_with_id(sub_id, vec![filter], None).await;
Ok(())
}
@@ -656,7 +656,8 @@ pub async fn user_to_bech32(user: &str, state: State<'_, Nostr>) -> Result<Strin
.into_iter()
.map(|i| i.0.to_string())
.collect::<Vec<_>>();
let profile = Nip19Profile::new(public_key, relays).map_err(|err| err.to_string())?;
let profile =
Nip19Profile::new(public_key, relays).map_err(|err| err.to_string())?;
Ok(profile.to_bech32().map_err(|err| err.to_string())?)
}
+49 -39
View File
@@ -1,18 +1,20 @@
use keyring::Entry;
use keyring_search::{Limit, List, Search};
use nostr_sdk::prelude::*;
use serde::Serialize;
use specta::Type;
use std::time::Duration;
use tauri::{EventTarget, Manager, State};
use tauri_plugin_notification::NotificationExt;
#[cfg(target_os = "macos")]
use crate::commands::tray::create_tray_panel;
use crate::nostr::event::RichEvent;
use crate::nostr::internal::{get_user_settings, init_nip65};
use crate::nostr::utils::parse_event;
use crate::{Nostr, NEWSFEED_NEG_LIMIT, NOTIFICATION_NEG_LIMIT};
use keyring::Entry;
use keyring_search::{Limit, List, Search};
use nostr_sdk::prelude::*;
use serde::Serialize;
use specta::Type;
use std::collections::HashSet;
use std::time::Duration;
use tauri::{Emitter, EventTarget, Manager, State};
use tauri_plugin_notification::NotificationExt;
#[derive(Serialize, Type)]
pub struct Account {
npub: String,
@@ -21,28 +23,17 @@ pub struct Account {
#[tauri::command]
#[specta::specta]
pub fn get_accounts() -> Result<Vec<String>, String> {
let search = Search::new().unwrap();
let results = search.by("Account", "nostr_secret");
match List::list_credentials(results, Limit::All) {
Ok(list) => {
let search: Vec<String> = list
pub fn get_accounts() -> Vec<String> {
let search = Search::new().expect("Unexpected.");
let results = search.by_service("Lume");
let list = List::list_credentials(&results, Limit::All);
let accounts: HashSet<String> = list
.split_whitespace()
.map(|v| v.to_string())
.filter(|v| v.starts_with("npub1"))
.map(String::from)
.collect();
let accounts: Vec<String> = search
.into_iter()
.collect::<std::collections::HashSet<_>>()
.into_iter()
.collect();
Ok(accounts)
}
Err(_) => Err("Empty.".into()),
}
accounts.into_iter().collect()
}
#[tauri::command]
@@ -63,7 +54,7 @@ pub fn create_account() -> Result<Account, String> {
#[tauri::command]
#[specta::specta]
pub fn get_private_key(npub: &str) -> Result<String, String> {
let keyring = Entry::new(npub, "nostr_secret").unwrap();
let keyring = Entry::new("Lume", npub).unwrap();
if let Ok(nsec) = keyring.get_password() {
let secret_key = SecretKey::from_bech32(nsec).unwrap();
@@ -95,7 +86,7 @@ pub async fn save_account(
let npub = nostr_keys.public_key().to_bech32().unwrap();
let nsec = nostr_keys.secret_key().unwrap().to_bech32().unwrap();
let keyring = Entry::new(&npub, "nostr_secret").unwrap();
let keyring = Entry::new("Lume", &npub).unwrap();
let _ = keyring.set_password(&nsec);
let signer = NostrSigner::Keys(nostr_keys);
@@ -126,7 +117,7 @@ pub async fn connect_remote_account(uri: &str, state: State<'_, Nostr>) -> Resul
match Nip46Signer::new(bunker_uri, app_keys, Duration::from_secs(120), None).await {
Ok(signer) => {
let keyring = Entry::new(&remote_npub, "nostr_secret").unwrap();
let keyring = Entry::new("Lume", &remote_npub).unwrap();
let _ = keyring.set_password(&app_secret);
// Update signer
@@ -144,7 +135,7 @@ pub async fn connect_remote_account(uri: &str, state: State<'_, Nostr>) -> Resul
#[tauri::command]
#[specta::specta]
pub async fn get_encrypted_key(npub: &str, password: &str) -> Result<String, String> {
let keyring = Entry::new(npub, "nostr_secret").unwrap();
let keyring = Entry::new("Lume", npub).unwrap();
if let Ok(nsec) = keyring.get_password() {
let secret_key = SecretKey::from_bech32(nsec).unwrap();
@@ -170,7 +161,7 @@ pub async fn load_account(
) -> Result<bool, String> {
let handle = app.clone();
let client = &state.client;
let keyring = Entry::new(npub, "nostr_secret").unwrap();
let keyring = Entry::new("Lume", npub).unwrap();
let password = match keyring.get_password() {
Ok(pw) => pw,
@@ -179,11 +170,14 @@ pub async fn load_account(
match bunker {
Some(uri) => {
let app_keys = Keys::parse(password).expect("Secret Key is modified, please check again.");
let app_keys =
Keys::parse(password).expect("Secret Key is modified, please check again.");
match NostrConnectURI::parse(uri) {
Ok(bunker_uri) => {
match Nip46Signer::new(bunker_uri, app_keys, Duration::from_secs(30), None).await {
match Nip46Signer::new(bunker_uri, app_keys, Duration::from_secs(30), None)
.await
{
Ok(signer) => client.set_signer(Some(signer.into())).await,
Err(err) => return Err(err.to_string()),
}
@@ -284,7 +278,7 @@ pub async fn load_account(
.since(Timestamp::now());
// Subscribing for new notification...
client
let _ = client
.subscribe_with_id(subscription_id, vec![subscription], None)
.await;
@@ -320,7 +314,11 @@ pub async fn load_account(
.notification()
.builder()
.body("Mentioned you in a thread.")
.title(author.display_name.unwrap_or_else(|| "Lume".to_string()))
.title(
author
.display_name
.unwrap_or_else(|| "Lume".to_string()),
)
.show()
{
println!("Failed to show notification: {:?}", e);
@@ -331,7 +329,11 @@ pub async fn load_account(
.notification()
.builder()
.body("Reposted your note.")
.title(author.display_name.unwrap_or_else(|| "Lume".to_string()))
.title(
author
.display_name
.unwrap_or_else(|| "Lume".to_string()),
)
.show()
{
println!("Failed to show notification: {:?}", e);
@@ -343,7 +345,11 @@ pub async fn load_account(
.notification()
.builder()
.body(content)
.title(author.display_name.unwrap_or_else(|| "Lume".to_string()))
.title(
author
.display_name
.unwrap_or_else(|| "Lume".to_string()),
)
.show()
{
println!("Failed to show notification: {:?}", e);
@@ -354,7 +360,11 @@ pub async fn load_account(
.notification()
.builder()
.body("Zapped you.")
.title(author.display_name.unwrap_or_else(|| "Lume".to_string()))
.title(
author
.display_name
.unwrap_or_else(|| "Lume".to_string()),
)
.show()
{
println!("Failed to show notification: {:?}", e);
+6 -3
View File
@@ -359,7 +359,7 @@ pub async fn remove_wallet(state: State<'_, Nostr>) -> Result<(), ()> {
let client = &state.client;
let keyring = Entry::new("Lume Secret", "Bitcoin Connect").unwrap();
match keyring.delete_password() {
match keyring.delete_credential() {
Ok(_) => {
client.unset_zapper().await;
Ok(())
@@ -449,7 +449,9 @@ pub async fn friend_to_friend(npub: &str, state: State<'_, Nostr>) -> Result<boo
.kind(Kind::ContactList)
.limit(1);
if let Ok(contact_list_events) = client.get_events_of(vec![contact_list_filter], None).await {
if let Ok(contact_list_events) =
client.get_events_of(vec![contact_list_filter], None).await
{
for event in contact_list_events.into_iter() {
for tag in event.into_iter_tags() {
if let Some(TagStandard::PublicKey {
@@ -575,7 +577,8 @@ pub async fn get_settings(state: State<'_, Nostr>) -> Result<Settings, ()> {
#[tauri::command]
#[specta::specta]
pub async fn set_new_settings(settings: &str, state: State<'_, Nostr>) -> Result<(), ()> {
let parsed: Settings = serde_json::from_str(settings).expect("Could not parse settings payload");
let parsed: Settings =
serde_json::from_str(settings).expect("Could not parse settings payload");
*state.settings.lock().unwrap() = parsed;
Ok(())
+4 -1
View File
@@ -39,7 +39,8 @@ pub async fn get_relays(state: State<'_, Nostr>) -> Result<Relays, String> {
match client.get_events_of(vec![filter], None).await {
Ok(events) => {
if let Some(event) = events.first() {
let nip65_list = nip65::extract_relay_list(event);
let nip65_list = nip65::extract_relay_list(event).collect::<Vec<_>>();
let read = nip65_list
.iter()
.filter_map(|(url, meta)| {
@@ -50,6 +51,7 @@ pub async fn get_relays(state: State<'_, Nostr>) -> Result<Relays, String> {
}
})
.collect();
let write = nip65_list
.iter()
.filter_map(|(url, meta)| {
@@ -60,6 +62,7 @@ pub async fn get_relays(state: State<'_, Nostr>) -> Result<Relays, String> {
}
})
.collect();
let both = nip65_list
.iter()
.filter_map(|(url, meta)| {
+7 -19
View File
@@ -1,7 +1,7 @@
{
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
"productName": "Lume",
"version": "4.0.13",
"version": "4.0.15",
"identifier": "nu.lume.Lume",
"build": {
"beforeBuildCommand": "pnpm desktop:build",
@@ -34,6 +34,7 @@
},
"bundle": {
"licenseFile": "../LICENSE",
"homepage": "https://lume.nu",
"longDescription": "nostr client for desktop",
"shortDescription": "nostr client",
"targets": "all",
@@ -65,21 +66,6 @@
}
},
"macOS": {
"dmg": {
"appPosition": {
"x": 180,
"y": 170
},
"applicationFolderPosition": {
"x": 480,
"y": 170
},
"windowSize": {
"height": 400,
"width": 660
}
},
"files": {},
"minimumSystemVersion": "10.15"
},
"windows": {
@@ -99,7 +85,7 @@
"fileAssociations": [
{
"name": "bech32",
"description": "Nostr Bech32",
"description": "Nostr BECH32",
"ext": [
"npub",
"nsec",
@@ -110,7 +96,8 @@
],
"role": "Viewer"
}
]
],
"createUpdaterArtifacts": true
},
"plugins": {
"updater": {
@@ -121,7 +108,8 @@
},
"endpoints": [
"https://lus.reya3772.workers.dev/v1/{{target}}/{{arch}}/{{current_version}}",
"https://lus.reya3772.workers.dev/{{target}}/{{current_version}}"
"https://lus.reya3772.workers.dev/{{target}}/{{current_version}}",
"https://github.com/lumehq/lume/releases/latest/download/latest.json"
]
}
}
+3 -4
View File
@@ -5,11 +5,10 @@
{
"title": "Lume",
"label": "main",
"titleBarStyle": "Overlay",
"width": 500,
"width": 1045,
"height": 800,
"minWidth": 500,
"minHeight": 800
"minWidth": 480,
"minHeight": 760
}
]
}
+1
View File
@@ -17,6 +17,7 @@
"minWidth": 480,
"minHeight": 760,
"hiddenTitle": true,
"transparent": true,
"windowEffects": {
"state": "followsWindowActiveState",
"effects": [
+6 -4
View File
@@ -5,13 +5,15 @@
{
"title": "Lume",
"label": "main",
"width": 500,
"width": 1045,
"height": 800,
"minWidth": 500,
"minHeight": 800,
"minWidth": 480,
"minHeight": 760,
"transparent": true,
"windowEffects": {
"effects": ["mica"]
"effects": [
"mica"
]
}
}
]