diff --git a/Cargo.lock b/Cargo.lock index cdbfaac..6432133 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -87,9 +87,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base64" @@ -124,12 +124,6 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" -[[package]] -name = "bumpalo" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad807f2fc2bf185eeb98ff3a901bd46dc5ad58163d0fa4577ba0d25674d71708" - [[package]] name = "bumpalo" version = "3.9.1" @@ -265,15 +259,6 @@ dependencies = [ "x11rb", ] -[[package]] -name = "cmake" -version = "0.1.48" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8ad8cef104ac57b68b89df3208164d228503abbdce70f6880ffa3d970e7443a" -dependencies = [ - "cc", -] - [[package]] name = "cocoa" version = "0.24.0" @@ -283,7 +268,7 @@ dependencies = [ "bitflags", "block", "cocoa-foundation", - "core-foundation 0.9.2", + "core-foundation 0.9.3", "core-graphics 0.22.3", "foreign-types", "libc", @@ -298,7 +283,7 @@ checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" dependencies = [ "bitflags", "block", - "core-foundation 0.9.2", + "core-foundation 0.9.3", "core-graphics-types", "foreign-types", "libc", @@ -344,9 +329,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" dependencies = [ "core-foundation-sys 0.8.3", "libc", @@ -383,7 +368,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" dependencies = [ "bitflags", - "core-foundation 0.9.2", + "core-foundation 0.9.3", "core-graphics-types", "foreign-types", "libc", @@ -396,19 +381,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" dependencies = [ "bitflags", - "core-foundation 0.9.2", - "foreign-types", - "libc", -] - -[[package]] -name = "core-text" -version = "19.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d74ada66e07c1cefa18f8abfba765b486f250de2e4a999e5727fc0dd4b4a25" -dependencies = [ - "core-foundation 0.9.2", - "core-graphics 0.22.3", + "core-foundation 0.9.3", "foreign-types", "libc", ] @@ -428,9 +401,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.3.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2209c310e29876f7f0b2721e7e26b84aff178aa3da5d091f9bfbf47669e60e3" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if 1.0.0", ] @@ -458,9 +431,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.6" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97242a70df9b89a65d0b6df3c4bf5b9ce03c5b7309019777fbde37e7537f8762" +checksum = "c00d6d2ea26e8b151d99093005cb442fb9a37aeaca582a03ec70946f49ab5ed9" dependencies = [ "cfg-if 1.0.0", "crossbeam-utils", @@ -471,9 +444,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcae03edb34f947e64acdb1c33ec169824e20657e9ecb61cef6c8c74dcb8120" +checksum = "b5e5bed1f1c269533fa816a0a5492b3545209a205ca1a54842be180eb63a16a6" dependencies = [ "cfg-if 1.0.0", "lazy_static", @@ -540,16 +513,6 @@ dependencies = [ "dirs-sys", ] -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if 1.0.0", - "dirs-sys-next", -] - [[package]] name = "dirs-sys" version = "0.3.6" @@ -561,17 +524,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - [[package]] name = "dispatch" version = "0.2.0" @@ -587,40 +539,12 @@ dependencies = [ "libloading", ] -[[package]] -name = "dodrio" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7593dfc68e57dc1d058ada0f151ba07f4b05183c4da4c4df8ff651a81ef0fab" -dependencies = [ - "bumpalo 2.6.0", - "cfg-if 0.1.10", - "fxhash", - "js-sys", - "longest-increasing-subsequence", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - [[package]] name = "downcast-rs" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" -[[package]] -name = "dwrote" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439a1c2ba5611ad3ed731280541d36d2e9c4ac5e7fb818a27b604bdc5a6aa65b" -dependencies = [ - "lazy_static", - "libc", - "winapi", - "wio", -] - [[package]] name = "either" version = "1.6.1" @@ -646,16 +570,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "expat-sys" -version = "2.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658f19728920138342f68408b7cf7644d90d4784353d8ebc32e7e8663dbe45fa" -dependencies = [ - "cmake", - "pkg-config", -] - [[package]] name = "fern" version = "0.6.0" @@ -666,6 +580,18 @@ dependencies = [ "log", ] +[[package]] +name = "filetime" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall", + "winapi", +] + [[package]] name = "flate2" version = "1.0.22" @@ -678,43 +604,12 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "float-ord" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bad48618fdb549078c333a7a8528acb57af271d0433bdecd523eb620628364e" - [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "font-kit" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c9a156ec38864999bc9c4156e5f3b50224d4a5578028a64e5a3875caa9ee28" -dependencies = [ - "bitflags", - "byteorder", - "core-foundation 0.9.2", - "core-graphics 0.22.3", - "core-text", - "dirs-next", - "dwrote", - "float-ord", - "freetype", - "lazy_static", - "libc", - "log", - "pathfinder_geometry", - "pathfinder_simd", - "servo-fontconfig", - "walkdir", - "winapi", -] - [[package]] name = "foreign-types" version = "0.3.2" @@ -740,32 +635,11 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "freetype" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee38378a9e3db1cc693b4f88d166ae375338a0ff75cb8263e1c601d51f35dc6" -dependencies = [ - "freetype-sys", - "libc", -] - -[[package]] -name = "freetype-sys" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a37d4011c0cc628dfa766fcc195454f4b068d7afdc2adfd28861191d866e731a" -dependencies = [ - "cmake", - "libc", - "pkg-config", -] - [[package]] name = "futures" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28560757fe2bb34e79f907794bb6b22ae8b0e5c669b638a1132f2592b19035b4" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" dependencies = [ "futures-channel", "futures-core", @@ -778,9 +652,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" dependencies = [ "futures-core", "futures-sink", @@ -788,15 +662,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" [[package]] name = "futures-executor" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29d6d2ff5bb10fb95c85b8ce46538a2e5f5e7fdc755623a7d4529ab8a4ed9d2a" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" dependencies = [ "futures-core", "futures-task", @@ -806,15 +680,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2" +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" [[package]] name = "futures-macro" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" dependencies = [ "proc-macro2", "quote", @@ -823,21 +697,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" [[package]] name = "futures-task" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" [[package]] name = "futures-util" -version = "0.3.19" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ "futures-channel", "futures-core", @@ -933,7 +807,7 @@ dependencies = [ "android_glue", "cgl", "cocoa", - "core-foundation 0.9.2", + "core-foundation 0.9.3", "glutin_egl_sys", "glutin_emscripten_sys", "glutin_gles2_sys", @@ -1106,13 +980,12 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" [[package]] name = "iced" version = "0.3.0" -source = "git+https://github.com/hecrj/iced.git#c75ed37148b019358b0297171cf31b2577eeb9ae" +source = "git+https://github.com/hecrj/iced.git#313aff573433d9a4bc750285104c069fca0a566c" dependencies = [ "iced_core", "iced_futures", "iced_glow", "iced_glutin", - "iced_web", "iced_wgpu", "iced_winit", "thiserror", @@ -1121,25 +994,27 @@ dependencies = [ [[package]] name = "iced_core" version = "0.4.0" -source = "git+https://github.com/hecrj/iced.git#c75ed37148b019358b0297171cf31b2577eeb9ae" +source = "git+https://github.com/hecrj/iced.git#313aff573433d9a4bc750285104c069fca0a566c" dependencies = [ "bitflags", + "wasm-timer", ] [[package]] name = "iced_futures" version = "0.3.0" -source = "git+https://github.com/hecrj/iced.git#c75ed37148b019358b0297171cf31b2577eeb9ae" +source = "git+https://github.com/hecrj/iced.git#313aff573433d9a4bc750285104c069fca0a566c" dependencies = [ "futures", "log", "wasm-bindgen-futures", + "wasm-timer", ] [[package]] name = "iced_glow" version = "0.2.0" -source = "git+https://github.com/hecrj/iced.git#c75ed37148b019358b0297171cf31b2577eeb9ae" +source = "git+https://github.com/hecrj/iced.git#313aff573433d9a4bc750285104c069fca0a566c" dependencies = [ "bytemuck", "euclid", @@ -1154,7 +1029,7 @@ dependencies = [ [[package]] name = "iced_glutin" version = "0.2.0" -source = "git+https://github.com/hecrj/iced.git#c75ed37148b019358b0297171cf31b2577eeb9ae" +source = "git+https://github.com/hecrj/iced.git#313aff573433d9a4bc750285104c069fca0a566c" dependencies = [ "glutin", "iced_graphics", @@ -1165,10 +1040,9 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.2.0" -source = "git+https://github.com/hecrj/iced.git#c75ed37148b019358b0297171cf31b2577eeb9ae" +source = "git+https://github.com/hecrj/iced.git#313aff573433d9a4bc750285104c069fca0a566c" dependencies = [ "bytemuck", - "font-kit", "glam", "iced_native", "iced_style", @@ -1179,7 +1053,7 @@ dependencies = [ [[package]] name = "iced_native" version = "0.4.0" -source = "git+https://github.com/hecrj/iced.git#c75ed37148b019358b0297171cf31b2577eeb9ae" +source = "git+https://github.com/hecrj/iced.git#313aff573433d9a4bc750285104c069fca0a566c" dependencies = [ "iced_core", "iced_futures", @@ -1192,32 +1066,15 @@ dependencies = [ [[package]] name = "iced_style" version = "0.3.0" -source = "git+https://github.com/hecrj/iced.git#c75ed37148b019358b0297171cf31b2577eeb9ae" +source = "git+https://github.com/hecrj/iced.git#313aff573433d9a4bc750285104c069fca0a566c" dependencies = [ "iced_core", ] -[[package]] -name = "iced_web" -version = "0.4.0" -source = "git+https://github.com/hecrj/iced.git#c75ed37148b019358b0297171cf31b2577eeb9ae" -dependencies = [ - "base64", - "dodrio", - "iced_core", - "iced_futures", - "iced_style", - "num-traits", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - [[package]] name = "iced_wgpu" version = "0.4.0" -source = "git+https://github.com/hecrj/iced.git#c75ed37148b019358b0297171cf31b2577eeb9ae" +source = "git+https://github.com/hecrj/iced.git#313aff573433d9a4bc750285104c069fca0a566c" dependencies = [ "bitflags", "bytemuck", @@ -1236,13 +1093,14 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.3.0" -source = "git+https://github.com/hecrj/iced.git#c75ed37148b019358b0297171cf31b2577eeb9ae" +source = "git+https://github.com/hecrj/iced.git#313aff573433d9a4bc750285104c069fca0a566c" dependencies = [ "iced_futures", "iced_graphics", "iced_native", "log", "thiserror", + "web-sys", "winapi", "window_clipboard", "winit", @@ -1347,9 +1205,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.116" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "565dbd88872dbe4cc8a46e527f26483c1d1f7afa6b884a3bd6cd893d4f98da74" +checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c" [[package]] name = "libloading" @@ -1385,12 +1243,6 @@ dependencies = [ "cfg-if 1.0.0", ] -[[package]] -name = "longest-increasing-subsequence" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3bd0dd2cd90571056fdb71f6275fada10131182f84899f4b2a916e565d81d86" - [[package]] name = "malloc_buf" version = "0.0.6" @@ -1744,40 +1596,12 @@ dependencies = [ "winapi", ] -[[package]] -name = "pathfinder_geometry" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b7e7b4ea703700ce73ebf128e1450eb69c3a8329199ffbfb9b2a0418e5ad3" -dependencies = [ - "log", - "pathfinder_simd", -] - -[[package]] -name = "pathfinder_simd" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39fe46acc5503595e5949c17b818714d26fdf9b4920eacf3b2947f0199f4a6ff" -dependencies = [ - "rustc_version", -] - [[package]] name = "percent-encoding" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" -[[package]] -name = "pest" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" -dependencies = [ - "ucd-trie", -] - [[package]] name = "pin-project-lite" version = "0.2.8" @@ -1968,6 +1792,15 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1382d1f0a252c4bf97dc20d979a2fdd05b024acd7c2ed0f7595d7817666a157" +[[package]] +name = "retry" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac95c60a949a63fd2822f4964939662d8f2c16c4fa0624fd954bc6e703b9a3f6" +dependencies = [ + "rand", +] + [[package]] name = "ring" version = "0.16.20" @@ -1989,15 +1822,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" -[[package]] -name = "rustc_version" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" -dependencies = [ - "semver", -] - [[package]] name = "rustls" version = "0.20.2" @@ -2016,15 +1840,6 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - [[package]] name = "scoped-tls" version = "1.0.0" @@ -2047,24 +1862,6 @@ dependencies = [ "untrusted", ] -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] - [[package]] name = "serde" version = "1.0.136" @@ -2096,27 +1893,6 @@ dependencies = [ "serde", ] -[[package]] -name = "servo-fontconfig" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e3e22fe5fd73d04ebf0daa049d3efe3eae55369ce38ab16d07ddd9ac5c217c" -dependencies = [ - "libc", - "servo-fontconfig-sys", -] - -[[package]] -name = "servo-fontconfig-sys" -version = "5.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36b879db9892dfa40f95da1c38a835d41634b825fbd8c4c418093d53c24b388" -dependencies = [ - "expat-sys", - "freetype-sys", - "pkg-config", -] - [[package]] name = "shared_library" version = "0.1.9" @@ -2256,6 +2032,17 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "tar" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" +dependencies = [ + "filetime", + "libc", + "xattr", +] + [[package]] name = "termcolor" version = "1.1.2" @@ -2338,27 +2125,24 @@ dependencies = [ [[package]] name = "uad_gui" -version = "0.4.1" +version = "0.3.1" dependencies = [ "chrono", "dirs", "fern", + "flate2", "iced", "log", "regex", + "retry", "serde", "serde_json", "static_init", + "tar", "toml", "ureq", ] -[[package]] -name = "ucd-trie" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" - [[package]] name = "unicode-bidi" version = "0.3.7" @@ -2376,9 +2160,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" +checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" [[package]] name = "unicode-width" @@ -2435,17 +2219,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "walkdir" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" -dependencies = [ - "same-file", - "winapi", - "winapi-util", -] - [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" @@ -2468,7 +2241,7 @@ version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" dependencies = [ - "bumpalo 3.9.1", + "bumpalo", "lazy_static", "log", "proc-macro2", @@ -2518,6 +2291,21 @@ version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" +[[package]] +name = "wasm-timer" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" +dependencies = [ + "futures", + "js-sys", + "parking_lot", + "pin-utils", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "wayland-client" version = "0.29.4" @@ -2794,7 +2582,7 @@ source = "git+https://github.com/iced-rs/winit?rev=02a12380960cec2f351c09a33d6a7 dependencies = [ "bitflags", "cocoa", - "core-foundation 0.9.2", + "core-foundation 0.9.3", "core-graphics 0.22.3", "core-video-sys", "dispatch", @@ -2819,15 +2607,6 @@ dependencies = [ "x11-dl", ] -[[package]] -name = "wio" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5" -dependencies = [ - "winapi", -] - [[package]] name = "x11-dl" version = "2.19.1" @@ -2851,6 +2630,15 @@ dependencies = [ "winapi-wsapoll", ] +[[package]] +name = "xattr" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" +dependencies = [ + "libc", +] + [[package]] name = "xcursor" version = "0.3.4" diff --git a/Cargo.toml b/Cargo.toml index 43e8528..c8e10a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,9 +12,11 @@ categories = ["gui"] edition = "2021" [features] -default = ["wgpu"] +default = ["wgpu", "self-update"] wgpu = [] # iced/wgpu is default glow = ["iced/glow"] # OpenGL support +self-update = ["flate2", "tar", "retry"] +no-self-update = [] [dependencies] iced = { git = "https://github.com/hecrj/iced.git" } @@ -28,6 +30,11 @@ regex = "^1.5" toml = "^0" dirs = "^4.0" ureq = { version = "*", features = ["json"] } +retry = { version = "^1.0", optional = true } + +[target.'cfg(not(target_os = "windows"))'.dependencies] +flate2 = { version = "^1", optional = true } +tar = { version = "^0", optional = true } [profile.release] opt-level = "s" diff --git a/src/core/mod.rs b/src/core/mod.rs index 129c7bf..d59e9c3 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -2,4 +2,5 @@ pub mod config; pub mod sync; pub mod theme; pub mod uad_lists; +pub mod update; pub mod utils; diff --git a/src/core/update.rs b/src/core/update.rs new file mode 100644 index 0000000..391bd3d --- /dev/null +++ b/src/core/update.rs @@ -0,0 +1,297 @@ +use serde::Deserialize; + +#[cfg(feature = "self-update")] +use { + retry::{delay::Fibonacci, retry, OperationResult}, + std::fs, + std::io, + std::io::copy, + std::path::Path, + std::path::PathBuf, +}; + +#[derive(Debug, Deserialize, Clone)] +pub struct Release { + pub tag_name: String, + pub assets: Vec, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct ReleaseAsset { + pub name: String, + #[serde(rename = "browser_download_url")] + pub download_url: String, +} + +#[derive(Default, Debug, Clone)] +pub struct SelfUpdateState { + pub latest_release: Option, + pub status: SelfUpdateStatus, +} + +#[derive(Debug, PartialEq, Clone)] +pub enum SelfUpdateStatus { + Updating, + Checking, + Done, + Failed, +} + +impl Default for SelfUpdateStatus { + fn default() -> Self { + SelfUpdateStatus::Checking + } +} + +impl std::fmt::Display for SelfUpdateStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let s = match self { + SelfUpdateStatus::Checking => "Checking updates...", + SelfUpdateStatus::Updating => "Updating...", + SelfUpdateStatus::Failed => "Failed to check update!", + SelfUpdateStatus::Done => "Done", + }; + write!(f, "{}", s) + } +} + +/// Download a file from the internet +#[cfg(feature = "self-update")] +pub async fn download_file(url: T, dest_file: PathBuf) -> Result<(), String> { + let url = url.to_string(); + debug!("downloading file from {}", &url); + + match ureq::get(&url).call() { + Ok(res) => { + let mut file = fs::File::create(&dest_file).unwrap(); + + if let Err(e) = copy(&mut res.into_reader(), &mut file) { + return Err(e.to_string()); + } + } + Err(e) => return Err(e.to_string()), + } + Ok(()) +} + +/// Downloads the latest release file that matches `bin_name`, renames the current +/// executable to a temp path, renames the new version as the original file name, +/// then returns both the original file name (new version) and temp path (old version) +#[cfg(feature = "self-update")] +pub async fn download_update_to_temp_file( + bin_name: String, + release: Release, +) -> Result<(PathBuf, PathBuf), ()> { + let current_bin_path = std::env::current_exe().unwrap(); + + // Path to download the new version to + let download_path = current_bin_path + .parent() + .unwrap() + .join(&format!("tmp_{}", bin_name)); + + // Path to temporarily force rename current process to, se we can then + // rename `download_path` to `current_bin_path` and then launch new version + // cleanly as `current_bin_path` + let tmp_path = current_bin_path + .parent() + .unwrap() + .join(&format!("tmp2_{}", bin_name)); + + // MacOS and Linux release are gziped tarball + #[cfg(not(target_os = "windows"))] + { + let asset_name = format!("{}.tar.gz", bin_name); + + let asset = release + .assets + .iter() + .find(|a| a.name == asset_name) + .cloned() + .unwrap(); + + let archive_path = current_bin_path.parent().unwrap().join(&asset_name); + + if let Err(e) = download_file(asset.download_url, archive_path.clone()).await { + error!("Couldn't download UAD update: {}", e); + return Err(()); + } + if extract_binary_from_tar(&archive_path, &download_path).is_err() { + error!("Couldn't extract UAD release tarball"); + return Err(()); + } + + std::fs::remove_file(&archive_path).unwrap(); + } + + // For Windows we download the new binary directly + #[cfg(target_os = "windows")] + { + let asset = release + .assets + .iter() + .find(|a| a.name == bin_name) + .cloned() + .unwrap(); + + if let Err(e) = download_file(asset.download_url, download_path.clone()).await { + error!("Couldn't download UAD update: {}", e); + return Err(()); + } + } + + // Make the file executable + #[cfg(not(target_os = "windows"))] + { + use std::os::unix::fs::PermissionsExt; + + let mut permissions = fs::metadata(&download_path).unwrap().permissions(); + permissions.set_mode(0o755); + if let Err(e) = fs::set_permissions(&download_path, permissions) { + error!("[SelfUpdate] Couldn't set permission to temp file: {}", e); + return Err(()); + } + } + + if let Err(e) = rename(¤t_bin_path, &tmp_path) { + error!("[SelfUpdate] Couldn't rename binary path: {}", e); + return Err(()); + } + if let Err(e) = rename(&download_path, ¤t_bin_path) { + error!("[SelfUpdate] Couldn't rename binary path: {}", e); + return Err(()); + } + + Ok((current_bin_path, tmp_path)) +} + +#[cfg(not(feature = "self-update"))] +pub fn get_latest_release() -> Result, ()> { + Ok(None) +} + +// UAD only has pre-releases so we can't use +// https://api.github.com/repos/0x192/universal-android-debloater/releases/latest +// to only get the latest release +#[cfg(feature = "self-update")] +pub fn get_latest_release() -> Result, ()> { + debug!("Checking for UAD update"); + + match ureq::get("https://api.github.com/repos/0x192/universal-android-debloater/releases") + .call() + { + Ok(res) => { + let release: Release = + serde_json::from_value(res.into_json::().unwrap()[0].clone()) + .unwrap(); + if release.tag_name.as_str() > env!("CARGO_PKG_VERSION") { + Ok(Some(release)) + } else { + Ok(None) + } + } + Err(_) => { + debug!("Failed to check UAD update"); + Err(()) + } + } +} + +/// Extracts the binary from a `tar.gz` archive to temp_file path +#[cfg(feature = "self-update")] +#[cfg(not(target_os = "windows"))] +pub fn extract_binary_from_tar(archive_path: &Path, temp_file: &Path) -> Result<(), ()> { + use flate2::read::GzDecoder; + use std::fs::File; + use tar::Archive; + let mut archive = Archive::new(GzDecoder::new(File::open(&archive_path).unwrap())); + + let mut temp_file = File::create(temp_file).unwrap(); + + for file in archive.entries().unwrap() { + let mut file = file.unwrap(); + + let path = file.path().unwrap(); + if path.to_str().is_some() { + io::copy(&mut file, &mut temp_file).unwrap(); + return Ok(()); + } + } + + Err(()) +} + +/// Hardcoded binary names for each compilation target +/// that gets published to the Github Release +#[cfg(feature = "self-update")] +pub const fn bin_name() -> &'static str { + #[cfg(target_os = "windows")] + { + "uad_gui.exe" + } + + #[cfg(target_os = "macos")] + { + "uad_gui-macos" + } + + #[cfg(not(any(target_os = "macos", target_os = "windows")))] + { + "uad_gui-linux" + } +} + +/// Rename a file or directory to a new name, retrying if the operation fails because of permissions +/// +/// Will retry for ~30 seconds with longer and longer delays between each, to allow for virus scan +/// and other automated operations to complete. +#[cfg(feature = "self-update")] +pub fn rename(from: F, to: T) -> Result<(), String> +where + F: AsRef, + T: AsRef, +{ + // 21 Fibonacci steps starting at 1 ms is ~28 seconds total + // See https://github.com/rust-lang/rustup/pull/1873 where this was used by Rustup to work around + // virus scanning file locks + let from = from.as_ref(); + let to = to.as_ref(); + + retry(Fibonacci::from_millis(1).take(21), || { + match fs::rename(from, to) { + Ok(_) => OperationResult::Ok(()), + Err(e) => match e.kind() { + io::ErrorKind::PermissionDenied => OperationResult::Retry(e), + _ => OperationResult::Err(e), + }, + } + }) + .map_err(|e| e.to_string()) +} + +/// Remove a file, retrying if the operation fails because of permissions +/// +/// Will retry for ~30 seconds with longer and longer delays between each, to allow for virus scan +/// and other automated operations to complete. +#[cfg(feature = "self-update")] +pub fn remove_file

(path: P) -> Result<(), String> +where + P: AsRef, +{ + // 21 Fibonacci steps starting at 1 ms is ~28 seconds total + // See https://github.com/rust-lang/rustup/pull/1873 where this was used by Rustup to work around + // virus scanning file locks + let path = path.as_ref(); + + retry( + Fibonacci::from_millis(1).take(21), + || match fs::remove_file(path) { + Ok(_) => OperationResult::Ok(()), + Err(e) => match e.kind() { + io::ErrorKind::PermissionDenied => OperationResult::Retry(e), + _ => OperationResult::Err(e), + }, + }, + ) + .map_err(|e| e.to_string()) +} diff --git a/src/gui/mod.rs b/src/gui/mod.rs index 9569d16..9de07f5 100644 --- a/src/gui/mod.rs +++ b/src/gui/mod.rs @@ -5,6 +5,7 @@ pub mod widgets; pub use crate::core::sync::{get_device_list, Phone}; use crate::core::uad_lists::load_debloat_lists; pub use crate::core::uad_lists::Package; +use crate::core::update::{get_latest_release, SelfUpdateState, SelfUpdateStatus}; use crate::core::utils::icon; use iced::{ button, pick_list, window::Settings as Window, Alignment, Application, Button, Column, Command, @@ -12,6 +13,7 @@ use iced::{ }; use std::collections::HashMap; use std::env; +use std::path::PathBuf; pub use views::about::{About as AboutView, Message as AboutMessage}; pub use views::list::{ List as AppsView, LoadingState as ListLoadingState, Message as AppsMessage, State as ListState, @@ -25,6 +27,9 @@ pub const ICONS: Font = Font::External { bytes: include_bytes!("../../resources/assets/icons.ttf"), }; +#[cfg(feature = "self-update")] +use crate::core::update::{bin_name, download_update_to_temp_file, remove_file}; + #[derive(Debug, Clone)] pub enum View { List, @@ -68,6 +73,7 @@ pub enum Message { UadListsDownloaded(HashMap), InitList, InitDevice(Vec), + _NewReleaseDownloaded(Result<(PathBuf, PathBuf), ()>), } impl Application for UadGui { @@ -81,6 +87,7 @@ impl Application for UadGui { Command::batch([ Command::perform(Self::download_uad_list(), |_| Message::InitList), Command::perform(get_device_list(), Message::InitDevice), + Command::perform(Self::send_self_update_message(), Message::SettingsAction), ]), ) } @@ -153,7 +160,8 @@ impl Application for UadGui { } Message::AboutPressed => { self.view = View::About; - Command::none() + self.settings_view.self_update_state = SelfUpdateState::default(); + Command::perform(Self::send_self_update_message(), Message::SettingsAction) } Message::SettingsPressed => { self.view = View::Settings; @@ -179,6 +187,36 @@ impl Application for UadGui { AboutMessage::UpdateUadLists => { Command::perform(Self::download_uad_list(), |_| Message::InitList) } + AboutMessage::DoSelfUpdate => { + #[cfg(feature = "self-update")] + if self + .settings_view + .self_update_state + .latest_release + .is_some() + { + self.settings_view.self_update_state.status = + SelfUpdateStatus::Updating; + self.apps_view.state = + ListState::Loading(ListLoadingState::_UpdatingUad); + let bin_name = bin_name().to_owned(); + let release = self + .settings_view + .self_update_state + .latest_release + .as_ref() + .unwrap() + .clone(); + Command::perform( + download_update_to_temp_file(bin_name, release), + Message::_NewReleaseDownloaded, + ) + } else { + Command::none() + } + #[cfg(not(feature = "self-update"))] + Command::none() + } _ => Command::none(), } } @@ -190,21 +228,93 @@ impl Application for UadGui { Message::AppsAction, ) } + Message::_NewReleaseDownloaded(_res) => { + debug!("UAD update has been download!"); + + #[cfg(feature = "self-update")] + match _res { + Ok((relaunch_path, cleanup_path)) => { + // Remove first arg, which is path to binary. We don't use this first + // arg as binary path because it's not reliable, per the docs. + let mut args = std::env::args(); + args.next(); + let mut args: Vec<_> = args.collect(); + + // Remove the `--self-update-temp` arg from args if it exists, + // since we need to pass it cleanly. Otherwise new process will + // fail during arg parsing. + if let Some(idx) = args.iter().position(|a| a == "--self-update-temp") { + args.remove(idx); + // Remove path passed after this arg + args.remove(idx); + } + + match std::process::Command::new(&relaunch_path) + .args(args) + .arg("--self-update-temp") + .arg(&cleanup_path) + .spawn() + { + Ok(_) => { + if let Err(e) = remove_file(cleanup_path) { + error!("Could not remove temp update file: {}", e); + } + std::process::exit(0) + } + Err(error) => { + if let Err(e) = remove_file(cleanup_path) { + error!("Could not remove temp update file: {}", e); + } + error!("Failed to update UAD: {}", error) + } + } + } + Err(()) => error!("Failed to update UAD!"), + } + Command::none() + } } } fn view(&mut self) -> Element { - let apps_btn = Button::new(&mut self.apps_btn, Text::new("Apps")) - .on_press(Message::AppsPress) - .padding(5) - .style(style::PrimaryButton(self.settings_view.theme.palette)); - let apps_refresh_btn = Button::new(&mut self.apps_refresh_btn, refresh_icon()) .on_press(Message::RefreshButtonPressed) .padding(5) .style(style::RefreshButton(self.settings_view.theme.palette)); - let uad_version = Text::new(env!("CARGO_PKG_VERSION")); + let uad_version_text = if let Some(r) = &self.settings_view.self_update_state.latest_release + { + if self.settings_view.self_update_state.status == SelfUpdateStatus::Updating { + Text::new("Updating please wait...") + .color(self.settings_view.theme.palette.normal.surface) + } else { + Text::new(format!( + "New UAD version available {} -> {}", + env!("CARGO_PKG_VERSION"), + r.tag_name + )) + .color(self.settings_view.theme.palette.normal.surface) + } + } else { + Text::new(env!("CARGO_PKG_VERSION")) + }; + + let apps_btn = if self + .settings_view + .self_update_state + .latest_release + .is_some() + { + Button::new(&mut self.apps_btn, Text::new("Update")) + .on_press(Message::AboutAction(AboutMessage::DoSelfUpdate)) + .padding(5) + .style(style::SelfUpdateButton(self.settings_view.theme.palette)) + } else { + Button::new(&mut self.apps_btn, Text::new("Apps")) + .on_press(Message::AppsPress) + .padding(5) + .style(style::PrimaryButton(self.settings_view.theme.palette)) + }; let about_btn = Button::new(&mut self.about_btn, Text::new("About")) .on_press(Message::AboutPressed) @@ -232,7 +342,7 @@ impl Application for UadGui { .push(apps_refresh_btn) .push(device_picklist) .push(Space::new(Length::Fill, Length::Shrink)) - .push(uad_version) + .push(uad_version_text) .push(apps_btn) .push(about_btn) .push(settings_btn), @@ -243,7 +353,7 @@ impl Application for UadGui { .push(apps_refresh_btn) .push(Text::new("no devices/emulators found")) .push(Space::new(Length::Fill, Length::Shrink)) - .push(uad_version) + .push(uad_version_text) .push(apps_btn) .push(about_btn) .push(settings_btn), @@ -308,6 +418,10 @@ impl UadGui { pub async fn download_uad_list() -> Message { Message::InitList } + + pub async fn send_self_update_message() -> SettingsMessage { + SettingsMessage::GetLatestRelease(get_latest_release()) + } } fn refresh_icon() -> Text { diff --git a/src/gui/style.rs b/src/gui/style.rs index fa386ff..f8e47dd 100644 --- a/src/gui/style.rs +++ b/src/gui/style.rs @@ -77,6 +77,33 @@ impl button::StyleSheet for UnavailableButton { } } +pub struct SelfUpdateButton(pub ColorPalette); +impl button::StyleSheet for SelfUpdateButton { + fn active(&self) -> button::Style { + button::Style { + border_color: Color { + a: 0.5, + ..self.0.bright.secondary + }, + border_width: 1.0, + border_radius: 2.0, + text_color: self.0.bright.secondary, + ..button::Style::default() + } + } + + fn hovered(&self) -> button::Style { + button::Style { + background: Some(Background::Color(Color { + a: 0.25, + ..self.0.normal.surface + })), + text_color: self.0.bright.secondary, + ..self.active() + } + } +} + pub struct RefreshButton(pub ColorPalette); impl button::StyleSheet for RefreshButton { fn active(&self) -> button::Style { diff --git a/src/gui/views/about.rs b/src/gui/views/about.rs index 52066d7..ebd45cd 100644 --- a/src/gui/views/about.rs +++ b/src/gui/views/about.rs @@ -5,6 +5,9 @@ use crate::CACHE_DIR; use iced::{button, Alignment, Button, Column, Container, Element, Length, Row, Space, Text}; use std::path::PathBuf; +#[cfg(feature = "self-update")] +use crate::core::update::SelfUpdateStatus; + #[derive(Default, Debug, Clone)] pub struct About { website_btn: button::State, @@ -12,12 +15,14 @@ pub struct About { wiki_btn: button::State, log_btn: button::State, lists_btn: button::State, + _self_update_btn: button::State, } #[derive(Debug, Clone)] pub enum Message { UrlPressed(PathBuf), UpdateUadLists, + DoSelfUpdate, } impl About { @@ -29,6 +34,9 @@ impl About { Message::UpdateUadLists => { // Action is taken by UadGui update() } + Message::DoSelfUpdate => { + // Action is taken by UadGui update() + } } } pub fn view(&mut self, settings: &Settings) -> Element { @@ -43,7 +51,8 @@ impl About { .style(style::NavigationContainer(settings.theme.palette)); let date = last_modified_date(CACHE_DIR.join("uad_lists.json")); - let uad_list_text = Text::new(format!("Documentation: v{}", date.format("%Y%m%d"))); + let uad_list_text = Text::new(format!("Documentation: v{}", date.format("%Y%m%d"))) + .width(Length::Units(250)); let last_update_text = Text::new(format!("(last was {})", format_diff_time_from_now(date))) .color(settings.theme.palette.normal.surface); let uad_lists_btn = Button::new(&mut self.lists_btn, Text::new("Update")) @@ -51,14 +60,69 @@ impl About { .padding(5) .style(style::PrimaryButton(settings.theme.palette)); + #[cfg(feature = "self-update")] + let self_update_btn = Button::new(&mut self._self_update_btn, Text::new("Update")) + .on_press(Message::DoSelfUpdate) + .padding(5) + .style(style::PrimaryButton(settings.theme.palette)); + + #[cfg(feature = "self-update")] + let uad_version_text = Text::new(format!("UAD version: v{}", env!("CARGO_PKG_VERSION"))) + .width(Length::Units(250)); + + #[cfg(feature = "self-update")] + let self_update_text = match &settings.self_update_state.latest_release { + Some(r) => { + if settings.self_update_state.status == SelfUpdateStatus::Updating { + settings.self_update_state.status.to_string() + } else { + format!("(v{} available)", r.tag_name) + } + } + None => { + if settings.self_update_state.status == SelfUpdateStatus::Done { + "(No update available)".to_string() + } else { + settings.self_update_state.status.to_string() + } + } + }; + + #[cfg(feature = "self-update")] + let last_self_update_text = + Text::new(self_update_text).color(settings.theme.palette.normal.surface); + + #[cfg(feature = "self-update")] + let self_update_row = Row::new() + .align_items(Alignment::Center) + .spacing(10) + .width(iced::Length::Units(550)) + .push(uad_version_text) + .push(self_update_btn) + .push(last_self_update_text); + let uad_list_row = Row::new() .align_items(Alignment::Center) .spacing(10) + .width(iced::Length::Units(550)) .push(uad_list_text) .push(uad_lists_btn) .push(last_update_text); - let update_container = Container::new(uad_list_row) + #[cfg(feature = "self-update")] + let update_column = Column::new() + .align_items(Alignment::Center) + .spacing(10) + .push(uad_list_row) + .push(self_update_row); + + #[cfg(not(feature = "self-update"))] + let update_column = Column::new() + .align_items(Alignment::Center) + .spacing(10) + .push(uad_list_row); + + let update_container = Container::new(update_column) .width(Length::Fill) .center_x() .padding(10) diff --git a/src/gui/views/list.rs b/src/gui/views/list.rs index 0a9062c..9f11ca3 100644 --- a/src/gui/views/list.rs +++ b/src/gui/views/list.rs @@ -34,6 +34,7 @@ pub enum Action { pub enum LoadingState { DownloadingList, LoadingPackages, + _UpdatingUad, } #[derive(Debug, Clone, PartialEq)] @@ -351,6 +352,10 @@ impl List { let text = "Pulling packages from the phone. Please wait..."; waiting_view(settings, text, None) } + State::Loading(LoadingState::_UpdatingUad) => { + let text = "Updating UAD. Please wait..."; + waiting_view(settings, text, None) + } State::Ready => { let search_packages = TextInput::new( &mut self.search_input, diff --git a/src/gui/views/settings.rs b/src/gui/views/settings.rs index 25538fe..a13c841 100644 --- a/src/gui/views/settings.rs +++ b/src/gui/views/settings.rs @@ -1,6 +1,7 @@ use crate::core::config::Config; use crate::core::sync::{get_android_sdk, Phone as CorePhone}; use crate::core::theme::Theme; +use crate::core::update::{Release, SelfUpdateState, SelfUpdateStatus}; use crate::core::utils::{open_url, string_to_theme}; use crate::gui::style; use crate::IN_FILE_CONFIGURATION; @@ -16,6 +17,7 @@ pub struct Settings { pub theme: Theme, theme_picklist: pick_list::State, unavailable_btn: button::State, + pub self_update_state: SelfUpdateState, } #[derive(Debug, Clone)] @@ -42,6 +44,7 @@ impl Default for Settings { theme: string_to_theme(IN_FILE_CONFIGURATION.theme.clone()), theme_picklist: pick_list::State::default(), unavailable_btn: button::State::default(), + self_update_state: SelfUpdateState::default(), } } } @@ -53,11 +56,21 @@ pub enum Message { MultiUserMode(bool), ApplyTheme(Theme), UrlPressed(PathBuf), + GetLatestRelease(Result, ()>), } impl Settings { pub fn update(&mut self, phone: &CorePhone, msg: Message) { match msg { + Message::GetLatestRelease(release) => { + match release { + Ok(r) => { + self.self_update_state.status = SelfUpdateStatus::Done; + self.self_update_state.latest_release = r + } + Err(_) => self.self_update_state.status = SelfUpdateStatus::Failed, + }; + } Message::ExpertMode(toggled) => { info!( "Expert mode {}", @@ -158,6 +171,7 @@ impl Settings { ))) .height(Length::Units(22)) .style(style::UnavailableButton(self.theme.palette)); + // Disabling package without root isn't really possible before Android Oreo (8.0) // see https://github.com/0x192/universal-android-debloater/wiki/ADB-reference let disable_mode_checkbox = Checkbox::new(