diff --git a/package.json b/package.json index 42b9b30e..d7ee0b64 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "@tanstack/react-query": "^5.8.4", "@tauri-apps/api": "2.0.0-alpha.11", "@tauri-apps/cli": "2.0.0-alpha.17", + "@tauri-apps/plugin-autostart": "2.0.0-alpha.3", "@tauri-apps/plugin-clipboard-manager": "2.0.0-alpha.3", "@tauri-apps/plugin-dialog": "2.0.0-alpha.3", "@tauri-apps/plugin-fs": "2.0.0-alpha.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4e1bea0c..5eda04c0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -56,6 +56,9 @@ dependencies: '@tauri-apps/cli': specifier: 2.0.0-alpha.17 version: 2.0.0-alpha.17 + '@tauri-apps/plugin-autostart': + specifier: 2.0.0-alpha.3 + version: 2.0.0-alpha.3 '@tauri-apps/plugin-clipboard-manager': specifier: 2.0.0-alpha.3 version: 2.0.0-alpha.3 @@ -2145,6 +2148,12 @@ packages: '@tauri-apps/cli-win32-x64-msvc': 2.0.0-alpha.17 dev: false + /@tauri-apps/plugin-autostart@2.0.0-alpha.3: + resolution: {integrity: sha512-FWXMun68YPs+czGj063B/R2ItK0lFAHz08GCY8Ez1v5qGfq48MqBVF6EB5AHqQ73Wyq3+RGgDTyxuRFzBnXr6A==} + dependencies: + '@tauri-apps/api': 2.0.0-alpha.11 + dev: false + /@tauri-apps/plugin-clipboard-manager@2.0.0-alpha.3: resolution: {integrity: sha512-Lo30EM8VRo9bYMeRHhZT65OUgajbxaK1A9UhD7/9VZIFoWGbzKU/jrP78mcJ77lc+RrcCcSJvkAgOaLtuOlhxw==} dependencies: diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 520a15f1..7a2b646f 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -137,10 +137,6 @@ fn main() { ) .build(), ) - .plugin(tauri_plugin_autostart::init( - MacosLauncher::LaunchAgent, - Some(vec!["--flag1", "--flag2"]), - )) .plugin(tauri_plugin_clipboard_manager::init()) .plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_fs::init()) @@ -151,6 +147,10 @@ fn main() { .plugin(tauri_plugin_shell::init()) .plugin(tauri_plugin_upload::init()) .plugin(tauri_plugin_window_state::Builder::default().build()) + .plugin(tauri_plugin_autostart::init( + MacosLauncher::LaunchAgent, + Some(vec![]), + )) .invoke_handler(tauri::generate_handler![ opengraph, secure_save, diff --git a/src/app/settings/about.tsx b/src/app/settings/about.tsx index 8bbbe597..91e1fe28 100644 --- a/src/app/settings/about.tsx +++ b/src/app/settings/about.tsx @@ -1,5 +1,6 @@ import { getVersion } from '@tauri-apps/api/app'; import { useEffect, useState } from 'react'; +import { Link } from 'react-router-dom'; export function AboutScreen() { const [version, setVersion] = useState(''); @@ -22,6 +23,20 @@ export function AboutScreen() {

Version {version}

+
+ + Website + + + Report a issue + +
); } diff --git a/src/app/settings/advanced.tsx b/src/app/settings/advanced.tsx index 8a5f8660..456c7056 100644 --- a/src/app/settings/advanced.tsx +++ b/src/app/settings/advanced.tsx @@ -1,21 +1,24 @@ +import { useStorage } from '@libs/storage/provider'; + export function AdvancedSettingScreen() { + const { db } = useStorage(); + + const clearCache = async () => { + await db.clearCache(); + }; + return (
-
Event Caches
+
+
Caches
+
Use for boost up NDK
+
-
-
-
User Caches
- diff --git a/src/app/settings/backup.tsx b/src/app/settings/backup.tsx index c0748879..abf3d77f 100644 --- a/src/app/settings/backup.tsx +++ b/src/app/settings/backup.tsx @@ -1,10 +1,19 @@ +import { nip19 } from 'nostr-tools'; import { useEffect, useState } from 'react'; import { useStorage } from '@libs/storage/provider'; +import { EyeOffIcon } from '@shared/icons'; + export function BackupSettingScreen() { const { db } = useStorage(); + const [privkey, setPrivkey] = useState(null); + const [showPassword, setShowPassword] = useState(false); + + const removePrivkey = async () => { + await db.secureRemove(db.account.pubkey); + }; useEffect(() => { async function loadPrivkey() { @@ -24,12 +33,30 @@ export function BackupSettingScreen() { You've stored private key on Lume
) : ( - + <> +
+ + +
+ + )}
diff --git a/src/app/settings/general.tsx b/src/app/settings/general.tsx index 1b823c84..8494906c 100644 --- a/src/app/settings/general.tsx +++ b/src/app/settings/general.tsx @@ -1,6 +1,8 @@ import * as Switch from '@radix-ui/react-switch'; import { invoke } from '@tauri-apps/api/primitives'; import { getCurrent } from '@tauri-apps/api/window'; +import { disable, enable, isEnabled } from '@tauri-apps/plugin-autostart'; +import { isPermissionGranted, requestPermission } from '@tauri-apps/plugin-notification'; import { useEffect, useState } from 'react'; import { twMerge } from 'tailwind-merge'; @@ -20,51 +22,86 @@ export function GeneralSettingScreen() { }); const changeTheme = async (theme: 'light' | 'dark' | 'auto') => { - await invoke('plugin:theme|set_theme', { - theme, - }); - await db.createSetting('appearance', theme); + await invoke('plugin:theme|set_theme', { theme }); // update state setSettings((prev) => ({ ...prev, appearance: theme })); }; + const toggleAutolaunch = async () => { + if (!settings.autolaunch) { + await enable(); + // update state + setSettings((prev) => ({ ...prev, autolaunch: true })); + } else { + await disable(); + // update state + setSettings((prev) => ({ ...prev, autolaunch: false })); + } + }; + + const toggleOutbox = async () => { + await db.createSetting('outbox', String(+!settings.outbox)); + // update state + setSettings((prev) => ({ ...prev, outbox: !settings.outbox })); + }; + + const toggleMedia = async () => { + await db.createSetting('media', String(+!settings.media)); + // update state + setSettings((prev) => ({ ...prev, media: !settings.media })); + }; + + const toggleHashtag = async () => { + await db.createSetting('hashtag', String(+!settings.hashtag)); + // update state + setSettings((prev) => ({ ...prev, hashtag: !settings.hashtag })); + }; + + const toggleNofitication = async () => { + if (settings.notification) return; + + await requestPermission(); + // update state + setSettings((prev) => ({ ...prev, notification: !settings.notification })); + }; + useEffect(() => { async function loadSettings() { const theme = await getCurrent().theme(); setSettings((prev) => ({ ...prev, appearance: theme })); + const autostart = await isEnabled(); + setSettings((prev) => ({ ...prev, autolaunch: autostart })); + + const permissionGranted = await isPermissionGranted(); + setSettings((prev) => ({ ...prev, notification: permissionGranted })); + const data = await db.getAllSettings(); if (!data) return; data.forEach((item) => { - if (item.key === 'autolaunch') - setSettings((prev) => ({ - ...prev, - autolaunch: item.value === '1' ? true : false, - })); - if (item.key === 'outbox') setSettings((prev) => ({ ...prev, - outbox: item.value === '1' ? true : false, + outbox: !!parseInt(item.value), })); if (item.key === 'media') setSettings((prev) => ({ ...prev, - media: item.value === '1' ? true : false, + media: !!parseInt(item.value), })); if (item.key === 'hashtag') setSettings((prev) => ({ ...prev, - hashtag: item.value === '1' ? true : false, + hashtag: !!parseInt(item.value), })); if (item.key === 'notification') setSettings((prev) => ({ ...prev, - notification: item.value === '1' ? true : false, + notification: !!parseInt(item.value), })); }); } @@ -82,6 +119,7 @@ export function GeneralSettingScreen() { toggleAutolaunch()} className="relative h-7 w-12 cursor-default rounded-full bg-neutral-200 outline-none data-[state=checked]:bg-blue-500 dark:bg-neutral-800" > @@ -94,6 +132,7 @@ export function GeneralSettingScreen() { toggleOutbox()} className="relative h-7 w-12 cursor-default rounded-full bg-neutral-200 outline-none data-[state=checked]:bg-blue-500 dark:bg-neutral-800" > @@ -106,6 +145,7 @@ export function GeneralSettingScreen() { toggleMedia()} className="relative h-7 w-12 cursor-default rounded-full bg-neutral-200 outline-none data-[state=checked]:bg-blue-500 dark:bg-neutral-800" > @@ -118,6 +158,7 @@ export function GeneralSettingScreen() { toggleHashtag()} className="relative h-7 w-12 cursor-default rounded-full bg-neutral-200 outline-none data-[state=checked]:bg-blue-500 dark:bg-neutral-800" > @@ -132,6 +173,8 @@ export function GeneralSettingScreen() { toggleNofitication()} className="relative h-7 w-12 cursor-default rounded-full bg-neutral-200 outline-none data-[state=checked]:bg-blue-500 dark:bg-neutral-800" > diff --git a/src/libs/storage/instance.ts b/src/libs/storage/instance.ts index 58cef831..37bc18c9 100644 --- a/src/libs/storage/instance.ts +++ b/src/libs/storage/instance.ts @@ -429,10 +429,20 @@ export class LumeStorage { } public async createSetting(key: string, value: string) { - return await this.db.execute( - 'INSERT OR IGNORE INTO settings (key, value) VALUES ($1, $2);', - [key, value] - ); + const currentSetting = await this.getSettingValue(key); + + if (!currentSetting) + return await this.db.execute( + 'INSERT OR IGNORE INTO settings (key, value) VALUES ($1, $2);', + [key, value] + ); + + const currentValue = !!parseInt(currentSetting); + + return await this.db.execute('UPDATE settings SET value = $1 WHERE key = $2;', [ + +!currentValue, + key, + ]); } public async getAllSettings() { @@ -452,6 +462,12 @@ export class LumeStorage { return results[0].value; } + public async clearCache() { + await this.db.execute('DELETE FROM ndk_events;'); + await this.db.execute('DELETE FROM ndk_eventtags;'); + await this.db.execute('DELETE FROM ndk_users;'); + } + public async accountLogout() { // update current account status await this.db.execute("UPDATE accounts SET is_active = '0' WHERE id = $1;", [ diff --git a/src/shared/layouts/settings.tsx b/src/shared/layouts/settings.tsx index f64972bb..083227a1 100644 --- a/src/shared/layouts/settings.tsx +++ b/src/shared/layouts/settings.tsx @@ -35,7 +35,8 @@ export function SettingsLayout() {
twMerge( 'flex w-20 shrink-0 flex-col items-center justify-center rounded-lg px-2 py-2 text-neutral-700 hover:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-900',