feat(dtmm): Implement rudimentary update check
The UI for it is rather ugly, still, but it works.
This commit is contained in:
parent
c7203127bb
commit
8edb8b357e
7 changed files with 589 additions and 6 deletions
427
Cargo.lock
generated
427
Cargo.lock
generated
|
@ -130,6 +130,12 @@ version = "0.13.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a"
|
||||
|
||||
[[package]]
|
||||
name = "base64ct"
|
||||
version = "1.6.0"
|
||||
|
@ -832,6 +838,15 @@ dependencies = [
|
|||
"wio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.8.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "endian-type"
|
||||
version = "0.1.2"
|
||||
|
@ -1022,6 +1037,15 @@ version = "0.1.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
|
||||
dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs_extra"
|
||||
version = "1.3.0"
|
||||
|
@ -1374,6 +1398,25 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5be7b54589b581f624f566bf5d8eb2bab1db736c51528720b6bd36b96b55924d"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"http",
|
||||
"indexmap",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
|
@ -1410,6 +1453,87 @@ dependencies = [
|
|||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"itoa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http-body"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httparse"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
|
||||
|
||||
[[package]]
|
||||
name = "httpdate"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "0.14.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
"itoa",
|
||||
"pin-project-lite",
|
||||
"socket2",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-tls"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"hyper",
|
||||
"native-tls",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
|
||||
dependencies = [
|
||||
"unicode-bidi",
|
||||
"unicode-normalization",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "im"
|
||||
version = "15.1.0"
|
||||
|
@ -1517,6 +1641,12 @@ dependencies = [
|
|||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipnet"
|
||||
version = "2.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30e22bd8629359895450b59ea7a776c850561b96a3b1d31321c1949d9e6c9146"
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.4"
|
||||
|
@ -1723,6 +1853,12 @@ dependencies = [
|
|||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
|
@ -1756,6 +1892,41 @@ version = "0.7.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nexusmods"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"lazy_static",
|
||||
"regex",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"time",
|
||||
"tokio",
|
||||
"tracing",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nibble_vec"
|
||||
version = "0.1.0"
|
||||
|
@ -1987,6 +2158,51 @@ version = "0.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.46"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd2523381e46256e40930512c7fd25562b9eae4812cb52078f155e87217c9d1e"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-macros"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "176be2629957c157240f68f61f2d0053ad3a4ecfdd9ebf1e6521d18d9635cf67"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.4.1"
|
||||
|
@ -2093,6 +2309,12 @@ dependencies = [
|
|||
"sha2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.5.6"
|
||||
|
@ -2398,6 +2620,43 @@ version = "0.6.28"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.11.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21eed90ec8570952d53b772ecf8f206aa1ec9a3d76b2521c56c42973f2d91ee9"
|
||||
dependencies = [
|
||||
"base64 0.21.0",
|
||||
"bytes",
|
||||
"encoding_rs",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"hyper-tls",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
"log",
|
||||
"mime",
|
||||
"native-tls",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tower-service",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
"winreg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "resvg"
|
||||
version = "0.25.0"
|
||||
|
@ -2533,6 +2792,15 @@ dependencies = [
|
|||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3"
|
||||
dependencies = [
|
||||
"windows-sys 0.42.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
|
@ -2566,6 +2834,29 @@ dependencies = [
|
|||
"tracing-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a332be01508d814fed64bf28f798a146d73792121129962fdf335bb3c49a4254"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"security-framework-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "self_cell"
|
||||
version = "0.10.2"
|
||||
|
@ -2598,6 +2889,17 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_sjson"
|
||||
version = "1.0.0"
|
||||
|
@ -2607,6 +2909,18 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[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 = "sha1"
|
||||
version = "0.10.5"
|
||||
|
@ -2687,6 +3001,16 @@ version = "1.10.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "steamid-ng"
|
||||
version = "1.0.0"
|
||||
|
@ -2926,6 +3250,21 @@ dependencies = [
|
|||
"displaydoc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
|
||||
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.26.0"
|
||||
|
@ -2940,6 +3279,7 @@ dependencies = [
|
|||
"num_cpus",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"tracing",
|
||||
"windows-sys 0.45.0",
|
||||
|
@ -2956,6 +3296,16 @@ dependencies = [
|
|||
"syn",
|
||||
]
|
||||
|
||||
[[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-stream"
|
||||
version = "0.1.12"
|
||||
|
@ -2967,6 +3317,20 @@ dependencies = [
|
|||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.11"
|
||||
|
@ -2993,6 +3357,12 @@ dependencies = [
|
|||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-service"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.37"
|
||||
|
@ -3076,6 +3446,12 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "try-lock"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
|
||||
|
||||
[[package]]
|
||||
name = "ttf-parser"
|
||||
version = "0.17.1"
|
||||
|
@ -3211,6 +3587,15 @@ version = "1.0.8"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
version = "0.1.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
|
||||
dependencies = [
|
||||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-script"
|
||||
version = "0.5.5"
|
||||
|
@ -3235,13 +3620,25 @@ version = "0.1.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||
|
||||
[[package]]
|
||||
name = "url"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"percent-encoding",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "usvg"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "585bb2d87c8fd6041a479dea01479dcf9094e61b5f9af221606927e61a2bd939"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"base64 0.13.1",
|
||||
"data-url",
|
||||
"flate2",
|
||||
"fontdb",
|
||||
|
@ -3279,6 +3676,12 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
|
||||
|
||||
[[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.1.1"
|
||||
|
@ -3323,6 +3726,16 @@ dependencies = [
|
|||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"try-lock",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
|
@ -3354,6 +3767,18 @@ dependencies = [
|
|||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f219e0d211ba40266969f6dbdd90636da12f75bee4fc9d6c23d1260dadb51454"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.84"
|
||||
|
|
|
@ -34,7 +34,7 @@ pub(crate) async fn import_mod(state: ActionState, info: FileInfo) -> Result<Mod
|
|||
.and_then(NexusApi::parse_file_name)
|
||||
.map(|(_, id, version, updated)| NexusInfo {
|
||||
id,
|
||||
version: Some(version),
|
||||
version,
|
||||
updated,
|
||||
});
|
||||
|
||||
|
@ -367,3 +367,55 @@ pub(crate) fn check_mod_order(state: &ActionState) -> Result<()> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(info, api), fields(id = info.id, name = info.name, version = info.version))]
|
||||
async fn check_mod_update(info: Arc<ModInfo>, api: Arc<NexusApi>) -> Result<Option<ModInfo>> {
|
||||
let Some(nexus) = &info.nexus else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
let updated_info = api
|
||||
.mods_id(nexus.id)
|
||||
.await
|
||||
.wrap_err_with(|| format!("Failed to query mod {} from Nexus", nexus.id))?;
|
||||
|
||||
let updated_nexus = NexusInfo {
|
||||
id: nexus.id,
|
||||
version: updated_info.version,
|
||||
updated: updated_info.updated_timestamp,
|
||||
};
|
||||
|
||||
let mut info = Arc::unwrap_or_clone(info);
|
||||
info.nexus = Some(updated_nexus);
|
||||
|
||||
Ok(Some(info))
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(state))]
|
||||
pub(crate) async fn check_updates(state: ActionState) -> Result<Vec<ModInfo>> {
|
||||
if state.nexus_api_key.is_empty() {
|
||||
eyre::bail!("Nexus API key not set. Cannot check for updates.");
|
||||
}
|
||||
|
||||
let api = NexusApi::new(state.nexus_api_key.to_string())
|
||||
.wrap_err("Failed to initialize Nexus API")?;
|
||||
let api = Arc::new(api);
|
||||
|
||||
let tasks = state
|
||||
.mods
|
||||
.iter()
|
||||
.map(|info| check_mod_update(info.clone(), api.clone()));
|
||||
|
||||
let results = futures::future::join_all(tasks).await;
|
||||
let updates = results
|
||||
.into_iter()
|
||||
.filter_map(|res| match res {
|
||||
Ok(info) => info,
|
||||
Err(err) => {
|
||||
tracing::error!("{:?}", err);
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
Ok(updates)
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ use tokio::sync::RwLock;
|
|||
use crate::controller::app::*;
|
||||
use crate::controller::game::*;
|
||||
use crate::state::AsyncAction;
|
||||
use crate::state::ACTION_FINISH_CHECK_UPDATE;
|
||||
use crate::state::ACTION_FINISH_SAVE_SETTINGS;
|
||||
use crate::state::ACTION_SHOW_ERROR_DIALOG;
|
||||
use crate::state::{
|
||||
|
@ -120,6 +121,29 @@ async fn handle_action(
|
|||
.submit_command(ACTION_FINISH_SAVE_SETTINGS, (), Target::Auto)
|
||||
.expect("failed to send command");
|
||||
}),
|
||||
AsyncAction::CheckUpdates(state) => tokio::spawn(async move {
|
||||
let updates = match check_updates(state)
|
||||
.await
|
||||
.wrap_err("Failed to check for updates")
|
||||
{
|
||||
Ok(updates) => updates,
|
||||
Err(err) => {
|
||||
tracing::error!("{:?}", err);
|
||||
send_error(event_sink.clone(), err).await;
|
||||
vec![]
|
||||
}
|
||||
};
|
||||
|
||||
event_sink
|
||||
.write()
|
||||
.await
|
||||
.submit_command(
|
||||
ACTION_FINISH_CHECK_UPDATE,
|
||||
SingleUse::new(updates),
|
||||
Target::Auto,
|
||||
)
|
||||
.expect("failed to send command");
|
||||
}),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#![recursion_limit = "256"]
|
||||
#![feature(let_chains)]
|
||||
#![feature(arc_unwrap_or_clone)]
|
||||
#![windows_subsystem = "windows"]
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
|
|
@ -73,7 +73,7 @@ impl From<dtmt_shared::ModDependency> for ModDependency {
|
|||
#[derive(Clone, Data, Debug, Lens, serde::Serialize, serde::Deserialize)]
|
||||
pub(crate) struct NexusInfo {
|
||||
pub id: u64,
|
||||
pub version: Option<String>,
|
||||
pub version: String,
|
||||
#[data(ignore)]
|
||||
#[serde(with = "time::serde::timestamp")]
|
||||
pub updated: OffsetDateTime,
|
||||
|
@ -97,6 +97,7 @@ pub(crate) struct ModInfo {
|
|||
#[data(ignore)]
|
||||
pub resources: ModResourceInfo,
|
||||
pub depends: Vector<ModDependency>,
|
||||
#[data(ignore)]
|
||||
pub nexus: Option<NexusInfo>,
|
||||
}
|
||||
|
||||
|
@ -139,6 +140,7 @@ pub(crate) struct State {
|
|||
pub is_reset_in_progress: bool,
|
||||
pub is_save_in_progress: bool,
|
||||
pub is_next_save_pending: bool,
|
||||
pub is_update_in_progress: bool,
|
||||
pub game_dir: Arc<PathBuf>,
|
||||
pub data_dir: Arc<PathBuf>,
|
||||
pub nexus_api_key: Arc<String>,
|
||||
|
@ -177,6 +179,7 @@ impl State {
|
|||
is_reset_in_progress: false,
|
||||
is_save_in_progress: false,
|
||||
is_next_save_pending: false,
|
||||
is_update_in_progress: false,
|
||||
config_path: Arc::new(config_path),
|
||||
game_dir: Arc::new(game_dir),
|
||||
data_dir: Arc::new(data_dir),
|
||||
|
|
|
@ -39,6 +39,11 @@ pub(crate) const ACTION_START_SAVE_SETTINGS: Selector =
|
|||
pub(crate) const ACTION_FINISH_SAVE_SETTINGS: Selector =
|
||||
Selector::new("dtmm.action.finish-save-settings");
|
||||
|
||||
pub(crate) const ACTION_START_CHECK_UPDATE: Selector =
|
||||
Selector::new("dtmm.action.start-check-update");
|
||||
pub(crate) const ACTION_FINISH_CHECK_UPDATE: Selector<SingleUse<Vec<ModInfo>>> =
|
||||
Selector::new("dtmm.action.finish-check-update");
|
||||
|
||||
pub(crate) const ACTION_SET_DIRTY: Selector = Selector::new("dtmm.action.set-dirty");
|
||||
|
||||
pub(crate) const ACTION_SHOW_ERROR_DIALOG: Selector<SingleUse<Report>> =
|
||||
|
@ -79,6 +84,7 @@ pub(crate) enum AsyncAction {
|
|||
AddMod(ActionState, FileInfo),
|
||||
DeleteMod(ActionState, Arc<ModInfo>),
|
||||
SaveSettings(ActionState),
|
||||
CheckUpdates(ActionState),
|
||||
}
|
||||
|
||||
pub(crate) struct Delegate {
|
||||
|
@ -304,6 +310,50 @@ impl AppDelegate<State> for Delegate {
|
|||
state.windows.insert(id, handle);
|
||||
Handled::Yes
|
||||
}
|
||||
cmd if cmd.is(ACTION_START_CHECK_UPDATE) => {
|
||||
if self
|
||||
.sender
|
||||
.send(AsyncAction::CheckUpdates(state.clone().into()))
|
||||
.is_ok()
|
||||
{
|
||||
state.is_update_in_progress = true;
|
||||
} else {
|
||||
tracing::error!("Failed to queue action to check updates");
|
||||
}
|
||||
Handled::Yes
|
||||
}
|
||||
cmd if cmd.is(ACTION_FINISH_CHECK_UPDATE) => {
|
||||
let mut updates = cmd
|
||||
.get(ACTION_FINISH_CHECK_UPDATE)
|
||||
.and_then(SingleUse::take)
|
||||
.expect("command type matched but didn't contain the expected value");
|
||||
|
||||
if tracing::enabled!(tracing::Level::DEBUG) {
|
||||
let mods: Vec<_> = updates
|
||||
.iter()
|
||||
.map(|info| {
|
||||
format!(
|
||||
"{}: {} -> {:?}",
|
||||
info.name,
|
||||
info.version,
|
||||
info.nexus.as_ref().map(|n| &n.version)
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
tracing::info!("Mod updates:\n{}", mods.join("\n"));
|
||||
}
|
||||
|
||||
for mod_info in state.mods.iter_mut() {
|
||||
if let Some(index) = updates.iter().position(|i2| i2.id == mod_info.id) {
|
||||
let update = updates.swap_remove(index);
|
||||
*mod_info = Arc::new(update);
|
||||
}
|
||||
}
|
||||
|
||||
state.is_update_in_progress = false;
|
||||
Handled::Yes
|
||||
}
|
||||
cmd => {
|
||||
if cfg!(debug_assertions) {
|
||||
tracing::warn!("Unknown command: {:?}", cmd);
|
||||
|
|
|
@ -15,8 +15,8 @@ use lazy_static::lazy_static;
|
|||
|
||||
use crate::state::{
|
||||
ModInfo, State, View, ACTION_ADD_MOD, ACTION_SELECTED_MOD_DOWN, ACTION_SELECTED_MOD_UP,
|
||||
ACTION_SELECT_MOD, ACTION_SET_WINDOW_HANDLE, ACTION_START_DELETE_SELECTED_MOD,
|
||||
ACTION_START_DEPLOY, ACTION_START_RESET_DEPLOYMENT,
|
||||
ACTION_SELECT_MOD, ACTION_SET_WINDOW_HANDLE, ACTION_START_CHECK_UPDATE,
|
||||
ACTION_START_DELETE_SELECTED_MOD, ACTION_START_DEPLOY, ACTION_START_RESET_DEPLOYMENT,
|
||||
};
|
||||
use crate::ui::theme::{self, ColorExt};
|
||||
use crate::ui::widget::border::Border;
|
||||
|
@ -49,6 +49,12 @@ fn build_top_bar() -> impl Widget<State> {
|
|||
state.current_view = View::Settings;
|
||||
});
|
||||
|
||||
let check_update_button = Button::with_label("Check for updates")
|
||||
.on_click(|ctx, _: &mut State, _| {
|
||||
ctx.submit_command(ACTION_START_CHECK_UPDATE);
|
||||
})
|
||||
.disabled_if(|data, _| data.is_update_in_progress);
|
||||
|
||||
let deploy_button = {
|
||||
let icon = Svg::new(SvgData::from_str(theme::icons::ALERT_CIRCLE).expect("invalid SVG"))
|
||||
.fix_height(druid::theme::TEXT_SIZE_NORMAL);
|
||||
|
@ -85,6 +91,8 @@ fn build_top_bar() -> impl Widget<State> {
|
|||
)
|
||||
.with_child(
|
||||
Flex::row()
|
||||
.with_child(check_update_button)
|
||||
.with_default_spacer()
|
||||
.with_child(deploy_button)
|
||||
.with_default_spacer()
|
||||
.with_child(reset_button),
|
||||
|
@ -118,10 +126,30 @@ fn build_mod_list() -> impl Widget<State> {
|
|||
let name =
|
||||
Label::raw().lens(lens!((usize, Arc<ModInfo>, bool), 1).then(ModInfo::name.in_arc()));
|
||||
|
||||
let version = Label::dynamic(|info: &Arc<ModInfo>, _| {
|
||||
let has_update = info
|
||||
.nexus
|
||||
.as_ref()
|
||||
.map(|n| info.version != n.version)
|
||||
.unwrap_or(false);
|
||||
if has_update {
|
||||
format!("! {}", info.version)
|
||||
} else {
|
||||
info.version.to_string()
|
||||
}
|
||||
})
|
||||
.lens(lens!((usize, Arc<ModInfo>, bool), 1));
|
||||
|
||||
let fields = Flex::row()
|
||||
.must_fill_main_axis(true)
|
||||
.main_axis_alignment(MainAxisAlignment::SpaceBetween)
|
||||
.with_child(name)
|
||||
.with_child(version);
|
||||
|
||||
Flex::row()
|
||||
.must_fill_main_axis(true)
|
||||
.with_child(checkbox)
|
||||
.with_child(name)
|
||||
.with_flex_child(fields, 1.)
|
||||
.padding((5.0, 4.0))
|
||||
.background(theme::keys::KEY_MOD_LIST_ITEM_BG_COLOR)
|
||||
.on_click(|ctx, (i, _, _), _env| ctx.submit_command(ACTION_SELECT_MOD.with(*i)))
|
||||
|
|
Loading…
Add table
Reference in a new issue