mirror of
https://github.com/moku-project/Moku.git
synced 2026-06-13 17:29:55 -05:00
Feat: Switch DRPC Plugins
This commit is contained in:
+1
-1
@@ -181,7 +181,7 @@ modules:
|
||||
path: .
|
||||
- type: file
|
||||
path: packaging/frontend-dist.tar.gz
|
||||
sha256: 43b7274bdab884aacbc3dad6f0f7c043d8e3d82b7bf7398e1df9f516ed553152
|
||||
sha256: d3ebde4d39e3de61420b78a9506df1a5c77c14d705e42662a45a2179bc96030e
|
||||
- packaging/cargo-sources.json
|
||||
- type: inline
|
||||
dest: src-tauri/.cargo
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
inherit version;
|
||||
src = frontendSrc;
|
||||
fetcherVersion = 1;
|
||||
hash = "sha256-ezlckHhfSIe/Hs30tbiN0a/EuvGxhO5L020aup23Ozg=";
|
||||
hash = "sha256-oJVMFL1wdAd1x4AQECTh/yPMhiirbjUduBelZ3bWQtI=";
|
||||
};
|
||||
|
||||
buildPhase = "pnpm build";
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
"clsx": "^2.1.1",
|
||||
"phosphor-svelte": "^3.1.0",
|
||||
"svelte-spa-router": "^4.0.1",
|
||||
"tauri-plugin-discord-rpc-api": "github:Youwes09/tauri-plugin-discord-rpc",
|
||||
"tauri-plugin-drpc": "^1.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
+115
-115
@@ -2030,92 +2030,92 @@
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/icu_collections/icu_collections-2.1.1.crate",
|
||||
"sha256": "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43",
|
||||
"dest": "cargo/vendor/icu_collections-2.1.1"
|
||||
"url": "https://static.crates.io/crates/icu_collections/icu_collections-2.2.0.crate",
|
||||
"sha256": "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c",
|
||||
"dest": "cargo/vendor/icu_collections-2.2.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/icu_collections-2.1.1",
|
||||
"contents": "{\"package\": \"2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/icu_collections-2.2.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/icu_locale_core/icu_locale_core-2.1.1.crate",
|
||||
"sha256": "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6",
|
||||
"dest": "cargo/vendor/icu_locale_core-2.1.1"
|
||||
"url": "https://static.crates.io/crates/icu_locale_core/icu_locale_core-2.2.0.crate",
|
||||
"sha256": "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29",
|
||||
"dest": "cargo/vendor/icu_locale_core-2.2.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/icu_locale_core-2.1.1",
|
||||
"contents": "{\"package\": \"92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/icu_locale_core-2.2.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/icu_normalizer/icu_normalizer-2.1.1.crate",
|
||||
"sha256": "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599",
|
||||
"dest": "cargo/vendor/icu_normalizer-2.1.1"
|
||||
"url": "https://static.crates.io/crates/icu_normalizer/icu_normalizer-2.2.0.crate",
|
||||
"sha256": "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4",
|
||||
"dest": "cargo/vendor/icu_normalizer-2.2.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/icu_normalizer-2.1.1",
|
||||
"contents": "{\"package\": \"c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/icu_normalizer-2.2.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/icu_normalizer_data/icu_normalizer_data-2.1.1.crate",
|
||||
"sha256": "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a",
|
||||
"dest": "cargo/vendor/icu_normalizer_data-2.1.1"
|
||||
"url": "https://static.crates.io/crates/icu_normalizer_data/icu_normalizer_data-2.2.0.crate",
|
||||
"sha256": "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38",
|
||||
"dest": "cargo/vendor/icu_normalizer_data-2.2.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/icu_normalizer_data-2.1.1",
|
||||
"contents": "{\"package\": \"da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/icu_normalizer_data-2.2.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/icu_properties/icu_properties-2.1.2.crate",
|
||||
"sha256": "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec",
|
||||
"dest": "cargo/vendor/icu_properties-2.1.2"
|
||||
"url": "https://static.crates.io/crates/icu_properties/icu_properties-2.2.0.crate",
|
||||
"sha256": "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de",
|
||||
"dest": "cargo/vendor/icu_properties-2.2.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/icu_properties-2.1.2",
|
||||
"contents": "{\"package\": \"bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/icu_properties-2.2.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/icu_properties_data/icu_properties_data-2.1.2.crate",
|
||||
"sha256": "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af",
|
||||
"dest": "cargo/vendor/icu_properties_data-2.1.2"
|
||||
"url": "https://static.crates.io/crates/icu_properties_data/icu_properties_data-2.2.0.crate",
|
||||
"sha256": "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14",
|
||||
"dest": "cargo/vendor/icu_properties_data-2.2.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/icu_properties_data-2.1.2",
|
||||
"contents": "{\"package\": \"8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/icu_properties_data-2.2.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/icu_provider/icu_provider-2.1.1.crate",
|
||||
"sha256": "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614",
|
||||
"dest": "cargo/vendor/icu_provider-2.1.1"
|
||||
"url": "https://static.crates.io/crates/icu_provider/icu_provider-2.2.0.crate",
|
||||
"sha256": "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421",
|
||||
"dest": "cargo/vendor/icu_provider-2.2.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/icu_provider-2.1.1",
|
||||
"contents": "{\"package\": \"139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/icu_provider-2.2.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
@@ -2186,14 +2186,14 @@
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/indexmap/indexmap-2.13.0.crate",
|
||||
"sha256": "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017",
|
||||
"dest": "cargo/vendor/indexmap-2.13.0"
|
||||
"url": "https://static.crates.io/crates/indexmap/indexmap-2.13.1.crate",
|
||||
"sha256": "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff",
|
||||
"dest": "cargo/vendor/indexmap-2.13.1"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/indexmap-2.13.0",
|
||||
"contents": "{\"package\": \"45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/indexmap-2.13.1",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
@@ -2459,14 +2459,14 @@
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/libc/libc-0.2.183.crate",
|
||||
"sha256": "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d",
|
||||
"dest": "cargo/vendor/libc-0.2.183"
|
||||
"url": "https://static.crates.io/crates/libc/libc-0.2.184.crate",
|
||||
"sha256": "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af",
|
||||
"dest": "cargo/vendor/libc-0.2.184"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/libc-0.2.183",
|
||||
"contents": "{\"package\": \"48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/libc-0.2.184",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
@@ -2511,14 +2511,14 @@
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/litemap/litemap-0.8.1.crate",
|
||||
"sha256": "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77",
|
||||
"dest": "cargo/vendor/litemap-0.8.1"
|
||||
"url": "https://static.crates.io/crates/litemap/litemap-0.8.2.crate",
|
||||
"sha256": "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0",
|
||||
"dest": "cargo/vendor/litemap-0.8.2"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/litemap-0.8.1",
|
||||
"contents": "{\"package\": \"92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/litemap-0.8.2",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
@@ -2719,14 +2719,14 @@
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/muda/muda-0.17.1.crate",
|
||||
"sha256": "01c1738382f66ed56b3b9c8119e794a2e23148ac8ea214eda86622d4cb9d415a",
|
||||
"dest": "cargo/vendor/muda-0.17.1"
|
||||
"url": "https://static.crates.io/crates/muda/muda-0.17.2.crate",
|
||||
"sha256": "7c9fec5a4e89860383d778d10563a605838f8f0b2f9303868937e5ff32e86177",
|
||||
"dest": "cargo/vendor/muda-0.17.2"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"01c1738382f66ed56b3b9c8119e794a2e23148ac8ea214eda86622d4cb9d415a\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/muda-0.17.1",
|
||||
"contents": "{\"package\": \"7c9fec5a4e89860383d778d10563a605838f8f0b2f9303868937e5ff32e86177\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/muda-0.17.2",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
@@ -3577,14 +3577,14 @@
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/potential_utf/potential_utf-0.1.4.crate",
|
||||
"sha256": "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77",
|
||||
"dest": "cargo/vendor/potential_utf-0.1.4"
|
||||
"url": "https://static.crates.io/crates/potential_utf/potential_utf-0.1.5.crate",
|
||||
"sha256": "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564",
|
||||
"dest": "cargo/vendor/potential_utf-0.1.5"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/potential_utf-0.1.4",
|
||||
"contents": "{\"package\": \"0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/potential_utf-0.1.5",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
@@ -5514,14 +5514,14 @@
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/tinystr/tinystr-0.8.2.crate",
|
||||
"sha256": "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869",
|
||||
"dest": "cargo/vendor/tinystr-0.8.2"
|
||||
"url": "https://static.crates.io/crates/tinystr/tinystr-0.8.3.crate",
|
||||
"sha256": "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d",
|
||||
"dest": "cargo/vendor/tinystr-0.8.3"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/tinystr-0.8.2",
|
||||
"contents": "{\"package\": \"c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/tinystr-0.8.3",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
@@ -5696,27 +5696,27 @@
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/toml_edit/toml_edit-0.25.9+spec-1.1.0.crate",
|
||||
"sha256": "da053d28fe57e2c9d21b48261e14e7b4c8b670b54d2c684847b91feaf4c7dac5",
|
||||
"dest": "cargo/vendor/toml_edit-0.25.9+spec-1.1.0"
|
||||
"url": "https://static.crates.io/crates/toml_edit/toml_edit-0.25.10+spec-1.1.0.crate",
|
||||
"sha256": "a82418ca169e235e6c399a84e395ab6debeb3bc90edc959bf0f48647c6a32d1b",
|
||||
"dest": "cargo/vendor/toml_edit-0.25.10+spec-1.1.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"da053d28fe57e2c9d21b48261e14e7b4c8b670b54d2c684847b91feaf4c7dac5\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/toml_edit-0.25.9+spec-1.1.0",
|
||||
"contents": "{\"package\": \"a82418ca169e235e6c399a84e395ab6debeb3bc90edc959bf0f48647c6a32d1b\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/toml_edit-0.25.10+spec-1.1.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/toml_parser/toml_parser-1.1.1+spec-1.1.0.crate",
|
||||
"sha256": "39ca317ebc49f06bd748bfba29533eac9485569dc9bf80b849024b025e814fb9",
|
||||
"dest": "cargo/vendor/toml_parser-1.1.1+spec-1.1.0"
|
||||
"url": "https://static.crates.io/crates/toml_parser/toml_parser-1.1.2+spec-1.1.0.crate",
|
||||
"sha256": "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526",
|
||||
"dest": "cargo/vendor/toml_parser-1.1.2+spec-1.1.0"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"39ca317ebc49f06bd748bfba29533eac9485569dc9bf80b849024b025e814fb9\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/toml_parser-1.1.1+spec-1.1.0",
|
||||
"contents": "{\"package\": \"a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/toml_parser-1.1.2+spec-1.1.0",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
@@ -7438,14 +7438,14 @@
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/writeable/writeable-0.6.2.crate",
|
||||
"sha256": "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9",
|
||||
"dest": "cargo/vendor/writeable-0.6.2"
|
||||
"url": "https://static.crates.io/crates/writeable/writeable-0.6.3.crate",
|
||||
"sha256": "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4",
|
||||
"dest": "cargo/vendor/writeable-0.6.3"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/writeable-0.6.2",
|
||||
"contents": "{\"package\": \"1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/writeable-0.6.3",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
@@ -7503,27 +7503,27 @@
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/yoke/yoke-0.8.1.crate",
|
||||
"sha256": "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954",
|
||||
"dest": "cargo/vendor/yoke-0.8.1"
|
||||
"url": "https://static.crates.io/crates/yoke/yoke-0.8.2.crate",
|
||||
"sha256": "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca",
|
||||
"dest": "cargo/vendor/yoke-0.8.2"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/yoke-0.8.1",
|
||||
"contents": "{\"package\": \"abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/yoke-0.8.2",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/yoke-derive/yoke-derive-0.8.1.crate",
|
||||
"sha256": "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d",
|
||||
"dest": "cargo/vendor/yoke-derive-0.8.1"
|
||||
"url": "https://static.crates.io/crates/yoke-derive/yoke-derive-0.8.2.crate",
|
||||
"sha256": "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e",
|
||||
"dest": "cargo/vendor/yoke-derive-0.8.2"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/yoke-derive-0.8.1",
|
||||
"contents": "{\"package\": \"de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/yoke-derive-0.8.2",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
@@ -7555,27 +7555,27 @@
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/zerofrom/zerofrom-0.1.6.crate",
|
||||
"sha256": "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5",
|
||||
"dest": "cargo/vendor/zerofrom-0.1.6"
|
||||
"url": "https://static.crates.io/crates/zerofrom/zerofrom-0.1.7.crate",
|
||||
"sha256": "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df",
|
||||
"dest": "cargo/vendor/zerofrom-0.1.7"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/zerofrom-0.1.6",
|
||||
"contents": "{\"package\": \"69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/zerofrom-0.1.7",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/zerofrom-derive/zerofrom-derive-0.1.6.crate",
|
||||
"sha256": "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502",
|
||||
"dest": "cargo/vendor/zerofrom-derive-0.1.6"
|
||||
"url": "https://static.crates.io/crates/zerofrom-derive/zerofrom-derive-0.1.7.crate",
|
||||
"sha256": "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1",
|
||||
"dest": "cargo/vendor/zerofrom-derive-0.1.7"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/zerofrom-derive-0.1.6",
|
||||
"contents": "{\"package\": \"11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/zerofrom-derive-0.1.7",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
@@ -7594,40 +7594,40 @@
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/zerotrie/zerotrie-0.2.3.crate",
|
||||
"sha256": "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851",
|
||||
"dest": "cargo/vendor/zerotrie-0.2.3"
|
||||
"url": "https://static.crates.io/crates/zerotrie/zerotrie-0.2.4.crate",
|
||||
"sha256": "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf",
|
||||
"dest": "cargo/vendor/zerotrie-0.2.4"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/zerotrie-0.2.3",
|
||||
"contents": "{\"package\": \"0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/zerotrie-0.2.4",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/zerovec/zerovec-0.11.5.crate",
|
||||
"sha256": "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002",
|
||||
"dest": "cargo/vendor/zerovec-0.11.5"
|
||||
"url": "https://static.crates.io/crates/zerovec/zerovec-0.11.6.crate",
|
||||
"sha256": "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239",
|
||||
"dest": "cargo/vendor/zerovec-0.11.6"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/zerovec-0.11.5",
|
||||
"contents": "{\"package\": \"90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/zerovec-0.11.6",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
"type": "archive",
|
||||
"archive-type": "tar-gzip",
|
||||
"url": "https://static.crates.io/crates/zerovec-derive/zerovec-derive-0.11.2.crate",
|
||||
"sha256": "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3",
|
||||
"dest": "cargo/vendor/zerovec-derive-0.11.2"
|
||||
"url": "https://static.crates.io/crates/zerovec-derive/zerovec-derive-0.11.3.crate",
|
||||
"sha256": "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555",
|
||||
"dest": "cargo/vendor/zerovec-derive-0.11.3"
|
||||
},
|
||||
{
|
||||
"type": "inline",
|
||||
"contents": "{\"package\": \"eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/zerovec-derive-0.11.2",
|
||||
"contents": "{\"package\": \"625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555\", \"files\": {}}",
|
||||
"dest": "cargo/vendor/zerovec-derive-0.11.3",
|
||||
"dest-filename": ".cargo-checksum.json"
|
||||
},
|
||||
{
|
||||
|
||||
Generated
+11
@@ -26,6 +26,9 @@ importers:
|
||||
svelte-spa-router:
|
||||
specifier: ^4.0.1
|
||||
version: 4.0.2
|
||||
tauri-plugin-discord-rpc-api:
|
||||
specifier: github:Youwes09/tauri-plugin-discord-rpc
|
||||
version: https://codeload.github.com/Youwes09/tauri-plugin-discord-rpc/tar.gz/4b20388e4b65e0efcff2aa9a8622b5884554cd8a
|
||||
tauri-plugin-drpc:
|
||||
specifier: ^1.0.3
|
||||
version: 1.0.3(typescript@5.9.3)
|
||||
@@ -747,6 +750,10 @@ packages:
|
||||
resolution: {integrity: sha512-TTDxwYnHkova6Wsyj1PGt9TByuWqvMoeY1bQiuAf2DM/JeDSMw7FjRKzk8K/5mJ99vGOKhbCqTDpyAKwjp4igg==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
tauri-plugin-discord-rpc-api@https://codeload.github.com/Youwes09/tauri-plugin-discord-rpc/tar.gz/4b20388e4b65e0efcff2aa9a8622b5884554cd8a:
|
||||
resolution: {tarball: https://codeload.github.com/Youwes09/tauri-plugin-discord-rpc/tar.gz/4b20388e4b65e0efcff2aa9a8622b5884554cd8a}
|
||||
version: 0.1.0
|
||||
|
||||
tauri-plugin-drpc@1.0.3:
|
||||
resolution: {integrity: sha512-vl5dXhjKbl7+Nf9veW12usdmIUtZXwEf91SzxQPZlbRRJ/sjizbbQlnkUTtx6baJuGzz0KXXgP9xUhF39BdiXQ==}
|
||||
peerDependencies:
|
||||
@@ -1372,6 +1379,10 @@ snapshots:
|
||||
magic-string: 0.30.21
|
||||
zimmerframe: 1.1.4
|
||||
|
||||
tauri-plugin-discord-rpc-api@https://codeload.github.com/Youwes09/tauri-plugin-discord-rpc/tar.gz/4b20388e4b65e0efcff2aa9a8622b5884554cd8a:
|
||||
dependencies:
|
||||
'@tauri-apps/api': 2.10.1
|
||||
|
||||
tauri-plugin-drpc@1.0.3(typescript@5.9.3):
|
||||
dependencies:
|
||||
typescript: 5.9.3
|
||||
|
||||
Generated
+55
-28
@@ -268,9 +268,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.58"
|
||||
version = "1.2.59"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1"
|
||||
checksum = "b7a4d3ec6524d28a329fc53654bbadc9bdd7b0431f5d65f1a56ffb28a1ee5283"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"shlex",
|
||||
@@ -699,6 +699,21 @@ dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "discord-rich-presence"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90c55d69cab17c19677ce3a5f8face993a9e6eaf847fecac3547f3a3ff4a2494"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"thiserror 2.0.18",
|
||||
"uuid 0.8.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dispatch2"
|
||||
version = "0.3.1"
|
||||
@@ -2109,10 +2124,10 @@ dependencies = [
|
||||
"dirs 5.0.1",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sysinfo",
|
||||
"sysinfo 0.32.1",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"tauri-plugin-drpc",
|
||||
"tauri-plugin-discord-rpc",
|
||||
"tauri-plugin-http",
|
||||
"tauri-plugin-os",
|
||||
"tauri-plugin-process",
|
||||
@@ -2370,6 +2385,16 @@ dependencies = [
|
||||
"objc2-core-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-io-kit"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33fafba39597d6dc1fb709123dfa8289d39406734be322956a69f0931c73bb15"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"objc2-core-foundation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc2-io-surface"
|
||||
version = "0.3.2"
|
||||
@@ -3341,19 +3366,6 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rpcdiscord"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71aa9a2097dc0176805e24debcb5d3ea5a17b796cd1d28e76b29f78fb49d7d5d"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"uuid 0.8.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.2"
|
||||
@@ -3605,9 +3617,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.27"
|
||||
version = "1.0.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
|
||||
checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_core",
|
||||
@@ -4082,6 +4094,20 @@ dependencies = [
|
||||
"windows 0.57.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sysinfo"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "252800745060e7b9ffb7b2badbd8b31cfa4aa2e61af879d0a3bf2a317c20217d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"memchr",
|
||||
"ntapi",
|
||||
"objc2-core-foundation",
|
||||
"objc2-io-kit",
|
||||
"windows 0.61.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration"
|
||||
version = "0.7.0"
|
||||
@@ -4314,15 +4340,16 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-drpc"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b291669b7dbc05471fba380eeecf31e3f733ae6013aaa5216a43ca376027e5a"
|
||||
name = "tauri-plugin-discord-rpc"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/Youwes09/tauri-plugin-discord-rpc#d2fd312945d0573153e0e7e2d2dfb131acecc52c"
|
||||
dependencies = [
|
||||
"discord-rich-presence",
|
||||
"libc",
|
||||
"log",
|
||||
"rpcdiscord",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sysinfo 0.36.1",
|
||||
"tauri",
|
||||
"tauri-plugin",
|
||||
"thiserror 2.0.18",
|
||||
@@ -4689,9 +4716,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.50.0"
|
||||
version = "1.51.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d"
|
||||
checksum = "2bd1c4c0fc4a7ab90fc15ef6daaa3ec3b893f004f915f2392557ed23237820cd"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"libc",
|
||||
@@ -4704,9 +4731,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.6.1"
|
||||
version = "2.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c"
|
||||
checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
||||
+16
-16
@@ -15,22 +15,22 @@ path = "src/main.rs"
|
||||
tauri-build = { version = "2.0", features = [] }
|
||||
|
||||
[dependencies]
|
||||
tauri = { version = "2.0", features = [] }
|
||||
tauri-plugin-shell = "2"
|
||||
tauri-plugin-updater = "2"
|
||||
tauri-plugin-process = "2"
|
||||
tauri-plugin-http = "2"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
walkdir = "2"
|
||||
sysinfo = "0.32"
|
||||
dirs = "5"
|
||||
tauri-plugin-os = "2.3.2"
|
||||
tauri-plugin-drpc = "0.1.6"
|
||||
tauri = { version = "2.0", features = [] }
|
||||
tauri-plugin-shell = "2"
|
||||
tauri-plugin-updater = "2"
|
||||
tauri-plugin-process = "2"
|
||||
tauri-plugin-http = "2"
|
||||
tauri-plugin-os = "2.3.2"
|
||||
tauri-plugin-discord-rpc = { git = "https://github.com/Youwes09/tauri-plugin-discord-rpc" }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
walkdir = "2"
|
||||
sysinfo = "0.32"
|
||||
dirs = "5"
|
||||
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
lto = true
|
||||
opt-level = "s"
|
||||
panic = "abort"
|
||||
strip = true
|
||||
lto = true
|
||||
opt-level = "s"
|
||||
panic = "abort"
|
||||
strip = true
|
||||
|
||||
@@ -33,11 +33,11 @@
|
||||
"process:allow-restart",
|
||||
"http:default",
|
||||
"http:allow-fetch",
|
||||
"drpc:default",
|
||||
"drpc:allow-is-running",
|
||||
"drpc:allow-spawn-thread",
|
||||
"drpc:allow-destroy-thread",
|
||||
"drpc:allow-set-activity",
|
||||
"drpc:allow-clear-activity"
|
||||
"discord-rpc:default",
|
||||
"discord-rpc:allow-connect",
|
||||
"discord-rpc:allow-disconnect",
|
||||
"discord-rpc:allow-set-activity",
|
||||
"discord-rpc:allow-clear-activity",
|
||||
"discord-rpc:allow-is-running"
|
||||
]
|
||||
}
|
||||
|
||||
+48
-198
@@ -26,9 +26,6 @@ pub enum SpawnError {
|
||||
SpawnFailed(String),
|
||||
}
|
||||
|
||||
// ── Update types ──────────────────────────────────────────────────────────────
|
||||
|
||||
/// A single GitHub release returned to the frontend.
|
||||
#[derive(Serialize, Clone)]
|
||||
pub struct ReleaseInfo {
|
||||
pub tag_name: String,
|
||||
@@ -38,7 +35,6 @@ pub struct ReleaseInfo {
|
||||
pub html_url: String,
|
||||
}
|
||||
|
||||
/// Progress event emitted during download — matches what the frontend listens for.
|
||||
#[derive(Clone, serde::Serialize)]
|
||||
#[cfg_attr(not(target_os = "windows"), allow(dead_code))]
|
||||
struct UpdateProgress {
|
||||
@@ -46,8 +42,6 @@ struct UpdateProgress {
|
||||
total: Option<u64>,
|
||||
}
|
||||
|
||||
/// Strip the \\?\ extended-length path prefix that Windows adds to long paths.
|
||||
/// Java and many other tools do not accept this prefix and will fail silently.
|
||||
fn strip_unc(path: PathBuf) -> PathBuf {
|
||||
let s = path.to_string_lossy();
|
||||
if let Some(stripped) = s.strip_prefix(r"\\?\") {
|
||||
@@ -61,10 +55,6 @@ fn resolve_downloads_path(downloads_path: &str) -> PathBuf {
|
||||
if !downloads_path.trim().is_empty() {
|
||||
return PathBuf::from(downloads_path);
|
||||
}
|
||||
// Mirror Suwayomi-Server's own default: <data_dir>/Tachidesk/downloads
|
||||
// Windows: %LOCALAPPDATA%\Tachidesk\downloads
|
||||
// macOS: ~/Library/Application Support/Tachidesk/downloads
|
||||
// Linux: $XDG_DATA_HOME/Tachidesk/downloads (~/.local/share/Tachidesk/downloads)
|
||||
let base = std::env::var("XDG_DATA_HOME")
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|_| dirs::data_dir().unwrap_or_else(|| PathBuf::from("/")));
|
||||
@@ -108,34 +98,23 @@ fn get_storage_info(downloads_path: String) -> Result<StorageInfo, String> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the resolved default downloads path for the current platform.
|
||||
/// This mirrors resolve_downloads_path("") so the frontend can display it.
|
||||
#[tauri::command]
|
||||
fn get_default_downloads_path() -> String {
|
||||
resolve_downloads_path("").to_string_lossy().into_owned()
|
||||
}
|
||||
|
||||
/// Returns true if the given path exists and is a directory.
|
||||
#[tauri::command]
|
||||
fn check_path_exists(path: String) -> bool {
|
||||
std::path::Path::new(path.trim()).is_dir()
|
||||
}
|
||||
|
||||
/// Creates a directory and all missing parent directories.
|
||||
#[tauri::command]
|
||||
fn create_directory(path: String) -> Result<(), String> {
|
||||
std::fs::create_dir_all(path.trim()).map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
/// Moves all content from `src` into `dst`, then removes `src`.
|
||||
/// Emits `migrate_progress` events: `{ done, total, current }`.
|
||||
/// Only deletes the source tree after every file is confirmed copied.
|
||||
#[tauri::command]
|
||||
async fn migrate_downloads(
|
||||
app: tauri::AppHandle,
|
||||
src: String,
|
||||
dst: String,
|
||||
) -> Result<(), String> {
|
||||
async fn migrate_downloads(app: tauri::AppHandle, src: String, dst: String) -> Result<(), String> {
|
||||
use tauri::Emitter;
|
||||
use std::fs;
|
||||
|
||||
@@ -143,19 +122,16 @@ async fn migrate_downloads(
|
||||
let dst_path = std::path::PathBuf::from(dst.trim());
|
||||
|
||||
if !src_path.is_dir() {
|
||||
return Ok(()); // nothing to migrate
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// Count files first so the frontend can show accurate progress
|
||||
let total: u64 = WalkDir::new(&src_path)
|
||||
.into_iter()
|
||||
.filter_map(|e| e.ok())
|
||||
.filter(|e| e.file_type().is_file())
|
||||
.count() as u64;
|
||||
|
||||
let _ = app.emit("migrate_progress", serde_json::json!({
|
||||
"done": 0u64, "total": total, "current": ""
|
||||
}));
|
||||
let _ = app.emit("migrate_progress", serde_json::json!({ "done": 0u64, "total": total, "current": "" }));
|
||||
|
||||
let mut done: u64 = 0;
|
||||
|
||||
@@ -172,23 +148,15 @@ async fn migrate_downloads(
|
||||
fs::copy(entry.path(), &target).map_err(|e| e.to_string())?;
|
||||
done += 1;
|
||||
let _ = app.emit("migrate_progress", serde_json::json!({
|
||||
"done": done,
|
||||
"total": total,
|
||||
"current": rel.to_string_lossy()
|
||||
"done": done, "total": total, "current": rel.to_string_lossy()
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
// Only remove source after all files are confirmed copied
|
||||
fs::remove_dir_all(&src_path).map_err(|e| e.to_string())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns the OS/monitor DPI scale factor for the window's current monitor.
|
||||
/// This is the real hardware scale — 1.0 on standard displays, 2.0 on HiDPI/4K,
|
||||
/// 1.25–1.5 on Windows displays with OS-level scaling applied.
|
||||
/// The frontend multiplies this by the user's uiZoom preference to get the
|
||||
/// final effective zoom applied to document.documentElement.
|
||||
#[tauri::command]
|
||||
fn get_platform_ui_scale(window: tauri::Window) -> f64 {
|
||||
window.scale_factor().unwrap_or(1.0)
|
||||
@@ -210,8 +178,6 @@ fn kill_tachidesk(app: &tauri::AppHandle) {
|
||||
.creation_flags(CREATE_NO_WINDOW)
|
||||
.status();
|
||||
|
||||
// Poll until no java.exe remains (up to ~3 s) so the installer can
|
||||
// overwrite the JRE DLLs without hitting a sharing-violation error.
|
||||
for _ in 0..30 {
|
||||
let still_running = std::process::Command::new("tasklist")
|
||||
.args(["/FI", "IMAGENAME eq java.exe", "/NH"])
|
||||
@@ -220,20 +186,15 @@ fn kill_tachidesk(app: &tauri::AppHandle) {
|
||||
.map(|o| String::from_utf8_lossy(&o.stdout).contains("java.exe"))
|
||||
.unwrap_or(false);
|
||||
|
||||
if !still_running {
|
||||
break;
|
||||
}
|
||||
if !still_running { break; }
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let _ = std::process::Command::new("pkill")
|
||||
.args(["-f", "tachidesk"])
|
||||
.status();
|
||||
let _ = std::process::Command::new("pkill").args(["-f", "tachidesk"]).status();
|
||||
}
|
||||
|
||||
|
||||
const DEFAULT_SERVER_CONF: &str = r#"server.ip = "127.0.0.1"
|
||||
server.port = 4567
|
||||
server.webUIEnabled = false
|
||||
@@ -328,23 +289,14 @@ struct ServerInvocation {
|
||||
working_dir: Option<PathBuf>,
|
||||
}
|
||||
|
||||
/// Locate the `java` / `java.exe` binary inside a bundled JRE directory.
|
||||
///
|
||||
/// Expected layout (Windows and Linux):
|
||||
/// <bundle_dir>/jre/bin/java[.exe]
|
||||
///
|
||||
/// On Windows `strip_unc` is applied so Java doesn't choke on `\\?\` prefixes.
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
fn find_java_in_bundle(bundle_dir: &PathBuf, log: &mut Option<std::fs::File>) -> Option<PathBuf> {
|
||||
#[cfg(target_os = "windows")]
|
||||
let java = strip_unc(bundle_dir.join("jre").join("bin").join("java.exe"));
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let java = bundle_dir.join("jre").join("bin").join("java");
|
||||
|
||||
do_log(log, &format!("[find_java] checking path: {:?}", java));
|
||||
do_log(log, &format!("[find_java] exists: {}", java.exists()));
|
||||
|
||||
do_log(log, &format!("[find_java] path: {:?} exists: {}", java, java.exists()));
|
||||
if java.exists() { Some(java) } else { None }
|
||||
}
|
||||
|
||||
@@ -360,12 +312,8 @@ fn resolve_server_binary(
|
||||
app: &tauri::AppHandle,
|
||||
log: &mut Option<std::fs::File>,
|
||||
) -> Result<ServerInvocation, SpawnError> {
|
||||
do_log(log, &format!("[resolve] binary arg = {:?}", binary));
|
||||
do_log(log, &format!("[resolve] binary = {:?}", binary));
|
||||
|
||||
// ── 1. User-specified binary path ─────────────────────────────────────────
|
||||
// Primary: honour the path as-is (doc-2 behaviour — trust the user).
|
||||
// Fallback: if the path doesn't exist after stripping UNC, log a warning
|
||||
// and continue so the bundled detection still has a chance.
|
||||
if !binary.trim().is_empty() {
|
||||
let path = strip_unc(PathBuf::from(binary.trim()));
|
||||
do_log(log, &format!("[resolve] user path: {:?} exists={}", path, path.exists()));
|
||||
@@ -376,62 +324,44 @@ fn resolve_server_binary(
|
||||
working_dir: path.parent().map(|p| p.to_path_buf()),
|
||||
});
|
||||
}
|
||||
// Fallback: path was set but file is missing — warn and keep trying.
|
||||
do_log(log, "[resolve] WARNING: user-supplied path not found, falling through to bundled detection");
|
||||
do_log(log, "[resolve] user path not found, falling through");
|
||||
}
|
||||
|
||||
// Resolve and UNC-strip resource_dir once; used by all non-macOS branches.
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
let resource_dir = {
|
||||
let raw = app.path().resource_dir().unwrap_or_default();
|
||||
let stripped = strip_unc(raw);
|
||||
do_log(log, &format!("[resolve] resource_dir (stripped) = {:?}", stripped));
|
||||
do_log(log, &format!("[resolve] resource_dir = {:?}", stripped));
|
||||
stripped
|
||||
};
|
||||
|
||||
// ── 2. Bundled JRE + JAR (Windows / Linux — specific layout) ─────────────
|
||||
// Primary path from doc-2: binaries/suwayomi-bundle/bin/Suwayomi-Server.jar
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
let bundle_dir = resource_dir.join("binaries").join("suwayomi-bundle");
|
||||
let jar = bundle_dir.join("bin").join("Suwayomi-Server.jar");
|
||||
|
||||
do_log(log, &format!("[resolve] bundle_dir = {:?}", bundle_dir));
|
||||
do_log(log, &format!("[resolve] bundle_dir exists: {}", bundle_dir.exists()));
|
||||
do_log(log, &format!("[resolve] jar = {:?}", jar));
|
||||
do_log(log, &format!("[resolve] jar exists: {}", jar.exists()));
|
||||
do_log(log, &format!("[resolve] bundle_dir={:?} exists={}", bundle_dir, bundle_dir.exists()));
|
||||
do_log(log, &format!("[resolve] jar={:?} exists={}", jar, jar.exists()));
|
||||
|
||||
match find_java_in_bundle(&bundle_dir, log) {
|
||||
Some(java) => {
|
||||
do_log(log, &format!("[resolve] java found: {:?}", java));
|
||||
if jar.exists() {
|
||||
do_log(log, "[resolve] both java and jar found — using bundled JRE");
|
||||
return Ok(ServerInvocation {
|
||||
bin: java.to_string_lossy().into_owned(),
|
||||
args: vec!["-jar".to_string(), jar.to_string_lossy().into_owned()],
|
||||
working_dir: Some(bundle_dir),
|
||||
});
|
||||
}
|
||||
do_log(log, "[resolve] java found but jar MISSING — falling through");
|
||||
}
|
||||
None => {
|
||||
do_log(log, "[resolve] java NOT found in bundle — falling through");
|
||||
Some(java) if jar.exists() => {
|
||||
do_log(log, "[resolve] using bundled JRE");
|
||||
return Ok(ServerInvocation {
|
||||
bin: java.to_string_lossy().into_owned(),
|
||||
args: vec!["-jar".to_string(), jar.to_string_lossy().into_owned()],
|
||||
working_dir: Some(bundle_dir),
|
||||
});
|
||||
}
|
||||
_ => do_log(log, "[resolve] bundled JRE/jar not found, falling through"),
|
||||
}
|
||||
}
|
||||
|
||||
// ── 2b. Bundled launcher scripts / native sidecars (Windows / Linux) ──────
|
||||
// Fallback for older bundle layouts that ship a wrapper script instead of a
|
||||
// bare JRE + JAR. Also scans for any *.jar in resource_dir as a last resort.
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
// Named launcher scripts.
|
||||
let script_candidates = ["suwayomi-launcher", "suwayomi-launcher.sh", "tachidesk-server"];
|
||||
for name in &script_candidates {
|
||||
for name in &["suwayomi-launcher", "suwayomi-launcher.sh", "tachidesk-server"] {
|
||||
let p = resource_dir.join(name);
|
||||
do_log(log, &format!("[resolve] sidecar candidate: {:?} exists={}", p, p.exists()));
|
||||
do_log(log, &format!("[resolve] sidecar: {:?} exists={}", p, p.exists()));
|
||||
if p.exists() {
|
||||
do_log(log, &format!("[resolve] using sidecar: {:?}", p));
|
||||
return Ok(ServerInvocation {
|
||||
bin: p.to_string_lossy().into_owned(),
|
||||
args: vec![],
|
||||
@@ -440,50 +370,31 @@ fn resolve_server_binary(
|
||||
}
|
||||
}
|
||||
|
||||
// Generic JRE at resource_dir root + any *.jar alongside it.
|
||||
do_log(log, "[resolve] no named sidecar found, trying generic JRE + any jar in resource_dir");
|
||||
if let Some(java) = find_java_in_bundle(&resource_dir, log) {
|
||||
let jar = std::fs::read_dir(&resource_dir)
|
||||
.ok()
|
||||
.and_then(|mut rd| {
|
||||
rd.find(|e| {
|
||||
e.as_ref()
|
||||
.map(|e| e.file_name().to_string_lossy().ends_with(".jar"))
|
||||
.unwrap_or(false)
|
||||
})
|
||||
.and_then(|e| e.ok())
|
||||
.map(|e| e.path())
|
||||
rd.find(|e| e.as_ref().map(|e| e.file_name().to_string_lossy().ends_with(".jar")).unwrap_or(false))
|
||||
.and_then(|e| e.ok())
|
||||
.map(|e| e.path())
|
||||
});
|
||||
|
||||
do_log(log, &format!("[resolve] generic jar candidate: {:?}", jar));
|
||||
|
||||
if let Some(jar_path) = jar {
|
||||
do_log(log, &format!("[resolve] using generic JRE java={:?} jar={:?}", java, jar_path));
|
||||
do_log(log, &format!("[resolve] generic JRE java={:?} jar={:?}", java, jar_path));
|
||||
return Ok(ServerInvocation {
|
||||
bin: java.to_string_lossy().into_owned(),
|
||||
args: vec!["-jar".to_string(), jar_path.to_string_lossy().into_owned()],
|
||||
working_dir: Some(resource_dir),
|
||||
});
|
||||
}
|
||||
do_log(log, "[resolve] generic JRE found but no .jar — falling through");
|
||||
}
|
||||
}
|
||||
|
||||
// ── 3. macOS app bundle — MacOS/ then Resources/ ──────────────────────────
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
let resource_dir = app.path().resource_dir().unwrap_or_default();
|
||||
let macos_dir = resource_dir
|
||||
.parent()
|
||||
.map(|p| p.join("MacOS"))
|
||||
.unwrap_or_default();
|
||||
let macos_dir = resource_dir.parent().map(|p| p.join("MacOS")).unwrap_or_default();
|
||||
|
||||
do_log(log, &format!("[resolve] macOS macos_dir = {:?}", macos_dir));
|
||||
|
||||
// Tauri strips the target triple when installing externalBin sidecars into
|
||||
// Contents/MacOS/, so the binary is "suwayomi-server" at runtime.
|
||||
// Triple-suffixed names are kept as a belt-and-suspenders fallback for
|
||||
// dev / flat layouts.
|
||||
let candidates = [
|
||||
"suwayomi-server",
|
||||
"suwayomi-server-aarch64-apple-darwin",
|
||||
@@ -498,7 +409,6 @@ fn resolve_server_binary(
|
||||
let p = search_dir.join(name);
|
||||
do_log(log, &format!("[resolve] macOS candidate: {:?} exists={}", p, p.exists()));
|
||||
if p.exists() {
|
||||
do_log(log, &format!("[resolve] using macOS sidecar: {:?}", p));
|
||||
return Ok(ServerInvocation {
|
||||
bin: p.to_string_lossy().into_owned(),
|
||||
args: vec![],
|
||||
@@ -509,37 +419,17 @@ fn resolve_server_binary(
|
||||
}
|
||||
}
|
||||
|
||||
// ── 4. PATH fallback ──────────────────────────────────────────────────────
|
||||
// Use `where` on Windows, `which` everywhere else.
|
||||
do_log(log, "[resolve] trying PATH fallback");
|
||||
for name in &["suwayomi-server", "tachidesk-server"] {
|
||||
#[cfg(target_os = "windows")]
|
||||
let found = std::process::Command::new("where")
|
||||
.arg(name)
|
||||
.output()
|
||||
.map(|o| o.status.success())
|
||||
.unwrap_or(false);
|
||||
|
||||
let found = std::process::Command::new("where").arg(name).output().map(|o| o.status.success()).unwrap_or(false);
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let found = std::process::Command::new("which")
|
||||
.arg(name)
|
||||
.output()
|
||||
.map(|o| o.status.success())
|
||||
.unwrap_or(false);
|
||||
|
||||
do_log(log, &format!("[resolve] PATH check {:?}: found={}", name, found));
|
||||
let found = std::process::Command::new("which").arg(name).output().map(|o| o.status.success()).unwrap_or(false);
|
||||
|
||||
if found {
|
||||
do_log(log, &format!("[resolve] using PATH binary: {}", name));
|
||||
return Ok(ServerInvocation {
|
||||
bin: name.to_string(),
|
||||
args: vec![],
|
||||
working_dir: None,
|
||||
});
|
||||
return Ok(ServerInvocation { bin: name.to_string(), args: vec![], working_dir: None });
|
||||
}
|
||||
}
|
||||
|
||||
do_log(log, "[resolve] FAILED — no binary found anywhere");
|
||||
Err(SpawnError::NotConfigured(
|
||||
"Server binary not found. Install Suwayomi-Server or set the path in Settings.".to_string(),
|
||||
))
|
||||
@@ -555,50 +445,28 @@ fn spawn_server(binary: String, app: tauri::AppHandle) -> Result<(), SpawnError>
|
||||
}
|
||||
|
||||
let data_dir = suwayomi_data_dir();
|
||||
|
||||
let log_path = data_dir.join("moku-spawn.log");
|
||||
let _ = std::fs::create_dir_all(&data_dir);
|
||||
let mut log = std::fs::OpenOptions::new()
|
||||
.create(true)
|
||||
.append(true)
|
||||
.open(&log_path)
|
||||
.ok();
|
||||
let mut log = std::fs::OpenOptions::new().create(true).append(true).open(&log_path).ok();
|
||||
|
||||
do_log(&mut log, "");
|
||||
do_log(&mut log, "========================================");
|
||||
do_log(&mut log, &format!("[spawn_server] called at {:?}", std::time::SystemTime::now()));
|
||||
do_log(&mut log, &format!("[spawn_server] binary arg = {:?}", binary));
|
||||
do_log(&mut log, &format!("[spawn_server] data_dir = {:?}", data_dir));
|
||||
do_log(&mut log, &format!("[spawn_server] log file = {:?}", log_path));
|
||||
do_log(&mut log, &format!("[spawn_server] APPDATA = {:?}", std::env::var("APPDATA")));
|
||||
do_log(&mut log, &format!("[spawn_server] LOCALAPPDATA = {:?}", std::env::var("LOCALAPPDATA")));
|
||||
do_log(&mut log, &format!("[spawn_server] current_dir = {:?}", std::env::current_dir()));
|
||||
do_log(&mut log, &format!("[spawn_server] binary={:?} data_dir={:?}", binary, data_dir));
|
||||
|
||||
seed_server_conf(&data_dir);
|
||||
do_log(&mut log, "[spawn_server] server.conf seeded");
|
||||
|
||||
let mut invocation = match resolve_server_binary(&binary, &app, &mut log) {
|
||||
Ok(i) => i,
|
||||
Err(e) => {
|
||||
do_log(&mut log, &format!("[spawn_server] resolve FAILED: {:?}", e));
|
||||
return Err(e);
|
||||
}
|
||||
};
|
||||
let mut invocation = resolve_server_binary(&binary, &app, &mut log).map_err(|e| {
|
||||
do_log(&mut log, &format!("[spawn_server] resolve failed: {:?}", e));
|
||||
e
|
||||
})?;
|
||||
|
||||
let bin_display = invocation.bin.clone();
|
||||
let rootdir_flag = format!(
|
||||
"-Dsuwayomi.tachidesk.config.server.rootDir={}",
|
||||
data_dir.to_string_lossy()
|
||||
);
|
||||
|
||||
invocation.args.insert(0, rootdir_flag);
|
||||
|
||||
let working_dir = invocation.working_dir
|
||||
.unwrap_or_else(|| std::env::current_dir().unwrap_or_default());
|
||||
let working_dir = invocation.working_dir.unwrap_or_else(|| std::env::current_dir().unwrap_or_default());
|
||||
|
||||
do_log(&mut log, &format!("[spawn_server] bin = {:?}", bin_display));
|
||||
do_log(&mut log, &format!("[spawn_server] args = {:?}", invocation.args));
|
||||
do_log(&mut log, &format!("[spawn_server] working_dir = {:?}", working_dir));
|
||||
do_log(&mut log, &format!("[spawn_server] bin={:?} args={:?} cwd={:?}", invocation.bin, invocation.args, working_dir));
|
||||
|
||||
let cmd = app.shell()
|
||||
.command(&invocation.bin)
|
||||
@@ -606,17 +474,13 @@ fn spawn_server(binary: String, app: tauri::AppHandle) -> Result<(), SpawnError>
|
||||
.args(&invocation.args)
|
||||
.current_dir(&working_dir);
|
||||
|
||||
do_log(&mut log, "[spawn_server] calling cmd.spawn()...");
|
||||
|
||||
match cmd.spawn() {
|
||||
Ok((_rx, child)) => {
|
||||
do_log(&mut log, &format!("[spawn_server] SUCCESS — spawned: {}", bin_display));
|
||||
*app.state::<ServerState>().0.lock().unwrap() = Some(child);
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => {
|
||||
do_log(&mut log, &format!("[spawn_server] SPAWN FAILED: {}", e));
|
||||
do_log(&mut log, &format!("[spawn_server] error kind: {:?}", e));
|
||||
do_log(&mut log, &format!("[spawn_server] spawn failed: {}", e));
|
||||
Err(SpawnError::SpawnFailed(e.to_string()))
|
||||
}
|
||||
}
|
||||
@@ -628,10 +492,6 @@ fn kill_server(app: tauri::AppHandle) -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// ── Update commands ───────────────────────────────────────────────────────────
|
||||
|
||||
/// Fetch the list of all GitHub releases so the frontend can show a version picker.
|
||||
/// Uses tauri-plugin-http so it goes through Tauri's permission system.
|
||||
#[tauri::command]
|
||||
async fn list_releases() -> Result<Vec<ReleaseInfo>, String> {
|
||||
use tauri_plugin_http::reqwest;
|
||||
@@ -663,22 +523,15 @@ async fn list_releases() -> Result<Vec<ReleaseInfo>, String> {
|
||||
let body = resp.text().await.map_err(|e| e.to_string())?;
|
||||
let releases: Vec<GhRelease> = serde_json::from_str(&body).map_err(|e| e.to_string())?;
|
||||
|
||||
Ok(releases
|
||||
.into_iter()
|
||||
.map(|r| ReleaseInfo {
|
||||
tag_name: r.tag_name.clone(),
|
||||
name: r.name.unwrap_or_else(|| r.tag_name.clone()),
|
||||
body: r.body.unwrap_or_default(),
|
||||
published_at: r.published_at.unwrap_or_default(),
|
||||
html_url: r.html_url,
|
||||
})
|
||||
.collect())
|
||||
Ok(releases.into_iter().map(|r| ReleaseInfo {
|
||||
tag_name: r.tag_name.clone(),
|
||||
name: r.name.unwrap_or_else(|| r.tag_name.clone()),
|
||||
body: r.body.unwrap_or_default(),
|
||||
published_at: r.published_at.unwrap_or_default(),
|
||||
html_url: r.html_url,
|
||||
}).collect())
|
||||
}
|
||||
|
||||
/// Download and install the latest update using tauri-plugin-updater.
|
||||
/// Emits `update-progress` events with `{ downloaded, total }` while downloading.
|
||||
/// On Windows the installer runs in passive (silent) mode; the frontend prompts restart.
|
||||
/// On other platforms this command is a no-op — the frontend opens the GitHub page instead.
|
||||
#[tauri::command]
|
||||
#[allow(unused_variables)]
|
||||
async fn download_and_install_update(app: tauri::AppHandle) -> Result<(), String> {
|
||||
@@ -693,7 +546,7 @@ async fn download_and_install_update(app: tauri::AppHandle) -> Result<(), String
|
||||
let update = updater.check().await.map_err(|e| e.to_string())?;
|
||||
|
||||
let Some(update) = update else {
|
||||
return Err("No update available from the updater endpoint.".into());
|
||||
return Err("No update available.".into());
|
||||
};
|
||||
|
||||
let app_clone = app.clone();
|
||||
@@ -711,18 +564,15 @@ async fn download_and_install_update(app: tauri::AppHandle) -> Result<(), String
|
||||
}
|
||||
}
|
||||
|
||||
/// Restart the app after a successful update install.
|
||||
#[tauri::command]
|
||||
fn restart_app(app: tauri::AppHandle) {
|
||||
tauri::process::restart(&app.env());
|
||||
}
|
||||
|
||||
// ── App entry point ───────────────────────────────────────────────────────────
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_drpc::init())
|
||||
.plugin(tauri_plugin_discord_rpc::init())
|
||||
.plugin(tauri_plugin_os::init())
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
.plugin(tauri_plugin_http::init())
|
||||
|
||||
+48
-48
@@ -1,79 +1,79 @@
|
||||
import { start, stop, setActivity, clearActivity } from "tauri-plugin-drpc";
|
||||
import { Activity, Assets, Button, Timestamps } from "tauri-plugin-drpc/activity";
|
||||
import type { Manga, Chapter } from "./types";
|
||||
import { connect, disconnect, setActivity, clearActivity } from "tauri-plugin-discord-rpc-api";
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
import type { Manga, Chapter } from './types'
|
||||
|
||||
const APP_ID = "1487894643613106298";
|
||||
const FALLBACK_IMAGE = "moku_logo";
|
||||
const APP_ID = '1487894643613106298'
|
||||
const FALLBACK_IMAGE = 'moku_logo'
|
||||
|
||||
let sessionStart: number | null = null;
|
||||
let sessionStart: number | null = null
|
||||
let unlisten: (() => void) | null = null
|
||||
|
||||
function isPublicUrl(url: string | null | undefined): boolean {
|
||||
return typeof url === "string" && url.startsWith("https://");
|
||||
return typeof url === 'string' && url.startsWith('https://')
|
||||
}
|
||||
|
||||
function resolveCoverImage(manga: Manga): string {
|
||||
return isPublicUrl(manga.thumbnailUrl) ? manga.thumbnailUrl : FALLBACK_IMAGE;
|
||||
return isPublicUrl(manga.thumbnailUrl) ? manga.thumbnailUrl : FALLBACK_IMAGE
|
||||
}
|
||||
|
||||
function trunc(s: string, max = 128): string {
|
||||
return s.length <= max ? s : `${s.slice(0, max - 1)}…`;
|
||||
return s.length <= max ? s : `${s.slice(0, max - 1)}…`
|
||||
}
|
||||
|
||||
function formatChapter(chapter: Chapter): string {
|
||||
const n = chapter.chapterNumber;
|
||||
return `Chapter ${Number.isInteger(n) ? n : n.toFixed(1)}`;
|
||||
}
|
||||
|
||||
function getTimestamps(): Timestamps {
|
||||
return new Timestamps(sessionStart ?? Date.now());
|
||||
const n = chapter.chapterNumber
|
||||
return `Chapter ${Number.isInteger(n) ? n : n.toFixed(1)}`
|
||||
}
|
||||
|
||||
const BUTTONS = [
|
||||
new Button("GitHub", "https://github.com/Youwes09/Moku"),
|
||||
new Button("Discord", "https://discord.gg/Jq3pwuNqPp"),
|
||||
];
|
||||
{ label: 'GitHub', url: 'https://github.com/Youwes09/Moku' },
|
||||
{ label: 'Discord', url: 'https://discord.gg/Jq3pwuNqPp' },
|
||||
]
|
||||
|
||||
export async function initRpc(): Promise<void> {
|
||||
sessionStart = Date.now();
|
||||
await start(APP_ID).catch(() => {});
|
||||
sessionStart = Date.now()
|
||||
|
||||
unlisten = await listen('discord-rpc://running', ({ payload }) => {
|
||||
if (payload) setIdle().catch(() => {})
|
||||
})
|
||||
|
||||
await connect(APP_ID).catch(() => {})
|
||||
}
|
||||
|
||||
export async function setReading(manga: Manga, chapter: Chapter): Promise<void> {
|
||||
const assets = new Assets()
|
||||
.setLargeImage(resolveCoverImage(manga))
|
||||
.setLargeText(trunc(manga.title))
|
||||
.setSmallImage(FALLBACK_IMAGE)
|
||||
.setSmallText("Moku");
|
||||
|
||||
const activity = new Activity()
|
||||
.setDetails(trunc(manga.title))
|
||||
.setState(`${formatChapter(chapter)} · Reading`)
|
||||
.setAssets(assets)
|
||||
.setTimestamps(getTimestamps());
|
||||
activity.setButton(BUTTONS);
|
||||
|
||||
await setActivity(activity).catch(() => {});
|
||||
await setActivity({
|
||||
details: trunc(manga.title),
|
||||
state: `${formatChapter(chapter)} · Reading`,
|
||||
timestamps: { start: sessionStart ?? Date.now() },
|
||||
assets: {
|
||||
largeImage: resolveCoverImage(manga),
|
||||
largeText: trunc(manga.title),
|
||||
smallImage: FALLBACK_IMAGE,
|
||||
smallText: 'Moku',
|
||||
},
|
||||
buttons: BUTTONS,
|
||||
}).catch(() => {})
|
||||
}
|
||||
|
||||
export async function setIdle(): Promise<void> {
|
||||
const assets = new Assets()
|
||||
.setLargeImage(FALLBACK_IMAGE)
|
||||
.setLargeText("Moku");
|
||||
|
||||
const activity = new Activity()
|
||||
.setDetails("Browsing")
|
||||
.setAssets(assets)
|
||||
.setTimestamps(getTimestamps());
|
||||
activity.setButton(BUTTONS);
|
||||
|
||||
await setActivity(activity).catch(() => {});
|
||||
await setActivity({
|
||||
details: 'Browsing',
|
||||
timestamps: { start: sessionStart ?? Date.now() },
|
||||
assets: {
|
||||
largeImage: FALLBACK_IMAGE,
|
||||
largeText: 'Moku',
|
||||
},
|
||||
buttons: BUTTONS,
|
||||
}).catch(() => {})
|
||||
}
|
||||
|
||||
export async function clearReading(): Promise<void> {
|
||||
await clearActivity().catch(() => {});
|
||||
await clearActivity().catch(() => {})
|
||||
}
|
||||
|
||||
export async function destroyRpc(): Promise<void> {
|
||||
sessionStart = null;
|
||||
await stop().catch(() => {});
|
||||
unlisten?.()
|
||||
unlisten = null
|
||||
sessionStart = null
|
||||
await disconnect().catch(() => {})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user