mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-07-04 20:11:48 +02:00
Add CEF runtime to Linux builds (#494)
This commit is contained in:
@@ -30,4 +30,4 @@ jobs:
|
|||||||
- name: Run JS Tests
|
- name: Run JS Tests
|
||||||
run: vp test
|
run: vp test
|
||||||
- name: Run Rust Tests
|
- name: Run Rust Tests
|
||||||
run: cargo test --all
|
run: cargo test --all --features yaak-app-client/wry
|
||||||
|
|||||||
@@ -14,33 +14,33 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- platform: "macos-latest" # for Arm-based Macs (M1 and above).
|
- platform: "macos-latest" # for Arm-based Macs (M1 and above).
|
||||||
args: "--target aarch64-apple-darwin"
|
args: '--target aarch64-apple-darwin --config ./tauri.release.conf.json --config ''{"build":{"features":["updater","license","wry"]}}'''
|
||||||
yaak_arch: "arm64"
|
yaak_arch: "arm64"
|
||||||
os: "macos"
|
os: "macos"
|
||||||
targets: "aarch64-apple-darwin"
|
targets: "aarch64-apple-darwin"
|
||||||
- platform: "macos-latest" # for Intel-based Macs.
|
- platform: "macos-latest" # for Intel-based Macs.
|
||||||
args: "--target x86_64-apple-darwin"
|
args: '--target x86_64-apple-darwin --config ./tauri.release.conf.json --config ''{"build":{"features":["updater","license","wry"]}}'''
|
||||||
yaak_arch: "x64"
|
yaak_arch: "x64"
|
||||||
os: "macos"
|
os: "macos"
|
||||||
targets: "x86_64-apple-darwin"
|
targets: "x86_64-apple-darwin"
|
||||||
- platform: "ubuntu-22.04"
|
- platform: "ubuntu-22.04"
|
||||||
args: ""
|
args: '--config ./tauri.release.conf.json --config ''{"build":{"features":["updater","license","cef"]}}'''
|
||||||
yaak_arch: "x64"
|
yaak_arch: "x64"
|
||||||
os: "ubuntu"
|
os: "ubuntu"
|
||||||
targets: ""
|
targets: ""
|
||||||
- platform: "ubuntu-22.04-arm"
|
- platform: "ubuntu-22.04-arm"
|
||||||
args: ""
|
args: '--config ./tauri.release.conf.json --config ''{"build":{"features":["updater","license","cef"]}}'''
|
||||||
yaak_arch: "arm64"
|
yaak_arch: "arm64"
|
||||||
os: "ubuntu"
|
os: "ubuntu"
|
||||||
targets: ""
|
targets: ""
|
||||||
- platform: "windows-latest"
|
- platform: "windows-latest"
|
||||||
args: ""
|
args: '--config ./tauri.release.conf.json --config ''{"build":{"features":["updater","license","wry"]}}'''
|
||||||
yaak_arch: "x64"
|
yaak_arch: "x64"
|
||||||
os: "windows"
|
os: "windows"
|
||||||
targets: ""
|
targets: ""
|
||||||
# Windows ARM64
|
# Windows ARM64
|
||||||
- platform: "windows-latest"
|
- platform: "windows-latest"
|
||||||
args: "--target aarch64-pc-windows-msvc"
|
args: '--target aarch64-pc-windows-msvc --config ./tauri.release.conf.json --config ''{"build":{"features":["updater","license","wry"]}}'''
|
||||||
yaak_arch: "arm64"
|
yaak_arch: "arm64"
|
||||||
os: "windows"
|
os: "windows"
|
||||||
targets: "aarch64-pc-windows-msvc"
|
targets: "aarch64-pc-windows-msvc"
|
||||||
@@ -66,11 +66,18 @@ jobs:
|
|||||||
shared-key: ci
|
shared-key: ci
|
||||||
cache-on-failure: true
|
cache-on-failure: true
|
||||||
|
|
||||||
|
- name: Cache CEF (Linux only)
|
||||||
|
if: matrix.os == 'ubuntu'
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: ~/.cache/tauri-cef
|
||||||
|
key: cef-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('Cargo.lock') }}
|
||||||
|
|
||||||
- name: install dependencies (Linux only)
|
- name: install dependencies (Linux only)
|
||||||
if: matrix.os == 'ubuntu'
|
if: matrix.os == 'ubuntu'
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf xdg-utils
|
sudo apt-get install -y cmake ninja-build libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf xdg-utils
|
||||||
|
|
||||||
- name: Install Protoc for plugin-runtime
|
- name: Install Protoc for plugin-runtime
|
||||||
uses: arduino/setup-protoc@v3
|
uses: arduino/setup-protoc@v3
|
||||||
@@ -98,7 +105,7 @@ jobs:
|
|||||||
- name: Run JS Tests
|
- name: Run JS Tests
|
||||||
run: vp test
|
run: vp test
|
||||||
- name: Run Rust Tests
|
- name: Run Rust Tests
|
||||||
run: cargo test --all --exclude yaak-cli
|
run: cargo test --all --exclude yaak-cli --features yaak-app-client/wry
|
||||||
|
|
||||||
- name: Set version
|
- name: Set version
|
||||||
run: npm run replace-version
|
run: npm run replace-version
|
||||||
@@ -150,13 +157,14 @@ jobs:
|
|||||||
AZURE_CLIENT_SECRET: ${{ matrix.os == 'windows' && secrets.AZURE_CLIENT_SECRET }}
|
AZURE_CLIENT_SECRET: ${{ matrix.os == 'windows' && secrets.AZURE_CLIENT_SECRET }}
|
||||||
AZURE_TENANT_ID: ${{ matrix.os == 'windows' && secrets.AZURE_TENANT_ID }}
|
AZURE_TENANT_ID: ${{ matrix.os == 'windows' && secrets.AZURE_TENANT_ID }}
|
||||||
with:
|
with:
|
||||||
|
tauriScript: "node ../../node_modules/@tauri-apps/cli/tauri.js"
|
||||||
tagName: "v__VERSION__"
|
tagName: "v__VERSION__"
|
||||||
releaseName: "Release __VERSION__"
|
releaseName: "Release __VERSION__"
|
||||||
releaseBody: "[Changelog __VERSION__](https://yaak.app/blog/__VERSION__)"
|
releaseBody: "[Changelog __VERSION__](https://yaak.app/blog/__VERSION__)"
|
||||||
releaseDraft: true
|
releaseDraft: true
|
||||||
prerelease: true
|
prerelease: true
|
||||||
projectPath: ./crates-tauri/yaak-app-client
|
projectPath: ./crates-tauri/yaak-app-client
|
||||||
args: "${{ matrix.args }} --config ./tauri.release.conf.json"
|
args: "${{ matrix.args }}"
|
||||||
|
|
||||||
# Build a per-machine NSIS installer for enterprise deployment (PDQ, SCCM, Intune)
|
# Build a per-machine NSIS installer for enterprise deployment (PDQ, SCCM, Intune)
|
||||||
- name: Build and upload machine-wide installer (Windows only)
|
- name: Build and upload machine-wide installer (Windows only)
|
||||||
@@ -173,7 +181,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
Get-ChildItem -Recurse -Path target -File -Filter "*.exe.sig" | Remove-Item -Force
|
Get-ChildItem -Recurse -Path target -File -Filter "*.exe.sig" | Remove-Item -Force
|
||||||
Push-Location crates-tauri/yaak-app-client
|
Push-Location crates-tauri/yaak-app-client
|
||||||
npx tauri bundle ${{ matrix.args }} --bundles nsis --config ./tauri.release.conf.json --config '{"bundle":{"createUpdaterArtifacts":true,"windows":{"nsis":{"installMode":"perMachine"}}}}'
|
npx tauri bundle ${{ matrix.args }} --bundles nsis --config '{"bundle":{"createUpdaterArtifacts":true,"windows":{"nsis":{"installMode":"perMachine"}}}}'
|
||||||
Pop-Location
|
Pop-Location
|
||||||
$setup = Get-ChildItem -Recurse -Path target -Filter "*setup*.exe" | Select-Object -First 1
|
$setup = Get-ChildItem -Recurse -Path target -Filter "*setup*.exe" | Select-Object -First 1
|
||||||
$setupSig = "$($setup.FullName).sig"
|
$setupSig = "$($setup.FullName).sig"
|
||||||
|
|||||||
Generated
+914
-96
File diff suppressed because it is too large
Load Diff
+11
-1
@@ -31,6 +31,7 @@ members = [
|
|||||||
"crates-tauri/yaak-fonts",
|
"crates-tauri/yaak-fonts",
|
||||||
"crates-tauri/yaak-license",
|
"crates-tauri/yaak-license",
|
||||||
"crates-tauri/yaak-mac-window",
|
"crates-tauri/yaak-mac-window",
|
||||||
|
"crates-tauri/yaak-system-appearance",
|
||||||
"crates-tauri/yaak-tauri-utils",
|
"crates-tauri/yaak-tauri-utils",
|
||||||
"crates-tauri/yaak-window",
|
"crates-tauri/yaak-window",
|
||||||
]
|
]
|
||||||
@@ -47,7 +48,11 @@ schemars = { version = "0.8.22", features = ["chrono"] }
|
|||||||
serde = "1.0.228"
|
serde = "1.0.228"
|
||||||
serde_json = "1.0.145"
|
serde_json = "1.0.145"
|
||||||
sha2 = "0.10.9"
|
sha2 = "0.10.9"
|
||||||
tauri = "2.11.1"
|
tauri = { version = "2.11.1", default-features = false, features = [
|
||||||
|
"common-controls-v6",
|
||||||
|
"compression",
|
||||||
|
"dynamic-acl",
|
||||||
|
] }
|
||||||
tauri-plugin = "2.6.1"
|
tauri-plugin = "2.6.1"
|
||||||
tauri-plugin-dialog = "2.7.1"
|
tauri-plugin-dialog = "2.7.1"
|
||||||
tauri-plugin-shell = "2.3.5"
|
tauri-plugin-shell = "2.3.5"
|
||||||
@@ -84,8 +89,13 @@ yaak-proxy-lib = { path = "crates-proxy/yaak-proxy-lib" }
|
|||||||
yaak-fonts = { path = "crates-tauri/yaak-fonts" }
|
yaak-fonts = { path = "crates-tauri/yaak-fonts" }
|
||||||
yaak-license = { path = "crates-tauri/yaak-license" }
|
yaak-license = { path = "crates-tauri/yaak-license" }
|
||||||
yaak-mac-window = { path = "crates-tauri/yaak-mac-window" }
|
yaak-mac-window = { path = "crates-tauri/yaak-mac-window" }
|
||||||
|
yaak-system-appearance = { path = "crates-tauri/yaak-system-appearance" }
|
||||||
yaak-tauri-utils = { path = "crates-tauri/yaak-tauri-utils" }
|
yaak-tauri-utils = { path = "crates-tauri/yaak-tauri-utils" }
|
||||||
yaak-window = { path = "crates-tauri/yaak-window" }
|
yaak-window = { path = "crates-tauri/yaak-window" }
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
strip = false
|
strip = false
|
||||||
|
|
||||||
|
[patch.crates-io]
|
||||||
|
tauri = { git = "https://github.com/tauri-apps/tauri", rev = "d9bc695c18d9a25baec21d8a5f36d72e3a14ee53" }
|
||||||
|
tauri-build = { git = "https://github.com/tauri-apps/tauri", rev = "d9bc695c18d9a25baec21d8a5f36d72e3a14ee53" }
|
||||||
|
|||||||
+51
-11
@@ -1,32 +1,49 @@
|
|||||||
import { listen } from "@tauri-apps/api/event";
|
import { listen } from "@tauri-apps/api/event";
|
||||||
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow";
|
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow";
|
||||||
|
import { type as osType } from "@tauri-apps/plugin-os";
|
||||||
import { setWindowTheme } from "@yaakapp-internal/mac-window";
|
import { setWindowTheme } from "@yaakapp-internal/mac-window";
|
||||||
import type { ModelPayload } from "@yaakapp-internal/models";
|
import type { ModelPayload } from "@yaakapp-internal/models";
|
||||||
import type { Appearance } from "@yaakapp-internal/theme";
|
import type { Appearance } from "@yaakapp-internal/theme";
|
||||||
import {
|
import {
|
||||||
applyThemeToDocument,
|
applyThemeToDocument,
|
||||||
getCSSAppearance,
|
getCSSAppearance,
|
||||||
subscribeToPreferredAppearance,
|
subscribeToPreferredAppearanceChange,
|
||||||
|
subscribeToSystemAppearanceChange,
|
||||||
} from "@yaakapp-internal/theme";
|
} from "@yaakapp-internal/theme";
|
||||||
import { getSettings } from "./lib/settings";
|
import { getSettings } from "./lib/settings";
|
||||||
import { getResolvedTheme } from "./lib/themes";
|
import { getResolvedTheme } from "./lib/themes";
|
||||||
|
|
||||||
// NOTE: CSS appearance isn't as accurate as getting it async from the window (next step), but we want
|
// NOTE: CSS appearance isn't as accurate as getting it async from the window (next step), but we want
|
||||||
// a good appearance guess so we're not waiting too long
|
// a good appearance guess so we're not waiting too long
|
||||||
let preferredAppearance: Appearance = getCSSAppearance();
|
let preferredAppearance: Appearance = getInitialAppearance();
|
||||||
subscribeToPreferredAppearance(async (a) => {
|
let linuxSystemAppearanceAvailable =
|
||||||
|
osType() === "linux" && window.__YAAK_INITIAL_APPEARANCE_SOURCE__ === "linux-system";
|
||||||
|
let configureThemeGeneration = 0;
|
||||||
|
let windowShown = false;
|
||||||
|
|
||||||
|
configureThemeAndShow().catch((err) => console.log("Failed to configure theme", err));
|
||||||
|
|
||||||
|
subscribeToPreferredAppearanceChange(async (a) => {
|
||||||
|
if (linuxSystemAppearanceAvailable) return;
|
||||||
preferredAppearance = a;
|
preferredAppearance = a;
|
||||||
await configureTheme();
|
await configureThemeAndShow();
|
||||||
});
|
});
|
||||||
|
|
||||||
configureTheme().then(
|
subscribeToSystemAppearanceChange(async (a) => {
|
||||||
async () => {
|
linuxSystemAppearanceAvailable = true;
|
||||||
|
preferredAppearance = a;
|
||||||
|
await configureThemeAndShow();
|
||||||
|
});
|
||||||
|
|
||||||
|
async function configureThemeAndShow() {
|
||||||
|
const applied = await configureTheme();
|
||||||
|
if (applied && !windowShown) {
|
||||||
|
windowShown = true;
|
||||||
// To prevent theme flashing, the backend hides new windows by default, so we
|
// To prevent theme flashing, the backend hides new windows by default, so we
|
||||||
// need to show it here, after configuring the theme for the first time.
|
// need to show it here, after configuring the theme for the first time.
|
||||||
await getCurrentWebviewWindow().show();
|
await getCurrentWebviewWindow().show();
|
||||||
},
|
}
|
||||||
(err) => console.log("Failed to configure theme", err),
|
}
|
||||||
);
|
|
||||||
|
|
||||||
// Listen for settings changes, the re-compute theme
|
// Listen for settings changes, the re-compute theme
|
||||||
listen<ModelPayload>("model_write", async (event) => {
|
listen<ModelPayload>("model_write", async (event) => {
|
||||||
@@ -34,10 +51,11 @@ listen<ModelPayload>("model_write", async (event) => {
|
|||||||
|
|
||||||
const model = event.payload.model.model;
|
const model = event.payload.model.model;
|
||||||
if (model !== "settings" && model !== "plugin") return;
|
if (model !== "settings" && model !== "plugin") return;
|
||||||
await configureTheme();
|
await configureThemeAndShow();
|
||||||
}).catch(console.error);
|
}).catch(console.error);
|
||||||
|
|
||||||
async function configureTheme() {
|
async function configureTheme(): Promise<boolean> {
|
||||||
|
const generation = ++configureThemeGeneration;
|
||||||
const settings = await getSettings();
|
const settings = await getSettings();
|
||||||
const theme = await getResolvedTheme(
|
const theme = await getResolvedTheme(
|
||||||
preferredAppearance,
|
preferredAppearance,
|
||||||
@@ -45,8 +63,30 @@ async function configureTheme() {
|
|||||||
settings.themeLight,
|
settings.themeLight,
|
||||||
settings.themeDark,
|
settings.themeDark,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (generation !== configureThemeGeneration) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
applyThemeToDocument(theme.active);
|
applyThemeToDocument(theme.active);
|
||||||
if (theme.active.base.surface != null) {
|
if (theme.active.base.surface != null) {
|
||||||
setWindowTheme(theme.active.base.surface);
|
setWindowTheme(theme.active.base.surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getInitialAppearance(): Appearance {
|
||||||
|
const initialAppearance = window.__YAAK_INITIAL_APPEARANCE__;
|
||||||
|
if (initialAppearance === "dark" || initialAppearance === "light") {
|
||||||
|
return initialAppearance;
|
||||||
|
}
|
||||||
|
return getCSSAppearance();
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
__YAAK_INITIAL_APPEARANCE__?: Appearance;
|
||||||
|
__YAAK_INITIAL_APPEARANCE_SOURCE__?: "settings" | "linux-system";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -855,8 +855,6 @@ exports.plugin = {
|
|||||||
assert_eq!(metadata["apis"]["workspaceActions"]["items"][0]["label"], "Sync workspace");
|
assert_eq!(metadata["apis"]["workspaceActions"]["items"][0]["label"], "Sync workspace");
|
||||||
assert_eq!(metadata["apis"]["lifecycle"]["items"][0]["name"], "init");
|
assert_eq!(metadata["apis"]["lifecycle"]["items"][0]["name"], "init");
|
||||||
assert!(metadata["apis"]["templateFunctions"]["items"][0]["onRender"].is_null());
|
assert!(metadata["apis"]["templateFunctions"]["items"][0]["onRender"].is_null());
|
||||||
assert!(
|
assert!(metadata["apis"]["templateFunctions"]["items"][0]["args"][0]["dynamic"].is_null());
|
||||||
metadata["apis"]["templateFunctions"]["items"][0]["args"][0]["dynamic"].is_null()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -470,11 +470,7 @@ async fn build_plugin_reply(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let names = cookie_jar
|
let names = cookie_jar.cookies.into_iter().map(|c| c.name).collect();
|
||||||
.cookies
|
|
||||||
.into_iter()
|
|
||||||
.map(|c| c.name)
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
Some(InternalEventPayload::ListCookieNamesResponse(ListCookieNamesResponse {
|
Some(InternalEventPayload::ListCookieNamesResponse(ListCookieNamesResponse {
|
||||||
names,
|
names,
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ crate-type = ["staticlib", "cdylib", "lib"]
|
|||||||
[features]
|
[features]
|
||||||
cargo-clippy = []
|
cargo-clippy = []
|
||||||
default = []
|
default = []
|
||||||
|
cef = ["tauri/cef"]
|
||||||
|
wry = ["tauri/wry", "tauri/x11", "tauri/dbus"]
|
||||||
updater = []
|
updater = []
|
||||||
license = ["yaak-license"]
|
license = ["yaak-license"]
|
||||||
|
|
||||||
@@ -82,6 +84,7 @@ yaak-mac-window = { workspace = true }
|
|||||||
yaak-models = { workspace = true }
|
yaak-models = { workspace = true }
|
||||||
yaak-plugins = { workspace = true }
|
yaak-plugins = { workspace = true }
|
||||||
yaak-sse = { workspace = true }
|
yaak-sse = { workspace = true }
|
||||||
|
yaak-system-appearance = { workspace = true }
|
||||||
yaak-sync = { workspace = true }
|
yaak-sync = { workspace = true }
|
||||||
yaak-templates = { workspace = true }
|
yaak-templates = { workspace = true }
|
||||||
yaak-tls = { workspace = true }
|
yaak-tls = { workspace = true }
|
||||||
|
|||||||
@@ -82,6 +82,14 @@ mod uri_scheme;
|
|||||||
mod window_menu;
|
mod window_menu;
|
||||||
mod ws_ext;
|
mod ws_ext;
|
||||||
|
|
||||||
|
#[cfg(not(any(feature = "cef", feature = "wry")))]
|
||||||
|
compile_error!("Enable one Tauri runtime feature: `cef` or `wry`.");
|
||||||
|
|
||||||
|
#[cfg(feature = "cef")]
|
||||||
|
type TauriRuntime = tauri::Cef;
|
||||||
|
#[cfg(all(not(feature = "cef"), feature = "wry"))]
|
||||||
|
type TauriRuntime = tauri::Wry;
|
||||||
|
|
||||||
fn setup_window_menu<R: Runtime>(win: &WebviewWindow<R>) -> Result<()> {
|
fn setup_window_menu<R: Runtime>(win: &WebviewWindow<R>) -> Result<()> {
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
let menu = window_menu::app_menu(win.app_handle())?;
|
let menu = window_menu::app_menu(win.app_handle())?;
|
||||||
@@ -150,6 +158,22 @@ fn setup_window_menu<R: Runtime>(win: &WebviewWindow<R>) -> Result<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn initial_appearance_script<R: Runtime>(app_handle: &AppHandle<R>) -> Option<String> {
|
||||||
|
use yaak_system_appearance::{Appearance, InitialAppearanceSource};
|
||||||
|
|
||||||
|
let settings = app_handle.db().get_settings();
|
||||||
|
let (appearance, source) = match settings.appearance.as_str() {
|
||||||
|
"dark" => (Appearance::Dark, InitialAppearanceSource::Settings),
|
||||||
|
"light" => (Appearance::Light, InitialAppearanceSource::Settings),
|
||||||
|
_ => (
|
||||||
|
yaak_system_appearance::system_appearance()?,
|
||||||
|
InitialAppearanceSource::LinuxSystem,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(yaak_system_appearance::initialization_script(appearance, source))
|
||||||
|
}
|
||||||
|
|
||||||
/// Extension trait for easily creating a PluginContext from a WebviewWindow
|
/// Extension trait for easily creating a PluginContext from a WebviewWindow
|
||||||
pub trait PluginContextExt<R: Runtime> {
|
pub trait PluginContextExt<R: Runtime> {
|
||||||
fn plugin_context(&self) -> PluginContext;
|
fn plugin_context(&self) -> PluginContext;
|
||||||
@@ -177,7 +201,7 @@ struct AppMetaData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_metadata(app_handle: AppHandle) -> YaakResult<AppMetaData> {
|
async fn cmd_metadata<R: Runtime>(app_handle: AppHandle<R>) -> YaakResult<AppMetaData> {
|
||||||
let app_data_dir = app_handle.path().app_data_dir()?;
|
let app_data_dir = app_handle.path().app_data_dir()?;
|
||||||
let app_log_dir = app_handle.path().app_log_dir()?;
|
let app_log_dir = app_handle.path().app_log_dir()?;
|
||||||
let vendored_plugin_dir =
|
let vendored_plugin_dir =
|
||||||
@@ -962,7 +986,7 @@ async fn cmd_send_ephemeral_request<R: Runtime>(
|
|||||||
mut request: HttpRequest,
|
mut request: HttpRequest,
|
||||||
environment_id: Option<&str>,
|
environment_id: Option<&str>,
|
||||||
cookie_jar_id: Option<&str>,
|
cookie_jar_id: Option<&str>,
|
||||||
window: WebviewWindow,
|
window: WebviewWindow<R>,
|
||||||
app_handle: AppHandle<R>,
|
app_handle: AppHandle<R>,
|
||||||
) -> YaakResult<HttpResponse> {
|
) -> YaakResult<HttpResponse> {
|
||||||
let response = HttpResponse::default();
|
let response = HttpResponse::default();
|
||||||
@@ -1588,20 +1612,22 @@ async fn cmd_get_workspace_meta<R: Runtime>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_new_child_window(
|
async fn cmd_new_child_window<R: Runtime>(
|
||||||
parent_window: WebviewWindow,
|
parent_window: WebviewWindow<R>,
|
||||||
url: &str,
|
url: &str,
|
||||||
label: &str,
|
label: &str,
|
||||||
title: &str,
|
title: &str,
|
||||||
inner_size: (f64, f64),
|
inner_size: (f64, f64),
|
||||||
) -> YaakResult<()> {
|
) -> YaakResult<()> {
|
||||||
let use_native_titlebar = parent_window.app_handle().db().get_settings().use_native_titlebar;
|
let use_native_titlebar = parent_window.app_handle().db().get_settings().use_native_titlebar;
|
||||||
|
let initialization_script = initial_appearance_script(&parent_window.app_handle());
|
||||||
let win = yaak_window::window::create_child_window(
|
let win = yaak_window::window::create_child_window(
|
||||||
&parent_window,
|
&parent_window,
|
||||||
url,
|
url,
|
||||||
label,
|
label,
|
||||||
title,
|
title,
|
||||||
inner_size,
|
inner_size,
|
||||||
|
initialization_script,
|
||||||
use_native_titlebar,
|
use_native_titlebar,
|
||||||
)?;
|
)?;
|
||||||
setup_window_menu(&win)?;
|
setup_window_menu(&win)?;
|
||||||
@@ -1609,9 +1635,15 @@ async fn cmd_new_child_window(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn cmd_new_main_window(app_handle: AppHandle, url: &str) -> YaakResult<()> {
|
async fn cmd_new_main_window<R: Runtime>(app_handle: AppHandle<R>, url: &str) -> YaakResult<()> {
|
||||||
let use_native_titlebar = app_handle.db().get_settings().use_native_titlebar;
|
let use_native_titlebar = app_handle.db().get_settings().use_native_titlebar;
|
||||||
let win = yaak_window::window::create_main_window(&app_handle, url, use_native_titlebar)?;
|
let initialization_script = initial_appearance_script(&app_handle);
|
||||||
|
let win = yaak_window::window::create_main_window(
|
||||||
|
&app_handle,
|
||||||
|
url,
|
||||||
|
initialization_script,
|
||||||
|
use_native_titlebar,
|
||||||
|
)?;
|
||||||
setup_window_menu(&win)?;
|
setup_window_menu(&win)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@@ -1631,8 +1663,9 @@ async fn cmd_check_for_updates<R: Runtime>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||||
|
#[cfg_attr(feature = "cef", tauri::cef_entry_point)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
let mut builder = tauri::Builder::default().plugin(
|
let mut builder = tauri::Builder::<TauriRuntime>::default().plugin(
|
||||||
Builder::default()
|
Builder::default()
|
||||||
.targets([
|
.targets([
|
||||||
Target::new(TargetKind::Stdout),
|
Target::new(TargetKind::Stdout),
|
||||||
@@ -1706,6 +1739,10 @@ pub fn run() {
|
|||||||
app.state::<yaak_models::query_manager::QueryManager>().inner().clone();
|
app.state::<yaak_models::query_manager::QueryManager>().inner().clone();
|
||||||
let app_id = app.config().identifier.to_string();
|
let app_id = app.config().identifier.to_string();
|
||||||
app.manage(yaak_crypto::manager::EncryptionManager::new(query_manager, app_id));
|
app.manage(yaak_crypto::manager::EncryptionManager::new(query_manager, app_id));
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
if let Some(state) = yaak_system_appearance::watch(app.app_handle().clone()) {
|
||||||
|
app.manage(state);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let app_handle = app.app_handle().clone();
|
let app_handle = app.app_handle().clone();
|
||||||
@@ -1894,9 +1931,11 @@ pub fn run() {
|
|||||||
match event {
|
match event {
|
||||||
RunEvent::Ready => {
|
RunEvent::Ready => {
|
||||||
let use_native_titlebar = app_handle.db().get_settings().use_native_titlebar;
|
let use_native_titlebar = app_handle.db().get_settings().use_native_titlebar;
|
||||||
|
let initialization_script = initial_appearance_script(app_handle);
|
||||||
if let Ok(win) = yaak_window::window::create_main_window(
|
if let Ok(win) = yaak_window::window::create_main_window(
|
||||||
app_handle,
|
app_handle,
|
||||||
"/",
|
"/",
|
||||||
|
initialization_script,
|
||||||
use_native_titlebar,
|
use_native_titlebar,
|
||||||
) {
|
) {
|
||||||
let _ = setup_window_menu(&win);
|
let _ = setup_window_menu(&win);
|
||||||
@@ -1917,6 +1956,13 @@ pub fn run() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
RunEvent::WindowEvent { event: WindowEvent::Focused(true), label, .. } => {
|
RunEvent::WindowEvent { event: WindowEvent::Focused(true), label, .. } => {
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
if let Some(state) =
|
||||||
|
app_handle.try_state::<yaak_system_appearance::SystemAppearanceState>()
|
||||||
|
{
|
||||||
|
yaak_system_appearance::emit_change(app_handle, &state);
|
||||||
|
}
|
||||||
|
|
||||||
if cfg!(feature = "updater") {
|
if cfg!(feature = "updater") {
|
||||||
// Run update check whenever the window is focused
|
// Run update check whenever the window is focused
|
||||||
let w = app_handle.get_webview_window(&label).unwrap();
|
let w = app_handle.get_webview_window(&label).unwrap();
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
"beforeBuildCommand": "npm --prefix ../.. run client:tauri-before-build",
|
"beforeBuildCommand": "npm --prefix ../.. run client:tauri-before-build",
|
||||||
"beforeDevCommand": "npm --prefix ../.. run client:tauri-before-dev",
|
"beforeDevCommand": "npm --prefix ../.. run client:tauri-before-dev",
|
||||||
"devUrl": "http://localhost:1420",
|
"devUrl": "http://localhost:1420",
|
||||||
"frontendDist": "../../dist/apps/yaak-client"
|
"frontendDist": "../../dist/apps/yaak-client",
|
||||||
|
"features": ["wry"]
|
||||||
},
|
},
|
||||||
"app": {
|
"app": {
|
||||||
"withGlobalTauri": false,
|
"withGlobalTauri": false,
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
{
|
{
|
||||||
"build": {
|
|
||||||
"features": ["updater", "license"]
|
|
||||||
},
|
|
||||||
"app": {
|
"app": {
|
||||||
"security": {
|
"security": {
|
||||||
"capabilities": [
|
"capabilities": [
|
||||||
|
|||||||
@@ -12,6 +12,10 @@ crate-type = ["staticlib", "cdylib", "lib"]
|
|||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
tauri-build = { version = "2.6.1", features = [] }
|
tauri-build = { version = "2.6.1", features = [] }
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["wry"]
|
||||||
|
wry = ["tauri/wry", "tauri/x11", "tauri/dbus"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
[package]
|
||||||
|
name = "yaak-system-appearance"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
publish = false
|
||||||
|
|
||||||
|
[target.'cfg(target_os = "linux")'.dependencies]
|
||||||
|
dark-light = "2.0.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
log = { workspace = true }
|
||||||
|
tauri = { workspace = true }
|
||||||
@@ -0,0 +1,151 @@
|
|||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use log::{debug, warn};
|
||||||
|
use tauri::{AppHandle, Emitter, Runtime};
|
||||||
|
|
||||||
|
pub const INITIAL_APPEARANCE_GLOBAL: &str = "__YAAK_INITIAL_APPEARANCE__";
|
||||||
|
pub const INITIAL_APPEARANCE_SOURCE_GLOBAL: &str = "__YAAK_INITIAL_APPEARANCE_SOURCE__";
|
||||||
|
pub const SYSTEM_APPEARANCE_CHANGE_EVENT: &str = "system_appearance_change";
|
||||||
|
|
||||||
|
const SYSTEM_APPEARANCE_POLL_INTERVAL: Duration = Duration::from_secs(1);
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
|
pub enum Appearance {
|
||||||
|
Dark,
|
||||||
|
Light,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Appearance {
|
||||||
|
pub fn as_str(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::Dark => "dark",
|
||||||
|
Self::Light => "light",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
|
pub enum InitialAppearanceSource {
|
||||||
|
Settings,
|
||||||
|
LinuxSystem,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InitialAppearanceSource {
|
||||||
|
fn as_str(self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Self::Settings => "settings",
|
||||||
|
Self::LinuxSystem => "linux-system",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct SystemAppearanceState {
|
||||||
|
last_appearance: Arc<Mutex<Option<Appearance>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn initialization_script(appearance: Appearance, source: InitialAppearanceSource) -> String {
|
||||||
|
let appearance = appearance.as_str();
|
||||||
|
let source = source.as_str();
|
||||||
|
format!(
|
||||||
|
"window.{INITIAL_APPEARANCE_GLOBAL} = {appearance:?};\
|
||||||
|
window.{INITIAL_APPEARANCE_SOURCE_GLOBAL} = {source:?};"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub fn system_appearance() -> Option<Appearance> {
|
||||||
|
if let Some(appearance) = gsettings_system_appearance() {
|
||||||
|
return Some(appearance);
|
||||||
|
}
|
||||||
|
|
||||||
|
match dark_light::detect() {
|
||||||
|
Ok(dark_light::Mode::Dark) => Some(Appearance::Dark),
|
||||||
|
Ok(dark_light::Mode::Light) => Some(Appearance::Light),
|
||||||
|
Ok(dark_light::Mode::Unspecified) => None,
|
||||||
|
Err(err) => {
|
||||||
|
debug!("Failed to detect Linux system appearance: {err:?}");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "linux"))]
|
||||||
|
pub fn system_appearance() -> Option<Appearance> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub fn watch<R: Runtime>(app_handle: AppHandle<R>) -> Option<SystemAppearanceState> {
|
||||||
|
let last_appearance = system_appearance();
|
||||||
|
if last_appearance.is_none() {
|
||||||
|
debug!("Linux system appearance detection unavailable");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let state = SystemAppearanceState { last_appearance: Arc::new(Mutex::new(last_appearance)) };
|
||||||
|
let thread_state = state.clone();
|
||||||
|
let _ = std::thread::spawn(move || {
|
||||||
|
loop {
|
||||||
|
std::thread::sleep(SYSTEM_APPEARANCE_POLL_INTERVAL);
|
||||||
|
emit_change(&app_handle, &thread_state);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Some(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(target_os = "linux"))]
|
||||||
|
pub fn watch<R: Runtime>(_app_handle: AppHandle<R>) -> Option<SystemAppearanceState> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub fn emit_change<R: Runtime>(app_handle: &AppHandle<R>, state: &SystemAppearanceState) {
|
||||||
|
let appearance = system_appearance();
|
||||||
|
let mut last_appearance =
|
||||||
|
state.last_appearance.lock().expect("system appearance lock poisoned");
|
||||||
|
if appearance == *last_appearance {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
*last_appearance = appearance;
|
||||||
|
if let Some(appearance) = appearance {
|
||||||
|
let appearance = appearance.as_str();
|
||||||
|
debug!("System appearance changed to {appearance}");
|
||||||
|
if let Err(err) = app_handle.emit(SYSTEM_APPEARANCE_CHANGE_EVENT, appearance) {
|
||||||
|
warn!("Failed to emit system appearance change: {err:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
fn gsettings_system_appearance() -> Option<Appearance> {
|
||||||
|
let color_scheme = std::process::Command::new("gsettings")
|
||||||
|
.args(["get", "org.gnome.desktop.interface", "color-scheme"])
|
||||||
|
.output()
|
||||||
|
.ok()
|
||||||
|
.and_then(|output| String::from_utf8(output.stdout).ok())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
if color_scheme.contains("prefer-dark") {
|
||||||
|
return Some(Appearance::Dark);
|
||||||
|
}
|
||||||
|
if color_scheme.contains("prefer-light") {
|
||||||
|
return Some(Appearance::Light);
|
||||||
|
}
|
||||||
|
|
||||||
|
let gtk_theme = std::process::Command::new("gsettings")
|
||||||
|
.args(["get", "org.gnome.desktop.interface", "gtk-theme"])
|
||||||
|
.output()
|
||||||
|
.ok()
|
||||||
|
.and_then(|output| String::from_utf8(output.stdout).ok())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
if gtk_theme.to_lowercase().contains("dark") {
|
||||||
|
return Some(Appearance::Dark);
|
||||||
|
}
|
||||||
|
|
||||||
|
(!gtk_theme.trim().is_empty()).then_some(Appearance::Light)
|
||||||
|
}
|
||||||
@@ -26,6 +26,7 @@ pub struct CreateWindowConfig<'s> {
|
|||||||
pub navigation_tx: Option<mpsc::Sender<String>>,
|
pub navigation_tx: Option<mpsc::Sender<String>>,
|
||||||
pub close_tx: Option<mpsc::Sender<()>>,
|
pub close_tx: Option<mpsc::Sender<()>>,
|
||||||
pub data_dir_key: Option<String>,
|
pub data_dir_key: Option<String>,
|
||||||
|
pub initialization_script: Option<String>,
|
||||||
pub hidden: bool,
|
pub hidden: bool,
|
||||||
pub hide_titlebar: bool,
|
pub hide_titlebar: bool,
|
||||||
pub use_native_titlebar: bool,
|
pub use_native_titlebar: bool,
|
||||||
@@ -59,6 +60,10 @@ pub fn create_window<R: Runtime>(
|
|||||||
.maximized(maximized)
|
.maximized(maximized)
|
||||||
.min_inner_size(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT);
|
.min_inner_size(MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT);
|
||||||
|
|
||||||
|
if let Some(script) = config.initialization_script {
|
||||||
|
win_builder = win_builder.initialization_script(script);
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(key) = config.data_dir_key {
|
if let Some(key) = config.data_dir_key {
|
||||||
#[cfg(not(target_os = "macos"))]
|
#[cfg(not(target_os = "macos"))]
|
||||||
{
|
{
|
||||||
@@ -138,11 +143,12 @@ pub fn create_window<R: Runtime>(
|
|||||||
Ok(win)
|
Ok(win)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_main_window(
|
pub fn create_main_window<R: Runtime>(
|
||||||
handle: &AppHandle,
|
handle: &AppHandle<R>,
|
||||||
url: &str,
|
url: &str,
|
||||||
|
initialization_script: Option<String>,
|
||||||
use_native_titlebar: bool,
|
use_native_titlebar: bool,
|
||||||
) -> tauri::Result<WebviewWindow> {
|
) -> tauri::Result<WebviewWindow<R>> {
|
||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
let label = loop {
|
let label = loop {
|
||||||
let label = format!("{MAIN_WINDOW_PREFIX}{counter}");
|
let label = format!("{MAIN_WINDOW_PREFIX}{counter}");
|
||||||
@@ -165,6 +171,8 @@ pub fn create_main_window(
|
|||||||
100.0 + random::<f64>() * 20.0,
|
100.0 + random::<f64>() * 20.0,
|
||||||
)),
|
)),
|
||||||
restore_position: Some(counter == 0),
|
restore_position: Some(counter == 0),
|
||||||
|
initialization_script,
|
||||||
|
hidden: true,
|
||||||
hide_titlebar: true,
|
hide_titlebar: true,
|
||||||
use_native_titlebar,
|
use_native_titlebar,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@@ -173,14 +181,15 @@ pub fn create_main_window(
|
|||||||
create_window(handle, config)
|
create_window(handle, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_child_window(
|
pub fn create_child_window<R: Runtime>(
|
||||||
parent_window: &WebviewWindow,
|
parent_window: &WebviewWindow<R>,
|
||||||
url: &str,
|
url: &str,
|
||||||
label: &str,
|
label: &str,
|
||||||
title: &str,
|
title: &str,
|
||||||
inner_size: (f64, f64),
|
inner_size: (f64, f64),
|
||||||
|
initialization_script: Option<String>,
|
||||||
use_native_titlebar: bool,
|
use_native_titlebar: bool,
|
||||||
) -> tauri::Result<WebviewWindow> {
|
) -> tauri::Result<WebviewWindow<R>> {
|
||||||
let app_handle = parent_window.app_handle();
|
let app_handle = parent_window.app_handle();
|
||||||
let state_key = label.to_string();
|
let state_key = label.to_string();
|
||||||
let label = format!("{OTHER_WINDOW_PREFIX}_{label}");
|
let label = format!("{OTHER_WINDOW_PREFIX}_{label}");
|
||||||
@@ -202,6 +211,8 @@ pub fn create_child_window(
|
|||||||
url,
|
url,
|
||||||
inner_size: Some(inner_size),
|
inner_size: Some(inner_size),
|
||||||
position: Some(position),
|
position: Some(position),
|
||||||
|
initialization_script,
|
||||||
|
hidden: true,
|
||||||
hide_titlebar: true,
|
hide_titlebar: true,
|
||||||
use_native_titlebar,
|
use_native_titlebar,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|||||||
@@ -29,10 +29,7 @@ pub async fn delete_and_uninstall(
|
|||||||
let db = query_manager.connect();
|
let db = query_manager.connect();
|
||||||
db.delete_plugin_by_id(plugin_id, &update_source)?
|
db.delete_plugin_by_id(plugin_id, &update_source)?
|
||||||
};
|
};
|
||||||
if let Err(err) = plugin_manager
|
if let Err(err) = plugin_manager.uninstall(plugin_context, plugin.directory.as_str()).await {
|
||||||
.uninstall(plugin_context, plugin.directory.as_str())
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
if !matches!(err, PluginNotFoundErr(_)) {
|
if !matches!(err, PluginNotFoundErr(_)) {
|
||||||
return Err(err);
|
return Err(err);
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+126
-59
@@ -80,7 +80,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rolldown/plugin-babel": "^0.2.3",
|
"@rolldown/plugin-babel": "^0.2.3",
|
||||||
"@tailwindcss/postcss": "^4.3.2",
|
"@tailwindcss/postcss": "^4.3.2",
|
||||||
"@tauri-apps/cli": "^2.11.1",
|
"@tauri-apps/cli": "npm:@tauri-apps/cli-cef@3.0.0-alpha.6",
|
||||||
"@types/babel__core": "^7.20.5",
|
"@types/babel__core": "^7.20.5",
|
||||||
"@vitejs/plugin-react": "^6.0.1",
|
"@vitejs/plugin-react": "^6.0.1",
|
||||||
"@yaakapp/cli": "^0.5.1",
|
"@yaakapp/cli": "^0.5.1",
|
||||||
@@ -4143,6 +4143,72 @@
|
|||||||
"node": ">=14.0.0"
|
"node": ">=14.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": {
|
||||||
|
"version": "1.11.1",
|
||||||
|
"dev": true,
|
||||||
|
"inBundle": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@emnapi/wasi-threads": "1.2.2",
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": {
|
||||||
|
"version": "1.11.1",
|
||||||
|
"dev": true,
|
||||||
|
"inBundle": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": {
|
||||||
|
"version": "1.2.2",
|
||||||
|
"dev": true,
|
||||||
|
"inBundle": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"dev": true,
|
||||||
|
"inBundle": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@tybys/wasm-util": "^0.10.1"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/Brooooooklyn"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@emnapi/core": "^1.7.1",
|
||||||
|
"@emnapi/runtime": "^1.7.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": {
|
||||||
|
"version": "0.10.2",
|
||||||
|
"dev": true,
|
||||||
|
"inBundle": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"dev": true,
|
||||||
|
"inBundle": true,
|
||||||
|
"license": "0BSD",
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
"node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
|
"node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
|
||||||
"version": "4.3.2",
|
"version": "4.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.2.tgz",
|
||||||
@@ -4458,9 +4524,10 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tauri-apps/cli": {
|
"node_modules/@tauri-apps/cli": {
|
||||||
"version": "2.11.1",
|
"name": "@tauri-apps/cli-cef",
|
||||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.11.1.tgz",
|
"version": "3.0.0-alpha.6",
|
||||||
"integrity": "sha512-rpEbaJ/HzNb6fwsquwoAbq29/Vt4gADhS423A8fdkwL4edJ0wZmoB8ar7O6JPDL834MUKOCm/rrJ7c9oAaEaYQ==",
|
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-cef/-/cli-cef-3.0.0-alpha.6.tgz",
|
||||||
|
"integrity": "sha512-4Y52FZZuK6rpDDsJgxMp5q85QpQjf7Yo5IvLZs/CUBaIuMkGBDguDRcfkxhMJlu9qM/cLlBRW27OtqNdOW730w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0 OR MIT",
|
"license": "Apache-2.0 OR MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -4474,23 +4541,23 @@
|
|||||||
"url": "https://opencollective.com/tauri"
|
"url": "https://opencollective.com/tauri"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@tauri-apps/cli-darwin-arm64": "2.11.1",
|
"@tauri-apps/cli-cef-darwin-arm64": "3.0.0-alpha.6",
|
||||||
"@tauri-apps/cli-darwin-x64": "2.11.1",
|
"@tauri-apps/cli-cef-darwin-x64": "3.0.0-alpha.6",
|
||||||
"@tauri-apps/cli-linux-arm-gnueabihf": "2.11.1",
|
"@tauri-apps/cli-cef-linux-arm-gnueabihf": "3.0.0-alpha.6",
|
||||||
"@tauri-apps/cli-linux-arm64-gnu": "2.11.1",
|
"@tauri-apps/cli-cef-linux-arm64-gnu": "3.0.0-alpha.6",
|
||||||
"@tauri-apps/cli-linux-arm64-musl": "2.11.1",
|
"@tauri-apps/cli-cef-linux-arm64-musl": "3.0.0-alpha.6",
|
||||||
"@tauri-apps/cli-linux-riscv64-gnu": "2.11.1",
|
"@tauri-apps/cli-cef-linux-riscv64-gnu": "3.0.0-alpha.6",
|
||||||
"@tauri-apps/cli-linux-x64-gnu": "2.11.1",
|
"@tauri-apps/cli-cef-linux-x64-gnu": "3.0.0-alpha.6",
|
||||||
"@tauri-apps/cli-linux-x64-musl": "2.11.1",
|
"@tauri-apps/cli-cef-linux-x64-musl": "3.0.0-alpha.6",
|
||||||
"@tauri-apps/cli-win32-arm64-msvc": "2.11.1",
|
"@tauri-apps/cli-cef-win32-arm64-msvc": "3.0.0-alpha.6",
|
||||||
"@tauri-apps/cli-win32-ia32-msvc": "2.11.1",
|
"@tauri-apps/cli-cef-win32-ia32-msvc": "3.0.0-alpha.6",
|
||||||
"@tauri-apps/cli-win32-x64-msvc": "2.11.1"
|
"@tauri-apps/cli-cef-win32-x64-msvc": "3.0.0-alpha.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tauri-apps/cli-darwin-arm64": {
|
"node_modules/@tauri-apps/cli-cef-darwin-arm64": {
|
||||||
"version": "2.11.1",
|
"version": "3.0.0-alpha.6",
|
||||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-cef-darwin-arm64/-/cli-cef-darwin-arm64-3.0.0-alpha.6.tgz",
|
||||||
"integrity": "sha512-6eEKMBXsQPCuM1EmvrjT2+aBuxWQuFdKdW8pzNuNQtpq45nEEpBlD5gr8pUeAyOU1DQKlkFaEc/MPBxb/Pfjtg==",
|
"integrity": "sha512-j6XHXCku1q82SXSXlQdzT7MbgOBX/ziOD+Z4c+B5D51zsaP3h6kcefpMzs71n9ZUegdw6AXpZpk+c+knOh2trQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -4504,10 +4571,10 @@
|
|||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tauri-apps/cli-darwin-x64": {
|
"node_modules/@tauri-apps/cli-cef-darwin-x64": {
|
||||||
"version": "2.11.1",
|
"version": "3.0.0-alpha.6",
|
||||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-cef-darwin-x64/-/cli-cef-darwin-x64-3.0.0-alpha.6.tgz",
|
||||||
"integrity": "sha512-LQUO7exfRWjWALNhetph5guWpMeHphRpokOLk0OIbTTExaNwJNFu3I4vb+CCM/4G/QGoZe/5XikZOJdNEFP1ig==",
|
"integrity": "sha512-zBNxrXomAXSZPCYspOjvoi8aVAnJtkSOy3cVD+9aYDpf2zZL4R7VQXcY4M76PvqbGUmCOXT9ztzxV2MyWnBoDQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -4521,10 +4588,10 @@
|
|||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tauri-apps/cli-linux-arm-gnueabihf": {
|
"node_modules/@tauri-apps/cli-cef-linux-arm-gnueabihf": {
|
||||||
"version": "2.11.1",
|
"version": "3.0.0-alpha.6",
|
||||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-cef-linux-arm-gnueabihf/-/cli-cef-linux-arm-gnueabihf-3.0.0-alpha.6.tgz",
|
||||||
"integrity": "sha512-5i/awiBCRRhOUG8yjn0fMHXIWD5Ez8eEk5LtvOxyQrKuJkRaZDvnbIjZbE183blAwkoA4xN3aO/prJiqscl02Q==",
|
"integrity": "sha512-EcNXX9xsAZj0BuRXBwliR35XML6B5aIbgH8blbEGAr3pDaSCBnNyS/dpORgSdCKuysLidBT7K8fer5mMtbSoUQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -4538,10 +4605,10 @@
|
|||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tauri-apps/cli-linux-arm64-gnu": {
|
"node_modules/@tauri-apps/cli-cef-linux-arm64-gnu": {
|
||||||
"version": "2.11.1",
|
"version": "3.0.0-alpha.6",
|
||||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-cef-linux-arm64-gnu/-/cli-cef-linux-arm64-gnu-3.0.0-alpha.6.tgz",
|
||||||
"integrity": "sha512-9LrwDw3S9Fygtw/Q6WDhOP+3svJRGAsejeE+GKrc0eO1ThMVhwi2LL6hw4dlKw93IfS7VY1G19sWGxJ/NcU4nA==",
|
"integrity": "sha512-/AwSRWuE5UKGumrXdpRnIBDWVjFAMEMkSFbB/vpFx9PogQ/A0R+i6+zuBh7JPV7FKmyRzVJuNxZ8EmZ319Ir8g==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -4555,10 +4622,10 @@
|
|||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tauri-apps/cli-linux-arm64-musl": {
|
"node_modules/@tauri-apps/cli-cef-linux-arm64-musl": {
|
||||||
"version": "2.11.1",
|
"version": "3.0.0-alpha.6",
|
||||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-cef-linux-arm64-musl/-/cli-cef-linux-arm64-musl-3.0.0-alpha.6.tgz",
|
||||||
"integrity": "sha512-mNA5dbbqPqDUdTIwdUYYuhO2GvIe9UnB2r0VU2njxBOS3Opbx4gKNC5yP0Iu4rYmEmqdlwry9VzGZQ3wq9dyFg==",
|
"integrity": "sha512-OZ5gjROy4/TlaYQ33roxQYcFIFJH+HZMER9gwTkWxfYUC1gTLLhsBeIYUZzWqm1NQiIc07likg081wsHkCRrWw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -4572,10 +4639,10 @@
|
|||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tauri-apps/cli-linux-riscv64-gnu": {
|
"node_modules/@tauri-apps/cli-cef-linux-riscv64-gnu": {
|
||||||
"version": "2.11.1",
|
"version": "3.0.0-alpha.6",
|
||||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-cef-linux-riscv64-gnu/-/cli-cef-linux-riscv64-gnu-3.0.0-alpha.6.tgz",
|
||||||
"integrity": "sha512-fZj3Gwq+6fUs305T5WQiD5iSGJw+j/4w/HGmk4sHDAcy+rp9zU5eaxB7nOyz5/I/nkNAuKPqfp6uIbiUBXkBCw==",
|
"integrity": "sha512-r9TQKmN4KfeXiiusn0cppRxljKsf96vTsC1ehYi4beh+6JlmGR4pK7eb+LuOGJscnjurAA9b153fpeYO/O1PTw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
@@ -4589,10 +4656,10 @@
|
|||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tauri-apps/cli-linux-x64-gnu": {
|
"node_modules/@tauri-apps/cli-cef-linux-x64-gnu": {
|
||||||
"version": "2.11.1",
|
"version": "3.0.0-alpha.6",
|
||||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-cef-linux-x64-gnu/-/cli-cef-linux-x64-gnu-3.0.0-alpha.6.tgz",
|
||||||
"integrity": "sha512-XFxGxOvHM7jjeD6ozCKdGfhzJ7lERYDGZl1/Kb4fsvchaJsfLJ981TlyTG8Qy/gFq+f5GitH3bfrX9JAkjPEyw==",
|
"integrity": "sha512-9rrMBVlqbNlp8nTJuZIDQ7iKFwGaVMRCNPIsUIZ56DiaCLoP4po+yvR48n+TyRPZYp1sb3q2Nr/5/zI2q/jFAQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -4606,10 +4673,10 @@
|
|||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tauri-apps/cli-linux-x64-musl": {
|
"node_modules/@tauri-apps/cli-cef-linux-x64-musl": {
|
||||||
"version": "2.11.1",
|
"version": "3.0.0-alpha.6",
|
||||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-cef-linux-x64-musl/-/cli-cef-linux-x64-musl-3.0.0-alpha.6.tgz",
|
||||||
"integrity": "sha512-d5C2/Zm+68v7R9wTuTCjRQEVrWjcdMkJBZ1+rXse+QdMMlTB9+u9PDNDLw9PQflWxYLaYZ7tjxxL9Nb9II6PbA==",
|
"integrity": "sha512-pcFL71xscjEM/03lrH/GiqIr4SwBWlbvaRh8GxDePJqqrQojNn+kTzVvqowaXVbTrNr5rbHbXzY4rC/5/1Tbsw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -4623,10 +4690,10 @@
|
|||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tauri-apps/cli-win32-arm64-msvc": {
|
"node_modules/@tauri-apps/cli-cef-win32-arm64-msvc": {
|
||||||
"version": "2.11.1",
|
"version": "3.0.0-alpha.6",
|
||||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-cef-win32-arm64-msvc/-/cli-cef-win32-arm64-msvc-3.0.0-alpha.6.tgz",
|
||||||
"integrity": "sha512-YdeVWFAR1pTXzUU6NLstPq4G6OLxuDrXCXEBdmBH+5EZIDXUx0D2kJlz3+YjpazkKvAzYpgziTsyRagls0OfRQ==",
|
"integrity": "sha512-IrMgveBs0HNO7C7BaZCUHGtO9jPbop/iU/5XWNqBx7uYHJL565+yIlpzWPoXhT3qbt8h8FQFO6SU3N+zfvLipA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -4640,10 +4707,10 @@
|
|||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tauri-apps/cli-win32-ia32-msvc": {
|
"node_modules/@tauri-apps/cli-cef-win32-ia32-msvc": {
|
||||||
"version": "2.11.1",
|
"version": "3.0.0-alpha.6",
|
||||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-cef-win32-ia32-msvc/-/cli-cef-win32-ia32-msvc-3.0.0-alpha.6.tgz",
|
||||||
"integrity": "sha512-VBGkuH0eB9K9LLSMv361Gzr5Ou72sCS4+ztpmkWEQ+wd/amhcYOsf3X6qn1RJZDzIhiOYHJEOysZUC3baD01rA==",
|
"integrity": "sha512-qA/VaRdRwdMt9L2oDGNZPur108mUleKRUSCk6X8sVPcnPjzMfN4/aESeOKsW+zHXN/VhZbV3UieEg4IcYeI2RQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ia32"
|
"ia32"
|
||||||
],
|
],
|
||||||
@@ -4657,10 +4724,10 @@
|
|||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@tauri-apps/cli-win32-x64-msvc": {
|
"node_modules/@tauri-apps/cli-cef-win32-x64-msvc": {
|
||||||
"version": "2.11.1",
|
"version": "3.0.0-alpha.6",
|
||||||
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.11.1.tgz",
|
"resolved": "https://registry.npmjs.org/@tauri-apps/cli-cef-win32-x64-msvc/-/cli-cef-win32-x64-msvc-3.0.0-alpha.6.tgz",
|
||||||
"integrity": "sha512-b3ORhIAKgp9ZYY+zBt7b7r0kLU2kjvyGF0+MS2SBym3emsweGPybEqocJcmtMuxyBhkOKHP4CiuEJEDuAlTx6A==",
|
"integrity": "sha512-EzlhstDVyvHy3M5ieSoH3VBlikgqQS99vFEDKFoy16mwIWUrTG1LkoSI0mKbqmO8DWIEzeSV17XiCw2XEcYslQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
|
|||||||
+1
-1
@@ -113,7 +113,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rolldown/plugin-babel": "^0.2.3",
|
"@rolldown/plugin-babel": "^0.2.3",
|
||||||
"@tailwindcss/postcss": "^4.3.2",
|
"@tailwindcss/postcss": "^4.3.2",
|
||||||
"@tauri-apps/cli": "^2.11.1",
|
"@tauri-apps/cli": "npm:@tauri-apps/cli-cef@3.0.0-alpha.6",
|
||||||
"@types/babel__core": "^7.20.5",
|
"@types/babel__core": "^7.20.5",
|
||||||
"@vitejs/plugin-react": "^6.0.1",
|
"@vitejs/plugin-react": "^6.0.1",
|
||||||
"@yaakapp/cli": "^0.5.1",
|
"@yaakapp/cli": "^0.5.1",
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
import { listen } from "@tauri-apps/api/event";
|
||||||
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow";
|
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow";
|
||||||
|
|
||||||
export type Appearance = "light" | "dark";
|
export type Appearance = "light" | "dark";
|
||||||
|
|
||||||
|
const SYSTEM_APPEARANCE_CHANGE_EVENT = "system_appearance_change";
|
||||||
|
|
||||||
export function getCSSAppearance(): Appearance {
|
export function getCSSAppearance(): Appearance {
|
||||||
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
||||||
}
|
}
|
||||||
@@ -11,6 +14,13 @@ export async function getWindowAppearance(): Promise<Appearance> {
|
|||||||
return appearance ?? getCSSAppearance();
|
return appearance ?? getCSSAppearance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function subscribeToCSSAppearanceChange(cb: (appearance: Appearance) => void): () => void {
|
||||||
|
const media = window.matchMedia("(prefers-color-scheme: dark)");
|
||||||
|
const listener = () => cb(media.matches ? "dark" : "light");
|
||||||
|
media.addEventListener("change", listener);
|
||||||
|
return () => media.removeEventListener("change", listener);
|
||||||
|
}
|
||||||
|
|
||||||
export function subscribeToWindowAppearanceChange(
|
export function subscribeToWindowAppearanceChange(
|
||||||
cb: (appearance: Appearance) => void,
|
cb: (appearance: Appearance) => void,
|
||||||
): () => void {
|
): () => void {
|
||||||
@@ -29,6 +39,22 @@ export function subscribeToWindowAppearanceChange(
|
|||||||
return () => container.unsubscribe();
|
return () => container.unsubscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function subscribeToSystemAppearanceChange(
|
||||||
|
cb: (appearance: Appearance) => void,
|
||||||
|
): () => void {
|
||||||
|
const container = {
|
||||||
|
unsubscribe: () => {},
|
||||||
|
};
|
||||||
|
|
||||||
|
void listen<Appearance>(SYSTEM_APPEARANCE_CHANGE_EVENT, (event) => {
|
||||||
|
cb(event.payload);
|
||||||
|
}).then((listener) => {
|
||||||
|
container.unsubscribe = listener;
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => container.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
export function resolveAppearance(
|
export function resolveAppearance(
|
||||||
preferredAppearance: Appearance,
|
preferredAppearance: Appearance,
|
||||||
appearanceSetting: string,
|
appearanceSetting: string,
|
||||||
@@ -40,5 +66,16 @@ export function resolveAppearance(
|
|||||||
export function subscribeToPreferredAppearance(cb: (appearance: Appearance) => void) {
|
export function subscribeToPreferredAppearance(cb: (appearance: Appearance) => void) {
|
||||||
cb(getCSSAppearance());
|
cb(getCSSAppearance());
|
||||||
void getWindowAppearance().then(cb);
|
void getWindowAppearance().then(cb);
|
||||||
subscribeToWindowAppearanceChange(cb);
|
return subscribeToPreferredAppearanceChange(cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function subscribeToPreferredAppearanceChange(cb: (appearance: Appearance) => void) {
|
||||||
|
const unsubscribeCSS = subscribeToCSSAppearanceChange(cb);
|
||||||
|
const unsubscribeWindow = subscribeToWindowAppearanceChange(cb);
|
||||||
|
const unsubscribeSystem = subscribeToSystemAppearanceChange(cb);
|
||||||
|
return () => {
|
||||||
|
unsubscribeCSS();
|
||||||
|
unsubscribeWindow();
|
||||||
|
unsubscribeSystem();
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
export type { Appearance } from "./appearance";
|
export type { Appearance } from "./appearance";
|
||||||
export {
|
export {
|
||||||
|
subscribeToCSSAppearanceChange,
|
||||||
getCSSAppearance,
|
getCSSAppearance,
|
||||||
getWindowAppearance,
|
getWindowAppearance,
|
||||||
resolveAppearance,
|
resolveAppearance,
|
||||||
subscribeToPreferredAppearance,
|
subscribeToPreferredAppearance,
|
||||||
|
subscribeToPreferredAppearanceChange,
|
||||||
|
subscribeToSystemAppearanceChange,
|
||||||
subscribeToWindowAppearanceChange,
|
subscribeToWindowAppearanceChange,
|
||||||
} from "./appearance";
|
} from "./appearance";
|
||||||
export { defaultDarkTheme, defaultLightTheme } from "./defaultThemes";
|
export { defaultDarkTheme, defaultLightTheme } from "./defaultThemes";
|
||||||
|
|||||||
+2
-1
@@ -70,7 +70,8 @@ const normalizedAdditionalArgs = [];
|
|||||||
for (let i = 0; i < additionalArgs.length; i++) {
|
for (let i = 0; i < additionalArgs.length; i++) {
|
||||||
const arg = additionalArgs[i];
|
const arg = additionalArgs[i];
|
||||||
if (arg === "--") {
|
if (arg === "--") {
|
||||||
continue;
|
normalizedAdditionalArgs.push(arg, ...additionalArgs.slice(i + 1));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (arg === "--config" && i + 1 < additionalArgs.length) {
|
if (arg === "--config" && i + 1 < additionalArgs.length) {
|
||||||
const value = additionalArgs[i + 1];
|
const value = additionalArgs[i + 1];
|
||||||
|
|||||||
Reference in New Issue
Block a user