From f066593285d6f9307831943e74b2b440c84e64c2 Mon Sep 17 00:00:00 2001 From: Kamiya <58339640+kamiya10@users.noreply.github.com> Date: Wed, 14 Feb 2024 00:59:36 +0800 Subject: [PATCH 1/3] feat: startup with system --- CHANGELOG.md | 3 + package-lock.json | 9 ++ package.json | 1 + src-tauri/Cargo.lock | 122 +++++++++++++++++++++++++++- src-tauri/Cargo.toml | 23 +++--- src-tauri/src/main.rs | 29 +++++-- src-tauri/tauri.conf.json | 11 +++ src/assets/json/default_config.json | 19 +++-- src/main.ts | 43 ++++++++-- src/types.ts | 19 +++-- 10 files changed, 238 insertions(+), 41 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8e62c3..b871e23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ### ✨ 新功能 +* 新增開機時自動啟動的設定 (https://github.com/ExpTechTW/TREM-tauri/pull/30) +* 新增啟動參數 `--quiet` (https://github.com/ExpTechTW/TREM-tauri/pull/30) + **完整變更紀錄**: https://github.com/ExpTechTW/TREM-tauri/compare/v0.0.0-alpha.2...v0.0.0-alpha.3 diff --git a/package-lock.json b/package-lock.json index 4cf9b30..ef0898e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "jszip": "^3.10.1", "maplibre-gl": "^4.0.0", "material-symbols": "^0.14.6", + "tauri-plugin-autostart-api": "github:tauri-apps/tauri-plugin-autostart#v1", "tauri-settings": "^0.3.4", "vue": "^3.3.4", "ws": "^8.16.0" @@ -4016,6 +4017,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tauri-plugin-autostart-api": { + "version": "0.0.0", + "resolved": "git+ssh://git@github.com/tauri-apps/tauri-plugin-autostart.git#a534e61e246e6d96ab938fcd3e644dcb74d5c0bf", + "license": "MIT or APACHE-2.0", + "dependencies": { + "@tauri-apps/api": "1.5.3" + } + }, "node_modules/tauri-settings": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/tauri-settings/-/tauri-settings-0.3.4.tgz", diff --git a/package.json b/package.json index d25ee19..1e7ead2 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "jszip": "^3.10.1", "maplibre-gl": "^4.0.0", "material-symbols": "^0.14.6", + "tauri-plugin-autostart-api": "github:tauri-apps/tauri-plugin-autostart#v1", "tauri-settings": "^0.3.4", "vue": "^3.3.4", "ws": "^8.16.0" diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index ae5b4da..b92769e 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -105,6 +105,28 @@ dependencies = [ "system-deps 6.2.0", ] +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "auto-launch" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f012b8cc0c850f34117ec8252a44418f2e34a2cf501de89e29b241ae5f79471" +dependencies = [ + "dirs", + "thiserror", + "winreg 0.10.1", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -321,6 +343,30 @@ dependencies = [ "windows-targets 0.52.0", ] +[[package]] +name = "clap" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +dependencies = [ + "atty", + "bitflags 1.3.2", + "clap_lex", + "indexmap 1.9.3", + "strsim", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "clipboard-win" version = "5.1.0" @@ -602,6 +648,15 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + [[package]] name = "dirs-next" version = "2.0.0" @@ -612,6 +667,17 @@ dependencies = [ "dirs-sys-next", ] +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "dirs-sys-next" version = "0.1.2" @@ -1249,6 +1315,15 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + [[package]] name = "hermit-abi" version = "0.3.4" @@ -1850,7 +1925,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.4", "libc", ] @@ -1983,6 +2058,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "os_str_bytes" +version = "6.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + [[package]] name = "overload" version = "0.1.1" @@ -3059,6 +3140,7 @@ checksum = "fd27c04b9543776a972c86ccf70660b517ecabbeced9fb58d8b961a13ad129af" dependencies = [ "anyhow", "bytes", + "clap", "cocoa", "dirs-next", "embed_plist", @@ -3159,6 +3241,19 @@ dependencies = [ "tauri-utils", ] +[[package]] +name = "tauri-plugin-autostart" +version = "0.0.0" +source = "git+https://github.com/tauri-apps/plugins-workspace?branch=v1#67405aed06f495c3ea42e0a62b789e2be48abb3a" +dependencies = [ + "auto-launch", + "log", + "serde", + "serde_json", + "tauri", + "thiserror", +] + [[package]] name = "tauri-runtime" version = "0.14.2" @@ -3265,6 +3360,21 @@ dependencies = [ "utf-8", ] +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" + [[package]] name = "thin-slice" version = "0.1.1" @@ -3550,6 +3660,7 @@ dependencies = [ "serde_json", "tauri", "tauri-build", + "tauri-plugin-autostart", ] [[package]] @@ -4211,6 +4322,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + [[package]] name = "winreg" version = "0.50.0" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 33e7f41..d07b9e9 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -13,25 +13,28 @@ edition = "2021" tauri-build = { version = "1.5", features = [] } [dependencies] -tauri = { version = "1.5", features = [ +tauri = { version = "1.5", features = [ "cli", "clipboard-write-text", "http-request", - "window-set-always-on-top", - "window-request-user-attention", - "window-set-focus", - "window-set-skip-taskbar", - "window-show", - "window-set-title", - "system-tray", - "fs-write-file", - "fs-read-file", "fs-create-dir", "fs-read-dir", + "fs-read-file", + "fs-write-file", "path-all", "shell-open", + "system-tray", + "window-close", + "window-hide", + "window-request-user-attention", + "window-set-always-on-top", + "window-set-focus", + "window-set-skip-taskbar", + "window-set-title", + "window-show", ] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +tauri-plugin-autostart = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" } [features] # this feature is used for production builds or when `devPath` points to the filesystem diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 8f28dec..237a2f1 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -4,6 +4,7 @@ use tauri::{ CustomMenuItem, Manager, SystemTray, SystemTrayEvent, SystemTrayMenu, SystemTrayMenuItem, }; +use tauri_plugin_autostart::MacosLauncher; fn main() { let tray_menu = SystemTrayMenu::new() @@ -17,9 +18,28 @@ fn main() { .add_native_item(SystemTrayMenuItem::Separator) .add_item(CustomMenuItem::new("quit".to_string(), "關閉")); - let system_tray = SystemTray::new().with_menu(tray_menu).with_tooltip("TREM Tauri | 臺灣即時地震監測"); + let system_tray = SystemTray::new() + .with_menu(tray_menu) + .with_tooltip("TREM Tauri | 臺灣即時地震監測"); tauri::Builder::default() + .setup(|app| { + match app.get_cli_matches() { + Ok(matches) => match matches.args["quiet"].value.as_bool() { + Some(true) => {} + _ => { + let window = app.get_window("main").unwrap(); + window.show().unwrap(); + } + }, + Err(_) => {} + } + Ok(()) + }) + .plugin(tauri_plugin_autostart::init( + MacosLauncher::LaunchAgent, + Some(vec!["--quiet"]), + )) .system_tray(system_tray) .on_system_tray_event(|app, event| match event { SystemTrayEvent::LeftClick { @@ -38,13 +58,6 @@ fn main() { }, _ => {} }) - .on_window_event(|event| match event.event() { - tauri::WindowEvent::CloseRequested { api, .. } => { - event.window().hide().unwrap(); - api.prevent_close(); - } - _ => {} - }) .run(tauri::generate_context!()) .expect("error while running tauri application"); } diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index f16683f..757a590 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -35,6 +35,8 @@ }, "window": { "all": false, + "close": true, + "hide": true, "requestUserAttention": true, "setAlwaysOnTop": true, "setFocus": true, @@ -64,6 +66,14 @@ } } }, + "cli":{ + "args": [ + { + "name": "quiet", + "short": "q" + } + ] + }, "security": { "csp": null }, @@ -71,6 +81,7 @@ { "fullscreen": false, "resizable": true, + "visible": false, "title": "TREM Tauri | 臺灣即時地震監測", "width": 1200, "height": 720 diff --git a/src/assets/json/default_config.json b/src/assets/json/default_config.json index 8c0e017..aa87518 100644 --- a/src/assets/json/default_config.json +++ b/src/assets/json/default_config.json @@ -5,6 +5,14 @@ "cacheExpire": 60, "replayMode": 1 }, + "audio": { + "enabled": true, + "theme": "trem_default", + "alwaysPlayWhenCancel": false, + "alwaysPlayWhenIntensity": true, + "alwaysPlayWhenPga": true, + "alwaysPlayWhenUpdate": true + }, "behavior": { "focusWindowWhenEew": true, "flashWindowWhenEew": true, @@ -17,12 +25,9 @@ "area": "", "station": "" }, - "audio": { - "enabled": true, - "theme": "trem_default", - "alwaysPlayWhenCancel": false, - "alwaysPlayWhenIntensity": true, - "alwaysPlayWhenPga": true, - "alwaysPlayWhenUpdate": true + "system": { + "startWithSystem": false, + "quiet": false, + "closeToTray": true } } \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 9427918..051bdea 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,9 +1,14 @@ import App from "./App.vue"; +import { + enable as enableAutoStart, + disable as disableAutoStart, +} from "tauri-plugin-autostart-api"; import { createApp, reactive, ref } from "vue"; import { SettingsManager } from "tauri-settings"; import { fs, window as win } from "@tauri-apps/api"; import { UserAttentionType } from "@tauri-apps/api/window"; +import { getMatches } from "@tauri-apps/api/cli"; import JSZip from "jszip"; import type { Station, PartialReport, Rts, Eew } from "./scripts/class/api"; @@ -23,13 +28,13 @@ import { WebSocketEvent, } from "./scripts/class/api"; import { AudioType } from "./types"; +import { RefreshableTimeout } from "./scripts/class/timeout"; import { getAudio } from "./scripts/helper/audio"; import DefaultConfig from "./assets/json/default_config.json"; import code from "./assets/json/code.json"; import "maplibre-gl/dist/maplibre-gl.css"; import "./styles.css"; -import { RefreshableTimeout } from "./scripts/class/timeout"; const browserWindow = win.getCurrent(); @@ -45,11 +50,9 @@ const timer: Record = {}; const eewTimer: Record = {}; const setting = new SettingsManager( - DefaultConfig as DefaultConfigSchema, - { - prettify: true, - } -); + DefaultConfig as DefaultConfigSchema, { + prettify: true, +}); const api = new ExpTechApi(); const ntp = { remote: Date.now(), server: Date.now(), client: Date.now() }; @@ -61,7 +64,18 @@ app.provide("api", api); const instance = app.mount("#app") as InstanceType; +getMatches().then((matches) => { + console.log(matches); + console.log("quiet", matches.args.quiet.value); + + if (!matches.args.quiet.value) { + browserWindow.setFocus(); + } +}); + (async () => { + + await setting.initialize(); await setting.syncCache(); @@ -71,6 +85,12 @@ const instance = app.mount("#app") as InstanceType; props.stations.value = await api.getStations(); await browserWindow.setAlwaysOnTop(setting.settings.behavior.alwaysOnTop); + + if (setting.settings.system.startWithSystem) { + await enableAutoStart(); + } else { + disableAutoStart(); + } })(); let replayMode: boolean = false; @@ -343,14 +363,14 @@ browserWindow.onFileDropEvent(async (e) => { `[Replay] Loading replay ${e.payload.paths[0].split(/(\\|\/)/g).pop()}` ); - const replayData: { rts: Rts; eew: Eew[]; time: number }[] = []; + const replayData: { rts: Rts; eew: Eew[]; time: number; }[] = []; const binary = await fs.readBinaryFile(e.payload.paths[0]); const zip = await JSZip.loadAsync(binary); for (let i = 0, k = Object.keys(zip.files), n = k.length; i < n; i++) { const filename = k[i]; const content = await zip.files[filename].async("string"); - const data: { rts: Rts; eew: Eew[]; time: number } = JSON.parse(content); + const data: { rts: Rts; eew: Eew[]; time: number; } = JSON.parse(content); data.rts.replay = true; data.eew.forEach((e) => (e.replay = true)); data.time = +filename; @@ -403,3 +423,10 @@ browserWindow.onFileDropEvent(async (e) => { replayMode = false; } }); + +browserWindow.onCloseRequested((event) => { + if (setting.settings.system.closeToTray) { + event.preventDefault(); + browserWindow.hide(); + } +}); diff --git a/src/types.ts b/src/types.ts index 6a47c70..686a945 100644 --- a/src/types.ts +++ b/src/types.ts @@ -13,6 +13,14 @@ export interface DefaultConfigSchema { cacheExpire: number; replayMode: number; }; + audio: { + enabled: boolean; + theme: string; + alwaysPlayWhenCancel: boolean; + alwaysPlayWhenIntensity: boolean; + alwaysPlayWhenPga: boolean; + alwaysPlayWhenUpdate: boolean; + }; behavior: { focusWindowWhenEew: boolean; flashWindowWhenEew: boolean; @@ -25,13 +33,10 @@ export interface DefaultConfigSchema { area: keyof typeof code; station: string; }; - audio: { - enabled: boolean; - theme: string; - alwaysPlayWhenCancel: boolean; - alwaysPlayWhenIntensity: boolean; - alwaysPlayWhenPga: boolean; - alwaysPlayWhenUpdate: boolean; + system: { + startWithSystem: boolean; + quiet: boolean; + closeToTray: boolean; }; } From f30acbec9b3e8a4e03d787df1ce42675dc90b79b Mon Sep 17 00:00:00 2001 From: Kamiya <58339640+kamiya10@users.noreply.github.com> Date: Wed, 14 Feb 2024 01:04:14 +0800 Subject: [PATCH 2/3] chore: changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b871e23..0c6984a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,8 @@ ### ✨ 新功能 * 新增開機時自動啟動的設定 (https://github.com/ExpTechTW/TREM-tauri/pull/30) -* 新增啟動參數 `--quiet` (https://github.com/ExpTechTW/TREM-tauri/pull/30) +* 新增最小化至系統匣的設定 (https://github.com/ExpTechTW/TREM-tauri/pull/30) +* 新增啟動參數 `--quiet` 在開啟程式時隱藏視窗 (https://github.com/ExpTechTW/TREM-tauri/pull/30) **完整變更紀錄**: https://github.com/ExpTechTW/TREM-tauri/compare/v0.0.0-alpha.2...v0.0.0-alpha.3 From aa12f79be9cf05a6ceeaefea7e149f09df657e30 Mon Sep 17 00:00:00 2001 From: Kamiya <58339640+kamiya10@users.noreply.github.com> Date: Wed, 14 Feb 2024 01:07:23 +0800 Subject: [PATCH 3/3] chore: remove test code --- src/main.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/main.ts b/src/main.ts index 051bdea..1d2d5c5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,7 +8,6 @@ import { createApp, reactive, ref } from "vue"; import { SettingsManager } from "tauri-settings"; import { fs, window as win } from "@tauri-apps/api"; import { UserAttentionType } from "@tauri-apps/api/window"; -import { getMatches } from "@tauri-apps/api/cli"; import JSZip from "jszip"; import type { Station, PartialReport, Rts, Eew } from "./scripts/class/api"; @@ -64,18 +63,7 @@ app.provide("api", api); const instance = app.mount("#app") as InstanceType; -getMatches().then((matches) => { - console.log(matches); - console.log("quiet", matches.args.quiet.value); - - if (!matches.args.quiet.value) { - browserWindow.setFocus(); - } -}); - (async () => { - - await setting.initialize(); await setting.syncCache();