Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5255fa503 | ||
|
|
954a17b541 | ||
|
|
a55b31b0e6 | ||
|
|
bdf3ffd7bf | ||
|
|
07ce253f5b | ||
|
|
f3db010c74 | ||
|
|
dcf2791fe5 | ||
|
|
8fcf3551d8 | ||
|
|
2d987849d8 | ||
|
|
3b99926f3b | ||
|
|
113d69a4df | ||
|
|
5d12ba7216 | ||
|
|
72b59020b4 | ||
|
|
4c323b9daa |
@@ -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
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
},
|
||||
}),
|
||||
]);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -11,7 +11,6 @@ interface RouterContext {
|
||||
export const Route = createRootRouteWithContext<RouterContext>()({
|
||||
component: () => <Outlet />,
|
||||
pendingComponent: Pending,
|
||||
wrapInSuspense: true,
|
||||
});
|
||||
|
||||
function Pending() {
|
||||
|
||||
@@ -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 !!!
|
||||
|
||||
@@ -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 () => {
|
||||
|
||||
@@ -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]);
|
||||
});
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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 });
|
||||
};
|
||||
|
||||
|
||||
@@ -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,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",
|
||||
},
|
||||
|
||||
@@ -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
@@ -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
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
"devDependencies": {
|
||||
"@lume/tsconfig": "workspace:*",
|
||||
"@types/react": "^18.3.3",
|
||||
"typescript": "^5.5.2"
|
||||
"typescript": "^5.5.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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`);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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") {
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
"access": "public"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.5.2"
|
||||
"typescript": "^5.5.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+836
-927
File diff suppressed because it is too large
Load Diff
@@ -1 +0,0 @@
|
||||
tab_spaces=2
|
||||
Generated
+273
-219
File diff suppressed because it is too large
Load Diff
+10
-5
@@ -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
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#[cfg(target_os = "macos")]
|
||||
pub mod fns;
|
||||
#[cfg(target_os = "macos")]
|
||||
pub mod tray;
|
||||
pub mod window;
|
||||
|
||||
@@ -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
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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(())
|
||||
|
||||
@@ -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)| {
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,10 @@
|
||||
{
|
||||
"title": "Lume",
|
||||
"label": "main",
|
||||
"titleBarStyle": "Overlay",
|
||||
"width": 500,
|
||||
"width": 1045,
|
||||
"height": 800,
|
||||
"minWidth": 500,
|
||||
"minHeight": 800
|
||||
"minWidth": 480,
|
||||
"minHeight": 760
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"minWidth": 480,
|
||||
"minHeight": 760,
|
||||
"hiddenTitle": true,
|
||||
"transparent": true,
|
||||
"windowEffects": {
|
||||
"state": "followsWindowActiveState",
|
||||
"effects": [
|
||||
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user