mirror of
https://github.com/luminous-devs/lume.git
synced 2024-09-29 16:30:55 +00:00
feat: add theme switcher
This commit is contained in:
parent
4dc13385a5
commit
5ca9444358
@ -2,6 +2,7 @@ import { NostrQuery } from "@lume/system";
|
||||
import type { Settings } from "@lume/types";
|
||||
import * as Switch from "@radix-ui/react-switch";
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { requestPermission } from "@tauri-apps/plugin-notification";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
@ -61,6 +62,19 @@ function Screen() {
|
||||
}));
|
||||
};
|
||||
|
||||
const changeTheme = (theme: string) => {
|
||||
if (theme === "auto" || theme === "light" || theme === "dark") {
|
||||
invoke("plugin:theme|set_theme", {
|
||||
theme: theme,
|
||||
}).then(() =>
|
||||
setNewSettings((prev) => ({
|
||||
...prev,
|
||||
theme,
|
||||
})),
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const updateSettings = useDebouncedCallback(() => {
|
||||
NostrQuery.setSettings(newSettings);
|
||||
}, 200);
|
||||
@ -173,24 +187,42 @@ function Screen() {
|
||||
Interface
|
||||
</h2>
|
||||
<div className="flex flex-col divide-y divide-black/10 dark:divide-white/10 bg-black/5 dark:bg-white/5 rounded-xl px-3">
|
||||
<div className="flex flex-col gap-4">
|
||||
<div className="flex w-full items-start justify-between gap-4 py-3">
|
||||
<div className="flex-1">
|
||||
<h3 className="font-semibold">Zap</h3>
|
||||
<p className="text-sm text-neutral-700 dark:text-neutral-300">
|
||||
Show the Zap button in each note and user's profile screen,
|
||||
use for send bitcoin tip to other users.
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-36 flex justify-end shrink-0">
|
||||
<Switch.Root
|
||||
checked={newSettings.zap}
|
||||
onClick={() => toggleZap()}
|
||||
className="relative h-7 w-12 shrink-0 cursor-default rounded-full bg-black/10 outline-none data-[state=checked]:bg-blue-500 dark:bg-white/10"
|
||||
>
|
||||
<Switch.Thumb className="block size-6 translate-x-0.5 rounded-full bg-white transition-transform duration-100 will-change-transform data-[state=checked]:translate-x-[19px]" />
|
||||
</Switch.Root>
|
||||
</div>
|
||||
<div className="flex w-full items-start justify-between gap-4 py-3">
|
||||
<div className="flex-1">
|
||||
<h3 className="font-semibold">Zap</h3>
|
||||
<p className="text-sm text-neutral-700 dark:text-neutral-300">
|
||||
Show the Zap button in each note and user's profile screen,
|
||||
use for send bitcoin tip to other users.
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-36 flex justify-end shrink-0">
|
||||
<Switch.Root
|
||||
checked={newSettings.zap}
|
||||
onClick={() => toggleZap()}
|
||||
className="relative h-7 w-12 shrink-0 cursor-default rounded-full bg-black/10 outline-none data-[state=checked]:bg-blue-500 dark:bg-white/10"
|
||||
>
|
||||
<Switch.Thumb className="block size-6 translate-x-0.5 rounded-full bg-white transition-transform duration-100 will-change-transform data-[state=checked]:translate-x-[19px]" />
|
||||
</Switch.Root>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex w-full items-start justify-between gap-4 py-3">
|
||||
<div className="flex-1">
|
||||
<h3 className="font-semibold">Appearance</h3>
|
||||
<p className="text-sm text-neutral-700 dark:text-neutral-300">
|
||||
* Require restarting the app to take effect.
|
||||
</p>
|
||||
</div>
|
||||
<div className="w-36 flex justify-end shrink-0">
|
||||
<select
|
||||
name="theme"
|
||||
className="bg-transparent shadow-none outline-none rounded-lg border-1 border-black/10 dark:border-white/10 py-1 w-24"
|
||||
defaultValue={settings.theme}
|
||||
onChange={(e) => changeTheme(e.target.value)}
|
||||
>
|
||||
<option value="auto">Auto</option>
|
||||
<option value="light">Light</option>
|
||||
<option value="dark">Dark</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -5,6 +5,7 @@ import { readFile, readTextFile } from "@tauri-apps/plugin-fs";
|
||||
import { isPermissionGranted } from "@tauri-apps/plugin-notification";
|
||||
import { open } from "@tauri-apps/plugin-dialog";
|
||||
import { dedupEvents } from "./dedup";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
|
||||
enum NSTORE_KEYS {
|
||||
settings = "lume_user_settings",
|
||||
@ -201,8 +202,11 @@ export class NostrQuery {
|
||||
if (query.status === "ok") {
|
||||
const settings: Settings = query.data ? JSON.parse(query.data) : null;
|
||||
const isGranted = await isPermissionGranted();
|
||||
const theme: "auto" | "light" | "dark" = await invoke(
|
||||
"plugin:theme|get_theme",
|
||||
);
|
||||
|
||||
return { ...settings, notification: isGranted };
|
||||
return { ...settings, theme, notification: isGranted };
|
||||
} else {
|
||||
const initial: Settings = {
|
||||
autoUpdate: false,
|
||||
@ -210,6 +214,8 @@ export class NostrQuery {
|
||||
notification: false,
|
||||
zap: false,
|
||||
nsfw: false,
|
||||
gossip: false,
|
||||
theme: "auto",
|
||||
};
|
||||
|
||||
return initial;
|
||||
|
1
packages/types/index.d.ts
vendored
1
packages/types/index.d.ts
vendored
@ -5,6 +5,7 @@ export interface Settings {
|
||||
zap: boolean;
|
||||
nsfw: boolean;
|
||||
gossip: boolean;
|
||||
theme: "auto" | "light" | "dark";
|
||||
[key: string]: string | number | boolean;
|
||||
}
|
||||
|
||||
|
29
src-tauri/Cargo.lock
generated
29
src-tauri/Cargo.lock
generated
@ -2907,6 +2907,7 @@ dependencies = [
|
||||
"tauri-plugin-os",
|
||||
"tauri-plugin-process",
|
||||
"tauri-plugin-shell",
|
||||
"tauri-plugin-theme",
|
||||
"tauri-plugin-updater",
|
||||
"tauri-plugin-upload",
|
||||
"tauri-plugin-window-state",
|
||||
@ -5514,6 +5515,24 @@ dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-theme"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c23856e93f56cd8d1868e7dd8a4b529b836fd5da315cefd7702b252a850cdf5a"
|
||||
dependencies = [
|
||||
"cocoa",
|
||||
"dirs-next",
|
||||
"futures-lite 2.3.0",
|
||||
"gtk",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"tauri",
|
||||
"tauri-plugin",
|
||||
"tintanum",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-updater"
|
||||
version = "2.0.0-beta.5"
|
||||
@ -5805,6 +5824,16 @@ dependencies = [
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tintanum"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7abbcf9173afc80733c20b7e27a30bc9284d6535bdbde2a70904032de63e16e8"
|
||||
dependencies = [
|
||||
"futures-lite 1.13.0",
|
||||
"zbus 3.15.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.6.0"
|
||||
|
@ -39,6 +39,7 @@ keyring = "2"
|
||||
keyring-search = "0.2.0"
|
||||
specta = "=2.0.0-rc.12"
|
||||
tauri-specta = { version = "=2.0.0-rc.10", features = ["typescript"] }
|
||||
tauri-plugin-theme = "0.4.1"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
cocoa = "0.25.0"
|
||||
|
@ -56,6 +56,8 @@
|
||||
"dialog:allow-message",
|
||||
"process:allow-restart",
|
||||
"fs:allow-read-file",
|
||||
"theme:allow-set-theme",
|
||||
"theme:allow-get-theme",
|
||||
"shell:allow-open",
|
||||
{
|
||||
"identifier": "http:default",
|
||||
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
{"desktop-capability":{"identifier":"desktop-capability","description":"Capability for the desktop","local":true,"windows":["main","splash","settings","search","nwc","activity","zap-*","event-*","user-*","editor-*","column-*"],"permissions":["path:default","event:default","window:default","app:default","resources:default","menu:default","tray:default","notification:allow-is-permission-granted","notification:allow-request-permission","notification:default","os:allow-locale","os:allow-platform","os:allow-os-type","updater:default","updater:allow-check","updater:allow-download-and-install","window:allow-start-dragging","window:allow-create","window:allow-close","window:allow-set-focus","window:allow-center","window:allow-minimize","window:allow-maximize","window:allow-set-size","window:allow-set-focus","window:allow-start-dragging","decorum:allow-show-snap-overlay","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","webview:allow-create-webview-window","webview:allow-create-webview","webview:allow-set-webview-size","webview:allow-set-webview-position","webview:allow-webview-close","dialog:allow-open","dialog:allow-ask","dialog:allow-message","process:allow-restart","fs:allow-read-file","shell:allow-open",{"identifier":"http:default","allow":[{"url":"http://**/"},{"url":"https://**/"}]},{"identifier":"fs:allow-read-text-file","allow":[{"path":"$RESOURCE/locales/*"},{"path":"$RESOURCE/resources/*"}]}],"platforms":["linux","macOS","windows"]}}
|
||||
{"desktop-capability":{"identifier":"desktop-capability","description":"Capability for the desktop","local":true,"windows":["main","splash","settings","search","nwc","activity","zap-*","event-*","user-*","editor-*","column-*"],"permissions":["path:default","event:default","window:default","app:default","resources:default","menu:default","tray:default","notification:allow-is-permission-granted","notification:allow-request-permission","notification:default","os:allow-locale","os:allow-platform","os:allow-os-type","updater:default","updater:allow-check","updater:allow-download-and-install","window:allow-start-dragging","window:allow-create","window:allow-close","window:allow-set-focus","window:allow-center","window:allow-minimize","window:allow-maximize","window:allow-set-size","window:allow-set-focus","window:allow-start-dragging","decorum:allow-show-snap-overlay","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","webview:allow-create-webview-window","webview:allow-create-webview","webview:allow-set-webview-size","webview:allow-set-webview-position","webview:allow-webview-close","dialog:allow-open","dialog:allow-ask","dialog:allow-message","process:allow-restart","fs:allow-read-file","theme:allow-set-theme","theme:allow-get-theme","shell:allow-open",{"identifier":"http:default","allow":[{"url":"http://**/"},{"url":"https://**/"}]},{"identifier":"fs:allow-read-text-file","allow":[{"path":"$RESOURCE/locales/*"},{"path":"$RESOURCE/resources/*"}]}],"platforms":["linux","macOS","windows"]}}
|
@ -5654,6 +5654,40 @@
|
||||
"shell:deny-stdin-write"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"theme:default"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "theme:allow-get-theme -> Enables the get_theme command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"theme:allow-get-theme"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "theme:allow-set-theme -> Enables the set_theme command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"theme:allow-set-theme"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "theme:deny-get-theme -> Denies the get_theme command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"theme:deny-get-theme"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "theme:deny-set-theme -> Denies the set_theme command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"theme:deny-set-theme"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "tray:default -> Default permissions for the plugin.",
|
||||
"type": "string",
|
||||
|
@ -5654,6 +5654,40 @@
|
||||
"shell:deny-stdin-write"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"theme:default"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "theme:allow-get-theme -> Enables the get_theme command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"theme:allow-get-theme"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "theme:allow-set-theme -> Enables the set_theme command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"theme:allow-set-theme"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "theme:deny-get-theme -> Denies the get_theme command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"theme:deny-get-theme"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "theme:deny-set-theme -> Denies the set_theme command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"theme:deny-set-theme"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "tray:default -> Default permissions for the plugin.",
|
||||
"type": "string",
|
||||
|
@ -24,6 +24,7 @@ pub struct Nostr {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut ctx = tauri::generate_context!();
|
||||
let invoke_handler = {
|
||||
let builder = tauri_specta::ts::builder().commands(tauri_specta::collect_commands![
|
||||
nostr::relay::get_relays,
|
||||
@ -135,13 +136,7 @@ fn main() {
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.on_window_event(|window, event| match event {
|
||||
tauri::WindowEvent::CloseRequested { api, .. } => {
|
||||
window.hide().unwrap();
|
||||
api.prevent_close();
|
||||
}
|
||||
_ => {}
|
||||
})
|
||||
.plugin(tauri_plugin_theme::init(ctx.config_mut()))
|
||||
.plugin(tauri_plugin_decorum::init())
|
||||
.plugin(tauri_plugin_clipboard_manager::init())
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
@ -154,6 +149,6 @@ fn main() {
|
||||
.plugin(tauri_plugin_upload::init())
|
||||
.plugin(tauri_plugin_updater::Builder::new().build())
|
||||
.invoke_handler(invoke_handler)
|
||||
.run(tauri::generate_context!())
|
||||
.run(ctx)
|
||||
.expect("error while running tauri application")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user