Merge pull request #80 from luminous-devs/revert-to-tauri-v1

Revert to Tauri v1.4.0
This commit is contained in:
Ren Amamiya 2023-09-02 12:49:51 +07:00 committed by GitHub
commit 4309f734b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 1196 additions and 1444 deletions

View File

@ -29,22 +29,7 @@
"@radix-ui/react-tooltip": "^1.0.6", "@radix-ui/react-tooltip": "^1.0.6",
"@tanstack/react-query": "^4.33.0", "@tanstack/react-query": "^4.33.0",
"@tanstack/react-virtual": "3.0.0-beta.54", "@tanstack/react-virtual": "3.0.0-beta.54",
"@tauri-apps/api": "2.0.0-alpha.6", "@tauri-apps/api": "^1.4.0",
"@tauri-apps/cli": "2.0.0-alpha.11",
"@tauri-apps/plugin-app": "github:tauri-apps/tauri-plugin-app#v2",
"@tauri-apps/plugin-autostart": "github:tauri-apps/tauri-plugin-autostart#v2",
"@tauri-apps/plugin-clipboard-manager": "github:tauri-apps/tauri-plugin-clipboard-manager#v2",
"@tauri-apps/plugin-dialog": "github:tauri-apps/tauri-plugin-dialog#v2",
"@tauri-apps/plugin-fs": "github:tauri-apps/tauri-plugin-fs#v2",
"@tauri-apps/plugin-notification": "github:tauri-apps/tauri-plugin-notification#v2",
"@tauri-apps/plugin-os": "github:tauri-apps/tauri-plugin-os#v2",
"@tauri-apps/plugin-process": "github:tauri-apps/tauri-plugin-process#v2",
"@tauri-apps/plugin-shell": "github:tauri-apps/tauri-plugin-shell#v2",
"@tauri-apps/plugin-sql": "github:tauri-apps/tauri-plugin-sql#v2",
"@tauri-apps/plugin-store": "github:tauri-apps/tauri-plugin-store#v2",
"@tauri-apps/plugin-stronghold": "github:tauri-apps/tauri-plugin-stronghold#v2",
"@tauri-apps/plugin-upload": "github:tauri-apps/tauri-plugin-upload#v2",
"@tauri-apps/plugin-window": "github:tauri-apps/tauri-plugin-window#v2",
"@tiptap/extension-image": "^2.1.7", "@tiptap/extension-image": "^2.1.7",
"@tiptap/extension-mention": "^2.1.7", "@tiptap/extension-mention": "^2.1.7",
"@tiptap/extension-placeholder": "^2.1.7", "@tiptap/extension-placeholder": "^2.1.7",
@ -60,7 +45,7 @@
"light-bolt11-decoder": "^3.0.0", "light-bolt11-decoder": "^3.0.0",
"lru-cache": "^10.0.1", "lru-cache": "^10.0.1",
"minidenticons": "^4.2.0", "minidenticons": "^4.2.0",
"nostr-fetch": "^0.12.2", "nostr-fetch": "^0.13.0",
"nostr-tools": "^1.14.2", "nostr-tools": "^1.14.2",
"qrcode.react": "^3.1.0", "qrcode.react": "^3.1.0",
"react": "^18.2.0", "react": "^18.2.0",
@ -73,19 +58,24 @@
"react-textarea-autosize": "^8.5.3", "react-textarea-autosize": "^8.5.3",
"react-virtuoso": "^4.5.0", "react-virtuoso": "^4.5.0",
"remark-gfm": "^3.0.1", "remark-gfm": "^3.0.1",
"tauri-plugin-sql-api": "github:tauri-apps/tauri-plugin-sql#v1",
"tauri-plugin-store-api": "github:tauri-apps/tauri-plugin-store#v1",
"tauri-plugin-stronghold-api": "github:tauri-apps/tauri-plugin-stronghold#v1",
"tauri-plugin-upload-api": "github:tauri-apps/tauri-plugin-upload#v1",
"tippy.js": "^6.3.7", "tippy.js": "^6.3.7",
"zustand": "^4.4.1" "zustand": "^4.4.1"
}, },
"devDependencies": { "devDependencies": {
"@tailwindcss/typography": "^0.5.9", "@tailwindcss/typography": "^0.5.9",
"@tauri-apps/cli": "^1.4.0",
"@trivago/prettier-plugin-sort-imports": "^4.2.0", "@trivago/prettier-plugin-sort-imports": "^4.2.0",
"@types/html-to-text": "^9.0.1", "@types/html-to-text": "^9.0.1",
"@types/node": "^20.5.6", "@types/node": "^20.5.8",
"@types/react": "^18.2.21", "@types/react": "^18.2.21",
"@types/react-dom": "^18.2.7", "@types/react-dom": "^18.2.7",
"@types/youtube-player": "^5.5.7", "@types/youtube-player": "^5.5.7",
"@typescript-eslint/eslint-plugin": "^6.4.1", "@typescript-eslint/eslint-plugin": "^6.5.0",
"@typescript-eslint/parser": "^6.4.1", "@typescript-eslint/parser": "^6.5.0",
"@vitejs/plugin-react-swc": "^3.3.2", "@vitejs/plugin-react-swc": "^3.3.2",
"autoprefixer": "^10.4.15", "autoprefixer": "^10.4.15",
"clsx": "^2.0.0", "clsx": "^2.0.0",
@ -99,9 +89,9 @@
"eslint-plugin-simple-import-sort": "^10.0.0", "eslint-plugin-simple-import-sort": "^10.0.0",
"husky": "^8.0.3", "husky": "^8.0.3",
"lint-staged": "^14.0.1", "lint-staged": "^14.0.1",
"postcss": "^8.4.28", "postcss": "^8.4.29",
"prettier": "^3.0.2", "prettier": "^3.0.3",
"prettier-plugin-tailwindcss": "^0.5.3", "prettier-plugin-tailwindcss": "^0.5.4",
"prop-types": "^15.8.1", "prop-types": "^15.8.1",
"tailwind-merge": "^1.14.0", "tailwind-merge": "^1.14.0",
"tailwindcss": "^3.3.3", "tailwindcss": "^3.3.3",

File diff suppressed because it is too large Load Diff

1422
src-tauri/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -11,40 +11,44 @@ rust-version = "1.71"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[build-dependencies] [build-dependencies]
tauri-build = { version = "2.0.0-alpha.8", features = [] } tauri-build = { version = "1.4.0", features = [] }
[dependencies] [dependencies]
serde_json = "1.0" serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
tauri = { git = "https://git.nextgraph.org/NextGraph/tauri.git", branch = "alpha.11-nextgraph", features = [ tauri = { version = "1.4.0", features = [
"protocol-asset", "window-start-dragging",
"path-all",
"http-all",
"clipboard-write-text",
"os-all",
"notification-all",
"clipboard-read-text",
"window-set-resizable",
"window-set-size",
"shell-open",
"fs-write-file",
"app-all",
"fs-remove-file",
"window-center",
"dialog-all",
"macos-private-api", "macos-private-api",
"no-ipc-custom-protocol",
] } ] }
tauri-plugin-single-instance = { git = "https://github.com/luminous-devs/plugins-workspace", branch = "v2" } tauri-plugin-single-instance = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
tauri-plugin-autostart = { git = "https://github.com/luminous-devs/plugins-workspace", branch = "v2" } tauri-plugin-autostart = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
tauri-plugin-stronghold = { git = "https://github.com/luminous-devs/plugins-workspace", branch = "v2" } tauri-plugin-stronghold = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
tauri-plugin-upload = { git = "https://github.com/luminous-devs/plugins-workspace", branch = "v2" } tauri-plugin-store = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
tauri-plugin-updater = { git = "https://github.com/luminous-devs/plugins-workspace", branch = "v2" } tauri-plugin-upload = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
tauri-plugin-dialog = { git = "https://github.com/luminous-devs/plugins-workspace", branch = "v2" } window-vibrancy = { git = "https://github.com/tauri-apps/window-vibrancy", branch = "dev" }
tauri-plugin-http = { git = "https://github.com/luminous-devs/plugins-workspace", branch = "v2" } window-shadows = { git = "https://github.com/tauri-apps/window-shadows", branch = "dev" }
tauri-plugin-fs = { git = "https://github.com/luminous-devs/plugins-workspace", branch = "v2" }
tauri-plugin-clipboard-manager = { git = "https://github.com/luminous-devs/plugins-workspace", branch = "v2" }
tauri-plugin-notification = { git = "https://github.com/luminous-devs/plugins-workspace", branch = "v2" }
tauri-plugin-app = { git = "https://github.com/luminous-devs/plugins-workspace", branch = "v2" }
tauri-plugin-process = { git = "https://github.com/luminous-devs/plugins-workspace", branch = "v2" }
tauri-plugin-os = { git = "https://github.com/luminous-devs/plugins-workspace", branch = "v2" }
tauri-plugin-window = { git = "https://github.com/luminous-devs/plugins-workspace", branch = "v2" }
tauri-plugin-store = { git = "https://github.com/luminous-devs/plugins-workspace", branch = "v2" }
tauri-plugin-shell = { git = "https://github.com/luminous-devs/plugins-workspace", branch = "v2" }
sqlx-cli = { version = "0.7.0", default-features = false, features = [ sqlx-cli = { version = "0.7.0", default-features = false, features = [
"sqlite", "sqlite",
] } ] }
rust-argon2 = "1.0" rust-argon2 = "1.0"
[dependencies.tauri-plugin-sql] [dependencies.tauri-plugin-sql]
git = "https://github.com/luminous-devs/plugins-workspace" git = "hhttps://github.com/tauri-apps/plugins-workspace"
branch = "v2" branch = "v1"
features = ["sqlite"] features = ["sqlite"]
[features] [features]

View File

@ -6,6 +6,8 @@
use tauri::Manager; use tauri::Manager;
use tauri_plugin_autostart::MacosLauncher; use tauri_plugin_autostart::MacosLauncher;
use tauri_plugin_sql::{Migration, MigrationKind}; use tauri_plugin_sql::{Migration, MigrationKind};
use window_shadows::set_shadow;
use window_vibrancy::{apply_mica, apply_vibrancy, NSVisualEffectMaterial};
#[derive(Clone, serde::Serialize)] #[derive(Clone, serde::Serialize)]
struct Payload { struct Payload {
@ -168,20 +170,25 @@ fn main() {
.emit_all("single-instance", Payload { args: argv, cwd }) .emit_all("single-instance", Payload { args: argv, cwd })
.unwrap(); .unwrap();
})) }))
.plugin(tauri_plugin_updater::Builder::new().build())
.plugin(tauri_plugin_upload::init()) .plugin(tauri_plugin_upload::init())
.plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_http::init())
.plugin(tauri_plugin_fs::init())
.plugin(tauri_plugin_clipboard_manager::init())
.plugin(tauri_plugin_notification::init())
.plugin(tauri_plugin_app::init())
.plugin(tauri_plugin_process::init())
.plugin(tauri_plugin_os::init())
.plugin(tauri_plugin_window::init())
.plugin(tauri_plugin_store::Builder::default().build()) .plugin(tauri_plugin_store::Builder::default().build())
.plugin(tauri_plugin_shell::init())
.invoke_handler(tauri::generate_handler![close_splashscreen]) .invoke_handler(tauri::generate_handler![close_splashscreen])
.setup(|app| {
let window = app.get_window("main").unwrap();
#[cfg(target_os = "macos")]
apply_vibrancy(&window, NSVisualEffectMaterial::HudWindow, None, None)
.expect("Unsupported platform! 'apply_vibrancy' is only supported on macOS");
#[cfg(target_os = "windows")]
apply_mica(&window, Some(true))
.expect("Unsupported platform! 'apply_blur' is only supported on Windows");
// set native shadow
set_shadow(&window, true).expect("Unsupported platform!");
Ok(())
})
.run(tauri::generate_context!()) .run(tauri::generate_context!())
.expect("error while running tauri application"); .expect("error while running tauri application");
} }

View File

@ -10,38 +10,71 @@
"productName": "Lume", "productName": "Lume",
"version": "1.2.1" "version": "1.2.1"
}, },
"plugins": {
"fs": {
"scope": [
"$APPDATA/*",
"$DATA/*",
"$LOCALDATA/*",
"$DESKTOP/*",
"$DOCUMENT/*",
"$DOWNLOAD/*",
"$HOME/*",
"$PICTURE/*",
"$PUBLIC/*",
"$VIDEO/*"
]
},
"http": {
"scope": [
"http://**/",
"https://**/"
]
},
"shell": {
"open": true
},
"updater": {
"endpoints": [
"https://lus.reya3772.workers.dev/v1/{{target}}/{{arch}}/{{current_version}}",
"https://lus.reya3772.workers.dev/{{target}}/{{current_version}}"
]
}
},
"tauri": { "tauri": {
"allowlist": {
"app": {
"all": true,
"show": true,
"hide": true
},
"path": {
"all": true
},
"dialog": {
"all": true,
"ask": true,
"confirm": true,
"message": true,
"open": true,
"save": true
},
"fs": {
"all": false,
"removeFile": true,
"writeFile": true,
"scope": [
"$APPDATA/*",
"$DATA/*",
"$LOCALDATA/*",
"$DESKTOP/*",
"$DOCUMENT/*",
"$DOWNLOAD/*",
"$HOME/*",
"$PICTURE/*",
"$PUBLIC/*",
"$VIDEO/*"
]
},
"http": {
"all": true,
"scope": [
"http://**",
"https://**"
]
},
"shell": {
"all": false,
"open": true
},
"os": {
"all": true
},
"window": {
"all": false,
"center": true,
"setResizable": true,
"setSize": true,
"startDragging": true
},
"clipboard": {
"all": false,
"writeText": true,
"readText": true
},
"notification": {
"all": true
}
},
"bundle": { "bundle": {
"active": true, "active": true,
"appimage": { "appimage": {
@ -79,18 +112,15 @@
"timestampUrl": "" "timestampUrl": ""
} }
}, },
"updater": {
"endpoints": [
"https://lus.reya3772.workers.dev/v1/{{target}}/{{arch}}/{{current_version}}",
"https://lus.reya3772.workers.dev/{{target}}/{{current_version}}"
]
},
"security": { "security": {
"csp": { "csp": {
"connect-src": "ipc: https://ipc.localhost",
"content-security-policy": "upgrade-insecure-requests" "content-security-policy": "upgrade-insecure-requests"
},
"freezePrototype": false,
"assetProtocol": {
"enable": true,
"scope": {
"allow": ["$APPCONFIG/*.db", "$RESOURCE/**"],
"deny": ["$APPCONFIG/*.stronghold"]
}
} }
}, },
"macOSPrivateApi": true "macOSPrivateApi": true

View File

@ -27,11 +27,7 @@
"fullscreen": false, "fullscreen": false,
"hiddenTitle": true, "hiddenTitle": true,
"visible": false, "visible": false,
"fileDropEnabled": true, "fileDropEnabled": true
"windowEffects": {
"effects": ["hudWindow"],
"state": "followsWindowActiveState"
}
} }
] ]
} }

View File

@ -24,11 +24,7 @@
"fullscreen": false, "fullscreen": false,
"hiddenTitle": true, "hiddenTitle": true,
"visible": false, "visible": false,
"fileDropEnabled": true, "fileDropEnabled": true
"windowEffects": {
"effects": ["micaDark", "micaLight", "acrylic"],
"state": "followsWindowActiveState"
}
} }
] ]
} }

View File

@ -1,4 +1,4 @@
import { BaseDirectory, writeTextFile } from '@tauri-apps/plugin-fs'; import { BaseDirectory, writeTextFile } from '@tauri-apps/api/fs';
import { generatePrivateKey, getPublicKey, nip19 } from 'nostr-tools'; import { generatePrivateKey, getPublicKey, nip19 } from 'nostr-tools';
import { useEffect, useMemo, useState } from 'react'; import { useEffect, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';

View File

@ -1,8 +1,8 @@
import { appConfigDir } from '@tauri-apps/api/path'; import { appConfigDir } from '@tauri-apps/api/path';
import { Stronghold } from '@tauri-apps/plugin-stronghold';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { Resolver, useForm } from 'react-hook-form'; import { Resolver, useForm } from 'react-hook-form';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { Stronghold } from 'tauri-plugin-stronghold-api';
import { useStorage } from '@libs/storage/provider'; import { useStorage } from '@libs/storage/provider';

View File

@ -1,8 +1,8 @@
import { appConfigDir } from '@tauri-apps/api/path'; import { appConfigDir } from '@tauri-apps/api/path';
import { Stronghold } from '@tauri-apps/plugin-stronghold';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { Resolver, useForm } from 'react-hook-form'; import { Resolver, useForm } from 'react-hook-form';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { Stronghold } from 'tauri-plugin-stronghold-api';
import { useStorage } from '@libs/storage/provider'; import { useStorage } from '@libs/storage/provider';

View File

@ -1,9 +1,9 @@
import { useQueryClient } from '@tanstack/react-query'; import { useQueryClient } from '@tanstack/react-query';
import { appConfigDir } from '@tauri-apps/api/path'; import { appConfigDir } from '@tauri-apps/api/path';
import { Stronghold } from '@tauri-apps/plugin-stronghold';
import { useState } from 'react'; import { useState } from 'react';
import { Resolver, useForm } from 'react-hook-form'; import { Resolver, useForm } from 'react-hook-form';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { Stronghold } from 'tauri-plugin-stronghold-api';
import { useStorage } from '@libs/storage/provider'; import { useStorage } from '@libs/storage/provider';

View File

@ -1,9 +1,9 @@
import { appConfigDir } from '@tauri-apps/api/path'; import { appConfigDir } from '@tauri-apps/api/path';
import { Stronghold } from '@tauri-apps/plugin-stronghold';
import { getPublicKey, nip19 } from 'nostr-tools'; import { getPublicKey, nip19 } from 'nostr-tools';
import { useState } from 'react'; import { useState } from 'react';
import { Resolver, useForm } from 'react-hook-form'; import { Resolver, useForm } from 'react-hook-form';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { Stronghold } from 'tauri-plugin-stronghold-api';
import { useStorage } from '@libs/storage/provider'; import { useStorage } from '@libs/storage/provider';

View File

@ -1,8 +1,8 @@
import { appConfigDir } from '@tauri-apps/api/path'; import { appConfigDir } from '@tauri-apps/api/path';
import { Stronghold } from '@tauri-apps/plugin-stronghold';
import { useState } from 'react'; import { useState } from 'react';
import { Resolver, useForm } from 'react-hook-form'; import { Resolver, useForm } from 'react-hook-form';
import { Link, useNavigate } from 'react-router-dom'; import { Link, useNavigate } from 'react-router-dom';
import { Stronghold } from 'tauri-plugin-stronghold-api';
import { User } from '@app/auth/components/user'; import { User } from '@app/auth/components/user';

View File

@ -1,4 +1,4 @@
import { LogicalSize, getCurrent } from '@tauri-apps/plugin-window'; import { LogicalSize, getCurrent } from '@tauri-apps/api/window';
import { useEffect } from 'react'; import { useEffect } from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';

View File

@ -19,8 +19,8 @@ export function ErrorScreen() {
useEffect(() => { useEffect(() => {
async function getInformation() { async function getInformation() {
const { platform, version } = await import('@tauri-apps/plugin-os'); const { platform, version } = await import('@tauri-apps/api/os');
const { getVersion } = await import('@tauri-apps/plugin-app'); const { getVersion } = await import('@tauri-apps/api/app');
const platformName = await platform(); const platformName = await platform();
const osVersion = await version(); const osVersion = await version();

View File

@ -1,5 +1,5 @@
import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk'; import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk';
import { writeText } from '@tauri-apps/plugin-clipboard-manager'; import { writeText } from '@tauri-apps/api/clipboard';
import { nip19 } from 'nostr-tools'; import { nip19 } from 'nostr-tools';
import { EventPointer } from 'nostr-tools/lib/nip19'; import { EventPointer } from 'nostr-tools/lib/nip19';
import { useRef, useState } from 'react'; import { useRef, useState } from 'react';

View File

@ -1,5 +1,5 @@
import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk'; import { NDKEvent, NDKKind } from '@nostr-dev-kit/ndk';
import { writeText } from '@tauri-apps/plugin-clipboard-manager'; import { writeText } from '@tauri-apps/api/clipboard';
import { nip19 } from 'nostr-tools'; import { nip19 } from 'nostr-tools';
import { EventPointer } from 'nostr-tools/lib/nip19'; import { EventPointer } from 'nostr-tools/lib/nip19';
import { useRef, useState } from 'react'; import { useRef, useState } from 'react';

View File

@ -1,4 +1,4 @@
import { getVersion } from '@tauri-apps/plugin-app'; import { getVersion } from '@tauri-apps/api/app';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
export function VersionSetting() { export function VersionSetting() {

View File

@ -1,5 +1,5 @@
import { message } from '@tauri-apps/api/dialog';
import { invoke } from '@tauri-apps/api/tauri'; import { invoke } from '@tauri-apps/api/tauri';
import { message } from '@tauri-apps/plugin-dialog';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { useNDK } from '@libs/ndk/provider'; import { useNDK } from '@libs/ndk/provider';
@ -11,7 +11,7 @@ import { useNostr } from '@utils/hooks/useNostr';
export function SplashScreen() { export function SplashScreen() {
const { db } = useStorage(); const { db } = useStorage();
const { ndk, relayUrls } = useNDK(); const { ndk } = useNDK();
const { fetchUserData, prefetchEvents } = useNostr(); const { fetchUserData, prefetchEvents } = useNostr();
const [isLoading, setIsLoading] = useState<boolean>(true); const [isLoading, setIsLoading] = useState<boolean>(true);
@ -68,9 +68,7 @@ export function SplashScreen() {
{isLoading ? ( {isLoading ? (
<div className="flex flex-col gap-1 text-center"> <div className="flex flex-col gap-1 text-center">
<h3 className="text-lg font-semibold leading-none text-white"> <h3 className="text-lg font-semibold leading-none text-white">
{!ndk {!ndk ? 'Connecting to relay...' : 'Fetching events from the last login.'}
? 'Connecting to relay...'
: `Connected to ${relayUrls.length} relays`}
</h3> </h3>
<p className="text-sm text-white/50"> <p className="text-sm text-white/50">
This may take a few seconds, please don&apos;t close app. This may take a few seconds, please don&apos;t close app.

View File

@ -1,6 +1,6 @@
import { NDKCacheAdapter } from '@nostr-dev-kit/ndk'; import { NDKCacheAdapter } from '@nostr-dev-kit/ndk';
import { NDKEvent, NDKSubscription } from '@nostr-dev-kit/ndk'; import { NDKEvent, NDKSubscription } from '@nostr-dev-kit/ndk';
import { Store } from '@tauri-apps/plugin-store'; import { Store } from 'tauri-plugin-store-api';
export default class TauriAdapter implements NDKCacheAdapter { export default class TauriAdapter implements NDKCacheAdapter {
public store: Store; public store: Store;

View File

@ -1,6 +1,6 @@
// inspire by: https://github.com/nostr-dev-kit/ndk-react/ // inspire by: https://github.com/nostr-dev-kit/ndk-react/
import NDK from '@nostr-dev-kit/ndk'; import NDK from '@nostr-dev-kit/ndk';
import { message } from '@tauri-apps/plugin-dialog'; import { message } from '@tauri-apps/api/dialog';
import { useEffect, useMemo, useState } from 'react'; import { useEffect, useMemo, useState } from 'react';
import TauriAdapter from '@libs/ndk/cache'; import TauriAdapter from '@libs/ndk/cache';

View File

@ -1,7 +1,7 @@
import { NDKEvent } from '@nostr-dev-kit/ndk'; import { NDKEvent } from '@nostr-dev-kit/ndk';
import { BaseDirectory, removeFile } from '@tauri-apps/plugin-fs'; import { BaseDirectory, removeFile } from '@tauri-apps/api/fs';
import Database from '@tauri-apps/plugin-sql'; import Database from 'tauri-plugin-sql-api';
import { Stronghold } from '@tauri-apps/plugin-stronghold'; import { Stronghold } from 'tauri-plugin-stronghold-api';
import { Account, DBEvent, Relays, Widget } from '@utils/types'; import { Account, DBEvent, Relays, Widget } from '@utils/types';

View File

@ -1,6 +1,6 @@
import { message } from '@tauri-apps/plugin-dialog'; import { message } from '@tauri-apps/api/dialog';
import Database from '@tauri-apps/plugin-sql';
import { PropsWithChildren, createContext, useContext, useEffect, useState } from 'react'; import { PropsWithChildren, createContext, useContext, useEffect, useState } from 'react';
import Database from 'tauri-plugin-sql-api';
import { LumeStorage } from '@libs/storage/instance'; import { LumeStorage } from '@libs/storage/instance';

View File

@ -1,3 +1,4 @@
import { message } from '@tauri-apps/api/dialog';
import Image from '@tiptap/extension-image'; import Image from '@tiptap/extension-image';
import Mention from '@tiptap/extension-mention'; import Mention from '@tiptap/extension-mention';
import Placeholder from '@tiptap/extension-placeholder'; import Placeholder from '@tiptap/extension-placeholder';
@ -9,24 +10,21 @@ import { useState } from 'react';
import { twMerge } from 'tailwind-merge'; import { twMerge } from 'tailwind-merge';
import { Suggestion } from '@shared/composer'; import { Suggestion } from '@shared/composer';
import { CancelIcon, LoaderIcon, PlusCircleIcon } from '@shared/icons'; import { CancelIcon, LoaderIcon, MediaIcon, MentionIcon } from '@shared/icons';
import { MentionNote } from '@shared/notes'; import { MentionNote } from '@shared/notes';
import { useComposer } from '@stores/composer'; import { useComposer } from '@stores/composer';
import { useNostr } from '@utils/hooks/useNostr'; import { useNostr } from '@utils/hooks/useNostr';
import { useImageUploader } from '@utils/hooks/useUploader';
import { sendNativeNotification } from '@utils/notification'; import { sendNativeNotification } from '@utils/notification';
export function Composer() { export function Composer() {
const { publish } = useNostr(); const [loading, setLoading] = useState<boolean>(false);
const [status, setStatus] = useState<null | 'loading' | 'done'>(null);
const [reply, clearReply] = useComposer((state) => [state.reply, state.clearReply]); const [reply, clearReply] = useComposer((state) => [state.reply, state.clearReply]);
const expand = useComposer((state) => state.expand) const { publish, upload } = useNostr();
const upload = useImageUploader();
const expand = useComposer((state) => state.expand);
const editor = useEditor({ const editor = useEditor({
extensions: [ extensions: [
StarterKit.configure({ StarterKit.configure({
@ -65,9 +63,9 @@ export function Composer() {
}; };
const submit = async () => { const submit = async () => {
setStatus('loading');
try { try {
setLoading(true);
// get plaintext content // get plaintext content
const html = editor.getHTML(); const html = editor.getHTML();
const serializedContent = convert(html, { const serializedContent = convert(html, {
@ -108,18 +106,19 @@ export function Composer() {
await publish({ content: serializedContent, kind: 1, tags }); await publish({ content: serializedContent, kind: 1, tags });
// send native notifiation // send native notifiation
await sendNativeNotification('Publish post successfully'); await sendNativeNotification('Post has been published successfully.');
// update state // update state
setStatus('done'); setLoading(false);
// reset editor // reset editor
editor.commands.clearContent(); editor.commands.clearContent();
// reset reply
if (reply.id) { if (reply.id) {
clearReply(); clearReply();
} }
} catch { } catch {
setStatus(null); setLoading(false);
console.log('failed to publish'); await message('Publishing post failed.', { title: 'Lume', type: 'error' });
} }
}; };
@ -136,7 +135,10 @@ export function Composer() {
autoComplete="off" autoComplete="off"
autoCorrect="off" autoCorrect="off"
autoCapitalize="off" autoCapitalize="off"
className={twMerge('scrollbar-hide markdown break-all max-h-[500px] overflow-y-auto outline-none pr-2', expand ? 'min-h-[500px]' : 'min-h-[120px]')} className={twMerge(
'scrollbar-hide markdown max-h-[500px] overflow-y-auto break-all pr-2 outline-none',
expand ? 'min-h-[500px]' : 'min-h-[120px]'
)}
/> />
{reply.id && ( {reply.id && (
<div className="relative"> <div className="relative">
@ -152,17 +154,31 @@ export function Composer() {
)} )}
</div> </div>
</div> </div>
<div className="flex items-center justify-between bg-white/5 rounded-b-xl p-2 border-t border-white/10"> <div className="flex items-center justify-between rounded-b-xl border-t border-white/10 bg-white/5 p-2">
<div className="inline-flex items-center gap-1">
<button
type="button"
onClick={() => uploadImage()}
className="ml-2 inline-flex h-10 w-max items-center justify-center gap-1.5 rounded-lg px-2 text-sm font-medium text-white/80 hover:bg-white/10 hover:backdrop-blur-xl"
>
<MediaIcon className="h-5 w-5 text-white/80" />
Add media
</button>
<button
type="button"
onClick={() => uploadImage()}
className="inline-flex h-10 w-10 items-center justify-center rounded-lg hover:bg-white/10 hover:backdrop-blur-xl"
>
<MentionIcon className="h-5 w-5 text-white/80" />
</button>
</div>
<button <button
type="button" onClick={() => submit()}
onClick={() => uploadImage()} disabled={editor && editor.isEmpty}
className="ml-2 inline-flex h-10 w-10 items-center justify-center rounded-lg backdrop-blur-xl hover:bg-white/10" className="inline-flex h-10 w-20 items-center justify-center rounded-lg bg-fuchsia-500 px-2 font-semibold hover:bg-fuchsia-600 disabled:opacity-50"
> >
<PlusCircleIcon className="h-5 w-5 text-white" /> {loading === true ? (
</button> <LoaderIcon className="h-5 w-5 animate-spin text-white" />
<button onClick={() => submit()} className="inline-flex items-center justify-center w-max px-8 rounded-lg font-bold h-10 bg-fuchsia-500 hover:bg-fuchsia-600">
{status === 'loading' ? (
<LoaderIcon className="h-4 w-4 animate-spin text-white" />
) : ( ) : (
'Post' 'Post'
)} )}

View File

@ -0,0 +1,7 @@
export function MentionPopup() {
return (
<div>
<p>TODO</p>
</div>
);
}

View File

@ -57,3 +57,4 @@ export * from './focus';
export * from './chevronUp'; export * from './chevronUp';
export * from './secure'; export * from './secure';
export * from './verified'; export * from './verified';
export * from './mention';

View File

@ -0,0 +1,22 @@
import { SVGProps } from 'react';
export function MentionIcon(props: JSX.IntrinsicAttributes & SVGProps<SVGSVGElement>) {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
fill="none"
viewBox="0 0 24 24"
{...props}
>
<path
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="1.5"
d="M11.85 13.251c-3.719.065-6.427 2.567-7.18 5.915-.13.575.338 1.084.927 1.084h6.901m-.647-6.999l.147-.001c.353 0 .696.022 1.03.064m-1.177-.063a7.889 7.889 0 00-1.852.249m3.028-.186c.334.042.658.104.972.186m-.972-.186a7.475 7.475 0 011.972.524m3.25 1.412v3m0 0v3m0-3h-3m3 0h3m-5.5-11.75a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0z"
></path>
</svg>
);
}

View File

@ -1,6 +1,5 @@
import * as Dialog from '@radix-ui/react-dialog'; import * as Dialog from '@radix-ui/react-dialog';
import { useQueryClient } from '@tanstack/react-query'; import { useQueryClient } from '@tanstack/react-query';
import { relaunch } from '@tauri-apps/plugin-process';
import { CancelIcon, LogoutIcon } from '@shared/icons'; import { CancelIcon, LogoutIcon } from '@shared/icons';
@ -12,8 +11,6 @@ export function Logout() {
// await removeAll(); // await removeAll();
// reset react query // reset react query
queryClient.clear(); queryClient.clear();
// navigate
await relaunch();
}; };
return ( return (

View File

@ -1,4 +1,5 @@
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { fetch } from '@tauri-apps/api/http';
import { twMerge } from 'tailwind-merge'; import { twMerge } from 'tailwind-merge';
import { UnverifiedIcon, VerifiedIcon } from '@shared/icons'; import { UnverifiedIcon, VerifiedIcon } from '@shared/icons';
@ -29,6 +30,7 @@ export function NIP05({
const res = await fetch(verifyURL, { const res = await fetch(verifyURL, {
method: 'GET', method: 'GET',
timeout: 10,
headers: { headers: {
'Content-Type': 'application/json; charset=utf-8', 'Content-Type': 'application/json; charset=utf-8',
}, },
@ -36,9 +38,9 @@ export function NIP05({
if (!res.ok) throw new Error(`Failed to fetch NIP-05 service: ${nip05}`); if (!res.ok) throw new Error(`Failed to fetch NIP-05 service: ${nip05}`);
const data: NIP05 = await res.json(); const data = res.data as NIP05;
if (data.names) { if (data.names) {
if (data.names.username !== pubkey) return false; if (data.names[localPath] !== pubkey) return false;
return true; return true;
} }
return false; return false;

View File

@ -1,6 +1,6 @@
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'; import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
import * as Tooltip from '@radix-ui/react-tooltip'; import * as Tooltip from '@radix-ui/react-tooltip';
import { writeText } from '@tauri-apps/plugin-clipboard-manager'; import { writeText } from '@tauri-apps/api/clipboard';
import { nip19 } from 'nostr-tools'; import { nip19 } from 'nostr-tools';
import { EventPointer } from 'nostr-tools/lib/nip19'; import { EventPointer } from 'nostr-tools/lib/nip19';
import { useState } from 'react'; import { useState } from 'react';

View File

@ -1,5 +1,5 @@
import { downloadDir } from '@tauri-apps/api/path'; import { downloadDir } from '@tauri-apps/api/path';
import { download } from '@tauri-apps/plugin-upload'; import { download } from 'tauri-plugin-upload-api';
import { DownloadIcon } from '@shared/icons'; import { DownloadIcon } from '@shared/icons';
import { Image } from '@shared/image'; import { Image } from '@shared/image';

View File

@ -28,7 +28,7 @@ export function LocalNetworkWidget() {
useInfiniteQuery({ useInfiniteQuery({
queryKey: ['local-network-widget'], queryKey: ['local-network-widget'],
queryFn: async ({ pageParam = 0 }) => { queryFn: async ({ pageParam = 0 }) => {
return await db.getAllEvents(30, pageParam); return await db.getAllEvents(20, pageParam);
}, },
getNextPageParam: (lastPage) => lastPage.nextCursor, getNextPageParam: (lastPage) => lastPage.nextCursor,
}); });

View File

@ -1,4 +1,4 @@
import Database from '@tauri-apps/plugin-sql'; import Database from 'tauri-plugin-sql-api';
import { Account } from '@utils/types'; import { Account } from '@utils/types';

View File

@ -1,4 +1,4 @@
import { readBinaryFile } from '@tauri-apps/plugin-fs'; import { readBinaryFile } from '@tauri-apps/api/fs';
export async function createBlobFromFile(path: string): Promise<Blob> { export async function createBlobFromFile(path: string): Promise<Blob> {
const file = await readBinaryFile(path); const file = await readBinaryFile(path);

View File

@ -1,3 +1,4 @@
import { magnetDecode } from '@ctrl/magnet-link';
import { import {
NDKEvent, NDKEvent,
NDKFilter, NDKFilter,
@ -7,6 +8,8 @@ import {
NDKUser, NDKUser,
} from '@nostr-dev-kit/ndk'; } from '@nostr-dev-kit/ndk';
import { ndkAdapter } from '@nostr-fetch/adapter-ndk'; import { ndkAdapter } from '@nostr-fetch/adapter-ndk';
import { message, open } from '@tauri-apps/api/dialog';
import { VoidApi } from '@void-cat/api';
import { LRUCache } from 'lru-cache'; import { LRUCache } from 'lru-cache';
import { NostrFetcher } from 'nostr-fetch'; import { NostrFetcher } from 'nostr-fetch';
import { nip19 } from 'nostr-tools'; import { nip19 } from 'nostr-tools';
@ -17,6 +20,7 @@ import { useStorage } from '@libs/storage/provider';
import { useStronghold } from '@stores/stronghold'; import { useStronghold } from '@stores/stronghold';
import { createBlobFromFile } from '@utils/createBlobFromFile';
import { nHoursAgo } from '@utils/date'; import { nHoursAgo } from '@utils/date';
import { NDKEventWithReplies } from '@utils/types'; import { NDKEventWithReplies } from '@utils/types';
@ -324,6 +328,91 @@ export function useNostr() {
return res; return res;
}; };
const upload = async (file: null | string, nip94?: boolean) => {
try {
const voidcat = new VoidApi('https://void.cat');
let filepath = file;
if (!file) {
const selected = await open({
multiple: false,
filters: [
{
name: 'Media',
extensions: [
'png',
'jpeg',
'jpg',
'gif',
'mp4',
'mp3',
'webm',
'mkv',
'avi',
'mov',
],
},
],
});
if (Array.isArray(selected)) {
// user selected multiple files
} else if (selected === null) {
return {
url: null,
error: 'Cancelled',
};
} else {
filepath = selected;
}
}
const filename = filepath.split('/').pop();
const filetype = filename.split('.').pop();
const blob = await createBlobFromFile(filepath);
const uploader = voidcat.getUploader(blob);
// upload file
const res = await uploader.upload();
if (res.ok) {
const url =
res.file?.metadata?.url ?? `https://void.cat/d/${res.file?.id}.${filetype}`;
if (nip94) {
const tags = [
['url', url],
['x', res.file?.metadata?.digest ?? ''],
['m', res.file?.metadata?.mimeType ?? 'application/octet-stream'],
['size', res.file?.metadata?.size.toString() ?? '0'],
];
if (res.file?.metadata?.magnetLink) {
tags.push(['magnet', res.file.metadata.magnetLink]);
const parsedMagnet = magnetDecode(res.file.metadata.magnetLink);
if (parsedMagnet?.infoHash) {
tags.push(['i', parsedMagnet?.infoHash]);
}
}
await publish({ content: '', kind: 1063, tags: tags });
}
return {
url: url,
error: null,
};
}
return {
url: null,
error: 'Upload failed',
};
} catch (e) {
await message(e, { title: 'Lume', type: 'error' });
}
};
return { return {
sub, sub,
fetchUserData, fetchUserData,
@ -336,5 +425,6 @@ export function useNostr() {
fetchAllReplies, fetchAllReplies,
publish, publish,
createZap, createZap,
upload,
}; };
} }

View File

@ -1,5 +1,5 @@
import { magnetDecode } from '@ctrl/magnet-link'; import { magnetDecode } from '@ctrl/magnet-link';
import { open } from '@tauri-apps/plugin-dialog'; import { open } from '@tauri-apps/api/dialog';
import { VoidApi } from '@void-cat/api'; import { VoidApi } from '@void-cat/api';
import { createBlobFromFile } from '@utils/createBlobFromFile'; import { createBlobFromFile } from '@utils/createBlobFromFile';
@ -18,7 +18,18 @@ export function useImageUploader() {
filters: [ filters: [
{ {
name: 'Image', name: 'Image',
extensions: ['png', 'jpeg', 'jpg', 'gif'], extensions: [
'png',
'jpeg',
'jpg',
'gif',
'mp4',
'mp3',
'webm',
'mkv',
'avi',
'mov',
],
}, },
], ],
}); });
@ -27,7 +38,7 @@ export function useImageUploader() {
} else if (selected === null) { } else if (selected === null) {
// user cancelled the selection // user cancelled the selection
} else { } else {
filepath = selected.path; filepath = selected;
} }
} }

View File

@ -2,7 +2,7 @@ import {
isPermissionGranted, isPermissionGranted,
requestPermission, requestPermission,
sendNotification, sendNotification,
} from '@tauri-apps/plugin-notification'; } from '@tauri-apps/api/notification';
export async function sendNativeNotification(content: string, title?: string) { export async function sendNativeNotification(content: string, title?: string) {
let permissionGranted = await isPermissionGranted(); let permissionGranted = await isPermissionGranted();