From 626a9c21b0a4bda7a4c6991848fd04849daec271 Mon Sep 17 00:00:00 2001 From: Julian Freeman Date: Mon, 30 Mar 2026 17:45:09 -0400 Subject: [PATCH] fetch essentials from url --- src-tauri/Cargo.lock | 525 ++++++++++++++++++++++++++++++++++++- src-tauri/Cargo.toml | 1 + src-tauri/src/lib.rs | 129 ++++++--- src/components/Sidebar.vue | 50 ++-- src/router/index.ts | 4 + src/store/software.ts | 28 +- src/views/Settings.vue | 298 +++++++++++++++++++++ 7 files changed, 980 insertions(+), 55 deletions(-) create mode 100644 src/views/Settings.vue diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 0d11494..1f4cf71 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -444,6 +444,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chrono" version = "0.4.44" @@ -493,6 +499,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation" version = "0.10.1" @@ -516,9 +532,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "064badf302c3194842cf2c5d61f56cc88e54a759313879cdf03abdd27d0c3b97" dependencies = [ "bitflags 2.11.0", - "core-foundation", + "core-foundation 0.10.1", "core-graphics-types", - "foreign-types", + "foreign-types 0.5.0", "libc", ] @@ -529,7 +545,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ "bitflags 2.11.0", - "core-foundation", + "core-foundation 0.10.1", "libc", ] @@ -852,6 +868,15 @@ version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + [[package]] name = "endi" version = "1.1.1" @@ -986,6 +1011,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared 0.1.1", +] + [[package]] name = "foreign-types" version = "0.5.0" @@ -993,7 +1027,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" dependencies = [ "foreign-types-macros", - "foreign-types-shared", + "foreign-types-shared 0.3.1", ] [[package]] @@ -1007,6 +1041,12 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "foreign-types-shared" version = "0.3.1" @@ -1252,8 +1292,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi 0.11.1+wasi-snapshot-preview1", + "wasm-bindgen", ] [[package]] @@ -1263,9 +1305,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 5.3.0", "wasip2", + "wasm-bindgen", ] [[package]] @@ -1429,6 +1473,25 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "h2" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap 2.13.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1545,6 +1608,7 @@ dependencies = [ "bytes", "futures-channel", "futures-core", + "h2", "http", "http-body", "httparse", @@ -1556,6 +1620,39 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + [[package]] name = "hyper-util" version = "0.1.20" @@ -1574,9 +1671,11 @@ dependencies = [ "percent-encoding", "pin-project-lite", "socket2", + "system-configuration", "tokio", "tower-service", "tracing", + "windows-registry", ] [[package]] @@ -1982,6 +2081,12 @@ version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "mac" version = "0.1.1" @@ -2093,6 +2198,23 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "native-tls" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "465500e14ea162429d264d44189adc38b199b62b1c21eea9f69e4b73cb03bbf2" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "ndk" version = "0.9.0" @@ -2313,6 +2435,50 @@ dependencies = [ "pathdiff", ] +[[package]] +name = "openssl" +version = "0.10.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "951c002c75e16ea2c65b8c7e4d3d51d5530d8dfa7d060b4776828c88cfb18ecf" +dependencies = [ + "bitflags 2.11.0", + "cfg-if", + "foreign-types 0.3.2", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + +[[package]] +name = "openssl-sys" +version = "0.9.112" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d55af3b3e226502be1526dfdba67ab0e9c96fc293004e79576b2b9edb0dbdb" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -2768,6 +2934,61 @@ dependencies = [ "memchr", ] +[[package]] +name = "quinn" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror 2.0.18", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +dependencies = [ + "bytes", + "getrandom 0.3.4", + "lru-slab", + "rand 0.9.2", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.18", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.60.2", +] + [[package]] name = "quote" version = "1.0.45" @@ -2814,6 +3035,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.5", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -2834,6 +3065,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + [[package]] name = "rand_core" version = "0.5.1" @@ -2852,6 +3093,15 @@ dependencies = [ "getrandom 0.2.17", ] +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +dependencies = [ + "getrandom 0.3.4", +] + [[package]] name = "rand_hc" version = "0.2.0" @@ -2945,6 +3195,50 @@ version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-core", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "js-sys", + "log", + "mime", + "native-tls", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-native-tls", + "tokio-rustls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", +] + [[package]] name = "reqwest" version = "0.13.2" @@ -2979,6 +3273,20 @@ dependencies = [ "web-sys", ] +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.17", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] name = "rustc-hash" version = "2.1.1" @@ -3007,12 +3315,53 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "rustls" +version = "0.23.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" +dependencies = [ + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + [[package]] name = "same-file" version = "1.0.6" @@ -3022,6 +3371,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91c1b7e4904c873ef0710c1f407dde2e6287de2bebc1bbbf7d430bb7cbffd939" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "schemars" version = "0.8.22" @@ -3079,6 +3437,29 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "security-framework" +version = "3.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" +dependencies = [ + "bitflags 2.11.0", + "core-foundation 0.10.1", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "selectors" version = "0.24.0" @@ -3221,6 +3602,18 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "serde_with" version = "3.18.0" @@ -3469,6 +3862,12 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "swift-rs" version = "1.0.7" @@ -3522,6 +3921,27 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "system-configuration" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +dependencies = [ + "bitflags 2.11.0", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "system-deps" version = "6.2.2" @@ -3543,7 +3963,7 @@ checksum = "6e06d52c379e63da659a483a958110bbde891695a0ecb53e48cc7786d5eda7bb" dependencies = [ "bitflags 2.11.0", "block2", - "core-foundation", + "core-foundation 0.10.1", "core-graphics", "crossbeam-channel", "dispatch2", @@ -3620,7 +4040,7 @@ dependencies = [ "percent-encoding", "plist", "raw-window-handle", - "reqwest", + "reqwest 0.13.2", "serde", "serde_json", "serde_repr", @@ -3948,6 +4368,21 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tinyvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.50.0" @@ -3976,6 +4411,26 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.18" @@ -4280,6 +4735,12 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.8" @@ -4329,6 +4790,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version-compare" version = "0.2.1" @@ -4526,6 +4993,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "web_atoms" version = "0.2.3" @@ -4582,6 +5059,15 @@ dependencies = [ "system-deps", ] +[[package]] +name = "webpki-roots" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webview2-com" version = "0.38.2" @@ -4624,6 +5110,7 @@ version = "0.1.0" dependencies = [ "chrono", "regex", + "reqwest 0.12.28", "serde", "serde_json", "tauri", @@ -4781,6 +5268,17 @@ dependencies = [ "windows-link 0.1.3", ] +[[package]] +name = "windows-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + [[package]] name = "windows-result" version = "0.3.4" @@ -4826,6 +5324,15 @@ dependencies = [ "windows-targets 0.42.2", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.59.0" @@ -5369,6 +5876,12 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + [[package]] name = "zerotrie" version = "0.2.3" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index d02a938..3f1675b 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -25,4 +25,5 @@ serde_json = "1" tokio = { version = "1.50.0", features = ["full"] } chrono = "0.4.44" regex = "1.12.3" +reqwest = { version = "0.12", features = ["json", "rustls-tls"] } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index c37b300..bbcd7fc 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -4,12 +4,26 @@ use std::fs; use std::process::{Command, Stdio}; use std::os::windows::process::CommandExt; use std::io::{BufRead, BufReader}; +use std::path::PathBuf; use tokio::sync::mpsc; use tauri::{AppHandle, Manager, State, Emitter}; -use serde::Serialize; +use serde::{Serialize, Deserialize}; use winget::{Software, list_all_software, list_updates, ensure_winget_dependencies}; use regex::Regex; +#[derive(Clone, Serialize, Deserialize)] +pub struct AppSettings { + pub repo_url: String, +} + +impl Default for AppSettings { + fn default() -> Self { + Self { + repo_url: "https://karlblue.github.io/winget-repo".to_string(), + } + } +} + struct AppState { install_tx: mpsc::Sender, } @@ -34,46 +48,94 @@ pub fn emit_log(handle: &AppHandle, id: &str, command: &str, output: &str, statu }); } +fn get_settings_path(app: &AppHandle) -> PathBuf { + let app_data_dir = app.path().app_data_dir().unwrap_or_default(); + if !app_data_dir.exists() { + let _ = fs::create_dir_all(&app_data_dir); + } + app_data_dir.join("settings.json") +} + +fn get_essentials_path(app: &AppHandle) -> PathBuf { + let app_data_dir = app.path().app_data_dir().unwrap_or_default(); + if !app_data_dir.exists() { + let _ = fs::create_dir_all(&app_data_dir); + } + app_data_dir.join("setup-essentials.json") +} + +#[tauri::command] +fn get_settings(app: AppHandle) -> AppSettings { + let path = get_settings_path(&app); + if !path.exists() { + let default_settings = AppSettings::default(); + let _ = fs::write(&path, serde_json::to_string_pretty(&default_settings).unwrap()); + return default_settings; + } + let content = fs::read_to_string(path).unwrap_or_default(); + serde_json::from_str(&content).unwrap_or_default() +} + +#[tauri::command] +fn save_settings(app: AppHandle, settings: AppSettings) -> Result<(), String> { + let path = get_settings_path(&app); + let content = serde_json::to_string_pretty(&settings).map_err(|e| e.to_string())?; + fs::write(path, content).map_err(|e| e.to_string()) +} + +#[tauri::command] +async fn sync_essentials(app: AppHandle) -> Result { + let settings = get_settings(app.clone()); + let url = format!("{}/setup-essentials.json", settings.repo_url.trim_end_matches('/')); + + emit_log(&app, "sync-essentials", "Syncing Essentials", &format!("Downloading from {}...", url), "info"); + + let client = reqwest::Client::builder() + .timeout(std::time::Duration::from_secs(10)) + .build() + .map_err(|e| e.to_string())?; + + match client.get(&url).send().await { + Ok(response) => { + if response.status().is_success() { + let content = response.text().await.map_err(|e| e.to_string())?; + // 验证 JSON 格式 + let validation: Result, _> = serde_json::from_str(&content); + if validation.is_ok() { + let path = get_essentials_path(&app); + fs::write(path, content).map_err(|e| e.to_string())?; + emit_log(&app, "sync-essentials", "Result", "Essentials list updated successfully.", "success"); + Ok(true) + } else { + emit_log(&app, "sync-essentials", "Error", "Invalid JSON format from repository.", "error"); + Err("Invalid JSON format".to_string()) + } + } else { + let err_msg = format!("HTTP Error: {}", response.status()); + emit_log(&app, "sync-essentials", "Error", &err_msg, "error"); + Err(err_msg) + } + } + Err(e) => { + emit_log(&app, "sync-essentials", "Skipped", &format!("Network issue: {}. Using local cache.", e), "info"); + Ok(false) // 静默失败,返回 false 表示未更新但可继续 + } + } +} + #[tauri::command] async fn initialize_app(app: AppHandle) -> Result { + let app_clone = app.clone(); tokio::task::spawn_blocking(move || { - ensure_winget_dependencies(&app).map(|_| true) + ensure_winget_dependencies(&app_clone).map(|_| true) }).await.unwrap_or(Err("Initialization Task Panicked".to_string())) } #[tauri::command] fn get_essentials(app: AppHandle) -> Vec { - let app_data_dir = app.path().app_data_dir().unwrap_or_default(); - if !app_data_dir.exists() { - let _ = fs::create_dir_all(&app_data_dir); - } - - let file_path = app_data_dir.join("setup-essentials.json"); + let file_path = get_essentials_path(&app); if !file_path.exists() { - let default_essentials = vec![ - Software { - id: "Microsoft.PowerToys".to_string(), - name: "PowerToys".to_string(), - description: Some("Microsoft PowerToys 是一组实用程序,供高级用户调整和简化其 Windows 10 和 11 体验。".to_string()), - version: None, - available_version: None, - icon_url: Some("https://raw.githubusercontent.com/microsoft/PowerToys/master/doc/images/logo.png".to_string()), - status: "idle".to_string(), - progress: 0.0, - }, - Software { - id: "Google.Chrome".to_string(), - name: "Google Chrome".to_string(), - description: Some("Google Chrome 是一款快速、安全且免费的浏览器。".to_string()), - version: None, - available_version: None, - icon_url: Some("https://www.google.com/chrome/static/images/chrome-logo.svg".to_string()), - status: "idle".to_string(), - progress: 0.0, - } - ]; - let _ = fs::write(&file_path, serde_json::to_string_pretty(&default_essentials).unwrap()); - return default_essentials; + return vec![]; } let content = fs::read_to_string(file_path).unwrap_or_else(|_| "[]".to_string()); @@ -210,6 +272,9 @@ pub fn run() { }) .invoke_handler(tauri::generate_handler![ initialize_app, + get_settings, + save_settings, + sync_essentials, get_essentials, get_all_software, get_updates, diff --git a/src/components/Sidebar.vue b/src/components/Sidebar.vue index 4943bc2..54a4440 100644 --- a/src/components/Sidebar.vue +++ b/src/components/Sidebar.vue @@ -34,19 +34,30 @@ 全部软件 - - - - - - - - - - - - 运行日志 - + + @@ -106,8 +117,15 @@ justify-content: center; } -.nav-logs { - margin-top: auto; /* 将日志推到底部 */ - margin-bottom: 20px; +.sidebar-footer { + margin-top: auto; + padding-bottom: 20px; + display: flex; + flex-direction: column; + gap: 8px; +} + +.nav-logs, .nav-settings { + margin-top: 0; } diff --git a/src/router/index.ts b/src/router/index.ts index 102c119..90650cf 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -22,6 +22,10 @@ const router = createRouter({ { path: '/logs', component: () => import('../views/Logs.vue') + }, + { + path: '/settings', + component: () => import('../views/Settings.vue') } ] }) diff --git a/src/store/software.ts b/src/store/software.ts index 4f121b5..d0b34a9 100644 --- a/src/store/software.ts +++ b/src/store/software.ts @@ -20,12 +20,16 @@ export const useSoftwareStore = defineStore('software', { selectedEssentialIds: [] as string[], selectedUpdateIds: [] as string[], logs: [] as LogEntry[], + settings: { + repo_url: 'https://karlblue.github.io/winget-repo' + }, loading: false, isInitialized: false, initStatus: '正在检查系统环境...', lastFetched: 0 }), getters: { + // ... (mergedEssentials, sortedUpdates, sortedAllSoftware, isBusy getters stay the same) mergedEssentials: (state) => { return state.essentials.map(item => { const isInstalled = state.allSoftware.some(s => s.id.toLowerCase() === item.id.toLowerCase()); @@ -55,8 +59,10 @@ export const useSoftwareStore = defineStore('software', { actions: { async initializeApp() { if (this.isInitialized) return; - this.initStatus = '正在同步 Winget 模块...'; + this.initStatus = '正在加载应用配置...'; try { + this.settings = await invoke('get_settings'); + this.initStatus = '正在同步 Winget 模块...'; await invoke('initialize_app'); this.isInitialized = true; } catch (err) { @@ -64,6 +70,23 @@ export const useSoftwareStore = defineStore('software', { setTimeout(() => { this.isInitialized = true; }, 2000); } }, + + async saveSettings(newSettings: any) { + await invoke('save_settings', { settings: newSettings }); + this.settings = newSettings; + }, + + async syncEssentials() { + this.loading = true; + try { + await invoke('sync_essentials'); + await this.fetchEssentials(); + } finally { + this.loading = false; + } + }, + + // ... (Selection methods stay the same) toggleSelection(id: string, type: 'essential' | 'update') { if (this.isBusy) return; const list = type === 'essential' ? this.selectedEssentialIds : this.selectedUpdateIds; @@ -130,6 +153,9 @@ export const useSoftwareStore = defineStore('software', { async fetchAllData() { this.loading = true; try { + // 在获取全量数据之前,先同步云端清单 + await invoke('sync_essentials').catch(() => {}); + const [essentials, all, updates] = await Promise.all([ invoke('get_essentials'), invoke('get_all_software'), diff --git a/src/views/Settings.vue b/src/views/Settings.vue new file mode 100644 index 0000000..15c38e3 --- /dev/null +++ b/src/views/Settings.vue @@ -0,0 +1,298 @@ + + + + +