diff --git a/Cargo.lock b/Cargo.lock index 4237332a4..0a118aa35 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -104,9 +104,9 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "android-activity" -version = "0.5.2" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee91c0c2905bae44f84bfa4e044536541df26b7703fd0888deeb9060fcc44289" +checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" dependencies = [ "android-properties", "bitflags 2.6.0", @@ -118,7 +118,7 @@ dependencies = [ "log", "ndk", "ndk-context", - "ndk-sys", + "ndk-sys 0.6.0+11769913", "num_enum", "thiserror", ] @@ -213,7 +213,7 @@ dependencies = [ "url", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.5", + "wayland-protocols", "zbus", ] @@ -488,6 +488,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "base64-compat" version = "1.0.0" @@ -552,7 +558,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "rustc-hash", + "rustc-hash 1.1.0", "shlex", "syn 2.0.87", "which", @@ -739,32 +745,13 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae85a0696e7ea3b835a453750bf002770776609115e6d25c6d2ff28a8200f7e7" -dependencies = [ - "objc-sys", -] - -[[package]] -name = "block2" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68" -dependencies = [ - "block-sys", - "objc2 0.4.1", -] - [[package]] name = "block2" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" dependencies = [ - "objc2 0.5.2", + "objc2", ] [[package]] @@ -845,20 +832,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "calloop" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" -dependencies = [ - "bitflags 2.6.0", - "log", - "polling", - "rustix", - "slab", - "thiserror", -] - [[package]] name = "calloop" version = "0.13.0" @@ -873,25 +846,13 @@ dependencies = [ "thiserror", ] -[[package]] -name = "calloop-wayland-source" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02" -dependencies = [ - "calloop 0.12.4", - "rustix", - "wayland-backend", - "wayland-client", -] - [[package]] name = "calloop-wayland-source" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95a66a987056935f7efce4ab5668920b5d0dac4a7c99991a67395f13702ddd20" dependencies = [ - "calloop 0.13.0", + "calloop", "rustix", "wayland-backend", "wayland-client", @@ -1016,7 +977,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b7f4aaa047ba3c3630b080bb9860894732ff23e2aee290a418909aa6d5df38f" dependencies = [ - "objc2 0.5.2", + "objc2", "objc2-app-kit", "objc2-foundation", ] @@ -1232,19 +1193,21 @@ dependencies = [ [[package]] name = "cosmic-text" -version = "0.10.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75acbfb314aeb4f5210d379af45ed1ec2c98c7f1790bf57b8a4c562ac0c51b71" +checksum = "59fd57d82eb4bfe7ffa9b1cec0c05e2fd378155b47f255a67983cb4afe0e80c2" dependencies = [ - "fontdb", - "libm", + "bitflags 2.6.0", + "fontdb 0.16.2", "log", "rangemap", - "rustc-hash", - "rustybuzz 0.11.0", + "rayon", + "rustc-hash 1.1.0", + "rustybuzz", "self_cell", "swash", "sys-locale", + "ttf-parser 0.21.1", "unicode-bidi", "unicode-linebreak", "unicode-script", @@ -1507,6 +1470,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" +[[package]] +name = "dpi" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" + [[package]] name = "drm" version = "0.12.0" @@ -1834,17 +1803,14 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foldhash" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" - [[package]] name = "font-types" -version = "0.4.3" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b7f6040d337bd44434ab21fc6509154edf2cece88b23758d9d64654c4e7730b" +checksum = "b3971f9a5ca983419cdc386941ba3b9e1feba01a0ab888adf78739feb2798492" +dependencies = [ + "bytemuck", +] [[package]] name = "fontconfig-parser" @@ -1852,21 +1818,35 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1fcfcd44ca6e90c921fee9fa665d530b21ef1327a4c1a6c5250ea44b776ada7" dependencies = [ - "roxmltree 0.20.0", + "roxmltree", ] [[package]] name = "fontdb" -version = "0.15.0" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0299020c3ef3f60f526a4f64ab4a3d4ce116b1acbf24cdd22da0068e5d81dc3" +dependencies = [ + "fontconfig-parser", + "log", + "memmap2", + "slotmap", + "tinyvec", + "ttf-parser 0.20.0", +] + +[[package]] +name = "fontdb" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020e203f177c0fb250fb19455a252e838d2bbbce1f80f25ecc42402aafa8cd38" +checksum = "e32eac81c1135c1df01d4e6d4233c47ba11f6a6d07f33e0bba09d18797077770" dependencies = [ "fontconfig-parser", "log", - "memmap2 0.8.0", + "memmap2", "slotmap", "tinyvec", - "ttf-parser 0.19.2", + "ttf-parser 0.21.1", ] [[package]] @@ -2056,16 +2036,6 @@ dependencies = [ "polyval", ] -[[package]] -name = "gif" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045" -dependencies = [ - "color_quant", - "weezl", -] - [[package]] name = "gif" version = "0.13.1" @@ -2126,18 +2096,6 @@ dependencies = [ "gl_generator", ] -[[package]] -name = "glyphon" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a62d0338e4056db6a73221c2fb2e30619452f6ea9651bac4110f51b0f7a7581" -dependencies = [ - "cosmic-text", - "etagere", - "lru", - "wgpu", -] - [[package]] name = "gpu-alloc" version = "0.6.0" @@ -2267,11 +2225,6 @@ name = "hashbrown" version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" -dependencies = [ - "allocator-api2", - "equivalent", - "foldhash", -] [[package]] name = "hashlink" @@ -2476,9 +2429,9 @@ dependencies = [ [[package]] name = "iced" -version = "0.12.1" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d4eb0fbbefb8c428b70680e77ed9013887b17c1d6be366b40f264f956d1a096" +checksum = "88acfabc84ec077eaf9ede3457ffa3a104626d79022a9bf7f296093b1d60c73f" dependencies = [ "iced_core", "iced_futures", @@ -2491,40 +2444,56 @@ dependencies = [ [[package]] name = "iced_core" -version = "0.12.3" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d7e6bbd197f311ed3d8b71651876b0ce01318fde52cda862a9a7a4373c9b930" +checksum = "0013a238275494641bf8f1732a23a808196540dc67b22ff97099c044ae4c8a1c" dependencies = [ "bitflags 2.6.0", + "bytes", "glam", "log", "num-traits", + "once_cell", "palette", - "raw-window-handle", + "rustc-hash 2.1.0", "smol_str", "thiserror", "web-time", - "xxhash-rust", ] [[package]] name = "iced_futures" -version = "0.12.3" -source = "git+https://github.com/edouardparis/iced?branch=patch-0.12.3#459c8eb3da2ae21461ee56baea8a1b10d38ff6e0" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c04a6745ba2e80f32cf01e034fd00d853aa4f4cd8b91888099cb7aaee0d5d7c" dependencies = [ "futures", "iced_core", "log", + "rustc-hash 2.1.0", "tokio", "wasm-bindgen-futures", "wasm-timer", ] +[[package]] +name = "iced_glyphon" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41c3bb56f1820ca252bc1d0994ece33d233a55657c0c263ea7cb16895adbde82" +dependencies = [ + "cosmic-text", + "etagere", + "lru", + "rustc-hash 2.1.0", + "wgpu", +] + [[package]] name = "iced_graphics" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a044c193ef0840eacabfa05424717331d1fc5b3ecb9a89316200c75da2ba9a4" +checksum = "ba25a18cfa6d5cc160aca7e1b34f73ccdff21680fa8702168c09739767b6c66f" dependencies = [ "bitflags 2.6.0", "bytemuck", @@ -2538,17 +2507,16 @@ dependencies = [ "lyon_path", "once_cell", "raw-window-handle", - "rustc-hash", + "rustc-hash 2.1.0", "thiserror", "unicode-segmentation", - "xxhash-rust", ] [[package]] name = "iced_renderer" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c281e03001d566058f53dec9325bbe61c62da715341206d2627f57a3ecc7f69" +checksum = "73558208059f9e622df2bf434e044ee2f838ce75201a023cf0ca3e1244f46c2a" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -2559,31 +2527,22 @@ dependencies = [ [[package]] name = "iced_runtime" -version = "0.12.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a79f852c01cc6d61663c94379cb3974ac3ad315a28c504e847d573e094f46822" +checksum = "348b5b2c61c934d88ca3b0ed1ed913291e923d086a66fa288ce9669da9ef62b5" dependencies = [ + "bytes", "iced_core", "iced_futures", "raw-window-handle", "thiserror", ] -[[package]] -name = "iced_style" -version = "0.12.3" -source = "git+https://github.com/edouardparis/iced?branch=patch-0.12.3#459c8eb3da2ae21461ee56baea8a1b10d38ff6e0" -dependencies = [ - "iced_core", - "once_cell", - "palette", -] - [[package]] name = "iced_tiny_skia" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c2228781f4d381a1cbbd7905a9f077351aa8d37269094021d5d9e779f130aff" +checksum = "c625d368284fcc43b0b36b176f76eff1abebe7959dd58bd8ce6897d641962a50" dependencies = [ "bytemuck", "cosmic-text", @@ -2591,76 +2550,70 @@ dependencies = [ "kurbo 0.10.4", "log", "resvg", - "rustc-hash", + "rustc-hash 2.1.0", "softbuffer", "tiny-skia", - "xxhash-rust", ] [[package]] name = "iced_wgpu" -version = "0.12.1" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c243b6700452886aac1ee1987e84d9fb43b56b53fea9a1eb67713fd0fde244" +checksum = "15708887133671d2bcc6c1d01d1f176f43a64d6cdc3b2bf893396c3ee498295f" dependencies = [ "bitflags 2.6.0", "bytemuck", "futures", "glam", - "glyphon", "guillotiere", + "iced_glyphon", "iced_graphics", "log", "lyon", "once_cell", "resvg", + "rustc-hash 2.1.0", + "thiserror", "wgpu", ] [[package]] name = "iced_widget" -version = "0.12.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e01b2212adecf1cb80e2267f302c0e0c263e55f97812056949199ccf9f0b908" +checksum = "81429e1b950b0e4bca65be4c4278fea6678ea782030a411778f26fa9f8983e1d" dependencies = [ "iced_renderer", "iced_runtime", - "iced_style", "num-traits", + "once_cell", "ouroboros", "qrcode", + "rustc-hash 2.1.0", "thiserror", "unicode-segmentation", ] [[package]] name = "iced_winit" -version = "0.12.3" -source = "git+https://github.com/edouardparis/iced?branch=patch-0.12.3#459c8eb3da2ae21461ee56baea8a1b10d38ff6e0" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f44cd4e1c594b6334f409282937bf972ba14d31fedf03c23aa595d982a2fda28" dependencies = [ + "iced_futures", "iced_graphics", "iced_runtime", - "iced_style", "log", + "rustc-hash 2.1.0", "thiserror", "tracing", + "wasm-bindgen-futures", "web-sys", "winapi", "window_clipboard", "winit", ] -[[package]] -name = "icrate" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319" -dependencies = [ - "block2 0.3.0", - "dispatch", - "objc2 0.4.1", -] - [[package]] name = "icu_collections" version = "1.5.0" @@ -2810,7 +2763,7 @@ dependencies = [ "byteorder", "color_quant", "exr", - "gif 0.13.1", + "gif", "jpeg-decoder", "num-traits", "png", @@ -2943,10 +2896,11 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.72" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -3016,18 +2970,19 @@ checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" [[package]] name = "kurbo" -version = "0.9.5" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd85a5776cd9500c2e2059c8c76c3b01528566b7fcbaf8098b55a33fc298849b" +checksum = "1618d4ebd923e97d67e7cd363d80aef35fe961005cbbbb3d2dad8bdd1bc63440" dependencies = [ "arrayvec", + "smallvec", ] [[package]] name = "kurbo" -version = "0.10.4" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1618d4ebd923e97d67e7cd363d80aef35fe961005cbbbb3d2dad8bdd1bc63440" +checksum = "89234b2cc610a7dd927ebde6b41dd1a5d4214cffaef4cf1fb2195d592f92518f" dependencies = [ "arrayvec", "smallvec", @@ -3307,9 +3262,6 @@ name = "lru" version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" -dependencies = [ - "hashbrown 0.15.1", -] [[package]] name = "lyon" @@ -3387,15 +3339,6 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" -[[package]] -name = "memmap2" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a5a03cefb0d953ec0be133036f14e109412fa594edc2f77227249db66cc3ed" -dependencies = [ - "libc", -] - [[package]] name = "memmap2" version = "0.9.5" @@ -3544,7 +3487,7 @@ dependencies = [ "indexmap", "log", "num-traits", - "rustc-hash", + "rustc-hash 1.1.0", "spirv", "termcolor", "thiserror", @@ -3553,14 +3496,14 @@ dependencies = [ [[package]] name = "ndk" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ "bitflags 2.6.0", "jni-sys", "log", - "ndk-sys", + "ndk-sys 0.6.0+11769913", "num_enum", "raw-window-handle", "thiserror", @@ -3581,6 +3524,15 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys", +] + [[package]] name = "nix" version = "0.26.4" @@ -3733,16 +3685,6 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" -[[package]] -name = "objc2" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" -dependencies = [ - "objc-sys", - "objc2-encode 3.0.0", -] - [[package]] name = "objc2" version = "0.5.2" @@ -3750,7 +3692,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" dependencies = [ "objc-sys", - "objc2-encode 4.0.3", + "objc2-encode", ] [[package]] @@ -3760,15 +3702,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ "bitflags 2.6.0", - "block2 0.5.1", + "block2", "libc", - "objc2 0.5.2", + "objc2", "objc2-core-data", "objc2-core-image", "objc2-foundation", "objc2-quartz-core", ] +[[package]] +name = "objc2-cloud-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + +[[package]] +name = "objc2-contacts" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + [[package]] name = "objc2-core-data" version = "0.2.2" @@ -3776,8 +3742,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ "bitflags 2.6.0", - "block2 0.5.1", - "objc2 0.5.2", + "block2", + "objc2", "objc2-foundation", ] @@ -3787,17 +3753,23 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" dependencies = [ - "block2 0.5.1", - "objc2 0.5.2", + "block2", + "objc2", "objc2-foundation", "objc2-metal", ] [[package]] -name = "objc2-encode" -version = "3.0.0" +name = "objc2-core-location" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" +checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" +dependencies = [ + "block2", + "objc2", + "objc2-contacts", + "objc2-foundation", +] [[package]] name = "objc2-encode" @@ -3812,10 +3784,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ "bitflags 2.6.0", - "block2 0.5.1", + "block2", "dispatch", "libc", - "objc2 0.5.2", + "objc2", +] + +[[package]] +name = "objc2-link-presentation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" +dependencies = [ + "block2", + "objc2", + "objc2-app-kit", + "objc2-foundation", ] [[package]] @@ -3825,8 +3809,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ "bitflags 2.6.0", - "block2 0.5.1", - "objc2 0.5.2", + "block2", + "objc2", "objc2-foundation", ] @@ -3837,12 +3821,67 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ "bitflags 2.6.0", - "block2 0.5.1", - "objc2 0.5.2", + "block2", + "objc2", "objc2-foundation", "objc2-metal", ] +[[package]] +name = "objc2-symbols" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a684efe3dec1b305badae1a28f6555f6ddd3bb2c2267896782858d5a78404dc" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation", + "objc2-link-presentation", + "objc2-quartz-core", + "objc2-symbols", + "objc2-uniform-type-identifiers", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-uniform-type-identifiers" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" +dependencies = [ + "block2", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" +dependencies = [ + "bitflags 2.6.0", + "block2", + "objc2", + "objc2-core-location", + "objc2-foundation", +] + [[package]] name = "objc_exception" version = "0.1.2" @@ -4087,7 +4126,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" dependencies = [ - "siphasher", + "siphasher 0.3.11", ] [[package]] @@ -4096,6 +4135,26 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" +[[package]] +name = "pin-project" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e2ec53ad785f4d35dac0adea7f7dc6f1bb277ad84a680c7afefeae05d1f5916" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "pin-project-lite" version = "0.2.15" @@ -4442,12 +4501,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "rctree" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b42e27ef78c35d3998403c1d26f3efd9e135d3e5121b0a4845cc5cc27547f4f" - [[package]] name = "rdrand" version = "0.8.3" @@ -4459,10 +4512,11 @@ dependencies = [ [[package]] name = "read-fonts" -version = "0.15.6" +version = "0.22.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ea23eedb4d938031b6d4343222444608727a6aa68ec355e13588d9947ffe92" +checksum = "69aacb76b5c29acfb7f90155d39759a29496aebb49395830e928a9703d2eec2f" dependencies = [ + "bytemuck", "font-types", ] @@ -4477,9 +4531,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ "bitflags 1.3.2", ] @@ -4582,15 +4636,14 @@ dependencies = [ [[package]] name = "resvg" -version = "0.36.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7980f653f9a7db31acff916a262c3b78c562919263edea29bf41a056e20497" +checksum = "944d052815156ac8fa77eaac055220e95ba0b01fa8887108ca710c03805d9051" dependencies = [ - "gif 0.12.0", + "gif", "jpeg-decoder", "log", "pico-args", - "png", "rgb", "svgtypes", "tiny-skia", @@ -4614,10 +4667,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46f6f80a9b882647d9014673ca9925d30ffc9750f2eed2b4490e189eaebd01e8" dependencies = [ "ashpd", - "block2 0.5.1", + "block2", "js-sys", "log", - "objc2 0.5.2", + "objc2", "objc2-app-kit", "objc2-foundation", "pollster", @@ -4653,15 +4706,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "roxmltree" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862340e351ce1b271a378ec53f304a5558f7db87f3769dc655a8f6ecbb68b302" -dependencies = [ - "xmlparser", -] - [[package]] name = "roxmltree" version = "0.20.0" @@ -4704,6 +4748,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc-hash" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" + [[package]] name = "rustc_version" version = "0.4.1" @@ -4791,32 +4841,22 @@ dependencies = [ ] [[package]] -name = "rustybuzz" -version = "0.10.0" +name = "rustversion" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71cd15fef9112a1f94ac64b58d1e4628192631ad6af4dc69997f995459c874e7" -dependencies = [ - "bitflags 1.3.2", - "bytemuck", - "smallvec", - "ttf-parser 0.19.2", - "unicode-bidi-mirroring", - "unicode-ccc", - "unicode-properties", - "unicode-script", -] +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" [[package]] name = "rustybuzz" -version = "0.11.0" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee8fe2a8461a0854a37101fe7a1b13998d0cfa987e43248e81d2a5f4570f6fa" +checksum = "cfb9cf8877777222e4a3bc7eb247e398b56baba500c38c1c46842431adc8b55c" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "bytemuck", "libm", "smallvec", - "ttf-parser 0.20.0", + "ttf-parser 0.21.1", "unicode-bidi-mirroring", "unicode-ccc", "unicode-properties", @@ -4862,14 +4902,14 @@ dependencies = [ [[package]] name = "sctk-adwaita" -version = "0.8.3" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70b31447ca297092c5a9916fc3b955203157b37c19ca8edde4f52e9843e602c7" +checksum = "b6277f0217056f77f1d8f49f2950ac6c278c0d607c45f5ee99328d792ede24ec" dependencies = [ "ab_glyph", "log", - "memmap2 0.9.5", - "smithay-client-toolkit 0.18.1", + "memmap2", + "smithay-client-toolkit", "tiny-skia", ] @@ -5078,6 +5118,22 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + +[[package]] +name = "skrifa" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1c44ad1f6c5bdd4eefed8326711b7dbda9ea45dfd36068c427d332aa382cbe" +dependencies = [ + "bytemuck", + "read-fonts", +] + [[package]] name = "slab" version = "0.4.9" @@ -5102,31 +5158,6 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" -[[package]] -name = "smithay-client-toolkit" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a" -dependencies = [ - "bitflags 2.6.0", - "calloop 0.12.4", - "calloop-wayland-source 0.2.0", - "cursor-icon", - "libc", - "log", - "memmap2 0.9.5", - "rustix", - "thiserror", - "wayland-backend", - "wayland-client", - "wayland-csd-frame", - "wayland-cursor", - "wayland-protocols 0.31.2", - "wayland-protocols-wlr 0.2.0", - "wayland-scanner", - "xkeysym", -] - [[package]] name = "smithay-client-toolkit" version = "0.19.2" @@ -5134,20 +5165,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" dependencies = [ "bitflags 2.6.0", - "calloop 0.13.0", - "calloop-wayland-source 0.3.0", + "calloop", + "calloop-wayland-source", "cursor-icon", "libc", "log", - "memmap2 0.9.5", + "memmap2", "rustix", "thiserror", "wayland-backend", "wayland-client", "wayland-csd-frame", "wayland-cursor", - "wayland-protocols 0.32.5", - "wayland-protocols-wlr 0.3.5", + "wayland-protocols", + "wayland-protocols-wlr", "wayland-scanner", "xkeysym", ] @@ -5159,7 +5190,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc8216eec463674a0e90f29e0ae41a4db573ec5b56b1c6c1c71615d249b6d846" dependencies = [ "libc", - "smithay-client-toolkit 0.19.2", + "smithay-client-toolkit", "wayland-backend", ] @@ -5219,8 +5250,8 @@ dependencies = [ "foreign-types", "js-sys", "log", - "memmap2 0.9.5", - "objc2 0.5.2", + "memmap2", + "objc2", "objc2-foundation", "objc2-quartz-core", "raw-window-handle", @@ -5296,21 +5327,21 @@ checksum = "ce5d813d71d82c4cbc1742135004e4a79fd870214c155443451c139c9470a0aa" [[package]] name = "svgtypes" -version = "0.12.0" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71499ff2d42f59d26edb21369a308ede691421f79ebc0f001e2b1fd3a7c9e52" +checksum = "68c7541fff44b35860c1a7a47a7cadf3e4a304c457b58f9870d9706ece028afc" dependencies = [ - "kurbo 0.9.5", - "siphasher", + "kurbo 0.11.1", + "siphasher 1.0.1", ] [[package]] name = "swash" -version = "0.1.12" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d06ff4664af8923625604261c645f5c4cc610cc83c84bec74b50d76237089de7" +checksum = "cbd59f3f359ddd2c95af4758c18270eddd9c730dde98598023cdabff472c2ca2" dependencies = [ - "read-fonts", + "skrifa", "yazi", "zeno", ] @@ -5691,15 +5722,15 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "ttf-parser" -version = "0.19.2" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49d64318d8311fc2668e48b63969f4343e0a85c4a109aa8460d6672e364b8bd1" +checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4" [[package]] name = "ttf-parser" -version = "0.20.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4" +checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" [[package]] name = "ttf-parser" @@ -5741,15 +5772,15 @@ checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-bidi-mirroring" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56d12260fb92d52f9008be7e4bca09f584780eb2266dc8fecc6a192bec561694" +checksum = "23cb788ffebc92c5948d0e997106233eeb1d8b9512f93f41651f52b6c5f5af86" [[package]] name = "unicode-ccc" -version = "0.1.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2520efa644f8268dce4dcd3050eaa7fc044fca03961e9998ac7e2e92b77cf1" +checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656" [[package]] name = "unicode-ident" @@ -5844,63 +5875,29 @@ checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" [[package]] name = "usvg" -version = "0.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c51daa774fe9ee5efcf7b4fec13019b8119cda764d9a8b5b06df02bb1445c656" -dependencies = [ - "base64 0.21.7", - "log", - "pico-args", - "usvg-parser", - "usvg-text-layout", - "usvg-tree", - "xmlwriter", -] - -[[package]] -name = "usvg-parser" -version = "0.36.0" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45c88a5ffaa338f0e978ecf3d4e00d8f9f493e29bed0752e1a808a1db16afc40" +checksum = "b84ea542ae85c715f07b082438a4231c3760539d902e11d093847a0b22963032" dependencies = [ + "base64 0.22.1", "data-url", "flate2", + "fontdb 0.18.0", "imagesize", - "kurbo 0.9.5", + "kurbo 0.11.1", "log", - "roxmltree 0.18.1", + "pico-args", + "roxmltree", + "rustybuzz", "simplecss", - "siphasher", + "siphasher 1.0.1", + "strict-num", "svgtypes", - "usvg-tree", -] - -[[package]] -name = "usvg-text-layout" -version = "0.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d2374378cb7a3fb8f33894e0fdb8625e1bbc4f25312db8d91f862130b541593" -dependencies = [ - "fontdb", - "kurbo 0.9.5", - "log", - "rustybuzz 0.10.0", + "tiny-skia-path", "unicode-bidi", "unicode-script", "unicode-vo", - "usvg-tree", -] - -[[package]] -name = "usvg-tree" -version = "0.36.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cacb0c5edeaf3e80e5afcf5b0d4004cc1d36318befc9a7c6606507e5d0f4062" -dependencies = [ - "rctree", - "strict-num", - "svgtypes", - "tiny-skia-path", + "xmlwriter", ] [[package]] @@ -5960,24 +5957,24 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", "syn 2.0.87", @@ -5998,9 +5995,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6008,9 +6005,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", @@ -6021,9 +6018,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "wasm-timer" @@ -6088,18 +6088,6 @@ dependencies = [ "xcursor", ] -[[package]] -name = "wayland-protocols" -version = "0.31.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" -dependencies = [ - "bitflags 2.6.0", - "wayland-backend", - "wayland-client", - "wayland-scanner", -] - [[package]] name = "wayland-protocols" version = "0.32.5" @@ -6114,27 +6102,14 @@ dependencies = [ [[package]] name = "wayland-protocols-plasma" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" -dependencies = [ - "bitflags 2.6.0", - "wayland-backend", - "wayland-client", - "wayland-protocols 0.31.2", - "wayland-scanner", -] - -[[package]] -name = "wayland-protocols-wlr" -version = "0.2.0" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" +checksum = "9b31cab548ee68c7eb155517f2212049dc151f7cd7910c2b66abfd31c3ee12bd" dependencies = [ "bitflags 2.6.0", "wayland-backend", "wayland-client", - "wayland-protocols 0.31.2", + "wayland-protocols", "wayland-scanner", ] @@ -6147,7 +6122,7 @@ dependencies = [ "bitflags 2.6.0", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.5", + "wayland-protocols", "wayland-scanner", ] @@ -6176,9 +6151,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.67" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" dependencies = [ "js-sys", "wasm-bindgen", @@ -6186,9 +6161,9 @@ dependencies = [ [[package]] name = "web-time" -version = "0.2.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa30049b1c872b72c89866d458eae9f20380ab280ffd1b1e18df2d3e2d98cfe0" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", @@ -6249,7 +6224,7 @@ dependencies = [ "parking_lot 0.12.3", "profiling", "raw-window-handle", - "rustc-hash", + "rustc-hash 1.1.0", "smallvec", "thiserror", "web-sys", @@ -6285,7 +6260,7 @@ dependencies = [ "log", "metal", "naga", - "ndk-sys", + "ndk-sys 0.5.0+25.2.9519653", "objc", "once_cell", "parking_lot 0.12.3", @@ -6293,7 +6268,7 @@ dependencies = [ "range-alloc", "raw-window-handle", "renderdoc-sys", - "rustc-hash", + "rustc-hash 1.1.0", "smallvec", "thiserror", "wasm-bindgen", @@ -6611,47 +6586,51 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winit" -version = "0.29.15" +version = "0.30.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d59ad965a635657faf09c8f062badd885748428933dad8e8bdd64064d92e5ca" +checksum = "f5d74280aabb958072864bff6cfbcf9025cf8bfacdde5e32b5e12920ef703b0f" dependencies = [ "ahash", "android-activity", "atomic-waker", "bitflags 2.6.0", + "block2", "bytemuck", - "calloop 0.12.4", - "cfg_aliases 0.1.1", + "calloop", + "cfg_aliases 0.2.1", + "concurrent-queue", "core-foundation 0.9.4", "core-graphics 0.23.2", "cursor-icon", - "icrate", + "dpi", "js-sys", "libc", - "log", - "memmap2 0.9.5", + "memmap2", "ndk", - "ndk-sys", - "objc2 0.4.1", - "once_cell", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", "orbclient", "percent-encoding", + "pin-project", "raw-window-handle", - "redox_syscall 0.3.5", + "redox_syscall 0.4.1", "rustix", "sctk-adwaita", - "smithay-client-toolkit 0.18.1", + "smithay-client-toolkit", "smol_str", + "tracing", "unicode-segmentation", "wasm-bindgen", "wasm-bindgen-futures", "wayland-backend", "wayland-client", - "wayland-protocols 0.31.2", + "wayland-protocols", "wayland-protocols-plasma", "web-sys", "web-time", - "windows-sys 0.48.0", + "windows-sys 0.52.0", "x11-dl", "x11rb", "xkbcommon-dl", @@ -6772,24 +6751,12 @@ version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af310deaae937e48a26602b730250b4949e125f468f11e6990be3e5304ddd96f" -[[package]] -name = "xmlparser" -version = "0.13.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" - [[package]] name = "xmlwriter" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" -[[package]] -name = "xxhash-rust" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a5cbf750400958819fb6178eaa83bee5cd9c29a26a40cc241df8c70fdd46984" - [[package]] name = "yansi" version = "1.0.1" diff --git a/Cargo.toml b/Cargo.toml index a1e82188c..832f4a028 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,8 +8,3 @@ members = [ "liana-ui", ] default-members = ["liana", "lianad", "liana-gui", "liana-ui"] - -[patch.crates-io] -iced_style = { git = "https://github.com/edouardparis/iced", branch = "patch-0.12.3"} -iced_winit = { git = "https://github.com/edouardparis/iced", branch = "patch-0.12.3"} -iced_futures = { git = "https://github.com/edouardparis/iced", branch = "patch-0.12.3"} diff --git a/liana-gui/Cargo.toml b/liana-gui/Cargo.toml index f1fa10a82..291f3a379 100644 --- a/liana-gui/Cargo.toml +++ b/liana-gui/Cargo.toml @@ -18,12 +18,12 @@ async-trait = "0.1" async-hwi = { version = "0.0.26" } liana = { path = "../liana" } lianad = { path = "../lianad", default-features = false, features = ["nonblocking_shutdown"] } -liana-ui = { path = "../liana-ui" } +liana-ui = { path = "../liana-ui"} backtrace = "0.3" hex = "0.4.3" -iced = { version = "0.12.1", default-features = false, features = ["tokio", "svg", "qr_code", "image", "lazy", "wgpu", "advanced"] } -iced_runtime = "0.12.1" +iced = { version = "0.13.1", default-features = false, features = ["tokio", "svg", "qr_code", "image", "lazy", "wgpu", "advanced"] } +iced_runtime = "0.13.1" # Used to verify RFC-compliance of an email email_address = "0.2.7" diff --git a/liana-gui/src/app/mod.rs b/liana-gui/src/app/mod.rs index 0b72b3826..80680ebde 100644 --- a/liana-gui/src/app/mod.rs +++ b/liana-gui/src/app/mod.rs @@ -15,7 +15,7 @@ use std::path::PathBuf; use std::sync::Arc; use std::time::Duration; -use iced::{clipboard, time, Command, Subscription}; +use iced::{clipboard, time, Subscription, Task}; use tokio::runtime::Handle; use tracing::{error, info, warn}; @@ -148,7 +148,7 @@ impl App { daemon: Arc, data_dir: PathBuf, internal_bitcoind: Option, - ) -> (App, Command) { + ) -> (App, Task) { let mut panels = Panels::new( &cache, wallet.clone(), @@ -170,7 +170,7 @@ impl App { ) } - fn set_current_panel(&mut self, menu: Menu) -> Command { + fn set_current_panel(&mut self, menu: Menu) -> Task { self.panels.current_mut().interrupt(); match &menu { @@ -183,7 +183,7 @@ impl App { }) { self.panels.transactions.preselect(tx); self.panels.current = menu; - return Command::none(); + return Task::none(); }; } menu::Menu::PsbtPreSelected(txid) => { @@ -198,7 +198,7 @@ impl App { }) { self.panels.psbts.preselect(spend_tx); self.panels.current = menu; - return Command::none(); + return Task::none(); }; } menu::Menu::RefreshCoins(preselected) => { @@ -279,14 +279,14 @@ impl App { } } - pub fn update(&mut self, message: Message) -> Command { + pub fn update(&mut self, message: Message) -> Task { match message { Message::Tick => { let daemon = self.daemon.clone(); let datadir_path = self.cache.datadir_path.clone(); let network = self.cache.network; let last_poll_at_startup = self.cache.last_poll_at_startup; - Command::perform( + Task::perform( async move { // we check every 10 second if the daemon poller is alive // or if the access token is not expired. @@ -331,11 +331,11 @@ impl App { ) }) .collect(); - return Command::batch(commands); + return Task::batch(commands); } Err(e) => tracing::error!("Failed to update cache: {}", e), } - Command::none() + Task::none() } Message::LoadDaemonConfig(cfg) => { let path = self.config.daemon_config_path.clone().expect( diff --git a/liana-gui/src/app/state/coins.rs b/liana-gui/src/app/state/coins.rs index 2cdb9b224..e15028f8a 100644 --- a/liana-gui/src/app/state/coins.rs +++ b/liana-gui/src/app/state/coins.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use std::sync::Arc; use std::{cmp::Ordering, collections::HashSet}; -use iced::Command; +use iced::Task; use liana_ui::widget::Element; use lianad::commands::CoinStatus; @@ -113,7 +113,7 @@ impl State for CoinsPanel { daemon: Arc, _cache: &Cache, message: Message, - ) -> Command { + ) -> Task { match message { Message::Coins(res) => match res { Err(e) => self.warning = Some(e), @@ -150,18 +150,18 @@ impl State for CoinsPanel { } _ => {} }; - Command::none() + Task::none() } fn reload( &mut self, daemon: Arc, _wallet: Arc, - ) -> Command { + ) -> Task { let daemon1 = daemon.clone(); let daemon2 = daemon.clone(); - Command::batch(vec![ - Command::perform( + Task::batch(vec![ + Task::perform( async move { daemon1 .list_coins(&[CoinStatus::Unconfirmed, CoinStatus::Confirmed], &[]) @@ -171,7 +171,7 @@ impl State for CoinsPanel { }, Message::Coins, ), - Command::perform( + Task::perform( async move { let coins = daemon2 .list_coins(&[CoinStatus::Unconfirmed, CoinStatus::Confirmed], &[]) diff --git a/liana-gui/src/app/state/export.rs b/liana-gui/src/app/state/export.rs index 56de4565e..65e232a33 100644 --- a/liana-gui/src/app/state/export.rs +++ b/liana-gui/src/app/state/export.rs @@ -3,7 +3,7 @@ use std::{ sync::{Arc, Mutex}, }; -use iced::{Command, Subscription}; +use iced::{Subscription, Task}; use liana_ui::{component::modal::Modal, widget::Element}; use tokio::task::JoinHandle; @@ -37,13 +37,13 @@ impl ExportModal { } } - pub fn launch(&self) -> Command { - Command::perform(get_path(), |m| { + pub fn launch(&self) -> Task { + Task::perform(get_path(), |m| { Message::View(view::Message::Export(ExportMessage::Path(m))) }) } - pub fn update(&mut self, message: Message) -> Command { + pub fn update(&mut self, message: Message) -> Task { if let Message::View(view::Message::Export(m)) = message { match m { ExportMessage::ExportProgress(m) => match m { @@ -73,16 +73,16 @@ impl ExportModal { self.path = Some(path); self.start(); } else { - return Command::perform(async {}, |_| { + return Task::perform(async {}, |_| { Message::View(view::Message::Export(ExportMessage::Close)) }); } } ExportMessage::Close | ExportMessage::Open => { /* unreachable */ } } - Command::none() + Task::none() } else { - Command::none() + Task::none() } } pub fn view<'a>(&'a self, content: Element<'a, view::Message>) -> Element { diff --git a/liana-gui/src/app/state/label.rs b/liana-gui/src/app/state/label.rs index 1519f3abb..bc399f074 100644 --- a/liana-gui/src/app/state/label.rs +++ b/liana-gui/src/app/state/label.rs @@ -9,7 +9,7 @@ use crate::{ Daemon, }, }; -use iced::Command; +use iced::Task; use liana_ui::component::form; #[derive(Default)] @@ -24,7 +24,7 @@ impl LabelsEdited { daemon: Arc, message: Message, targets: T, - ) -> Result, Error> { + ) -> Result, Error> { match message { Message::View(view::Message::Label(items, msg)) => match msg { view::LabelMessage::Edited(value) => { @@ -64,7 +64,7 @@ impl LabelsEdited { } } } - return Ok(Command::perform( + return Ok(Task::perform( async move { daemon.update_labels(&updated_labels).await?; Ok(updated_labels_str) @@ -88,7 +88,7 @@ impl LabelsEdited { }, _ => {} }; - Ok(Command::none()) + Ok(Task::none()) } } diff --git a/liana-gui/src/app/state/mod.rs b/liana-gui/src/app/state/mod.rs index b848d0196..19a1d59d3 100644 --- a/liana-gui/src/app/state/mod.rs +++ b/liana-gui/src/app/state/mod.rs @@ -13,7 +13,7 @@ use std::convert::TryInto; use std::sync::Arc; use std::time::{SystemTime, UNIX_EPOCH}; -use iced::{Command, Subscription}; +use iced::{Subscription, Task}; use liana::miniscript::bitcoin::{Amount, OutPoint}; use liana_ui::widget::*; use lianad::commands::CoinStatus; @@ -50,8 +50,8 @@ pub trait State { _daemon: Arc, _cache: &Cache, _message: Message, - ) -> Command { - Command::none() + ) -> Task { + Task::none() } fn subscription(&self) -> Subscription { Subscription::none() @@ -61,14 +61,14 @@ pub trait State { &mut self, _daemon: Arc, _wallet: Arc, - ) -> Command { - Command::none() + ) -> Task { + Task::none() } } /// redirect to another state with a message menu -pub fn redirect(menu: Menu) -> Command { - Command::perform(async { menu }, |menu| { +pub fn redirect(menu: Menu) -> Task { + Task::perform(async { menu }, |menu| { Message::View(view::Message::Menu(menu)) }) } @@ -201,7 +201,7 @@ impl State for Home { daemon: Arc, cache: &Cache, message: Message, - ) -> Command { + ) -> Task { match message { Message::Coins(res) => match res { Err(e) => self.warning = Some(e), @@ -277,7 +277,7 @@ impl State for Home { } }, Message::View(view::Message::SelectPayment(outpoint)) => { - return Command::perform( + return Task::perform( async move { let tx = daemon.get_history_txs(&[outpoint.txid]).await?.remove(0); Ok((tx, outpoint.vout as usize)) @@ -318,7 +318,7 @@ impl State for Home { let daemon = daemon.clone(); let last_event_date = last.time.unwrap(); self.processing = true; - return Command::perform( + return Task::perform( async move { let last_event_date = last_event_date.timestamp() as u32; let mut limit = HISTORY_EVENT_PAGE_SIZE; @@ -359,20 +359,20 @@ impl State for Home { } _ => {} }; - Command::none() + Task::none() } fn reload( &mut self, daemon: Arc, wallet: Arc, - ) -> Command { + ) -> Task { // If the wallet is syncing, we expect it to finish soon and so better to wait for // updated data before reloading. Besides, if the wallet is syncing, the DB may be // locked if the poller is running and we wouldn't be able to reload data until // syncing completes anyway. if self.sync_status.wallet_is_syncing() { - return Command::none(); + return Task::none(); } self.selected_event = None; self.wallet = wallet; @@ -383,8 +383,8 @@ impl State for Home { .as_secs() .try_into() .unwrap(); - Command::batch(vec![ - Command::perform( + Task::batch(vec![ + Task::perform( async move { let mut payments = daemon .list_confirmed_payments(0, now, HISTORY_EVENT_PAGE_SIZE) @@ -397,7 +397,7 @@ impl State for Home { }, Message::Payments, ), - Command::perform( + Task::perform( async move { daemon2 .list_coins(&[CoinStatus::Unconfirmed, CoinStatus::Confirmed], &[]) diff --git a/liana-gui/src/app/state/psbt.rs b/liana-gui/src/app/state/psbt.rs index c2c4b23be..df074374d 100644 --- a/liana-gui/src/app/state/psbt.rs +++ b/liana-gui/src/app/state/psbt.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use iced::Subscription; -use iced::Command; +use iced::Task; use liana::{ descriptors::LianaPolicy, miniscript::bitcoin::{bip32::Fingerprint, psbt::Psbt, Network, Txid}, @@ -36,8 +36,8 @@ use crate::{ }; pub trait Action { - fn load(&self, _daemon: Arc) -> Command { - Command::none() + fn load(&self, _daemon: Arc) -> Task { + Task::none() } fn subscription(&self) -> Subscription { Subscription::none() @@ -47,8 +47,8 @@ pub trait Action { _daemon: Arc, _message: Message, _tx: &mut SpendTx, - ) -> Command { - Command::none() + ) -> Task { + Task::none() } fn view<'a>(&'a self, content: Element<'a, view::Message>) -> Element<'a, view::Message>; } @@ -120,11 +120,11 @@ impl PsbtState { } } - pub fn load(&self, daemon: Arc) -> Command { + pub fn load(&self, daemon: Arc) -> Task { if let Some(action) = &self.action { action.as_ref().load(daemon) } else { - Command::none() + Task::none() } } @@ -133,12 +133,12 @@ impl PsbtState { daemon: Arc, cache: &Cache, message: Message, - ) -> Command { + ) -> Task { match message { Message::View(view::Message::Spend(view::SpendTxMessage::Cancel)) => { if let Some(PsbtAction::Sign(SignAction { display_modal, .. })) = &mut self.action { *display_modal = false; - return Command::none(); + return Task::none(); } self.action = None; @@ -149,7 +149,7 @@ impl PsbtState { Message::View(view::Message::Spend(view::SpendTxMessage::Sign)) => { if let Some(PsbtAction::Sign(SignAction { display_modal, .. })) = &mut self.action { *display_modal = true; - return Command::none(); + return Task::none(); } let action = SignAction::new( @@ -171,7 +171,7 @@ impl PsbtState { } Message::View(view::Message::Spend(view::SpendTxMessage::Broadcast)) => { let outpoints: Vec<_> = self.tx.coins.keys().cloned().collect(); - return Command::perform( + return Task::perform( async move { daemon .list_coins(&[CoinStatus::Spending], &outpoints) @@ -231,7 +231,7 @@ impl PsbtState { } } }; - Command::none() + Task::none() } pub fn view<'a>(&'a self, cache: &'a Cache) -> Element<'a, view::Message> { @@ -265,7 +265,7 @@ impl Action for SaveAction { daemon: Arc, message: Message, tx: &mut SpendTx, - ) -> Command { + ) -> Task { match message { Message::View(view::Message::Spend(view::SpendTxMessage::Confirm)) => { let daemon = daemon.clone(); @@ -276,7 +276,7 @@ impl Action for SaveAction { labels.insert(label_item_from_str(item), Some(label.clone())); } } - return Command::perform( + return Task::perform( async move { daemon.update_spend_tx(&psbt).await?; daemon.update_labels(&labels).await.map_err(|e| e.into()) @@ -290,7 +290,7 @@ impl Action for SaveAction { }, _ => {} } - Command::none() + Task::none() } fn view<'a>(&'a self, content: Element<'a, view::Message>) -> Element<'a, view::Message> { modal::Modal::new( @@ -316,13 +316,13 @@ impl Action for BroadcastAction { daemon: Arc, message: Message, tx: &mut SpendTx, - ) -> Command { + ) -> Task { match message { Message::View(view::Message::Spend(view::SpendTxMessage::Confirm)) => { let daemon = daemon.clone(); let psbt = tx.psbt.clone(); self.error = None; - return Command::perform( + return Task::perform( async move { daemon .broadcast_spend_tx(&psbt.unsigned_tx.compute_txid()) @@ -341,7 +341,7 @@ impl Action for BroadcastAction { }, _ => {} } - Command::none() + Task::none() } fn view<'a>(&'a self, content: Element<'a, view::Message>) -> Element<'a, view::Message> { modal::Modal::new( @@ -369,13 +369,13 @@ impl Action for DeleteAction { daemon: Arc, message: Message, tx: &mut SpendTx, - ) -> Command { + ) -> Task { match message { Message::View(view::Message::Spend(view::SpendTxMessage::Confirm)) => { let daemon = daemon.clone(); let psbt = tx.psbt.clone(); self.error = None; - return Command::perform( + return Task::perform( async move { daemon .delete_spend_tx(&psbt.unsigned_tx.compute_txid()) @@ -391,7 +391,7 @@ impl Action for DeleteAction { }, _ => {} } - Command::none() + Task::none() } fn view<'a>(&'a self, content: Element<'a, view::Message>) -> Element<'a, view::Message> { modal::Modal::new( @@ -443,7 +443,7 @@ impl Action for SignAction { daemon: Arc, message: Message, tx: &mut SpendTx, - ) -> Command { + ) -> Task { match message { Message::View(view::Message::SelectHardwareWallet(i)) => { if let Some(HardwareWallet::Supported { @@ -456,14 +456,14 @@ impl Action for SignAction { self.signing.insert(*fingerprint); let psbt = tx.psbt.clone(); let fingerprint = *fingerprint; - return Command::perform( + return Task::perform( sign_psbt(self.wallet.clone(), device.clone(), psbt), move |res| Message::Signed(fingerprint, res), ); } } Message::View(view::Message::Spend(view::SpendTxMessage::SelectHotSigner)) => { - return Command::perform( + return Task::perform( sign_psbt_with_hot_signer(self.wallet.clone(), tx.psbt.clone()), |(fg, res)| Message::Signed(fg, res), ); @@ -482,7 +482,7 @@ impl Action for SignAction { let daemon = daemon.clone(); merge_signatures(&mut tx.psbt, &psbt); if self.is_saved { - return Command::perform( + return Task::perform( async move { daemon.update_spend_tx(&psbt).await.map_err(|e| e.into()) }, Message::Updated, ); @@ -495,7 +495,7 @@ impl Action for SignAction { labels.insert(label_item_from_str(item), Some(label.clone())); } } - return Command::perform( + return Task::perform( async move { daemon.update_spend_tx(&psbt).await?; daemon.update_labels(&labels).await.map_err(|e| e.into()) @@ -524,7 +524,7 @@ impl Action for SignAction { }, _ => {} }; - Command::none() + Task::none() } fn view<'a>(&'a self, content: Element<'a, view::Message>) -> Element<'a, view::Message> { let content = toast::Manager::new( @@ -683,7 +683,7 @@ impl Action for UpdateAction { daemon: Arc, message: Message, tx: &mut SpendTx, - ) -> Command { + ) -> Task { match message { Message::Updated(res) => { self.processing = false; @@ -715,7 +715,7 @@ impl Action for UpdateAction { self.processing = true; self.error = None; if let Ok(updated) = Psbt::from_str(&self.updated.value) { - return Command::perform( + return Task::perform( async move { daemon.update_spend_tx(&updated).await.map_err(|e| e.into()) }, Message::Updated, ); @@ -724,7 +724,7 @@ impl Action for UpdateAction { _ => {} } - Command::none() + Task::none() } } diff --git a/liana-gui/src/app/state/psbts.rs b/liana-gui/src/app/state/psbts.rs index 0c5f59a63..173a29813 100644 --- a/liana-gui/src/app/state/psbts.rs +++ b/liana-gui/src/app/state/psbts.rs @@ -1,7 +1,7 @@ use std::str::FromStr; use std::sync::Arc; -use iced::{Command, Subscription}; +use iced::{Subscription, Task}; use liana::miniscript::bitcoin::psbt::Psbt; use liana_ui::{ @@ -76,7 +76,7 @@ impl State for PsbtsPanel { daemon: Arc, cache: &Cache, message: Message, - ) -> Command { + ) -> Task { match message { Message::View(view::Message::Reload) | Message::View(view::Message::Close) => { return self.reload(daemon, self.wallet.clone()); @@ -122,7 +122,7 @@ impl State for PsbtsPanel { } } } - Command::none() + Task::none() } fn subscription(&self) -> Subscription { @@ -137,12 +137,12 @@ impl State for PsbtsPanel { &mut self, daemon: Arc, wallet: Arc, - ) -> Command { + ) -> Task { self.wallet = wallet; self.selected_tx = None; self.import_tx = None; let daemon = daemon.clone(); - Command::perform( + Task::perform( async move { daemon .list_spend_transactions(None) @@ -192,7 +192,7 @@ impl ImportPsbtModal { daemon: Arc, _cache: &Cache, message: Message, - ) -> Command { + ) -> Task { match message { Message::Updated(res) => { self.processing = false; @@ -213,7 +213,7 @@ impl ImportPsbtModal { self.processing = true; self.error = None; let imported = Psbt::from_str(&self.imported.value).expect("Already checked"); - return Command::perform( + return Task::perform( async move { daemon .update_spend_tx(&imported) @@ -227,6 +227,6 @@ impl ImportPsbtModal { _ => {} } - Command::none() + Task::none() } } diff --git a/liana-gui/src/app/state/receive.rs b/liana-gui/src/app/state/receive.rs index a2009cde1..d9dc81ba9 100644 --- a/liana-gui/src/app/state/receive.rs +++ b/liana-gui/src/app/state/receive.rs @@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet}; use std::path::PathBuf; use std::sync::Arc; -use iced::{widget::qr_code, Command, Subscription}; +use iced::{widget::qr_code, Subscription, Task}; use liana::miniscript::bitcoin::{ bip32::{ChildNumber, Fingerprint}, Address, Network, @@ -112,7 +112,7 @@ impl State for ReceivePanel { daemon: Arc, cache: &Cache, message: Message, - ) -> Command { + ) -> Task { match message { Message::View(view::Message::Label(_, _)) | Message::LabelsUpdated(_) => { match self.labels_edited.update( @@ -123,7 +123,7 @@ impl State for ReceivePanel { Ok(cmd) => cmd, Err(e) => { self.warning = Some(e); - Command::none() + Task::none() } } } @@ -136,11 +136,11 @@ impl State for ReceivePanel { } Err(e) => self.warning = Some(e), } - Command::none() + Task::none() } Message::View(view::Message::Close) => { self.modal = Modal::None; - Command::none() + Task::none() } Message::View(view::Message::Select(i)) => { self.modal = Modal::VerifyAddress(VerifyAddressModal::new( @@ -154,11 +154,11 @@ impl State for ReceivePanel { .get(i) .expect("Must be present"), )); - Command::none() + Task::none() } Message::View(view::Message::Next) => { let daemon = daemon.clone(); - Command::perform( + Task::perform( async move { daemon .get_new_address() @@ -178,13 +178,13 @@ impl State for ReceivePanel { self.modal = Modal::ShowQrCode(modal); } } - Command::none() + Task::none() } _ => { if let Modal::VerifyAddress(ref mut m) = self.modal { m.update(daemon, cache, message) } else { - Command::none() + Task::none() } } } @@ -194,10 +194,10 @@ impl State for ReceivePanel { &mut self, _daemon: Arc, wallet: Arc, - ) -> Command { + ) -> Task { self.wallet = wallet; self.addresses = Addresses::default(); - Command::none() + Task::none() } } @@ -253,13 +253,13 @@ impl VerifyAddressModal { _daemon: Arc, _cache: &Cache, message: Message, - ) -> Command { + ) -> Task { match message { Message::HardwareWallets(msg) => match self.hws.update(msg) { Ok(cmd) => cmd.map(Message::HardwareWallets), Err(e) => { self.warning = Some(e.into()); - Command::none() + Task::none() } }, Message::Verified(fg, res) => { @@ -267,7 +267,7 @@ impl VerifyAddressModal { if let Err(e) = res { self.warning = Some(e); } - Command::none() + Task::none() } Message::View(view::Message::SelectHardwareWallet(i)) => { if let Some(HardwareWallet::Supported { @@ -279,15 +279,15 @@ impl VerifyAddressModal { self.warning = None; self.chosen_hws.insert(*fingerprint); let fg = *fingerprint; - Command::perform( + Task::perform( verify_address(device.clone(), self.derivation_index), move |res| Message::Verified(fg, res), ) } else { - Command::none() + Task::none() } } - _ => Command::none(), + _ => Task::none(), } } } diff --git a/liana-gui/src/app/state/recovery.rs b/liana-gui/src/app/state/recovery.rs index a9a9f4349..aded04545 100644 --- a/liana-gui/src/app/state/recovery.rs +++ b/liana-gui/src/app/state/recovery.rs @@ -2,7 +2,7 @@ use std::collections::HashSet; use std::str::FromStr; use std::sync::Arc; -use iced::Command; +use iced::Task; use liana::miniscript::bitcoin::{ bip32::{DerivationPath, Fingerprint}, @@ -101,7 +101,7 @@ impl State for RecoveryPanel { daemon: Arc, cache: &Cache, message: Message, - ) -> Command { + ) -> Task { match message { Message::Coins(res) => match res { Err(e) => self.warning = Some(e), @@ -153,7 +153,7 @@ impl State for RecoveryPanel { .get(self.selected_path.expect("A path must be selected")) .map(|p| p.sequence); let network = cache.network; - return Command::perform( + return Task::perform( async move { let psbt = daemon .create_recovery(address, feerate_vb, sequence) @@ -192,14 +192,14 @@ impl State for RecoveryPanel { } } }; - Command::none() + Task::none() } fn reload( &mut self, daemon: Arc, wallet: Arc, - ) -> Command { + ) -> Task { let daemon = daemon.clone(); self.wallet = wallet; self.selected_path = None; @@ -207,7 +207,7 @@ impl State for RecoveryPanel { self.feerate = form::Value::default(); self.recipient = form::Value::default(); self.generated = None; - Command::perform( + Task::perform( async move { daemon .list_coins(&[CoinStatus::Unconfirmed, CoinStatus::Confirmed], &[]) diff --git a/liana-gui/src/app/state/settings/bitcoind.rs b/liana-gui/src/app/state/settings/bitcoind.rs index f9890378e..f4b5c8ce4 100644 --- a/liana-gui/src/app/state/settings/bitcoind.rs +++ b/liana-gui/src/app/state/settings/bitcoind.rs @@ -5,7 +5,7 @@ use std::str::FromStr; use std::sync::Arc; use chrono::{NaiveDate, Utc}; -use iced::{clipboard, Command}; +use iced::{clipboard, Task}; use tracing::info; use liana::miniscript::bitcoin::Network; @@ -90,7 +90,7 @@ impl State for BitcoindSettingsState { daemon: Arc, cache: &Cache, message: Message, - ) -> Command { + ) -> Task { match message { Message::DaemonConfigLoaded(res) => match res { Ok(()) => { @@ -98,7 +98,7 @@ impl State for BitcoindSettingsState { self.warning = None; if let Some(settings) = &mut self.bitcoind_settings { settings.edited(true); - return Command::perform(async {}, |_| { + return Task::perform(async {}, |_| { Message::View(view::Message::Settings( view::SettingsMessage::EditBitcoindSettings, )) @@ -106,7 +106,7 @@ impl State for BitcoindSettingsState { } if let Some(settings) = &mut self.electrum_settings { settings.edited(true); - return Command::perform(async {}, |_| { + return Task::perform(async {}, |_| { Message::View(view::Message::Settings( view::SettingsMessage::EditBitcoindSettings, )) @@ -158,7 +158,7 @@ impl State for BitcoindSettingsState { } _ => {} }; - Command::none() + Task::none() } fn view<'a>(&'a self, cache: &'a Cache) -> Element<'a, view::Message> { @@ -303,7 +303,7 @@ impl BitcoindSettings { daemon: Arc, _cache: &Cache, message: view::SettingsEditMessage, - ) -> Command { + ) -> Task { match message { view::SettingsEditMessage::Select => { if !self.processing { @@ -359,14 +359,14 @@ impl BitcoindSettings { addr: new_addr.unwrap(), })); self.processing = true; - return Command::perform(async move { daemon_config }, |cfg| { + return Task::perform(async move { daemon_config }, |cfg| { Message::LoadDaemonConfig(Box::new(cfg)) }); } } view::SettingsEditMessage::Clipboard(text) => return clipboard::write(text), }; - Command::none() + Task::none() } fn view<'a>(&self, cache: &'a Cache, can_edit: bool) -> Element<'a, view::SettingsEditMessage> { @@ -441,7 +441,7 @@ impl ElectrumSettings { daemon: Arc, _cache: &Cache, message: view::SettingsEditMessage, - ) -> Command { + ) -> Task { match message { view::SettingsEditMessage::Select => { if !self.processing { @@ -467,7 +467,7 @@ impl ElectrumSettings { addr: self.addr.value.clone(), })); self.processing = true; - return Command::perform(async move { daemon_config }, |cfg| { + return Task::perform(async move { daemon_config }, |cfg| { Message::LoadDaemonConfig(Box::new(cfg)) }); } @@ -475,7 +475,7 @@ impl ElectrumSettings { view::SettingsEditMessage::Clipboard(text) => return clipboard::write(text), _ => {} }; - Command::none() + Task::none() } fn view<'a>(&self, cache: &'a Cache, can_edit: bool) -> Element<'a, view::SettingsEditMessage> { @@ -537,7 +537,7 @@ impl RescanSetting { daemon: Arc, cache: &Cache, message: view::SettingsEditMessage, - ) -> Command { + ) -> Task { match message { view::SettingsEditMessage::FieldEdited(field, value) => { self.invalid_date = false; @@ -601,15 +601,15 @@ impl RescanSetting { } } else { self.invalid_date = true; - return Command::none(); + return Task::none(); }; if t > Utc::now().timestamp() { self.future_date = true; - return Command::none(); + return Task::none(); } self.processing = true; - info!("Asking daemon to rescan with timestamp: {}", t); - return Command::perform( + info!("Asking deamon to rescan with timestamp: {}", t); + return Task::perform( async move { daemon.start_rescan(t.try_into().expect("t cannot be inferior to 0 otherwise genesis block timestamp is chosen")) .await @@ -620,7 +620,7 @@ impl RescanSetting { } _ => {} }; - Command::none() + Task::none() } fn view<'a>(&self, cache: &'a Cache, can_edit: bool) -> Element<'a, view::SettingsEditMessage> { diff --git a/liana-gui/src/app/state/settings/mod.rs b/liana-gui/src/app/state/settings/mod.rs index d8c6505f3..64ec0b277 100644 --- a/liana-gui/src/app/state/settings/mod.rs +++ b/liana-gui/src/app/state/settings/mod.rs @@ -5,7 +5,7 @@ use std::convert::From; use std::path::PathBuf; use std::sync::Arc; -use iced::Command; +use iced::Task; use liana_ui::{component::form, widget::Element}; @@ -55,7 +55,7 @@ impl State for SettingsState { daemon: Arc, cache: &Cache, message: Message, - ) -> Command { + ) -> Task { match &message { Message::View(view::Message::Settings(view::SettingsMessage::EditBitcoindSettings)) => { self.setting = Some( @@ -71,13 +71,13 @@ impl State for SettingsState { self.setting .as_mut() .map(|s| s.reload(daemon, wallet)) - .unwrap_or_else(Command::none) + .unwrap_or_else(Task::none) } Message::View(view::Message::Settings( view::SettingsMessage::EditRemoteBackendSettings, )) => { self.setting = Some(BackendSettingsState::new().into()); - Command::none() + Task::none() } Message::View(view::Message::Settings(view::SettingsMessage::AboutSection)) => { self.setting = Some(AboutSettingsState::default().into()); @@ -85,7 +85,7 @@ impl State for SettingsState { self.setting .as_mut() .map(|s| s.reload(daemon, wallet)) - .unwrap_or_else(Command::none) + .unwrap_or_else(Task::none) } Message::View(view::Message::Settings(view::SettingsMessage::EditWalletSettings)) => { self.setting = Some( @@ -95,20 +95,20 @@ impl State for SettingsState { self.setting .as_mut() .map(|s| s.reload(daemon, wallet)) - .unwrap_or_else(Command::none) + .unwrap_or_else(Task::none) } Message::WalletUpdated(Ok(wallet)) => { self.wallet = wallet.clone(); self.setting .as_mut() .map(|s| s.update(daemon, cache, message)) - .unwrap_or_else(Command::none) + .unwrap_or_else(Task::none) } _ => self .setting .as_mut() .map(|s| s.update(daemon, cache, message)) - .unwrap_or_else(Command::none), + .unwrap_or_else(Task::none), } } @@ -132,10 +132,10 @@ impl State for SettingsState { &mut self, _daemon: Arc, wallet: Arc, - ) -> Command { + ) -> Task { self.setting = None; self.wallet = wallet; - Command::none() + Task::none() } } @@ -161,7 +161,7 @@ impl State for AboutSettingsState { daemon: Arc, _cache: &Cache, message: Message, - ) -> Command { + ) -> Task { if let Message::Info(res) = message { match res { Ok(info) => { @@ -175,15 +175,15 @@ impl State for AboutSettingsState { } } - Command::none() + Task::none() } fn reload( &mut self, daemon: Arc, _wallet: Arc, - ) -> Command { - Command::perform( + ) -> Task { + Task::perform( async move { daemon.get_info().await.map_err(|e| e.into()) }, Message::Info, ) @@ -231,20 +231,20 @@ impl State for BackendSettingsState { daemon: Arc, _cache: &Cache, message: Message, - ) -> Command { + ) -> Task { match message { Message::View(view::Message::Settings( view::SettingsMessage::RemoteBackendSettings(message), )) => match message { view::RemoteBackendSettingsMessage::SendInvitation => { if !self.email_form.valid { - return Command::none(); + return Task::none(); } let email = self.email_form.value.clone(); self.processing = true; self.success = false; self.warning = None; - Command::perform( + Task::perform( async move { daemon.send_wallet_invitation(&email).await?; Ok(()) @@ -262,7 +262,7 @@ impl State for BackendSettingsState { self.email_form.value = email; self.success = false; } - Command::none() + Task::none() } }, Message::Updated(res) => { @@ -274,9 +274,9 @@ impl State for BackendSettingsState { self.warning = Some(e); } } - Command::none() + Task::none() } - _ => Command::none(), + _ => Task::none(), } } } diff --git a/liana-gui/src/app/state/settings/wallet.rs b/liana-gui/src/app/state/settings/wallet.rs index e560ac8a1..a3564cef8 100644 --- a/liana-gui/src/app/state/settings/wallet.rs +++ b/liana-gui/src/app/state/settings/wallet.rs @@ -3,7 +3,7 @@ use std::convert::From; use std::path::PathBuf; use std::sync::Arc; -use iced::{Command, Subscription}; +use iced::{Subscription, Task}; use liana::{ descriptors::LianaDescriptor, @@ -107,7 +107,7 @@ impl State for WalletSettingsState { daemon: Arc, cache: &Cache, message: Message, - ) -> Command { + ) -> Task { match message { Message::WalletUpdated(res) => { self.processing = false; @@ -122,7 +122,7 @@ impl State for WalletSettingsState { } Err(e) => self.warning = Some(e), }; - Command::none() + Task::none() } } Message::View(view::Message::Settings( @@ -135,13 +135,13 @@ impl State for WalletSettingsState { { name.value = value; } - Command::none() + Task::none() } Message::View(view::Message::Settings(view::SettingsMessage::Save)) => { self.modal = None; self.processing = true; self.updated = false; - Command::perform( + Task::perform( update_keys_aliases( self.data_dir.clone(), cache.network, @@ -157,7 +157,7 @@ impl State for WalletSettingsState { } Message::View(view::Message::Close) => { self.modal = None; - Command::none() + Task::none() } Message::View(view::Message::Settings(view::SettingsMessage::RegisterWallet)) => { self.modal = Some(RegisterWalletModal::new( @@ -165,13 +165,13 @@ impl State for WalletSettingsState { self.wallet.clone(), cache.network, )); - Command::none() + Task::none() } _ => self .modal .as_mut() .map(|m| m.update(daemon, cache, message)) - .unwrap_or_else(Command::none), + .unwrap_or_else(Task::none), } } @@ -179,11 +179,11 @@ impl State for WalletSettingsState { &mut self, daemon: Arc, wallet: Arc, - ) -> Command { + ) -> Task { self.descriptor = wallet.main_descriptor.clone(); self.keys_aliases = Self::keys_aliases(&wallet); self.wallet = wallet; - Command::perform( + Task::perform( async move { daemon.get_info().await.map_err(|e| e.into()) }, Message::Info, ) @@ -244,18 +244,18 @@ impl RegisterWalletModal { daemon: Arc, cache: &Cache, message: Message, - ) -> Command { + ) -> Task { match message { Message::View(view::Message::Reload) => { self.chosen_hw = None; self.warning = None; - Command::none() + Task::none() } Message::HardwareWallets(msg) => match self.hws.update(msg) { Ok(cmd) => cmd.map(Message::HardwareWallets), Err(e) => { self.warning = Some(e.into()); - Command::none() + Task::none() } }, Message::WalletUpdated(res) => { @@ -275,7 +275,7 @@ impl RegisterWalletModal { } } } - Command::none() + Task::none() } Message::View(view::Message::SelectHardwareWallet(i)) => { if let Some(HardwareWallet::Supported { @@ -286,7 +286,7 @@ impl RegisterWalletModal { { self.chosen_hw = Some(i); self.processing = true; - Command::perform( + Task::perform( register_wallet( self.data_dir.clone(), cache.network, @@ -298,10 +298,10 @@ impl RegisterWalletModal { Message::WalletUpdated, ) } else { - Command::none() + Task::none() } } - _ => Command::none(), + _ => Task::none(), } } } diff --git a/liana-gui/src/app/state/spend/mod.rs b/liana-gui/src/app/state/spend/mod.rs index 61a581f0a..2b493277f 100644 --- a/liana-gui/src/app/state/spend/mod.rs +++ b/liana-gui/src/app/state/spend/mod.rs @@ -3,7 +3,7 @@ mod step; use std::collections::HashSet; use std::sync::Arc; -use iced::Command; +use iced::Task; use liana::miniscript::bitcoin::{Network, OutPoint}; use liana_ui::widget::Element; @@ -88,7 +88,7 @@ impl State for CreateSpendPanel { daemon: Arc, cache: &Cache, message: Message, - ) -> Command { + ) -> Task { if matches!(message, Message::View(view::Message::Close)) { return redirect(Menu::PSBTs); } @@ -114,18 +114,18 @@ impl State for CreateSpendPanel { return step.update(daemon, cache, message); } - Command::none() + Task::none() } fn reload( &mut self, daemon: Arc, _wallet: Arc, - ) -> Command { + ) -> Task { let daemon1 = daemon.clone(); let daemon2 = daemon.clone(); - Command::batch(vec![ - Command::perform( + Task::batch(vec![ + Task::perform( async move { daemon1 .list_coins(&[CoinStatus::Unconfirmed, CoinStatus::Confirmed], &[]) @@ -135,7 +135,7 @@ impl State for CreateSpendPanel { }, Message::Coins, ), - Command::perform( + Task::perform( async move { let coins = daemon .list_coins(&[CoinStatus::Unconfirmed, CoinStatus::Confirmed], &[]) diff --git a/liana-gui/src/app/state/spend/step.rs b/liana-gui/src/app/state/spend/step.rs index 98f78021a..e1079c4d1 100644 --- a/liana-gui/src/app/state/spend/step.rs +++ b/liana-gui/src/app/state/spend/step.rs @@ -6,7 +6,7 @@ use std::{ sync::Arc, }; -use iced::{Command, Subscription}; +use iced::{Subscription, Task}; use liana::{ descriptors::LianaDescriptor, miniscript::bitcoin::{ @@ -59,7 +59,7 @@ pub trait Step { daemon: Arc, cache: &Cache, message: Message, - ) -> Command; + ) -> Task; fn apply(&self, _draft: &mut TransactionDraft) {} fn interrupt(&mut self) {} fn load(&mut self, _draft: &TransactionDraft) {} @@ -394,7 +394,7 @@ impl Step for DefineSpend { daemon: Arc, cache: &Cache, message: Message, - ) -> Command { + ) -> Task { match message { Message::View(view::Message::CreateSpend(msg)) => { match msg { @@ -413,7 +413,7 @@ impl Step for DefineSpend { .as_slice(), self.timelock, ); - return Command::none(); + return Task::none(); } view::CreateSpendMessage::AddRecipient => { self.recipients.push(Recipient::default()); @@ -483,7 +483,7 @@ impl Step for DefineSpend { } let feerate_vb = self.feerate.value.parse::().unwrap_or(0); self.warning = None; - return Command::perform( + return Task::perform( async move { daemon .create_spend_tx(&inputs, &outputs, feerate_vb, None) @@ -535,7 +535,7 @@ impl Step for DefineSpend { Message::Psbt(res) => match res { Ok(psbt) => { self.generated = Some(psbt); - return Command::perform(async {}, |_| Message::View(view::Message::Next)); + return Task::perform(async {}, |_| Message::View(view::Message::Next)); } Err(e) => self.warning = Some(e), }, @@ -577,7 +577,7 @@ impl Step for DefineSpend { }, _ => {} }; - Command::none() + Task::none() } fn apply(&self, draft: &mut TransactionDraft) { @@ -799,11 +799,11 @@ impl Step for SaveSpend { daemon: Arc, cache: &Cache, message: Message, - ) -> Command { + ) -> Task { if let Some((psbt_state, _)) = &mut self.spend { psbt_state.update(daemon, cache, message) } else { - Command::none() + Task::none() } } diff --git a/liana-gui/src/app/state/transactions.rs b/liana-gui/src/app/state/transactions.rs index 2abc4f4e0..b01573e98 100644 --- a/liana-gui/src/app/state/transactions.rs +++ b/liana-gui/src/app/state/transactions.rs @@ -5,7 +5,7 @@ use std::{ time::{SystemTime, UNIX_EPOCH}, }; -use iced::Command; +use iced::Task; use liana::{ miniscript::bitcoin::{OutPoint, Txid}, spend::{SpendCreationError, MAX_FEERATE}, @@ -110,7 +110,7 @@ impl State for TransactionsPanel { daemon: Arc, _cache: &Cache, message: Message, - ) -> Command { + ) -> Task { match message { Message::HistoryTransactions(res) => match res { Err(e) => self.warning = Some(e), @@ -186,9 +186,9 @@ impl State for TransactionsPanel { ) }) .collect(); - return Command::perform( + return Task::perform( async move { - daemon + let res = daemon .list_coins(&[CoinStatus::Spending], &outpoints) .await .map(|res| { @@ -197,9 +197,10 @@ impl State for TransactionsPanel { .filter_map(|c| c.spend_info.map(|info| info.txid)) .collect() }) - .map_err(|e| e.into()) + .map_err(|e| e.into()); + (Box::new(tx), is_cancel, res) }, - move |res| Message::RbfModal(Box::new(tx), is_cancel, res), + |(tx, is_cancel, res)| Message::RbfModal(tx, is_cancel, res), ); } } @@ -230,7 +231,7 @@ impl State for TransactionsPanel { let daemon = daemon.clone(); let last_tx_date = last.time.unwrap(); self.processing = true; - return Command::perform( + return Task::perform( async move { let mut limit = HISTORY_EVENT_PAGE_SIZE; let mut txs = @@ -282,18 +283,18 @@ impl State for TransactionsPanel { return match &mut self.modal { TransactionsModal::CreateRbf(modal) => modal.update(daemon, _cache, message), TransactionsModal::Export(modal) => modal.update(message), - TransactionsModal::None => Command::none(), + TransactionsModal::None => Task::none(), }; } }; - Command::none() + Task::none() } fn reload( &mut self, daemon: Arc, _wallet: Arc, - ) -> Command { + ) -> Task { self.selected_tx = None; let now: u32 = SystemTime::now() .duration_since(UNIX_EPOCH) @@ -301,7 +302,7 @@ impl State for TransactionsPanel { .as_secs() .try_into() .unwrap(); - Command::batch(vec![Command::perform( + Task::batch(vec![Task::perform( async move { let mut txs = daemon .list_history_txs(0, now, HISTORY_EVENT_PAGE_SIZE) @@ -395,7 +396,7 @@ impl CreateRbfModal { daemon: Arc, _cache: &Cache, message: Message, - ) -> Command { + ) -> Task { match message { Message::View(view::Message::CreateRbf(view::CreateRbfMessage::FeerateEdited(s))) => { self.warning = None; @@ -424,14 +425,14 @@ impl CreateRbfModal { Message::View(view::Message::CreateRbf(view::CreateRbfMessage::Confirm)) => { self.warning = None; self.processing = true; - return Command::perform( + return Task::perform( rbf(daemon, self.tx.clone(), self.is_cancel, self.feerate_vb), Message::RbfPsbt, ); } _ => {} } - Command::none() + Task::none() } fn view<'a>(&'a self, content: Element<'a, view::Message>) -> Element { let modal = Modal::new( diff --git a/liana-gui/src/app/view/coins.rs b/liana-gui/src/app/view/coins.rs index 9fa2b2eee..def964f4b 100644 --- a/liana-gui/src/app/view/coins.rs +++ b/liana-gui/src/app/view/coins.rs @@ -46,7 +46,7 @@ pub fn coins_view<'a>( }, )), ) - .align_items(Alignment::Center) + .align_x(Alignment::Center) .spacing(30) .into() } @@ -84,7 +84,7 @@ fn coin_list_view<'a>( // It is not possible to know if a coin is a // change coin or not so for now, From is // enough - p1_regular("From").style(color::GREY_3), + p1_regular("From").color(color::GREY_3), ) .push(p1_regular(label)), ) @@ -101,7 +101,7 @@ fn coin_list_view<'a>( // It is not possible to know if a coin is a // change coin or not so for now, From is // enough - p1_regular("From").style(color::GREY_3), + p1_regular("From").color(color::GREY_3), ) .push(p1_regular(label)), ) @@ -123,14 +123,14 @@ fn coin_list_view<'a>( coin_sequence_label(seq, timelock as u32) }) .spacing(10) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill), ) .push(amount(&coin.amount)) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(20), ) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) .padding(10) .on_press(Message::Select(index)), ) @@ -156,7 +156,7 @@ fn coin_list_view<'a>( if blockheight > b as u32 + timelock as u32 { Some(Container::new( p1_bold("One of the recovery path is available") - .style(color::RED), + .color(color::RED), )) } else { Some(Container::new(p1_bold(format!( @@ -174,72 +174,72 @@ fn coin_list_view<'a>( Column::new() .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( p2_regular("Address label:") .bold() - .style(color::GREY_2), + .color(color::GREY_2), ) .push(if let Some(label) = labels.get(&address) { - p2_regular(label).style(color::GREY_2) + p2_regular(label).color(color::GREY_2) } else { - p2_regular("No label").style(color::GREY_2) + p2_regular("No label").color(color::GREY_2) }) .spacing(5), ) .push( Row::new() - .align_items(Alignment::Center) - .push(p2_regular("Address:").bold().style(color::GREY_2)) + .align_y(Alignment::Center) + .push(p2_regular("Address:").bold().color(color::GREY_2)) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( p2_regular(address.clone()) - .style(color::GREY_2), + .color(color::GREY_2), ) .push( Button::new(icon::clipboard_icon()) .on_press(Message::Clipboard( address.clone(), )) - .style(theme::Button::TransparentBorder), + .style(theme::button::transparent_border), ), ) .spacing(5), ) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( p2_regular("Deposit transaction label:") .bold() - .style(color::GREY_2), + .color(color::GREY_2), ) .push(if let Some(label) = labels.get(&txid) { - p2_regular(label).style(color::GREY_2) + p2_regular(label).color(color::GREY_2) } else { - p2_regular("No label").style(color::GREY_2) + p2_regular("No label").color(color::GREY_2) }) .spacing(5), ) .push( Row::new() - .align_items(Alignment::Center) - .push(p2_regular("Outpoint:").bold().style(color::GREY_2)) + .align_y(Alignment::Center) + .push(p2_regular("Outpoint:").bold().color(color::GREY_2)) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( p2_regular(format!("{}", coin.outpoint)) - .style(color::GREY_2), + .color(color::GREY_2), ) .push( Button::new(icon::clipboard_icon()) .on_press(Message::Clipboard( coin.outpoint.to_string(), )) - .style(theme::Button::TransparentBorder), + .style(theme::button::transparent_border), ), ) .spacing(5), @@ -247,9 +247,9 @@ fn coin_list_view<'a>( .push_maybe(coin.block_height.map(|b| { Row::new() .push( - p2_regular("Block height:").bold().style(color::GREY_2), + p2_regular("Block height:").bold().color(color::GREY_2), ) - .push(p2_regular(format!("{}", b)).style(color::GREY_2)) + .push(p2_regular(format!("{}", b)).color(color::GREY_2)) .spacing(5) })), ) @@ -257,7 +257,7 @@ fn coin_list_view<'a>( Column::new() .push( Row::new() - .push(p2_regular("Spend txid:").bold().style(color::GREY_2)) + .push(p2_regular("Spend txid:").bold().color(color::GREY_2)) .push(p2_regular(format!("{}", info.txid))) .spacing(5), ) @@ -266,13 +266,13 @@ fn coin_list_view<'a>( .push( p2_regular("Spend block height:") .bold() - .style(color::GREY_2), + .color(color::GREY_2), ) .push(p2_regular(format!("{}", height))) .spacing(5) } else { Row::new().push( - p2_regular("Not in a block").bold().style(color::GREY_2), + p2_regular("Not in a block").bold().color(color::GREY_2), ) }) .spacing(5) @@ -291,7 +291,7 @@ fn coin_list_view<'a>( None }), ) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) } pub fn coin_sequence_label<'a, T: 'a>(seq: u32, timelock: u32) -> Container<'a, T> { @@ -301,30 +301,30 @@ pub fn coin_sequence_label<'a, T: 'a>(seq: u32, timelock: u32) -> Container<'a, .spacing(5) .push(icon::clock_icon().width(Length::Fixed(20.0))) .push(p2_regular("Expired")) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) .padding(10) - .style(theme::Container::Pill(theme::Pill::Warning)) + .style(theme::pill::warning) } else if seq < timelock * 10 / 100 { Container::new( Row::new() .spacing(5) .push(icon::clock_icon().width(Length::Fixed(20.0))) .push(p2_regular(expire_message(seq))) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) .padding(10) - .style(theme::Container::Pill(theme::Pill::Simple)) + .style(theme::pill::simple) } else { Container::new( Row::new() .spacing(5) .push(icon::clock_icon().width(Length::Fixed(20.0))) - .push(p2_regular(expire_message(seq)).style(color::GREY_3)) - .align_items(Alignment::Center), + .push(p2_regular(expire_message(seq)).color(color::GREY_3)) + .align_y(Alignment::Center), ) .padding(10) - .style(theme::Container::Pill(theme::Pill::Simple)) + .style(theme::pill::simple) } } diff --git a/liana-gui/src/app/view/home.rs b/liana-gui/src/app/view/home.rs index 55f48aa06..58d6a89bc 100644 --- a/liana-gui/src/app/view/home.rs +++ b/liana-gui/src/app/view/home.rs @@ -69,13 +69,13 @@ pub fn home_view<'a>( SyncStatus::WalletFullScan => text("Syncing"), _ => text("Checking for new transactions"), } - .style(color::GREY_2), + .color(color::GREY_2), ) .push(spinner::typing_text_carousel( "...", true, Duration::from_millis(2000), - |content| text(content).style(color::GREY_2), + |content| text(content).color(color::GREY_2), )), ) } else { @@ -86,9 +86,9 @@ pub fn home_view<'a>( Some( Row::new() .spacing(10) - .push(text("+").size(H3_SIZE).style(color::GREY_3)) + .push(text("+").size(H3_SIZE).color(color::GREY_3)) .push(unconfirmed_amount_with_size(unconfirmed_balance, H3_SIZE)) - .push(text("unconfirmed").size(H3_SIZE).style(color::GREY_3)), + .push(text("unconfirmed").size(H3_SIZE).color(color::GREY_3)), ) } else { None @@ -100,7 +100,7 @@ pub fn home_view<'a>( Container::new( Row::new() .spacing(15) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( h4_regular(format!( "≈ {} left before first recovery path becomes available.", @@ -111,20 +111,20 @@ pub fn home_view<'a>( .push( icon::tooltip_icon() .size(20) - .style(color::GREY_3) + .color(color::GREY_3) .width(Length::Fixed(20.0)), ) .width(Length::Fill), ) .padding(25) - .style(theme::Card::Border) + .style(theme::card::border) }) } else { Some( Container::new( Row::new() .spacing(15) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( h4_regular(format!( "Recovery path is or will soon be available for {} coin(s).", @@ -140,7 +140,7 @@ pub fn home_view<'a>( ), ) .padding(25) - .style(theme::Card::Invalid), + .style(theme::card::invalid), ) }) .push( @@ -164,11 +164,11 @@ pub fn home_view<'a>( "See more" }) .width(Length::Fill) - .horizontal_alignment(alignment::Horizontal::Center), + .align_x(alignment::Horizontal::Center), ) .width(Length::Fill) .padding(15) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) .on_press_maybe(if !processing { Some(Message::Next) } else { @@ -176,7 +176,7 @@ pub fn home_view<'a>( }), ) .width(Length::Fill) - .style(theme::Container::Card(theme::Card::Simple)), + .style(theme::card::simple), ) } else { None @@ -193,7 +193,7 @@ fn event_list_view(event: &Payment) -> Element<'_, Message> { event .address_label .as_ref() - .map(|label| p1_regular(format!("address label: {}", label)).style(color::GREY_3)) + .map(|label| p1_regular(format!("address label: {}", label)).color(color::GREY_3)) }; if event.kind == PaymentKind::Incoming { if let Some(t) = event.time { @@ -297,8 +297,8 @@ pub fn payment_view<'a>( }) .push_maybe(tx.fee_amount.map(|fee_amount| { Row::new() - .align_items(Alignment::Center) - .push(h3("Miner fee: ").style(color::GREY_3)) + .align_y(Alignment::Center) + .push(h3("Miner fee: ").color(color::GREY_3)) .push(amount_with_size(&fee_amount, H3_SIZE)) .push(text(" ").size(H3_SIZE)) .push( @@ -307,7 +307,7 @@ pub fn payment_view<'a>( fee_amount.to_sat() / tx.tx.vsize() as u64 )) .size(H4_SIZE) - .style(color::GREY_3), + .color(color::GREY_3), ) })) .push(card::simple( @@ -325,11 +325,11 @@ pub fn payment_view<'a>( .push( Row::new() .width(Length::Fill) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push(Container::new(text("Txid:").bold()).width(Length::Fill)) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push(Container::new( text(format!("{}", tx.tx.compute_txid())).small(), )) @@ -338,7 +338,7 @@ pub fn payment_view<'a>( .on_press(Message::Clipboard( tx.tx.compute_txid().to_string(), )) - .style(theme::Button::TransparentBorder), + .style(theme::button::transparent_border), ) .width(Length::Shrink), ), diff --git a/liana-gui/src/app/view/hw.rs b/liana-gui/src/app/view/hw.rs index 4c15ef5fa..00759e7d3 100644 --- a/liana-gui/src/app/view/hw.rs +++ b/liana-gui/src/app/view/hw.rs @@ -69,7 +69,7 @@ pub fn hw_list_view( kind, pairing_code, .. } => hw::locked_hardware_wallet(kind, pairing_code.as_ref()), }) - .style(theme::Button::Border) + .style(theme::button::container_border) .width(Length::Fill); if !signing { if let HardwareWallet::Supported { registered, .. } = hw { @@ -80,7 +80,7 @@ pub fn hw_list_view( } Container::new(bttn) .width(Length::Fill) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) .into() } @@ -137,14 +137,14 @@ pub fn hw_list_view_for_registration( kind, pairing_code, .. } => hw::locked_hardware_wallet(kind, pairing_code.as_ref()), }) - .style(theme::Button::Border) + .style(theme::button::container_border) .width(Length::Fill); if !processing && hw.is_supported() { bttn = bttn.on_press(Message::SelectHardwareWallet(i)); } Container::new(bttn) .width(Length::Fill) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) .into() } @@ -222,13 +222,13 @@ pub fn hw_list_view_verify_address( ), }; let mut bttn = Button::new(content) - .style(theme::Button::Border) + .style(theme::button::container_border) .width(Length::Fill); if selectable && hw.is_supported() { bttn = bttn.on_press(Message::SelectHardwareWallet(i)); } Container::new(bttn) .width(Length::Fill) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) .into() } diff --git a/liana-gui/src/app/view/label.rs b/liana-gui/src/app/view/label.rs index 94826f9cd..b0cf1efc9 100644 --- a/liana-gui/src/app/view/label.rs +++ b/liana-gui/src/app/view/label.rs @@ -28,7 +28,7 @@ pub fn label_editable( ) ) .spacing(5) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) .into(); } @@ -61,7 +61,7 @@ pub fn label_editing( button::secondary(None, "Cancel").on_press(view::message::LabelMessage::Cancel) ) .spacing(5) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) .into(); e.map(move |msg| view::Message::Label(labelled.clone(), msg)) diff --git a/liana-gui/src/app/view/mod.rs b/liana-gui/src/app/view/mod.rs index d6ba29ee7..4e6d3ea16 100644 --- a/liana-gui/src/app/view/mod.rs +++ b/liana-gui/src/app/view/mod.rs @@ -38,7 +38,7 @@ use crate::app::{cache::Cache, error::Error, menu::Menu}; fn menu_green_bar<'a, T: 'a>() -> Container<'a, T> { Container::new(Space::with_width(Length::Fixed(2.0))) .height(Length::Fixed(50.0)) - .style(theme::Container::Custom(color::GREEN)) + .style(theme::container::custom(color::GREEN)) } pub fn sidebar<'a>(menu: &Menu, cache: &'a Cache) -> Container<'a, Message> { @@ -77,7 +77,7 @@ pub fn sidebar<'a>(menu: &Menu, cache: &'a Cache) -> Container<'a, Message> { ) } else { row!(button::menu(Some(coins_icon()), "Coins") - .style(theme::Button::Menu(false)) + .style(theme::button::menu) .on_press(Message::Menu(Menu::Coins)) .width(iced::Length::Fill)) }; @@ -161,14 +161,14 @@ pub fn sidebar<'a>(menu: &Menu, cache: &'a Cache) -> Container<'a, Message> { .push_maybe(cache.rescan_progress.map(|p| { Container::new(text(format!(" Rescan...{:.2}% ", p * 100.0))) .padding(5) - .style(theme::Pill::Simple) + .style(theme::pill::simple) })) .push(settings_button), ) .height(Length::Shrink), ), ) - .style(theme::Container::Foreground) + .style(theme::container::foreground) } pub fn dashboard<'a, T: Into>>( @@ -194,9 +194,8 @@ pub fn dashboard<'a, T: Into>>( .max_width(1500), Space::with_width(Length::FillPortion(1)), ))) - .center_x() - .style(theme::Container::Background) - .width(Length::Fill) + .center_x(Length::Fill) + .style(theme::container::background) .height(Length::Fill), ) .width(Length::FillPortion(10)), @@ -226,11 +225,11 @@ pub fn modal<'a, T: Into>, F: Into>>( } else { Column::new().width(Length::Fill) }) - .align_items(iced::Alignment::Center) + .align_y(iced::Alignment::Center) .push(button::secondary(Some(cross_icon()), "Close").on_press(Message::Close)), ) .padding(10) - .style(theme::Container::Background), + .style(theme::container::background), ) .push(modal_section(Container::new(scrollable(content)))) .push_maybe(fixed_footer) @@ -241,8 +240,8 @@ pub fn modal<'a, T: Into>, F: Into>>( fn modal_section<'a, T: 'a>(menu: Container<'a, T>) -> Container<'a, T> { Container::new(menu.max_width(1500)) - .style(theme::Container::Background) - .center_x() + .style(theme::container::background) + .center_x(Length::Fill) .width(Length::Fill) .height(Length::Fill) } diff --git a/liana-gui/src/app/view/psbt.rs b/liana-gui/src/app/view/psbt.rs index d860aa4c0..52cc9a997 100644 --- a/liana-gui/src/app/view/psbt.rs +++ b/liana-gui/src/app/view/psbt.rs @@ -56,7 +56,7 @@ pub fn psbt_view<'a>( .spacing(20) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) .push(Container::new(h3("PSBT")).width(Length::Fill)) .push_maybe(if !tx.sigs.recovery_paths().is_empty() { @@ -198,14 +198,14 @@ pub fn broadcast_action<'a>( Row::new() .padding([0, 30]) .spacing(5) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push(text(txid.to_string())) .push( Button::new( - icon::clipboard_icon().style(color::GREY_3), + icon::clipboard_icon().color(color::GREY_3), ) .on_press(Message::Clipboard(txid.to_string())) - .style(theme::Button::TransparentBorder), + .style(theme::button::transparent_border), ), ) }, @@ -233,7 +233,7 @@ pub fn delete_action<'a>(warning: Option<&Error>, deleted: bool) -> Element<'a, card::simple( Column::new() .spacing(20) - .align_items(Alignment::Center) + .align_x(Alignment::Center) .push(text("Successfully deleted this transaction.")) .push(button::secondary(None, "Go back to PSBTs").on_press(Message::Close)), ) @@ -296,8 +296,8 @@ pub fn spend_header<'a>( }) .push( Row::new() - .align_items(Alignment::Center) - .push(h3("Miner fee: ").style(color::GREY_3)) + .align_y(Alignment::Center) + .push(h3("Miner fee: ").color(color::GREY_3)) .push_maybe(if tx.fee_amount.is_none() { Some(text("Missing information about transaction inputs")) } else { @@ -308,7 +308,7 @@ pub fn spend_header<'a>( .push_maybe(tx.min_feerate_vb().map(|rate| { text(format!("(~{} sats/vbyte)", &rate)) .size(H4_SIZE) - .style(color::GREY_3) + .color(color::GREY_3) })), ), ) @@ -331,7 +331,7 @@ pub fn spend_overview_view<'a>( .spacing(10) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push(text("PSBT").bold().width(Length::Fill)) .push( Row::new() @@ -351,28 +351,28 @@ pub fn spend_overview_view<'a>( .on_press(Message::Spend(SpendTxMessage::EditPsbt)), ), ) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) .push( Row::new() .push(p1_bold("Tx ID").width(Length::Fill)) .push( p2_regular(tx.psbt.unsigned_tx.compute_txid().to_string()) - .style(color::GREY_3), + .color(color::GREY_3), ) .push( - Button::new(icon::clipboard_icon().style(color::GREY_3)) + Button::new(icon::clipboard_icon().color(color::GREY_3)) .on_press(Message::Clipboard( tx.psbt.unsigned_tx.compute_txid().to_string(), )) - .style(theme::Button::TransparentBorder), + .style(theme::button::transparent_border), ) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ), ) .push(signatures(tx, desc_info, key_aliases)), ) - .style(theme::Container::Card(theme::Card::Simple)), + .style(theme::card::simple), ) .push_maybe(if tx.status == SpendStatus::Pending { Some( @@ -391,7 +391,7 @@ pub fn spend_overview_view<'a>( .width(Length::Fixed(150.0)), ) }) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(20), ) } else { @@ -411,11 +411,11 @@ pub fn signatures<'a>( scrollable( Row::new() .spacing(5) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) .push(p1_bold("Status")) - .push(icon::circle_check_icon().style(color::GREEN)) - .push(text("Ready").bold().style(color::GREEN)) + .push(icon::circle_check_icon().color(color::GREEN)) + .push(text("Ready").bold().color(color::GREEN)) .push(text(" signed by")) .push(sigs.signed_pubkeys.keys().fold( Row::new().spacing(5), @@ -425,22 +425,22 @@ pub fn signatures<'a>( tooltip::Tooltip::new( Container::new(text(alias)) .padding(10) - .style(theme::Container::Pill(theme::Pill::Simple)), + .style(theme::pill::simple), text(value.to_string()), tooltip::Position::Bottom, ) - .style(theme::Container::Card(theme::Card::Simple)), + .style(theme::card::simple), ) } else { Container::new(text(value.to_string())) .padding(10) - .style(theme::Container::Pill(theme::Pill::Simple)) + .style(theme::pill::simple) }) }, )), ) .direction(scrollable::Direction::Horizontal( - scrollable::Properties::new().width(2).scroller_width(2), + scrollable::Scrollbar::new().width(2).scroller_width(2), )), ) .padding(15) @@ -449,42 +449,42 @@ pub fn signatures<'a>( move || { Button::new( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(20) .push(p1_bold("Status")) .push( Row::new() .spacing(5) - .align_items(Alignment::Center) - .push(icon::circle_cross_icon().style(color::RED)) - .push(text("Not ready").style(color::RED)) + .align_y(Alignment::Center) + .push(icon::circle_cross_icon().color(color::RED)) + .push(text("Not ready").color(color::RED)) .width(Length::Fill), ) .push(icon::collapse_icon()), ) .padding(15) .width(Length::Fill) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) }, move || { Button::new( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(20) .push(p1_bold("Status")) .push( Row::new() .spacing(5) - .align_items(Alignment::Center) - .push(icon::circle_cross_icon().style(color::RED)) - .push(text("Not ready").style(color::RED)) + .align_y(Alignment::Center) + .push(icon::circle_cross_icon().color(color::RED)) + .push(text("Not ready").color(color::RED)) .width(Length::Fill), ) .push(icon::collapsed_icon()), ) .padding(15) .width(Length::Fill) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) }, move || { Into::>::into( @@ -521,16 +521,16 @@ fn container_from_fg( tooltip::Tooltip::new( Container::new(text(alias)) .padding(10) - .style(theme::Container::Pill(theme::Pill::Simple)), + .style(theme::pill::simple), liana_ui::widget::Text::new(fg.to_string()), tooltip::Position::Bottom, ) - .style(theme::Container::Card(theme::Card::Simple)), + .style(theme::card::simple), ) } else { Container::new(text(fg.to_string())) .padding(10) - .style(theme::Container::Pill(theme::Pill::Simple)) + .style(theme::pill::simple) } } @@ -565,13 +565,13 @@ pub fn path_view<'a>( scrollable( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( Row::new() .push(if missing_signatures == 0 { - icon::circle_check_icon().style(color::GREEN) + icon::circle_check_icon().color(color::GREEN) } else { - icon::circle_cross_icon().style(color::GREY_3) + icon::circle_cross_icon().color(color::GREY_3) }) .push(Space::with_width(Length::Fixed(20.0))), ) @@ -587,17 +587,17 @@ pub fn path_view<'a>( " from " } )) - .style(color::GREY_3), + .color(color::GREY_3), ) .push_maybe(row_unsigned) .push_maybe( (!sigs.signed_pubkeys.is_empty()) - .then_some(p1_regular(", already signed by ").style(color::GREY_3)), + .then_some(p1_regular(", already signed by ").color(color::GREY_3)), ) .push(row_signed), ) .direction(scrollable::Direction::Horizontal( - scrollable::Properties::new().width(2).scroller_width(2), + scrollable::Scrollbar::new().width(2).scroller_width(2), )) .into() } @@ -612,7 +612,7 @@ pub fn inputs_view<'a>( move || { Button::new( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( h4_bold(format!( "{} coin{} spent", @@ -625,12 +625,12 @@ pub fn inputs_view<'a>( ) .padding(20) .width(Length::Fill) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) }, move || { Button::new( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( h4_bold(format!( "{} coin{} spent", @@ -643,7 +643,7 @@ pub fn inputs_view<'a>( ) .padding(20) .width(Length::Fill) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) }, move || { tx.input @@ -662,7 +662,7 @@ pub fn inputs_view<'a>( .into() }, )) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) .into() } @@ -695,7 +695,7 @@ pub fn outputs_view<'a>( move || { Button::new( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( h4_bold(format!( "{} payment{}", @@ -708,12 +708,12 @@ pub fn outputs_view<'a>( ) .padding(20) .width(Length::Fill) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) }, move || { Button::new( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( h4_bold(format!( "{} payment{}", @@ -726,7 +726,7 @@ pub fn outputs_view<'a>( ) .padding(20) .width(Length::Fill) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) }, move || { tx.output @@ -756,12 +756,12 @@ pub fn outputs_view<'a>( .into() }, )) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) } else { Container::new(h4_bold("0 payment")) .padding(20) .width(Length::Fill) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) } }) .push_maybe( @@ -775,24 +775,24 @@ pub fn outputs_view<'a>( move || { Button::new( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push(h4_bold("Change").width(Length::Fill)) .push(icon::collapse_icon()), ) .padding(20) .width(Length::Fill) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) }, move || { Button::new( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push(h4_bold("Change").width(Length::Fill)) .push(icon::collapsed_icon()), ) .padding(20) .width(Length::Fill) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) }, move || { tx.output @@ -808,7 +808,7 @@ pub fn outputs_view<'a>( .into() }, )) - .style(theme::Container::Card(theme::Card::Simple)), + .style(theme::card::simple), ) } else { None @@ -829,7 +829,7 @@ fn input_view<'a>( .push( Row::new() .spacing(5) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( Container::new(if let Some(label) = labels_editing.get(&outpoint) { label::label_editing(vec![outpoint.clone()], label, text::P1_SIZE) @@ -848,47 +848,47 @@ fn input_view<'a>( Column::new() .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(5) - .push(p1_bold("Outpoint:").style(color::GREY_3)) - .push(p2_regular(outpoint.clone()).style(color::GREY_3)) + .push(p1_bold("Outpoint:").color(color::GREY_3)) + .push(p2_regular(outpoint.clone()).color(color::GREY_3)) .push( - Button::new(icon::clipboard_icon().style(color::GREY_3)) + Button::new(icon::clipboard_icon().color(color::GREY_3)) .on_press(Message::Clipboard(outpoint.clone())) - .style(theme::Button::TransparentBorder), + .style(theme::button::transparent_border), ), ) .push_maybe(coin.map(|c| { let addr = c.address.to_string(); Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill) .spacing(5) - .push(p1_bold("Address:").style(color::GREY_3)) - .push(p2_regular(addr.clone()).style(color::GREY_3)) + .push(p1_bold("Address:").color(color::GREY_3)) + .push(p2_regular(addr.clone()).color(color::GREY_3)) .push( - Button::new(icon::clipboard_icon().style(color::GREY_3)) + Button::new(icon::clipboard_icon().color(color::GREY_3)) .on_press(Message::Clipboard(addr)) - .style(theme::Button::TransparentBorder), + .style(theme::button::transparent_border), ), ) })) .push_maybe(coin.and_then(|c| { labels.get(&c.address.to_string()).map(|label| { Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill) .spacing(5) - .push(p1_bold("Address label:").style(color::GREY_3)) - .push(p2_regular(label).style(color::GREY_3)), + .push(p1_bold("Address label:").color(color::GREY_3)) + .push(p2_regular(label).color(color::GREY_3)), ) }) })), @@ -927,7 +927,7 @@ fn payment_view<'a>( .push( Row::new() .spacing(5) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( Container::new(if let Some(label) = labels_editing.get(&outpoint) { label::label_editing(change_labels, label, text::P1_SIZE) @@ -942,33 +942,33 @@ fn payment_view<'a>( Column::new() .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill) .spacing(5) - .push(p1_bold("Address:").style(color::GREY_3)) - .push(p2_regular(addr.clone()).style(color::GREY_3)) + .push(p1_bold("Address:").color(color::GREY_3)) + .push(p2_regular(addr.clone()).color(color::GREY_3)) .push( - Button::new(icon::clipboard_icon().style(color::GREY_3)) + Button::new(icon::clipboard_icon().color(color::GREY_3)) .on_press(Message::Clipboard(addr.clone())) - .style(theme::Button::TransparentBorder), + .style(theme::button::transparent_border), ), ), ) .push_maybe(labels.get(&addr).map(|label| { Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill) .spacing(5) - .push(p1_bold("Address label:").style(color::GREY_3)) - .push(p2_regular(label).style(color::GREY_3)), + .push(p1_bold("Address label:").color(color::GREY_3)) + .push(p2_regular(label).color(color::GREY_3)), ) })) })) @@ -989,19 +989,19 @@ fn change_view(output: &TxOut, network: Network) -> Element { ) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill) .spacing(5) - .push(p1_bold("Address:").style(color::GREY_3)) - .push(p2_regular(addr.clone()).style(color::GREY_3)) + .push(p1_bold("Address:").color(color::GREY_3)) + .push(p2_regular(addr.clone()).color(color::GREY_3)) .push( - Button::new(icon::clipboard_icon().style(color::GREY_3)) + Button::new(icon::clipboard_icon().color(color::GREY_3)) .on_press(Message::Clipboard(addr)) - .style(theme::Button::TransparentBorder), + .style(theme::button::transparent_border), ), ), ) @@ -1051,14 +1051,14 @@ pub fn sign_action<'a>( }) .on_press(Message::Spend(SpendTxMessage::SelectHotSigner)) .padding(10) - .style(theme::Button::Border) + .style(theme::button::container_border) .width(Length::Fill) })) .width(Length::Fill), ) .spacing(20) .width(Length::Fill) - .align_items(Alignment::Center), + .align_x(Alignment::Center), )) .width(Length::Fixed(500.0)) .into() @@ -1086,7 +1086,7 @@ pub fn sign_action_toasts<'a>( kind, version.as_ref(), fingerprint, - alias.as_ref(), + alias.as_ref().map(|x| x.as_str()), ) .max_width(400.0) .into(), @@ -1131,7 +1131,7 @@ pub fn update_spend_view<'a>( button::secondary(Some(icon::clipboard_icon()), "Copy") .on_press(Message::Clipboard(psbt)), ) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) .push(separation().width(Length::Fill)) .push( @@ -1166,11 +1166,11 @@ pub fn update_spend_success_view<'a>() -> Element<'a, Message> { Column::new() .push( card::simple(Container::new( - text("Spend transaction is updated").style(color::GREEN), + text("Spend transaction is updated").color(color::GREEN), )) .padding(50), ) .width(Length::Fixed(400.0)) - .align_items(Alignment::Center) + .align_x(Alignment::Center) .into() } diff --git a/liana-gui/src/app/view/psbts.rs b/liana-gui/src/app/view/psbts.rs index 9a6444a71..49db59614 100644 --- a/liana-gui/src/app/view/psbts.rs +++ b/liana-gui/src/app/view/psbts.rs @@ -51,10 +51,10 @@ pub fn import_psbt_view<'a>( pub fn import_psbt_success_view<'a>() -> Element<'a, Message> { Column::new() .push( - card::simple(Container::new(text("PSBT is imported").style(color::GREEN))).padding(50), + card::simple(Container::new(text("PSBT is imported").color(color::GREEN))).padding(50), ) .width(Length::Fixed(400.0)) - .align_items(Alignment::Center) + .align_x(Alignment::Center) .into() } @@ -62,7 +62,7 @@ pub fn psbts_view(spend_txs: &[SpendTx]) -> Element<'_, Message> { Column::new() .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) .push(Container::new(h3("PSBTs")).width(Length::Fill)) .push( @@ -84,7 +84,7 @@ pub fn psbts_view(spend_txs: &[SpendTx]) -> Element<'_, Message> { }), ), ) - .align_items(Alignment::Center) + .align_x(Alignment::Center) .spacing(25) .into() } @@ -107,7 +107,7 @@ fn spend_tx_list_view(i: usize, tx: &SpendTx) -> Element<'_, Message> { Container::new( Row::new() .spacing(5) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( p2_regular(format!( "{}/{}", @@ -118,9 +118,9 @@ fn spend_tx_list_view(i: usize, tx: &SpendTx) -> Element<'_, Message> { }, sigs.threshold )) - .style(color::GREY_3), + .color(color::GREY_3), ) - .push(icon::key_icon().style(color::GREY_3)), + .push(icon::key_icon().color(color::GREY_3)), ) }) .push_maybe( @@ -129,7 +129,7 @@ fn spend_tx_list_view(i: usize, tx: &SpendTx) -> Element<'_, Message> { .map(p1_regular), ) .spacing(10) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill), ) .push_maybe(if tx.is_batch() { @@ -145,7 +145,7 @@ fn spend_tx_list_view(i: usize, tx: &SpendTx) -> Element<'_, Message> { }) .push( Column::new() - .align_items(Alignment::End) + .align_x(Alignment::End) .push(if !tx.is_send_to_self() { Container::new(amount(&tx.spend_amount)) } else { @@ -154,13 +154,13 @@ fn spend_tx_list_view(i: usize, tx: &SpendTx) -> Element<'_, Message> { .push_maybe(tx.fee_amount.map(|fee| amount_with_size(&fee, P2_SIZE))) .width(Length::Fixed(140.0)), ) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(20), ) .padding(10) .on_press(Message::Select(i)) - .style(theme::Button::TransparentBorder), + .style(theme::button::transparent_border), ) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) .into() } diff --git a/liana-gui/src/app/view/receive.rs b/liana-gui/src/app/view/receive.rs index c1421b220..fa88f1f3d 100644 --- a/liana-gui/src/app/view/receive.rs +++ b/liana-gui/src/app/view/receive.rs @@ -42,7 +42,7 @@ pub fn receive<'a>( Column::new() .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push(Container::new(h3("Receive")).width(Length::Fill)) .push( button::secondary(Some(icon::plus_icon()), "Generate address") @@ -85,7 +85,7 @@ pub fn receive<'a>( .push( p2_regular(addr) .small() - .style(color::GREY_3), + .color(color::GREY_3), ) // Space between the address and the scrollbar .push(Space::with_height( @@ -93,7 +93,7 @@ pub fn receive<'a>( )), ) .direction(scrollable::Direction::Horizontal( - scrollable::Properties::new() + scrollable::Scrollbar::new() .width(2) .scroller_width(2), )), @@ -102,12 +102,12 @@ pub fn receive<'a>( ) .push( Button::new( - icon::clipboard_icon().style(color::GREY_3), + icon::clipboard_icon().color(color::GREY_3), ) .on_press(Message::Clipboard(address.to_string())) - .style(theme::Button::TransparentBorder), + .style(theme::button::transparent_border), ) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) .push( Row::new() @@ -153,14 +153,14 @@ pub fn verify_address_modal<'a>( .push( Row::new() .width(Length::Fill) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( Container::new(text("Address:").bold()) .width(Length::Fill), ) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push(Container::new( text(address.to_string()).small(), )) @@ -169,7 +169,7 @@ pub fn verify_address_modal<'a>( .on_press(Message::Clipboard( address.to_string(), )) - .style(theme::Button::TransparentBorder), + .style(theme::button::transparent_border), ) .width(Length::Shrink), ), @@ -177,7 +177,7 @@ pub fn verify_address_modal<'a>( .push( Row::new() .width(Length::Fill) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( Container::new(text("Derivation index:").bold()) .width(Length::Fill), @@ -211,7 +211,7 @@ pub fn verify_address_modal<'a>( ) .spacing(20) .width(Length::Fill) - .align_items(Alignment::Center), + .align_x(Alignment::Center), )) .width(Length::Fill) .max_width(750) @@ -225,17 +225,12 @@ pub fn qr_modal<'a>(qr: &'a qr_code::Data, address: &'a String) -> Element<'a, M .push(Space::with_width(Length::Fill)) .push( Container::new(QRCode::::new(qr).cell_size(8)) - .padding(10) - .style(theme::Container::QrCode), + .padding(10), ) .push(Space::with_width(Length::Fill)), ) .push(Space::with_height(Length::Fixed(15.0))) - .push( - Container::new(text(address).size(15)) - .width(Length::Fill) - .center_x(), - ) + .push(Container::new(text(address).size(15)).center_x(Length::Fill)) .width(Length::Fill) .max_width(400) .into() diff --git a/liana-gui/src/app/view/recovery.rs b/liana-gui/src/app/view/recovery.rs index bfa68eaa7..b141ca1c7 100644 --- a/liana-gui/src/app/view/recovery.rs +++ b/liana-gui/src/app/view/recovery.rs @@ -44,16 +44,16 @@ pub fn recovery<'a>( .push( Row::new() .spacing(10) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( Button::new(text("Settings").size(30).bold()) - .style(theme::Button::Transparent) + .style(theme::button::transparent) .on_press(Message::Menu(Menu::Settings)), ) .push(icon::chevron_right().size(30)) .push( Button::new(text("Recovery").size(30).bold()) - .style(theme::Button::Transparent) + .style(theme::button::transparent) .on_press(Message::Menu(Menu::Recovery)), ), ) @@ -61,7 +61,7 @@ pub fn recovery<'a>( .push( Row::new() .spacing(20) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push(text("Destination").bold()) .push( Container::new( @@ -102,7 +102,7 @@ pub fn recovery<'a>( ))) .push(Column::with_children(recovery_paths).spacing(20)), ) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) .padding(20) }) .push_maybe(if no_recovery_paths { @@ -126,7 +126,7 @@ pub fn recovery<'a>( }, ) .spacing(20) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) }) .spacing(20), @@ -151,7 +151,7 @@ pub fn recovery_path_view<'a>( Column::new() .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) .push( text(format!( @@ -162,23 +162,23 @@ pub fn recovery_path_view<'a>( .bold(), ) .push(origins.iter().fold( - Row::new().align_items(Alignment::Center).spacing(5), + Row::new().align_y(Alignment::Center).spacing(5), |row, (fg, _)| { row.push(if let Some(alias) = key_aliases.get(fg) { Container::new( tooltip::Tooltip::new( Container::new(text(alias)) .padding(5) - .style(theme::Container::Pill(theme::Pill::Simple)), + .style(theme::pill::simple), liana_ui::widget::Text::new(fg.to_string()), tooltip::Position::Bottom, ) - .style(theme::Container::Card(theme::Card::Simple)), + .style(theme::card::simple), ) } else { Container::new(text(fg.to_string())) .padding(5) - .style(theme::Container::Pill(theme::Pill::Simple)) + .style(theme::pill::simple) }) }, )), @@ -197,7 +197,7 @@ pub fn recovery_path_view<'a>( .spacing(5), ) .width(Length::Fill) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(20) .into() } diff --git a/liana-gui/src/app/view/settings.rs b/liana-gui/src/app/view/settings.rs index 39be3cf6d..d1f72f1a7 100644 --- a/liana-gui/src/app/view/settings.rs +++ b/liana-gui/src/app/view/settings.rs @@ -46,99 +46,99 @@ pub fn list(cache: &Cache, is_remote_backend: bool) -> Element { .width(Length::Fill) .push( Button::new(text("Settings").size(30).bold()) - .style(theme::Button::Transparent) + .style(theme::button::transparent) .on_press(Message::Menu(Menu::Settings))) .push( if !is_remote_backend { Container::new( Button::new( Row::new() - .push(badge::Badge::new(icon::bitcoin_icon())) + .push(badge::badge(icon::bitcoin_icon())) .push(text("Node").bold()) .padding(10) .spacing(20) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill), ) .width(Length::Fill) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) .on_press(Message::Settings(SettingsMessage::EditBitcoindSettings)) ) .width(Length::Fill) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) } else { Container::new( Button::new( Row::new() - .push(badge::Badge::new(icon::bitcoin_icon())) + .push(badge::badge(icon::bitcoin_icon())) .push(text("Backend").bold()) .padding(10) .spacing(20) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill), ) .width(Length::Fill) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) .on_press(Message::Settings(SettingsMessage::EditRemoteBackendSettings)) ) .width(Length::Fill) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) } ) .push( Container::new( Button::new( Row::new() - .push(badge::Badge::new(icon::wallet_icon())) + .push(badge::badge(icon::wallet_icon())) .push(text("Wallet").bold()) .padding(10) .spacing(20) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill), ) .width(Length::Fill) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) .on_press(Message::Settings(SettingsMessage::EditWalletSettings)) ) .width(Length::Fill) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) ) .push( Container::new( Button::new( Row::new() - .push(badge::Badge::new(icon::recovery_icon())) + .push(badge::badge(icon::recovery_icon())) .push(text("Recovery").bold()) .push(tooltip("In case of loss of the main key, the recovery key can move the funds after a certain time.")) .padding(10) .spacing(20) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill), ) .width(Length::Fill) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) .on_press(Message::Menu(Menu::Recovery)) ) .width(Length::Fill) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) ) .push( Container::new( Button::new( Row::new() - .push(badge::Badge::new(icon::tooltip_icon())) + .push(badge::badge(icon::tooltip_icon())) .push(text("About").bold()) .padding(10) .spacing(20) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill), ) .width(Length::Fill) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) .on_press(Message::Settings(SettingsMessage::AboutSection)) ) .width(Length::Fill) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) ) ) } @@ -156,16 +156,16 @@ pub fn bitcoind_settings<'a>( .push( Row::new() .spacing(10) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( Button::new(text("Settings").size(30).bold()) - .style(theme::Button::Transparent) + .style(theme::button::transparent) .on_press(Message::Menu(Menu::Settings)), ) .push(icon::chevron_right().size(30)) .push( Button::new(text("Node").size(30).bold()) - .style(theme::Button::Transparent) + .style(theme::button::transparent) .on_press(Message::Settings(SettingsMessage::EditBitcoindSettings)), ), ) @@ -187,16 +187,16 @@ pub fn about_section<'a>( .push( Row::new() .spacing(10) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( Button::new(text("Settings").size(30).bold()) - .style(theme::Button::Transparent) + .style(theme::button::transparent) .on_press(Message::Menu(Menu::Settings)), ) .push(icon::chevron_right().size(30)) .push( Button::new(text("About").size(30).bold()) - .style(theme::Button::Transparent) + .style(theme::button::transparent) .on_press(Message::Settings(SettingsMessage::AboutSection)), ), ) @@ -205,11 +205,11 @@ pub fn about_section<'a>( Column::new() .push( Row::new() - .push(badge::Badge::new(icon::tooltip_icon())) + .push(badge::badge(icon::tooltip_icon())) .push(text("Version").bold()) .padding(10) .spacing(20) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill), ) .push(separation().width(Length::Fill)) @@ -246,16 +246,16 @@ pub fn remote_backend_section<'a>( .push( Row::new() .spacing(10) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( Button::new(text("Settings").size(30).bold()) - .style(theme::Button::Transparent) + .style(theme::button::transparent) .on_press(Message::Menu(Menu::Settings)), ) .push(icon::chevron_right().size(30)) .push( Button::new(text("Backend").size(30).bold()) - .style(theme::Button::Transparent) + .style(theme::button::transparent) .on_press(Message::Settings( SettingsMessage::EditRemoteBackendSettings, )), @@ -279,7 +279,7 @@ pub fn remote_backend_section<'a>( .push( Row::new() .push_maybe(if success { - Some(text("Invitation was sent").style(color::GREEN)) + Some(text("Invitation was sent").color(color::GREEN)) } else { None }) @@ -318,7 +318,7 @@ pub fn bitcoind_edit<'a>( Row::new() .push( Row::new() - .push(badge::Badge::new(icon::network_icon())) + .push(badge::badge(icon::network_icon())) .push( Column::new() .push(text("Network:")) @@ -329,7 +329,7 @@ pub fn bitcoind_edit<'a>( ) .push( Row::new() - .push(badge::Badge::new(icon::block_icon())) + .push(badge::badge(icon::block_icon())) .push( Column::new() .push(text("Block Height:")) @@ -358,7 +358,7 @@ pub fn bitcoind_edit<'a>( SettingsEditMessage::BitcoindRpcAuthTypeSelected, )) .spacing(30) - .align_items(Alignment::Center) + .align_y(Alignment::Center) }, ), ) @@ -423,11 +423,11 @@ pub fn bitcoind_edit<'a>( Column::new() .push( Row::new() - .push(badge::Badge::new(icon::bitcoin_icon())) + .push(badge::badge(icon::bitcoin_icon())) .push(text("Bitcoin Core").bold()) .padding(10) .spacing(20) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill), ) .push(separation().width(Length::Fill)) @@ -438,7 +438,7 @@ pub fn bitcoind_edit<'a>( .push(cancel_button) .push(confirm_button) .spacing(10) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) .width(Length::Fill) .align_x(alignment::Horizontal::Right), @@ -464,7 +464,7 @@ pub fn bitcoind<'a>( Row::new() .push( Row::new() - .push(badge::Badge::new(icon::network_icon())) + .push(badge::badge(icon::network_icon())) .push( Column::new() .push(text("Network:")) @@ -475,7 +475,7 @@ pub fn bitcoind<'a>( ) .push( Row::new() - .push(badge::Badge::new(icon::block_icon())) + .push(badge::badge(icon::block_icon())) .push( Column::new() .push(text("Block Height:")) @@ -516,10 +516,10 @@ pub fn bitcoind<'a>( .push(Space::with_width(10)) .push( Button::new(icon::clipboard_icon()) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) .on_press(SettingsEditMessage::Clipboard(v.to_string())), ) - .align_items(Alignment::Center) + .align_y(Alignment::Center) }); } @@ -529,7 +529,7 @@ pub fn bitcoind<'a>( Row::new() .push( Row::new() - .push(badge::Badge::new(icon::bitcoin_icon())) + .push(badge::badge(icon::bitcoin_icon())) .push(text("Bitcoin Core").bold()) .push_maybe(if is_configured_node_type { Some(is_running_label(is_running)) @@ -537,17 +537,17 @@ pub fn bitcoind<'a>( None }) .spacing(20) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill), ) .push(if can_edit { Button::new(icon::pencil_icon()) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) .on_press(SettingsEditMessage::Select) } else { - Button::new(icon::pencil_icon()).style(theme::Button::TransparentBorder) + Button::new(icon::pencil_icon()).style(theme::button::transparent_border) }) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) .push(separation().width(Length::Fill)) .push(col.push(col_fields)) @@ -571,7 +571,7 @@ pub fn electrum_edit<'a>( Row::new() .push( Row::new() - .push(badge::Badge::new(icon::network_icon())) + .push(badge::badge(icon::network_icon())) .push( Column::new() .push(text("Network:")) @@ -582,7 +582,7 @@ pub fn electrum_edit<'a>( ) .push( Row::new() - .push(badge::Badge::new(icon::block_icon())) + .push(badge::badge(icon::block_icon())) .push( Column::new() .push(text("Block Height:")) @@ -621,11 +621,11 @@ pub fn electrum_edit<'a>( Column::new() .push( Row::new() - .push(badge::Badge::new(icon::bitcoin_icon())) + .push(badge::badge(icon::bitcoin_icon())) .push(text("Electrum").bold()) .padding(10) .spacing(20) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill), ) .push(separation().width(Length::Fill)) @@ -636,7 +636,7 @@ pub fn electrum_edit<'a>( .push(cancel_button) .push(confirm_button) .spacing(10) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) .width(Length::Fill) .align_x(alignment::Horizontal::Right), @@ -662,7 +662,7 @@ pub fn electrum<'a>( Row::new() .push( Row::new() - .push(badge::Badge::new(icon::network_icon())) + .push(badge::badge(icon::network_icon())) .push( Column::new() .push(text("Network:")) @@ -673,7 +673,7 @@ pub fn electrum<'a>( ) .push( Row::new() - .push(badge::Badge::new(icon::block_icon())) + .push(badge::badge(icon::block_icon())) .push( Column::new() .push(text("Block Height:")) @@ -701,10 +701,10 @@ pub fn electrum<'a>( .push(Space::with_width(10)) .push( Button::new(icon::clipboard_icon()) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) .on_press(SettingsEditMessage::Clipboard(v.to_string())), ) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ); } @@ -714,7 +714,7 @@ pub fn electrum<'a>( Row::new() .push( Row::new() - .push(badge::Badge::new(icon::bitcoin_icon())) + .push(badge::badge(icon::bitcoin_icon())) .push(text("Electrum").bold()) .push_maybe(if is_configured_node_type { Some(is_running_label(is_running)) @@ -722,17 +722,17 @@ pub fn electrum<'a>( None }) .spacing(20) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill), ) .push(if can_edit { Button::new(icon::pencil_icon()) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) .on_press(SettingsEditMessage::Select) } else { - Button::new(icon::pencil_icon()).style(theme::Button::TransparentBorder) + Button::new(icon::pencil_icon()).style(theme::button::transparent_border) }) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) .push(separation().width(Length::Fill)) .push(col.push(col_fields)) @@ -747,16 +747,16 @@ pub fn is_running_label<'a, T: 'a>(is_running: Option) -> Container<'a, T> if running { Container::new( Row::new() - .push(icon::dot_icon().size(5).style(color::GREEN)) - .push(text("Running").small().style(color::GREEN)) - .align_items(Alignment::Center), + .push(icon::dot_icon().size(5).color(color::GREEN)) + .push(text("Running").small().color(color::GREEN)) + .align_y(Alignment::Center), ) } else { Container::new( Row::new() - .push(icon::dot_icon().size(5).style(color::RED)) - .push(text("Not running").small().style(color::RED)) - .align_items(Alignment::Center), + .push(icon::dot_icon().size(5).color(color::RED)) + .push(text("Not running").small().color(color::RED)) + .align_y(Alignment::Center), ) } } else { @@ -781,15 +781,15 @@ pub fn rescan<'a>( Column::new() .push( Row::new() - .push(badge::Badge::new(icon::block_icon())) + .push(badge::badge(icon::block_icon())) .push(text("Blockchain rescan").bold().width(Length::Fill)) .push_maybe(if success { - Some(text("Successfully rescanned the blockchain").style(color::GREEN)) + Some(text("Successfully rescanned the blockchain").color(color::GREEN)) } else { None }) .spacing(20) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill), ) .push(separation().width(Length::Fill)) @@ -830,24 +830,24 @@ pub fn rescan<'a>( .size(P1_SIZE) .padding(5), ) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10), ) .push_maybe(if invalid_date { - Some(p1_regular("Provided date is invalid").style(color::RED)) + Some(p1_regular("Provided date is invalid").color(color::RED)) } else { None }) .push_maybe(if past_possible_height { Some( p1_regular("Provided date earlier than the node prune height") - .style(color::RED), + .color(color::RED), ) } else { None }) .push_maybe(if future_date { - Some(p1_regular("Provided date is in the future").style(color::RED)) + Some(p1_regular("Provided date is in the future").color(color::RED)) } else { None }) @@ -910,16 +910,16 @@ pub fn wallet_settings<'a>( .push( Row::new() .spacing(10) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( Button::new(text("Settings").size(30).bold()) - .style(theme::Button::Transparent) + .style(theme::button::transparent) .on_press(Message::Menu(Menu::Settings)), ) .push(icon::chevron_right().size(30)) .push( Button::new(text("Wallet").size(30).bold()) - .style(theme::Button::Transparent) + .style(theme::button::transparent) .on_press(Message::Settings(SettingsMessage::EditWalletSettings)), ), ) @@ -935,7 +935,7 @@ pub fn wallet_settings<'a>( ) .direction( scrollable::Direction::Horizontal( - scrollable::Properties::new().width(5).scroller_width(5), + scrollable::Scrollbar::new().width(5).scroller_width(5), ), ), ) @@ -973,7 +973,7 @@ pub fn wallet_settings<'a>( col.push( Row::new() .spacing(10) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( text(fg.to_string()).bold().width(Length::Fixed(100.0)), ) @@ -994,14 +994,14 @@ pub fn wallet_settings<'a>( )) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push(Space::with_width(Length::Fill)) .push_maybe(if updated { Some( Row::new() - .align_items(Alignment::Center) - .push(icon::circle_check_icon().style(color::GREEN)) - .push(text("Updated").style(color::GREEN)), + .align_y(Alignment::Center) + .push(icon::circle_check_icon().color(color::GREEN)) + .push(text("Updated").color(color::GREEN)), ) } else { None @@ -1063,7 +1063,7 @@ fn display_policy( text(k.to_string()), iced_tooltip::Position::Bottom, ) - .style(theme::Container::Card(theme::Card::Simple)), + .style(theme::card::simple), ) } else { Container::new(text(format!("[{}]", k)).bold()) @@ -1116,7 +1116,7 @@ fn display_policy( text(k.to_string()), iced_tooltip::Position::Bottom, ) - .style(theme::Container::Card(theme::Card::Simple)), + .style(theme::card::simple), ) } else { Container::new(text(format!("[{}]", k)).bold()) @@ -1146,7 +1146,7 @@ fn display_policy( .spacing(10) .push(text("The wallet policy:").bold()) .push(scrollable(col).direction(scrollable::Direction::Horizontal( - scrollable::Properties::new().width(5).scroller_width(5), + scrollable::Scrollbar::new().width(5).scroller_width(5), ))) .into() } @@ -1228,7 +1228,7 @@ pub fn register_wallet_modal<'a>( ) .spacing(20) .width(Length::Fill) - .align_items(Alignment::Center), + .align_x(Alignment::Center), )) .width(Length::Fixed(500.0)) .into() diff --git a/liana-gui/src/app/view/spend/mod.rs b/liana-gui/src/app/view/spend/mod.rs index 8d818c5a9..9100f6a86 100644 --- a/liana-gui/src/app/view/spend/mod.rs +++ b/liana-gui/src/app/view/spend/mod.rs @@ -57,8 +57,8 @@ pub fn spend_view<'a>( col.push( Row::new() .spacing(5) - .push(icon::warning_icon().style(color::ORANGE)) - .push(text(warning).style(color::ORANGE)), + .push(icon::warning_icon().color(color::ORANGE)) + .push(text(warning).color(color::ORANGE)), ) }, )) @@ -154,7 +154,7 @@ pub fn create_spend_tx<'a>( Some( Container::new( text("Two payment addresses are the same") - .style(color::RED), + .color(color::RED), ) .padding(10), ) @@ -206,7 +206,7 @@ pub fn create_spend_tx<'a>( .spacing(10) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push(p1_bold("Coins selection").width(Length::Fill)) .push(if is_self_send { Row::new() @@ -226,7 +226,7 @@ pub fn create_spend_tx<'a>( ), P2_SIZE, )) - .push(p2_regular("selected").style(color::GREY_3)) + .push(p2_regular("selected").color(color::GREY_3)) } else if let Some(amount_left) = amount_left { if amount_left.to_sat() == 0 && !is_valid { // If amount left is set, the current configuration must be redraftable. @@ -237,20 +237,20 @@ pub fn create_spend_tx<'a>( // and it has the max selected. Row::new().push( text("Select at least one coin.") - .style(color::GREY_3), + .color(color::GREY_3), ) } else { // There must be a recipient with max selected and value 0. Row::new().push( text("Check max amount for recipient.") - .style(color::GREY_3), + .color(color::GREY_3), ) } } else { Row::new() .spacing(5) .push(amount_with_size(amount_left, P2_SIZE)) - .push(p2_regular("left to select").style(color::GREY_3)) + .push(p2_regular("left to select").color(color::GREY_3)) } } else { Row::new().push( @@ -259,7 +259,7 @@ pub fn create_spend_tx<'a>( } else { "Add recipient details." }) - .style(color::GREY_3), + .color(color::GREY_3), ) }) .width(Length::Fill), @@ -282,12 +282,12 @@ pub fn create_spend_tx<'a>( ), ) .padding(20) - .style(theme::Card::Simple), + .style(theme::card::simple), ) .push( Row::new() .spacing(20) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push(Space::with_width(Length::Fill)) .push( button::secondary(None, "Clear") @@ -325,14 +325,14 @@ pub fn recipient_view<'a>( .push( Row::new().push(Space::with_width(Length::Fill)).push( Button::new(icon::cross_icon()) - .style(theme::Button::Transparent) + .style(theme::button::transparent) .on_press(CreateSpendMessage::DeleteRecipient(index)) .width(Length::Shrink), ), ) .push( Row::new() - .align_items(Alignment::Start) + .align_y(Alignment::Start) .spacing(10) .push( Container::new(p1_bold("Address")) @@ -351,7 +351,7 @@ pub fn recipient_view<'a>( ) .push( Row::new() - .align_items(Alignment::Start) + .align_y(Alignment::Start) .spacing(10) .push( Container::new(p1_bold("Description")) @@ -370,7 +370,7 @@ pub fn recipient_view<'a>( ) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) .push( Container::new(p1_bold("Amount")) @@ -384,7 +384,7 @@ pub fn recipient_view<'a>( .map(amount_as_string) .unwrap_or(amount.value.clone()); Some( - Container::new(text(amount_txt).size(P1_SIZE).style(color::GREY_2)) + Container::new(text(amount_txt).size(P1_SIZE).color(color::GREY_2)) .padding(10) .width(Length::Fill), ) @@ -414,7 +414,7 @@ pub fn recipient_view<'a>( ), ) .padding(20) - .style(theme::Card::Simple) + .style(theme::card::simple) .into() } @@ -445,7 +445,7 @@ fn coin_list_view<'a>( // It is not possible to know if a coin is a // change coin or not so for now, From is // enough - p1_regular("From").style(color::GREY_3), + p1_regular("From").color(color::GREY_3), ) .push(p1_regular(label)), ) @@ -463,13 +463,13 @@ fn coin_list_view<'a>( coins::coin_sequence_label(seq, timelock as u32) }) .spacing(10) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill), ) .push(amount(&coin.amount)) // give some space for the scroll bar without using padding .push(Space::with_width(Length::Fixed(0.0))) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(20) .into() } diff --git a/liana-gui/src/app/view/transactions.rs b/liana-gui/src/app/view/transactions.rs index f87c4fc5c..1b9e80886 100644 --- a/liana-gui/src/app/view/transactions.rs +++ b/liana-gui/src/app/view/transactions.rs @@ -67,11 +67,11 @@ pub fn transactions_view<'a>( "See more" }) .width(Length::Fill) - .horizontal_alignment(alignment::Horizontal::Center), + .align_x(alignment::Horizontal::Center), ) .width(Length::Fill) .padding(15) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) .on_press_maybe(if !processing { Some(Message::Next) } else { @@ -79,13 +79,13 @@ pub fn transactions_view<'a>( }), ) .width(Length::Fill) - .style(theme::Container::Card(theme::Card::Simple)), + .style(theme::card::simple), ) } else { None }), ) - .align_items(Alignment::Center) + .align_x(Alignment::Center) .spacing(30), ) } @@ -121,13 +121,13 @@ fn tx_list_view(i: usize, tx: &HistoryTransaction) -> Element<'_, Message> { .format("%b. %d, %Y - %T") .to_string(), ) - .style(color::GREY_3) + .color(color::GREY_3) .small(), ) })), ) .spacing(10) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill), ) .push_maybe(if tx.time.is_none() { @@ -145,24 +145,24 @@ fn tx_list_view(i: usize, tx: &HistoryTransaction) -> Element<'_, Message> { .spacing(5) .push(text("+")) .push(amount(&tx.incoming_amount)) - .align_items(Alignment::Center) + .align_y(Alignment::Center) } else if tx.outgoing_amount != Amount::from_sat(0) { Row::new() .spacing(5) .push(text("-")) .push(amount(&tx.outgoing_amount)) - .align_items(Alignment::Center) + .align_y(Alignment::Center) } else { Row::new().push(text("Self-transfer")) }) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(20), ) .padding(10) .on_press(Message::Select(i)) - .style(theme::Button::TransparentBorder), + .style(theme::button::transparent_border), ) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) .into() } @@ -235,12 +235,12 @@ pub fn create_rbf_modal<'a>( Row::new() .padding([0, 30]) .spacing(5) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push(text(txid.to_string())) .push( - Button::new(icon::clipboard_icon().style(color::GREY_3)) + Button::new(icon::clipboard_icon().color(color::GREY_3)) .on_press(Message::Clipboard(txid.to_string())) - .style(theme::Button::TransparentBorder), + .style(theme::button::transparent_border), ), ) }, @@ -274,11 +274,11 @@ pub fn create_rbf_modal<'a>( } else { Row::new() .spacing(10) - .align_items(Alignment::Center) - .push(icon::circle_check_icon().style(color::GREEN)) + .align_y(Alignment::Center) + .push(icon::circle_check_icon().color(color::GREEN)) .push( text("Replacement PSBT created successfully and ready to be signed") - .style(color::GREEN), + .color(color::GREEN), ) })) .push_maybe(replacement_txid.map(|id| { @@ -342,8 +342,8 @@ pub fn tx_view<'a>( }) .push_maybe(tx.fee_amount.map(|fee_amount| { Row::new() - .align_items(Alignment::Center) - .push(h3("Miner fee: ").style(color::GREY_3)) + .align_y(Alignment::Center) + .push(h3("Miner fee: ").color(color::GREY_3)) .push(amount_with_size(&fee_amount, H3_SIZE)) .push(text(" ").size(H3_SIZE)) .push( @@ -352,7 +352,7 @@ pub fn tx_view<'a>( fee_amount.to_sat() / tx.tx.vsize() as u64 )) .size(H4_SIZE) - .style(color::GREY_3), + .color(color::GREY_3), ) })), ), @@ -396,16 +396,16 @@ pub fn tx_view<'a>( .push( Row::new() .width(Length::Fill) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push(Container::new(text("Txid:").bold()).width(Length::Fill)) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push(Container::new(text(txid.clone()).small())) .push( Button::new(icon::clipboard_icon()) .on_press(Message::Clipboard(txid.clone())) - .style(theme::Button::TransparentBorder), + .style(theme::button::transparent_border), ) .width(Length::Shrink), ), diff --git a/liana-gui/src/hw.rs b/liana-gui/src/hw.rs index f5e49ee9a..b217fa944 100644 --- a/liana-gui/src/hw.rs +++ b/liana-gui/src/hw.rs @@ -1,4 +1,4 @@ -use iced::Command; +use iced::Task; use std::{ collections::HashMap, path::PathBuf, @@ -215,7 +215,7 @@ impl HardwareWallets { pub fn update( &mut self, message: HardwareWalletMessage, - ) -> Result, async_hwi::Error> { + ) -> Result, async_hwi::Error> { match message { HardwareWalletMessage::Error(e) => Err(async_hwi::Error::Device(e)), HardwareWalletMessage::List(ConnectedList { still, mut new }) => { @@ -237,7 +237,7 @@ impl HardwareWallets { let id = id.to_string(); let network = self.network; let wallet = self.wallet.clone(); - cmds.push(Command::perform( + cmds.push(Task::perform( async move { ( id.clone(), @@ -252,7 +252,7 @@ impl HardwareWallets { let id_cloned = id.clone(); let network = self.network; let wallet = self.wallet.clone(); - cmds.push(Command::perform( + cmds.push(Task::perform( async move { if let Err(e) = device.auth().await { return (id_cloned, Err(e.into())); @@ -278,9 +278,9 @@ impl HardwareWallets { } } if cmds.is_empty() { - Ok(Command::none()) + Ok(Task::none()) } else { - Ok(Command::batch(cmds)) + Ok(Task::batch(cmds)) } } HardwareWalletMessage::Unlocked(id, res) => { @@ -307,7 +307,7 @@ impl HardwareWallets { } } } - Ok(Command::none()) + Ok(Task::none()) } } } diff --git a/liana-gui/src/installer/mod.rs b/liana-gui/src/installer/mod.rs index 01c40b83e..1e22f19da 100644 --- a/liana-gui/src/installer/mod.rs +++ b/liana-gui/src/installer/mod.rs @@ -4,7 +4,7 @@ mod prompt; mod step; mod view; -use iced::{clipboard, Command, Subscription}; +use iced::{clipboard, Subscription, Task}; use liana::miniscript::bitcoin::{self, Network}; use liana_ui::{ component::network_banner, @@ -64,13 +64,13 @@ pub struct Installer { } impl Installer { - fn previous(&mut self) -> Command { + fn previous(&mut self) -> Task { self.hws.reset_watch_list(); let network = self.network; if self.current > 0 { self.current -= 1; } else { - return Command::perform(async move { network }, Message::BackToLauncher); + return Task::perform(async move { network }, Message::BackToLauncher); } // skip the previous step according to the current context. while self @@ -82,14 +82,14 @@ impl Installer { if self.current > 0 { self.current -= 1; } else { - return Command::perform(async move { network }, Message::BackToLauncher); + return Task::perform(async move { network }, Message::BackToLauncher); } } if let Some(step) = self.steps.get(self.current) { step.revert(&mut self.context) } - Command::none() + Task::none() } pub fn new( @@ -97,7 +97,7 @@ impl Installer { network: bitcoin::Network, remote_backend: Option, user_flow: UserFlow, - ) -> (Installer, Command) { + ) -> (Installer, Task) { let signer = Arc::new(Mutex::new(Signer::generate(network).unwrap())); let context = Context::new( network, @@ -197,7 +197,7 @@ impl Installer { } } - fn next(&mut self) -> Command { + fn next(&mut self) -> Task { self.hws.reset_watch_list(); let current_step = self .steps @@ -209,7 +209,7 @@ impl Installer { } else { // The step is already the last current step. // No need to reload the current step. - return Command::none(); + return Task::none(); } // skip the step according to the current context. self.skip_steps(); @@ -222,16 +222,16 @@ impl Installer { current_step.load_context(&self.context); return current_step.load(); } - Command::none() + Task::none() } - pub fn update(&mut self, message: Message) -> Command { + pub fn update(&mut self, message: Message) -> Task { match message { Message::HardwareWallets(msg) => match self.hws.update(msg) { Ok(cmd) => cmd.map(Message::HardwareWallets), Err(e) => { error!("{}", e); - Command::none() + Task::none() } }, Message::Clibpboard(s) => clipboard::write(s), @@ -244,7 +244,7 @@ impl Installer { .expect("There is always a step") .update(&mut self.hws, message); match &self.context.remote_backend { - RemoteBackend::WithoutWallet(backend) => Command::perform( + RemoteBackend::WithoutWallet(backend) => Task::perform( create_remote_wallet( self.context.clone(), self.signer.clone(), @@ -252,11 +252,11 @@ impl Installer { ), Message::Installed, ), - RemoteBackend::WithWallet(backend) => Command::perform( + RemoteBackend::WithWallet(backend) => Task::perform( import_remote_wallet(self.context.clone(), backend.clone()), Message::Installed, ), - RemoteBackend::None => Command::perform( + RemoteBackend::None => Task::perform( install_local_wallet(self.context.clone(), self.signer.clone()), Message::Installed, ), diff --git a/liana-gui/src/installer/step/backend.rs b/liana-gui/src/installer/step/backend.rs index 2386e80cf..169babd93 100644 --- a/liana-gui/src/installer/step/backend.rs +++ b/liana-gui/src/installer/step/backend.rs @@ -1,6 +1,6 @@ use std::str::FromStr; -use iced::Command; +use iced::Task; use liana::{descriptors::LianaDescriptor, miniscript::bitcoin::Network}; use liana_ui::{component::form, widget::Element}; @@ -44,15 +44,15 @@ impl Step for ChooseBackend { fn skip(&self, _ctx: &Context) -> bool { self.network != Network::Bitcoin && self.network != Network::Signet } - fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command { + fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task { if let Message::SelectBackend(message::SelectBackend::ContinueWithLocalWallet( local_wallet, )) = message { self.remote_backend_is_selected = !local_wallet; - Command::perform(async move {}, |_| Message::Next) + Task::perform(async move {}, |_| Message::Next) } else { - Command::none() + Task::none() } } @@ -128,7 +128,7 @@ impl Step for RemoteBackendLogin { matches!(ctx.remote_backend, RemoteBackend::None) || (self.network != Network::Bitcoin && self.network != Network::Signet) } - fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command { + fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task { match &mut self.step { ConnectionStep::EnterEmail { email } => match message { Message::SelectBackend(message::SelectBackend::EmailEdited(value)) => { @@ -149,7 +149,7 @@ impl Step for RemoteBackendLogin { self.processing = true; self.connection_error = None; self.auth_error = None; - return Command::perform( + return Task::perform( async move { let config = client::get_service_config(network).await.map_err(|e| { @@ -211,7 +211,7 @@ impl Step for RemoteBackendLogin { self.processing = true; self.connection_error = None; self.auth_error = None; - return Command::perform( + return Task::perform( async move { client.resend_otp().await?; Ok(()) @@ -236,7 +236,7 @@ impl Step for RemoteBackendLogin { self.connection_error = None; self.auth_error = None; let network = self.network; - return Command::perform( + return Task::perform( async move { connect(client, otp, backend_api_url, network).await }, message::SelectBackend::Connected, ) @@ -252,7 +252,7 @@ impl Step for RemoteBackendLogin { email: email.clone(), remote_backend, }; - return Command::perform(async move {}, |_| Message::Next); + return Task::perform(async move {}, |_| Message::Next); } Err(e) => { if let Error::Auth(AuthError { http_status, .. }) = e { @@ -278,7 +278,7 @@ impl Step for RemoteBackendLogin { } } - Command::none() + Task::none() } fn apply(&mut self, ctx: &mut Context) -> bool { @@ -377,9 +377,9 @@ impl Step for ImportRemoteWallet { fn load_context(&mut self, ctx: &Context) { self.backend = ctx.remote_backend.clone(); } - fn load(&self) -> Command { + fn load(&self) -> Task { let backend = self.backend.clone(); - Command::perform( + Task::perform( async move { let wallets = match backend { context::RemoteBackend::WithoutWallet(backend) => { @@ -398,7 +398,7 @@ impl Step for ImportRemoteWallet { } // form value is set as valid each time it is edited. // Verification of the values is happening when the user click on Next button. - fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command { + fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task { match message { Message::ImportRemoteWallet(message::ImportRemoteWallet::ImportDescriptor(desc)) => { self.imported_descriptor.value = desc; @@ -430,7 +430,7 @@ impl Step for ImportRemoteWallet { context::RemoteBackend::WithoutWallet(backend.into_inner()); } self.descriptor = Some(desc); - return Command::perform(async {}, |_| Message::Next); + return Task::perform(async {}, |_| Message::Next); } } else { self.imported_descriptor.valid = false; @@ -455,7 +455,7 @@ impl Step for ImportRemoteWallet { }; let token = self.invitation_token.value.clone(); self.error = None; - return Command::perform( + return Task::perform( async move { let invitation = backend.get_wallet_invitation(&token).await?; Ok(invitation) @@ -481,7 +481,7 @@ impl Step for ImportRemoteWallet { }; let invitation = self.invitation.clone().expect("Invitation was fetched"); self.error = None; - return Command::perform( + return Task::perform( async move { backend.accept_wallet_invitation(&invitation.id).await?; let wallets = backend.list_wallets().await?; @@ -531,13 +531,13 @@ impl Step for ImportRemoteWallet { // ensure that no descriptor is imported. self.imported_descriptor = form::Value::default(); self.descriptor = Some(wallet.descriptor); - return Command::perform(async {}, |_| Message::Next); + return Task::perform(async {}, |_| Message::Next); } } _ => {} } - Command::none() + Task::none() } fn apply(&mut self, ctx: &mut Context) -> bool { diff --git a/liana-gui/src/installer/step/descriptor/editor/key.rs b/liana-gui/src/installer/step/descriptor/editor/key.rs index c8916b53b..2ddd8751f 100644 --- a/liana-gui/src/installer/step/descriptor/editor/key.rs +++ b/liana-gui/src/installer/step/descriptor/editor/key.rs @@ -2,7 +2,7 @@ use std::collections::HashSet; use std::str::FromStr; use std::sync::{Arc, Mutex}; -use iced::{Command, Subscription}; +use iced::{Subscription, Task}; use liana::miniscript::bitcoin::bip32::Xpub; use liana::miniscript::{ bitcoin::{ @@ -137,8 +137,8 @@ impl EditXpubModal { } } - pub fn load(&self) -> Command { - Command::none() + pub fn load(&self) -> Task { + Task::none() } } @@ -147,7 +147,7 @@ impl super::DescriptorEditModal for EditXpubModal { self.processing } - fn update(&mut self, hws: &mut HardwareWallets, message: Message) -> Command { + fn update(&mut self, hws: &mut HardwareWallets, message: Message) -> Task { // Reset these fields. // the function will setup them again if something is wrong self.duplicate_master_fg = false; @@ -167,10 +167,19 @@ impl super::DescriptorEditModal for EditXpubModal { let device_version = version.clone(); let fingerprint = *fingerprint; let device_kind = *kind; + let device_cloned = device.clone(); let network = self.network; - return Command::perform( - get_extended_pubkey(device.clone(), fingerprint, self.network), - move |res| { + return Task::perform( + async move { + ( + device_version, + device_kind, + fingerprint, + network, + get_extended_pubkey(device_cloned, fingerprint, network).await, + ) + }, + |(device_version, device_kind, fingerprint, network, res)| { Message::DefineDescriptor(message::DefineDescriptor::KeyModal( message::ImportKeyModal::FetchedKey(match res { Err(e) => Err(e), @@ -306,7 +315,7 @@ impl super::DescriptorEditModal for EditXpubModal { self.duplicate_master_fg = true; } else { let coordinate = self.keys_coordinate.clone(); - return Command::perform( + return Task::perform( async move { (coordinate, key) }, move |(coordinate, key)| { message::DefineDescriptor::KeysEdited(coordinate, key) @@ -326,7 +335,7 @@ impl super::DescriptorEditModal for EditXpubModal { }, _ => {} }; - Command::none() + Task::none() } fn subscription(&self, hws: &HardwareWallets) -> Subscription { diff --git a/liana-gui/src/installer/step/descriptor/editor/mod.rs b/liana-gui/src/installer/step/descriptor/editor/mod.rs index e2023b78f..f9fbce32e 100644 --- a/liana-gui/src/installer/step/descriptor/editor/mod.rs +++ b/liana-gui/src/installer/step/descriptor/editor/mod.rs @@ -6,7 +6,7 @@ use std::iter::FromIterator; use std::str::FromStr; use std::sync::{Arc, Mutex}; -use iced::{Command, Subscription}; +use iced::{Subscription, Task}; use liana::{ descriptors::{LianaDescriptor, LianaPolicy, PathInfo}, miniscript::{ @@ -38,8 +38,8 @@ pub trait DescriptorEditModal { fn processing(&self) -> bool { false } - fn update(&mut self, _hws: &mut HardwareWallets, _message: Message) -> Command { - Command::none() + fn update(&mut self, _hws: &mut HardwareWallets, _message: Message) -> Task { + Task::none() } fn view<'a>(&'a self, _hws: &'a HardwareWallets) -> Element<'a, Message>; fn subscription(&self, _hws: &HardwareWallets) -> Subscription { @@ -202,7 +202,7 @@ impl Step for DefineDescriptor { } // form value is set as valid each time it is edited. // Verification of the values is happening when the user click on Next button. - fn update(&mut self, hws: &mut HardwareWallets, message: Message) -> Command { + fn update(&mut self, hws: &mut HardwareWallets, message: Message) -> Task { self.error = None; match message { Message::Close => { @@ -294,7 +294,7 @@ impl Step for DefineDescriptor { } message::DefinePath::Key(j, msg) => match msg { message::DefineKey::Clipboard(key) => { - return Command::perform(async move { key }, Message::Clibpboard); + return Task::perform(async move { key }, Message::Clibpboard); } message::DefineKey::Edit => { @@ -347,7 +347,7 @@ impl Step for DefineDescriptor { } } }; - Command::none() + Task::none() } fn subscription(&self, hws: &HardwareWallets) -> Subscription { @@ -553,7 +553,7 @@ impl DescriptorEditModal for EditSequenceModal { false } - fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command { + fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task { if let Message::DefineDescriptor(message::DefineDescriptor::ThresholdSequenceModal(msg)) = message { @@ -570,7 +570,7 @@ impl DescriptorEditModal for EditSequenceModal { if self.sequence.valid { if let Ok(sequence) = u16::from_str(&self.sequence.value) { let path_index = self.path_index; - return Command::perform( + return Task::perform( async move { (path_index, sequence) }, |(path_index, sequence)| { message::DefineDescriptor::Path( @@ -586,7 +586,7 @@ impl DescriptorEditModal for EditSequenceModal { _ => {} } } - Command::none() + Task::none() } fn view(&self, _hws: &HardwareWallets) -> Element { @@ -613,7 +613,7 @@ impl DescriptorEditModal for EditThresholdModal { false } - fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command { + fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task { if let Message::DefineDescriptor(message::DefineDescriptor::ThresholdSequenceModal(msg)) = message { @@ -626,7 +626,7 @@ impl DescriptorEditModal for EditThresholdModal { message::ThresholdSequenceModal::Confirm => { let path_index = self.path_index; let threshold = self.threshold.0; - return Command::perform( + return Task::perform( async move { (path_index, threshold) }, |(path_index, threshold)| { message::DefineDescriptor::Path( @@ -640,7 +640,7 @@ impl DescriptorEditModal for EditThresholdModal { _ => {} } } - Command::none() + Task::none() } fn view(&self, _hws: &HardwareWallets) -> Element { diff --git a/liana-gui/src/installer/step/descriptor/editor/template.rs b/liana-gui/src/installer/step/descriptor/editor/template.rs index 4b9aee01e..c94949ee0 100644 --- a/liana-gui/src/installer/step/descriptor/editor/template.rs +++ b/liana-gui/src/installer/step/descriptor/editor/template.rs @@ -1,4 +1,4 @@ -use iced::Command; +use iced::Task; use liana_ui::widget::Element; @@ -23,12 +23,12 @@ impl From for Box { } } impl Step for ChooseDescriptorTemplate { - fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command { + fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task { if let Message::SelectDescriptorTemplate(template) = message { self.template = template; - Command::perform(async move {}, |_| Message::Next) + Task::perform(async move {}, |_| Message::Next) } else { - Command::none() + Task::none() } } diff --git a/liana-gui/src/installer/step/descriptor/mod.rs b/liana-gui/src/installer/step/descriptor/mod.rs index fe8e27b02..ce0ecb081 100644 --- a/liana-gui/src/installer/step/descriptor/mod.rs +++ b/liana-gui/src/installer/step/descriptor/mod.rs @@ -5,7 +5,7 @@ use std::{ str::FromStr, }; -use iced::{Command, Subscription}; +use iced::{Subscription, Task}; use liana::{ descriptors::LianaDescriptor, miniscript::bitcoin::{bip32::Fingerprint, Network}, @@ -77,14 +77,14 @@ impl Step for ImportDescriptor { } // form value is set as valid each time it is edited. // Verification of the values is happening when the user click on Next button. - fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command { + fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task { if let Message::DefineDescriptor(message::DefineDescriptor::ImportDescriptor(desc)) = message { self.imported_descriptor.value = desc; self.check_descriptor(self.network); } - Command::none() + Task::none() } fn apply(&mut self, ctx: &mut Context) -> bool { @@ -173,7 +173,7 @@ impl Step for RegisterDescriptor { map.insert(key.master_fingerprint, key.name.clone()); } } - fn update(&mut self, hws: &mut HardwareWallets, message: Message) -> Command { + fn update(&mut self, hws: &mut HardwareWallets, message: Message) -> Task { match message { Message::Select(i) => { if let Some(HardwareWallet::Supported { @@ -188,7 +188,7 @@ impl Step for RegisterDescriptor { self.chosen_hw = Some(i); self.processing = true; self.error = None; - return Command::perform( + return Task::perform( register_wallet( device.clone(), *fingerprint, @@ -229,7 +229,7 @@ impl Step for RegisterDescriptor { } _ => {} }; - Command::none() + Task::none() } fn skip(&self, ctx: &Context) -> bool { !ctx.hw_is_used @@ -243,8 +243,8 @@ impl Step for RegisterDescriptor { fn subscription(&self, hws: &HardwareWallets) -> Subscription { hws.refresh().map(Message::HardwareWallets) } - fn load(&self) -> Command { - Command::none() + fn load(&self) -> Task { + Task::none() } fn view<'a>( &'a self, @@ -295,11 +295,11 @@ pub struct BackupDescriptor { } impl Step for BackupDescriptor { - fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command { + fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task { if let Message::UserActionDone(done) = message { self.done = done; } - Command::none() + Task::none() } fn load_context(&mut self, ctx: &Context) { if self.descriptor != ctx.descriptor { diff --git a/liana-gui/src/installer/step/mnemonic.rs b/liana-gui/src/installer/step/mnemonic.rs index 8343fb135..a49b7f9da 100644 --- a/liana-gui/src/installer/step/mnemonic.rs +++ b/liana-gui/src/installer/step/mnemonic.rs @@ -1,7 +1,7 @@ use std::collections::HashSet; use std::sync::{Arc, Mutex}; -use iced::Command; +use iced::Task; use liana::{bip39, signer::HotSigner}; use liana_ui::widget::Element; @@ -36,11 +36,11 @@ impl From for Box { } impl Step for BackupMnemonic { - fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command { + fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task { if let Message::UserActionDone(done) = message { self.done = done; } - Command::none() + Task::none() } fn skip(&self, ctx: &Context) -> bool { if let Some(descriptor) = &ctx.descriptor { @@ -92,7 +92,7 @@ impl From for Box { } impl Step for RecoverMnemonic { - fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command { + fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task { match message { Message::MnemonicWord(index, value) => { if let Some((word, valid)) = self.words.get_mut(index) { @@ -116,11 +116,11 @@ impl Step for RecoverMnemonic { Message::ImportMnemonic(recover) => self.recover = recover, Message::Skip => { self.skip = true; - return Command::perform(async {}, |_| Message::Next); + return Task::perform(async {}, |_| Message::Next); } _ => {} } - Command::none() + Task::none() } fn apply(&mut self, ctx: &mut Context) -> bool { diff --git a/liana-gui/src/installer/step/mod.rs b/liana-gui/src/installer/step/mod.rs index a0562f05e..d799185bc 100644 --- a/liana-gui/src/installer/step/mod.rs +++ b/liana-gui/src/installer/step/mod.rs @@ -22,7 +22,7 @@ pub use share_xpubs::ShareXpubs; use std::path::PathBuf; -use iced::{Command, Subscription}; +use iced::{Subscription, Task}; use liana_ui::widget::*; @@ -33,8 +33,8 @@ use crate::{ }; pub trait Step { - fn update(&mut self, _hws: &mut HardwareWallets, _message: Message) -> Command { - Command::none() + fn update(&mut self, _hws: &mut HardwareWallets, _message: Message) -> Task { + Task::none() } fn subscription(&self, _hws: &HardwareWallets) -> Subscription { Subscription::none() @@ -47,8 +47,8 @@ pub trait Step { ) -> Element<'a, Message>; fn load_context(&mut self, _ctx: &Context) {} - fn load(&self) -> Command { - Command::none() + fn load(&self) -> Task { + Task::none() } fn skip(&self, _ctx: &Context) -> bool { false @@ -88,14 +88,14 @@ impl Step for Final { fn load_context(&mut self, ctx: &Context) { self.internal_bitcoind.clone_from(&ctx.internal_bitcoind); } - fn load(&self) -> Command { + fn load(&self) -> Task { if !self.generating && self.config_path.is_none() { - Command::perform(async {}, |_| Message::Install) + Task::perform(async {}, |_| Message::Install) } else { - Command::none() + Task::none() } } - fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command { + fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task { match message { Message::Installed(res) => { self.generating = false; @@ -107,9 +107,11 @@ impl Step for Final { Ok(path) => { self.config_path = Some(path.clone()); let internal_bitcoind = self.internal_bitcoind.clone(); - return Command::perform(async {}, move |_| { - Message::Exit(path.clone(), internal_bitcoind) - }); + let path = path.clone(); + return Task::perform( + async { (path, internal_bitcoind) }, + |(path, internal_bitcoind)| Message::Exit(path, internal_bitcoind), + ); } } } @@ -120,7 +122,7 @@ impl Step for Final { } _ => {} }; - Command::none() + Task::none() } fn view<'a>( diff --git a/liana-gui/src/installer/step/node/bitcoind.rs b/liana-gui/src/installer/step/node/bitcoind.rs index dd6ea627a..4916b8285 100644 --- a/liana-gui/src/installer/step/node/bitcoind.rs +++ b/liana-gui/src/installer/step/node/bitcoind.rs @@ -7,7 +7,7 @@ use std::str::FromStr; use bitcoin_hashes::{sha256, Hash}; #[cfg(any(target_os = "macos", target_os = "linux"))] use flate2::read::GzDecoder; -use iced::{Command, Subscription}; +use iced::{Subscription, Task}; use liana::miniscript::bitcoin::Network; use lianad::config::{BitcoinBackend, BitcoindConfig, BitcoindRpcAuth}; #[cfg(any(target_os = "macos", target_os = "linux"))] @@ -303,16 +303,16 @@ impl Step for SelectBitcoindTypeStep { fn skip(&self, ctx: &Context) -> bool { ctx.remote_backend.is_some() } - fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command { + fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task { if let Message::SelectBitcoindType(msg) = message { match msg { message::SelectBitcoindTypeMsg::UseExternal(selected) => { self.use_external = selected; } }; - return Command::perform(async {}, |_| Message::Next); + return Task::perform(async {}, |_| Message::Next); }; - Command::none() + Task::none() } fn apply(&mut self, ctx: &mut Context) -> bool { @@ -410,7 +410,7 @@ impl DefineBitcoind { self.network = Some(ctx.bitcoin_config.network); } - pub fn update(&mut self, message: message::DefineNode) -> Command { + pub fn update(&mut self, message: message::DefineNode) -> Task { if let message::DefineNode::DefineBitcoind(msg) = message { match msg { message::DefineBitcoind::ConfigFieldEdited(field, value) => match field { @@ -443,7 +443,7 @@ impl DefineBitcoind { } }; }; - Command::none() + Task::none() } pub fn apply(&mut self, ctx: &mut Context) -> bool { @@ -552,7 +552,7 @@ impl Step for InternalBitcoindStep { } } } - fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command { + fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task { if let Message::InternalBitcoind(msg) = message { match msg { message::InternalBitcoindMsg::Previous => { @@ -568,7 +568,7 @@ impl Step for InternalBitcoindStep { } } self.started = None; // clear both Ok and Err - return Command::perform(async {}, |_| Message::Previous); + return Task::perform(async {}, |_| Message::Previous); } message::InternalBitcoindMsg::Reload => { return self.load(); @@ -583,7 +583,7 @@ impl Step for InternalBitcoindStep { } Err(e) => { self.error = Some(e.to_string()); - return Command::none(); + return Task::none(); } }; let (rpc_port, p2p_port) = if let Some(network_conf) = @@ -599,18 +599,18 @@ impl Step for InternalBitcoindStep { "Could not get distinct ports. Please try again." .to_string(), ); - return Command::none(); + return Task::none(); } (rpc_port, p2p_port) } (Ok(_), Err(e)) | (Err(e), Ok(_)) => { self.error = Some(format!("Could not get available port: {}.", e)); - return Command::none(); + return Task::none(); } (Err(e1), Err(e2)) => { self.error = Some(format!("Could not get available ports: {}; {}.", e1, e2)); - return Command::none(); + return Task::none(); } } }; @@ -618,7 +618,7 @@ impl Step for InternalBitcoindStep { Ok((rpc_auth, password)) => (rpc_auth, password), Err(e) => { self.error = Some(e.to_string()); - return Command::none(); + return Task::none(); } }; let bitcoind_config = BitcoindConfig { @@ -637,12 +637,12 @@ impl Step for InternalBitcoindStep { &self.bitcoind_datadir, )) { self.error = Some(e.to_string()); - return Command::none(); + return Task::none(); }; self.error = None; self.internal_bitcoind_config = Some(conf); self.bitcoind_config = Some(bitcoind_config); - return Command::perform(async {}, |_| { + return Task::perform(async {}, |_| { Message::InternalBitcoind(message::InternalBitcoindMsg::Reload) }); } @@ -659,7 +659,7 @@ impl Step for InternalBitcoindStep { download.progress(progress); if let DownloadState::Finished(_) = &download.state { info!("Download of bitcoind complete."); - return Command::perform(async {}, |_| { + return Task::perform(async {}, |_| { Message::InternalBitcoind(message::InternalBitcoindMsg::Install) }); } @@ -681,7 +681,7 @@ impl Step for InternalBitcoindStep { &self.liana_datadir, VERSION, )); - return Command::perform(async {}, |_| { + return Task::perform(async {}, |_| { Message::InternalBitcoind( message::InternalBitcoindMsg::Start, ) @@ -691,7 +691,7 @@ impl Step for InternalBitcoindStep { info!("Installation of bitcoind failed."); self.install_state = Some(InstallState::Errored(e.clone())); self.error = Some(e.to_string()); - return Command::none(); + return Task::none(); } }; } @@ -702,7 +702,7 @@ impl Step for InternalBitcoindStep { self.started = Some(Err( StartInternalBitcoindError::CouldNotCanonicalizeDataDir(e.to_string()), )); - return Command::none(); + return Task::none(); }; let bitcoind_config = self .bitcoind_config @@ -713,7 +713,7 @@ impl Step for InternalBitcoindStep { Err(e) => { self.started = Some(Err(StartInternalBitcoindError::CommandError(e.to_string()))); - return Command::none(); + return Task::none(); } Ok(bitcoind) => { self.error = None; @@ -724,7 +724,7 @@ impl Step for InternalBitcoindStep { } }; }; - Command::none() + Task::none() } fn subscription(&self, _hws: &HardwareWallets) -> Subscription { @@ -734,25 +734,25 @@ impl Step for InternalBitcoindStep { Subscription::none() } - fn load(&self) -> Command { + fn load(&self) -> Task { if self.internal_bitcoind_config.is_none() { - return Command::perform(async {}, |_| { + return Task::perform(async {}, |_| { Message::InternalBitcoind(message::InternalBitcoindMsg::DefineConfig) }); } if let Some(download) = &self.exe_download { if let DownloadState::Idle = download.state { - return Command::perform(async {}, |_| { + return Task::perform(async {}, |_| { Message::InternalBitcoind(message::InternalBitcoindMsg::Download) }); } } if self.started.is_none() { - return Command::perform(async {}, |_| { + return Task::perform(async {}, |_| { Message::InternalBitcoind(message::InternalBitcoindMsg::Start) }); } - Command::none() + Task::none() } fn apply(&mut self, ctx: &mut Context) -> bool { diff --git a/liana-gui/src/installer/step/node/electrum.rs b/liana-gui/src/installer/step/node/electrum.rs index f594e6a22..5978e2f18 100644 --- a/liana-gui/src/installer/step/node/electrum.rs +++ b/liana-gui/src/installer/step/node/electrum.rs @@ -1,4 +1,4 @@ -use iced::Command; +use iced::Task; use liana_ui::{component::form, widget::*}; use lianad::{ config::ElectrumConfig, @@ -28,7 +28,7 @@ impl DefineElectrum { !self.address.value.is_empty() && self.address.valid } - pub fn update(&mut self, message: message::DefineNode) -> Command { + pub fn update(&mut self, message: message::DefineNode) -> Task { if let message::DefineNode::DefineElectrum(msg) = message { match msg { message::DefineElectrum::ConfigFieldEdited(field, value) => match field { @@ -40,7 +40,7 @@ impl DefineElectrum { }, }; }; - Command::none() + Task::none() } pub fn apply(&mut self, ctx: &mut Context) -> bool { diff --git a/liana-gui/src/installer/step/node/mod.rs b/liana-gui/src/installer/step/node/mod.rs index cb8b350dc..974934cb7 100644 --- a/liana-gui/src/installer/step/node/mod.rs +++ b/liana-gui/src/installer/step/node/mod.rs @@ -15,7 +15,7 @@ use crate::{ node::NodeType, }; -use iced::Command; +use iced::Task; use liana_ui::widget::Element; #[derive(Clone)] @@ -62,7 +62,7 @@ impl NodeDefinition { } } - fn update(&mut self, message: message::DefineNode) -> Command { + fn update(&mut self, message: message::DefineNode) -> Task { match self { NodeDefinition::Bitcoind(def) => def.update(message), NodeDefinition::Electrum(def) => def.update(message), @@ -154,11 +154,7 @@ impl DefineNode { .find(|node| node.definition.node_type() == node_type) } - fn update_node( - &mut self, - node_type: NodeType, - message: message::DefineNode, - ) -> Command { + fn update_node(&mut self, node_type: NodeType, message: message::DefineNode) -> Task { if let Some(node) = self.get_mut(node_type) { // Don't make changes while waiting for a ping result so that we // know which values the ping result applies to. @@ -167,7 +163,7 @@ impl DefineNode { return node.definition.update(message); } } - Command::none() + Task::none() } } @@ -183,7 +179,7 @@ impl Step for DefineNode { node.definition.load_context(ctx); } } - fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Command { + fn update(&mut self, _hws: &mut HardwareWallets, message: Message) -> Task { if let Message::DefineNode(msg) = message { match msg { message::DefineNode::NodeTypeSelected(node_type) => { @@ -198,7 +194,7 @@ impl Step for DefineNode { selected.is_running = None; let def = selected.definition.clone(); let node_type = def.node_type(); - return Command::perform(async move { def.ping() }, move |res| { + return Task::perform(async move { def.ping() }, move |res| { Message::DefineNode(message::DefineNode::PingResult((node_type, res))) }); } @@ -222,7 +218,7 @@ impl Step for DefineNode { } } } - Command::none() + Task::none() } fn apply(&mut self, ctx: &mut Context) -> bool { diff --git a/liana-gui/src/installer/step/share_xpubs.rs b/liana-gui/src/installer/step/share_xpubs.rs index 8f4c61262..39db3fb76 100644 --- a/liana-gui/src/installer/step/share_xpubs.rs +++ b/liana-gui/src/installer/step/share_xpubs.rs @@ -1,6 +1,6 @@ use std::sync::{Arc, Mutex}; -use iced::{Command, Subscription}; +use iced::{Subscription, Task}; use liana::miniscript::bitcoin::{ bip32::{ChildNumber, Fingerprint}, Network, @@ -85,7 +85,7 @@ impl ShareXpubs { impl Step for ShareXpubs { // form value is set as valid each time it is edited. // Verification of the values is happening when the user click on Next button. - fn update(&mut self, hws: &mut HardwareWallets, message: Message) -> Command { + fn update(&mut self, hws: &mut HardwareWallets, message: Message) -> Task { match message { Message::ImportXpub(fg, res) => { if let Some(hw_xpubs) = self.hw_xpubs.iter_mut().find(|x| x.fingerprint == fg) { @@ -133,7 +133,7 @@ impl Step for ShareXpubs { error: None, }); } - return Command::perform( + return Task::perform( async move { ( fingerprint, @@ -146,7 +146,7 @@ impl Step for ShareXpubs { } _ => {} }; - Command::none() + Task::none() } fn subscription(&self, hws: &HardwareWallets) -> Subscription { diff --git a/liana-gui/src/installer/view/editor/mod.rs b/liana-gui/src/installer/view/editor/mod.rs index 1f1977d7a..3fb562407 100644 --- a/liana-gui/src/installer/view/editor/mod.rs +++ b/liana-gui/src/installer/view/editor/mod.rs @@ -7,6 +7,7 @@ use liana::miniscript::bitcoin::Network; use liana_ui::component::text::{self, h3, p1_bold, p2_regular, H3_SIZE}; use liana_ui::image; use std::borrow::Cow; +use std::fmt::Display; use std::str::FromStr; use liana::miniscript::bitcoin::{self, bip32::Fingerprint}; @@ -62,7 +63,7 @@ pub fn define_descriptor_advanced_settings<'a>(use_taproot: bool) -> Element<'a, }), |kind| Message::CreateTaprootDescriptor(kind == DescriptorKind::Taproot), ) - .style(theme::PickList::Secondary) + .style(theme::pick_list::primary) .padding(10), )); @@ -75,7 +76,7 @@ pub fn define_descriptor_advanced_settings<'a>(use_taproot: bool) -> Element<'a, .push_maybe(if use_taproot { Some( p1_regular("Taproot is only supported by Liana version 5.0 and above") - .style(color::GREY_2), + .color(color::GREY_2), ) } else { None @@ -102,7 +103,7 @@ pub fn path( .push( Column::new() .spacing(5) - .align_items(Alignment::Center) + .align_x(Alignment::Center) .push(Column::with_children(keys).spacing(5)), ) .push_maybe(if fixed { @@ -124,22 +125,22 @@ pub fn path( }), ) .padding(10) - .style(theme::Container::Card(theme::Card::Border)) + .style(theme::card::border) .into() } pub fn uneditable_defined_key<'a>( alias: &'a str, color: iced::Color, - title: impl Into>, + title: impl Into> + std::fmt::Display, warning: Option<&'static str>, ) -> Element<'a, message::DefineKey> { card::simple( Row::new() .spacing(10) .width(Length::Fill) - .align_items(Alignment::Center) - .push(icon::round_key_icon().size(H3_SIZE).style(color)) + .align_y(Alignment::Center) + .push(icon::round_key_icon().size(H3_SIZE).color(color)) .push( Column::new() .width(Length::Fill) @@ -147,13 +148,13 @@ pub fn uneditable_defined_key<'a>( .push( Row::new() .spacing(10) - .push(p1_regular(title).style(color::GREY_2)) + .push(p1_regular(title).color(color::GREY_2)) .push(p1_bold(alias)), ) - .push_maybe(warning.map(|w| p2_regular(w).style(color::RED))), + .push_maybe(warning.map(|w| p2_regular(w).color(color::RED))), ) .push_maybe(if warning.is_none() { - Some(icon::check_icon().style(color::GREEN)) + Some(icon::check_icon().color(color::GREEN)) } else { None }), @@ -164,7 +165,7 @@ pub fn uneditable_defined_key<'a>( pub fn defined_key<'a>( alias: &'a str, color: iced::Color, - title: impl Into>, + title: impl Display, warning: Option<&'static str>, fixed: bool, ) -> Element<'a, message::DefineKey> { @@ -172,8 +173,8 @@ pub fn defined_key<'a>( Row::new() .spacing(10) .width(Length::Fill) - .align_items(Alignment::Center) - .push(icon::round_key_icon().size(H3_SIZE).style(color)) + .align_y(Alignment::Center) + .push(icon::round_key_icon().size(H3_SIZE).color(color)) .push( Column::new() .width(Length::Fill) @@ -181,13 +182,13 @@ pub fn defined_key<'a>( .push( Row::new() .spacing(10) - .push(p1_regular(title).style(color::GREY_2)) + .push(p1_regular(format!("{}", title)).color(color::GREY_2)) .push(p1_bold(alias)), ) - .push_maybe(warning.map(|w| p2_regular(w).style(color::RED))), + .push_maybe(warning.map(|w| p2_regular(w).color(color::RED))), ) .push_maybe(if warning.is_none() { - Some(icon::check_icon().style(color::GREEN)) + Some(icon::check_icon().color(color::GREEN)) } else { None }) @@ -200,7 +201,7 @@ pub fn defined_key<'a>( } else { Some( Button::new(icon::trash_icon()) - .style(theme::Button::Secondary) + .style(theme::button::secondary) .padding(5) .on_press(message::DefineKey::Delete), ) @@ -211,7 +212,7 @@ pub fn defined_key<'a>( pub fn undefined_key<'a>( color: iced::Color, - title: impl Into>, + title: impl Into> + std::fmt::Display, active: bool, fixed: bool, ) -> Element<'a, message::DefineKey> { @@ -219,8 +220,8 @@ pub fn undefined_key<'a>( Row::new() .spacing(10) .width(Length::Fill) - .align_items(Alignment::Center) - .push(icon::round_key_icon().size(H3_SIZE).style(color)) + .align_y(Alignment::Center) + .push(icon::round_key_icon().size(H3_SIZE).color(color)) .push( Column::new() .width(Length::Fill) @@ -240,7 +241,7 @@ pub fn undefined_key<'a>( } else { Some( Button::new(icon::trash_icon()) - .style(theme::Button::Secondary) + .style(theme::button::secondary) .padding(5) .on_press(message::DefineKey::Delete), ) @@ -274,7 +275,7 @@ pub fn edit_key_modal<'a>( .push(h3(title)) .push(Space::with_width(Length::Fill)) .push(button::transparent(Some(icon::cross_icon().size(40)), "").on_press(Message::Close)) - .align_items(Alignment::Center) + .align_y(Alignment::Center) ) .push( Column::new() @@ -294,14 +295,14 @@ pub fn edit_key_modal<'a>( }) .width(Length::Fill) .on_press(Message::UseHotSigner) - .style(theme::Button::Border), + .style(theme::button::container_border), ) .push(if manually_imported_xpub { card::simple(Column::new() .spacing(10) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push(p1_regular("Enter an extended public key:").width(Length::Fill)) .push(image::success_mark_icon().width(Length::Fixed(50.0))) ) @@ -329,7 +330,7 @@ pub fn edit_key_modal<'a>( Container::new( Button::new( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) .push(icon::import_icon()) .push(p1_regular("Enter an extended public key")) @@ -339,7 +340,7 @@ pub fn edit_key_modal<'a>( .on_press(Message::DefineDescriptor( message::DefineDescriptor::KeyModal(message::ImportKeyModal::ManuallyImportXpub) )) - .style(theme::Button::Secondary), + .style(theme::button::secondary), ) } ) @@ -355,7 +356,7 @@ pub fn edit_key_modal<'a>( .push(text("Key name:").bold()) .push(tooltip(prompt::DEFINE_DESCRIPTOR_FINGERPRINT_TOOLTIP)), ) - .push(p1_regular("Give this key a friendly name. It helps you identify it later").style(color::GREY_2)) + .push(p1_regular("Give this key a friendly name. It helps you identify it later").color(color::GREY_2)) .push( form::Form::new("Name", form_name, |msg| { Message::DefineDescriptor(message::DefineDescriptor::KeyModal( @@ -372,7 +373,7 @@ pub fn edit_key_modal<'a>( ) .push_maybe( if duplicate_master_fg { - Some(text("A single signing device may not be used more than once per path. (It can still be used in other paths.)").style(color::RED)) + Some(text("A single signing device may not be used more than once per path. (It can still be used in other paths.)").color(color::RED)) } else { None } @@ -390,7 +391,7 @@ pub fn edit_key_modal<'a>( } else {None}) .width(Length::Fixed(200.0)) ) - .align_items(Alignment::Center), + .align_x(Alignment::Center), )) .width(Length::Fixed(800.0)); scrollable(content).into() @@ -421,7 +422,7 @@ pub fn edit_sequence_modal<'a>(sequence: &form::Value) -> Element<'a, Me let mut col = Column::new() .width(Length::Fill) .spacing(20) - .align_items(Alignment::Center) + .align_x(Alignment::Center) .push(text("Keys can move the funds after inactivity of:")) .push( Row::new() @@ -502,7 +503,7 @@ pub fn edit_threshold_modal<'a>(threshold: (usize, usize)) -> Element<'a, Messag Column::new() .width(Length::Fill) .spacing(20) - .align_items(Alignment::Center) + .align_x(Alignment::Center) .push(threshsold_input::threshsold_input( threshold.0, threshold.1, @@ -592,7 +593,7 @@ mod threshsold_input { fn view(&self, _state: &Self::State) -> Element { let button = |label, on_press| { Button::new(label) - .style(theme::Button::Transparent) + .style(theme::button::transparent) .width(Length::Fixed(50.0)) .on_press(on_press) }; @@ -606,7 +607,7 @@ mod threshsold_input { .align_y(alignment::Vertical::Center), ) .push(button(icon::down_icon().size(30), Event::DecrementPressed)) - .align_items(Alignment::Center) + .align_x(Alignment::Center) .into() } } diff --git a/liana-gui/src/installer/view/editor/template/custom.rs b/liana-gui/src/installer/view/editor/template/custom.rs index 94224cf7f..e6eb0782f 100644 --- a/liana-gui/src/installer/view/editor/template/custom.rs +++ b/liana-gui/src/installer/view/editor/template/custom.rs @@ -25,18 +25,18 @@ pub fn custom_template_description(progress: (usize, usize)) -> Element<'static, None, "Introduction", Column::new() - .align_items(Alignment::Start) + .align_x(Alignment::Start) .push(h3("Build your own")) .max_width(800.0) .push(Container::new( p1_regular("For this setup you will need to define your primary and recovery spending policies. For security reasons, we suggest you use a separate Hardware Wallet for each key belonging to them.") - .style(color::GREY_2) - .horizontal_alignment(alignment::Horizontal::Left) + .color(color::GREY_2) + .align_x(alignment::Horizontal::Left) ).align_x(alignment::Horizontal::Left).width(Length::Fill)) .push(Container::new( p1_regular("The keys belonging to your primary policy can always spend. Those belonging to the recovery policies will be able to spend only after a defined time of wallet inactivity, allowing for secure recovery and advanced spending policies.") - .style(color::GREY_2) - .horizontal_alignment(alignment::Horizontal::Left) + .color(color::GREY_2) + .align_x(alignment::Horizontal::Left) ).align_x(alignment::Horizontal::Left).width(Length::Fill)) .push(image::custom_template_description().width(Length::Fill)) .push(Row::new().push(Space::with_width(Length::Fill)).push(button::primary(None, "Next").width(Length::Fixed(200.0)).on_press(Message::Next))) @@ -66,28 +66,28 @@ pub fn custom_template<'a>( None, "Set keys", Column::new() - .align_items(Alignment::Start) + .align_x(Alignment::Start) .max_width(1000.0) .push(collapse::Collapse::new( || { Button::new( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) .push(text("Advanced settings").small().bold()) .push(icon::collapse_icon()), ) - .style(theme::Button::Transparent) + .style(theme::button::transparent) }, || { Button::new( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) .push(text("Advanced settings").small().bold()) .push(icon::collapsed_icon()), ) - .style(theme::Button::Transparent) + .style(theme::button::transparent) }, move || define_descriptor_advanced_settings(use_taproot), )) diff --git a/liana-gui/src/installer/view/editor/template/inheritance.rs b/liana-gui/src/installer/view/editor/template/inheritance.rs index b709e7aa8..8fde513c7 100644 --- a/liana-gui/src/installer/view/editor/template/inheritance.rs +++ b/liana-gui/src/installer/view/editor/template/inheritance.rs @@ -26,34 +26,34 @@ pub fn inheritance_template_description(progress: (usize, usize)) -> Element<'st None, "Introduction", Column::new() - .align_items(Alignment::Start) + .align_x(Alignment::Start) .push(h3("Simple inheritance wallet")) .max_width(800.0) .push(Container::new( p1_regular("For this setup you will need 2 Keys: Your Primary Key (for yourself) and an Inheritance Key (for your heir). For security reasons, we suggest you use a separate Hardware Wallet for each key.") - .style(color::GREY_2) - .horizontal_alignment(alignment::Horizontal::Left) + .color(color::GREY_2) + .align_x(alignment::Horizontal::Left) ).align_x(alignment::Horizontal::Left).width(Length::Fill)) .push(Row::new() .spacing(30) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) - .push(icon::round_key_icon().size(H3_SIZE).style(color::GREEN)) + .push(icon::round_key_icon().size(H3_SIZE).color(color::GREEN)) .push(p1_regular("Primary key").bold()) ).push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) - .push(icon::round_key_icon().size(H3_SIZE).style(color::WHITE)) + .push(icon::round_key_icon().size(H3_SIZE).color(color::WHITE)) .push(p1_regular("Inheritance key").bold()) )) .push(Container::new( p1_regular("You will always be able to spend using your Primary Key. After a period of inactivity (but not before that) your Inheritance Key will become able to recover your funds.") - .style(color::GREY_2) - .horizontal_alignment(alignment::Horizontal::Left) + .color(color::GREY_2) + .align_x(alignment::Horizontal::Left) ).align_x(alignment::Horizontal::Left).width(Length::Fill)) .push(image::inheritance_template_description().width(Length::Fill)) .push(Row::new().push(Space::with_width(Length::Fill)).push(button::primary(None, "Next").width(Length::Fixed(200.0)).on_press(Message::Next))) @@ -77,28 +77,28 @@ pub fn inheritance_template<'a>( None, "Set keys", Column::new() - .align_items(Alignment::Start) + .align_x(Alignment::Start) .max_width(1000.0) .push(collapse::Collapse::new( || { Button::new( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) .push(text("Advanced settings").small().bold()) .push(icon::collapse_icon()), ) - .style(theme::Button::Transparent) + .style(theme::button::transparent) }, || { Button::new( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) .push(text("Advanced settings").small().bold()) .push(icon::collapsed_icon()), ) - .style(theme::Button::Transparent) + .style(theme::button::transparent) }, move || define_descriptor_advanced_settings(use_taproot), )) diff --git a/liana-gui/src/installer/view/editor/template/mod.rs b/liana-gui/src/installer/view/editor/template/mod.rs index c19947a07..33e3fd57c 100644 --- a/liana-gui/src/installer/view/editor/template/mod.rs +++ b/liana-gui/src/installer/view/editor/template/mod.rs @@ -21,13 +21,13 @@ pub fn choose_descriptor_template(progress: (usize, usize)) -> Element<'static, "Choose wallet type", Column::new() .max_width(800.0) - .align_items(Alignment::Start) + .align_x(Alignment::Start) .push( Button::new( Column::new() - .align_items(Alignment::Start) + .align_x(Alignment::Start) .push(h3("Simple inheritance")) - .push(p2_regular("Two keys required, one for yourself to spend and another for your heir.").style(color::GREY_2)) + .push(p2_regular("Two keys required, one for yourself to spend and another for your heir.").color(color::GREY_2)) .width(Length::Fill) ) .padding(15) @@ -35,15 +35,15 @@ pub fn choose_descriptor_template(progress: (usize, usize)) -> Element<'static, Message::SelectDescriptorTemplate( context::DescriptorTemplate::SimpleInheritance, ) - ).style(theme::Button::Secondary) + ).style(theme::button::secondary) .width(Length::Fill), ) .push( Button::new( Column::new() - .align_items(Alignment::Start) + .align_x(Alignment::Start) .push(h3("Expanding multisig")) - .push(p2_regular("Two keys required to spend, with an extra key as a backup.").style(color::GREY_2)) + .push(p2_regular("Two keys required to spend, with an extra key as a backup.").color(color::GREY_2)) .width(Length::Fill) ) .padding(15) @@ -51,15 +51,15 @@ pub fn choose_descriptor_template(progress: (usize, usize)) -> Element<'static, Message::SelectDescriptorTemplate( context::DescriptorTemplate::MultisigSecurity, ) - ).style(theme::Button::Secondary) + ).style(theme::button::secondary) .width(Length::Fill), ) .push( Button::new( Column::new() - .align_items(Alignment::Start) + .align_x(Alignment::Start) .push(h3("Build your own")) - .push(p2_regular("Create a custom setup that fits all your needs.").style(color::GREY_2)) + .push(p2_regular("Create a custom setup that fits all your needs.").color(color::GREY_2)) .width(Length::Fill) ) .padding(15) @@ -67,7 +67,7 @@ pub fn choose_descriptor_template(progress: (usize, usize)) -> Element<'static, Message::SelectDescriptorTemplate( context::DescriptorTemplate::Custom, ) - ).style(theme::Button::Secondary) + ).style(theme::button::secondary) .width(Length::Fill), ) .spacing(20), diff --git a/liana-gui/src/installer/view/editor/template/multisig_security_wallet.rs b/liana-gui/src/installer/view/editor/template/multisig_security_wallet.rs index 4f4c1ca45..078db8f39 100644 --- a/liana-gui/src/installer/view/editor/template/multisig_security_wallet.rs +++ b/liana-gui/src/installer/view/editor/template/multisig_security_wallet.rs @@ -31,39 +31,39 @@ pub fn multisig_security_template_description( None, "Introduction", Column::new() - .align_items(Alignment::Start) + .align_x(Alignment::Start) .push(h3("Expanding multisig wallet")) .max_width(800.0) .push(Container::new( p1_regular("For this setup you will need 3 keys: two Primary Keys and a Recovery Key. For security reasons, we suggest you use a separate Hardware Wallet for each key.") - .style(color::GREY_2) - .horizontal_alignment(alignment::Horizontal::Left) + .color(color::GREY_2) + .align_x(alignment::Horizontal::Left) ).align_x(alignment::Horizontal::Left).width(Length::Fill)) .push(Row::new() .spacing(30) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) - .push(icon::round_key_icon().size(H3_SIZE).style(color::GREEN)) + .push(icon::round_key_icon().size(H3_SIZE).color(color::GREEN)) .push(p1_regular("Primary key #1").bold()) ).push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) - .push(icon::round_key_icon().size(H3_SIZE).style(color::GREEN)) + .push(icon::round_key_icon().size(H3_SIZE).color(color::GREEN)) .push(p1_regular("Primary key #2").bold()) ).push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) - .push(icon::round_key_icon().size(H3_SIZE).style(color::ORANGE)) + .push(icon::round_key_icon().size(H3_SIZE).color(color::ORANGE)) .push(p1_regular("Recovery key").bold()) )) .push(Container::new( p1_regular("The Primary Keys will compose a 2-of-2 multisig which will always be able to spend. In case one of your keys becomes unavailable, after a period of inactivity you will be able to recover your funds using the Recovery Key together with one of your Primary Keys (2-of-3 multisig):") - .style(color::GREY_2) - .horizontal_alignment(alignment::Horizontal::Left) + .color(color::GREY_2) + .align_x(alignment::Horizontal::Left) ).align_x(alignment::Horizontal::Left).width(Length::Fill)) .push(image::multisig_security_template_description().width(Length::Fill)) .push(Row::new().push(Space::with_width(Length::Fill)).push(button::primary(None, "Next").width(Length::Fixed(200.0)).on_press(Message::Next))) @@ -88,28 +88,28 @@ pub fn multisig_security_template<'a>( None, "Set keys", Column::new() - .align_items(Alignment::Start) + .align_x(Alignment::Start) .max_width(1000.0) .push(collapse::Collapse::new( || { Button::new( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) .push(text("Advanced settings").small().bold()) .push(icon::collapse_icon()), ) - .style(theme::Button::Transparent) + .style(theme::button::transparent) }, || { Button::new( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) .push(text("Advanced settings").small().bold()) .push(icon::collapsed_icon()), ) - .style(theme::Button::Transparent) + .style(theme::button::transparent) }, move || define_descriptor_advanced_settings(use_taproot), )) diff --git a/liana-gui/src/installer/view/mod.rs b/liana-gui/src/installer/view/mod.rs index acd3b7d79..7fc106d3a 100644 --- a/liana-gui/src/installer/view/mod.rs +++ b/liana-gui/src/installer/view/mod.rs @@ -1,7 +1,7 @@ pub mod editor; use async_hwi::utils::extract_keys_and_template; -use iced::widget::{checkbox, radio, scrollable, scrollable::Properties, Button, Space, TextInput}; +use iced::widget::{checkbox, radio, scrollable, scrollable::Scrollbar, Button, Space, TextInput}; use iced::{ alignment, widget::{progress_bar, tooltip as iced_tooltip}, @@ -60,7 +60,7 @@ pub fn import_wallet_or_descriptor<'a>( for (i, wallet) in wallets.into_iter().enumerate() { col_wallets = col_wallets.push( Button::new(h5_regular(wallet).width(Length::Fill)) - .style(theme::Button::Secondary) + .style(theme::button::secondary) .padding(10) .on_press(Message::Select(i)), ); @@ -76,29 +76,29 @@ pub fn import_wallet_or_descriptor<'a>( Button::new( Column::new() .spacing(5) - .push(h4_bold("Load a shared wallet").style(color::WHITE)) + .push(h4_bold("Load a shared wallet").color(color::WHITE)) .push( text("If you received an invitation to join a shared wallet") - .style(color::GREY_3), + .color(color::GREY_3), ), ) .padding(15) .width(Length::Fill) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) }, || { Button::new( Column::new() .spacing(5) - .push(h4_bold("Load a shared wallet").style(color::WHITE)) + .push(h4_bold("Load a shared wallet").color(color::WHITE)) .push( text("Type the invitation token you received by email") - .style(color::GREY_3), + .color(color::GREY_3), ), ) .padding(15) .width(Length::Fill) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) }, move || { if let Some(wallet) = invitation_wallet { @@ -170,23 +170,23 @@ pub fn import_wallet_or_descriptor<'a>( Button::new( Column::new() .spacing(5) - .push(h4_bold("Load a wallet from descriptor").style(color::WHITE)) - .push(text("Creates a new wallet from the descriptor").style(color::GREY_3)), + .push(h4_bold("Load a wallet from descriptor").color(color::WHITE)) + .push(text("Creates a new wallet from the descriptor").color(color::GREY_3)), ) .padding(15) .width(Length::Fill) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) }, || { Button::new( Column::new() .spacing(5) - .push(h4_bold("Load a wallet from descriptor").style(color::WHITE)) - .push(text("Creates a new wallet from the descriptor").style(color::GREY_3)), + .push(h4_bold("Load a wallet from descriptor").color(color::WHITE)) + .push(text("Creates a new wallet from the descriptor").color(color::GREY_3)), ) .padding(15) .width(Length::Fill) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) }, move || { Element::<'a, Message>::from( @@ -316,17 +316,17 @@ pub fn signer_xpubs<'a>( Column::new() .push( Button::new( - Row::new().align_items(Alignment::Center).push( + Row::new().align_y(Alignment::Center).push( Column::new() .push(text("Generate a new mnemonic").bold()) - .push(text(BACKUP_WARNING).small().style(color::ORANGE)) + .push(text(BACKUP_WARNING).small().color(color::ORANGE)) .spacing(5) .width(Length::Fill), ), ) .on_press(Message::UseHotSigner) .padding(10) - .style(theme::Button::TransparentBorder) + .style(theme::button::transparent_border) .width(Length::Fill), ) .push_maybe(if xpubs.is_empty() { @@ -343,7 +343,7 @@ pub fn signer_xpubs<'a>( |acc, (i, w)| { acc.push( Row::new() - .align_items(Alignment::End) + .align_y(Alignment::End) .push( Container::new(text(format!("#{}", i + 1)).small()) .width(Length::Fixed(50.0)), @@ -374,12 +374,12 @@ pub fn signer_xpubs<'a>( col.push( Row::new() .spacing(5) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( Container::new( scrollable(Container::new(text(xpub).small()).padding(10)) .direction(scrollable::Direction::Horizontal( - Properties::new().width(5).scroller_width(5), + Scrollbar::new().width(5).scroller_width(5), )), ) .width(Length::Fill), @@ -398,7 +398,7 @@ pub fn signer_xpubs<'a>( None }), ) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) .into() } @@ -448,7 +448,7 @@ pub fn hardware_wallet_xpubs<'a>( kind, pairing_code, .. } => hw::locked_hardware_wallet(kind, pairing_code.as_ref()), }) - .style(theme::Button::Secondary) + .style(theme::button::secondary) .width(Length::Fill); if !processing && hw.is_supported() { bttn = bttn.on_press(Message::Select(i)); @@ -467,12 +467,12 @@ pub fn hardware_wallet_xpubs<'a>( col.push( Row::new() .spacing(5) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( Container::new( scrollable(Container::new(text(xpub).small()).padding(10)) .direction(scrollable::Direction::Horizontal( - Properties::new().width(5).scroller_width(5), + Scrollbar::new().width(5).scroller_width(5), )), ) .width(Length::Fill), @@ -489,7 +489,7 @@ pub fn hardware_wallet_xpubs<'a>( }) })), ) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) .into() } @@ -510,7 +510,7 @@ pub fn share_xpubs<'a>( .width(Length::Fill), ) .push_maybe(if hws.is_empty() { - Some(p1_regular("No signing device connected").style(color::GREY_3)) + Some(p1_regular("No signing device connected").color(color::GREY_3)) } else { None }) @@ -538,47 +538,22 @@ pub fn register_descriptor<'a>( done: bool, created_desc: bool, ) -> Element<'a, Message> { - let displayed_descriptor = if let Ok((template, keys)) = - extract_keys_and_template::(&descriptor) - { - let mut col = Column::new() - .push( - card::simple( - Column::new() - .push(text("Descriptor template:").small().bold()) - .push( - scrollable( - Column::new() - .push(text(template).small()) - .push(Space::with_height(Length::Fixed(5.0))), - ) - .direction( - scrollable::Direction::Horizontal( - scrollable::Properties::new().width(5).scroller_width(5), - ), - ), - ) - .spacing(10), - ) - .width(Length::Fill), - ) - .push(Space::with_height(5)); - - for (index, key) in keys.into_iter().enumerate() { - col = col + let displayed_descriptor = + if let Ok((template, keys)) = extract_keys_and_template::(&descriptor) { + let mut col = Column::new() .push( card::simple( Column::new() - .push(text(format!("Key @{}:", index)).small().bold()) + .push(text("Descriptor template:").small().bold()) .push( scrollable( Column::new() - .push(text(key.to_owned()).small()) + .push(text(template).small()) .push(Space::with_height(Length::Fixed(5.0))), ) .direction( scrollable::Direction::Horizontal( - scrollable::Properties::new().width(5).scroller_width(5), + scrollable::Scrollbar::new().width(5).scroller_width(5), ), ), ) @@ -587,32 +562,56 @@ pub fn register_descriptor<'a>( .width(Length::Fill), ) .push(Space::with_height(5)); - } - col - } else { - Column::new().push(card::simple( - Column::new() - .push(text("The descriptor:").small().bold()) - .push( - scrollable( - Column::new() - .push(text(descriptor.to_owned()).small()) - .push(Space::with_height(Length::Fixed(5.0))), + for (index, key) in keys.into_iter().enumerate() { + col = col + .push( + card::simple( + Column::new() + .push(text(format!("Key @{}:", index)).small().bold()) + .push( + scrollable( + Column::new() + .push(text(key.to_owned()).small()) + .push(Space::with_height(Length::Fixed(5.0))), + ) + .direction( + scrollable::Direction::Horizontal( + scrollable::Scrollbar::new().width(5).scroller_width(5), + ), + ), + ) + .spacing(10), + ) + .width(Length::Fill), ) - .direction(scrollable::Direction::Horizontal( - scrollable::Properties::new().width(5).scroller_width(5), - )), - ) - .push( - Row::new().push(Column::new().width(Length::Fill)).push( - button::secondary(Some(icon::clipboard_icon()), "Copy") - .on_press(Message::Clibpboard(descriptor)), - ), - ) - .spacing(10), - )) - }; + .push(Space::with_height(5)); + } + + col + } else { + Column::new().push(card::simple( + Column::new() + .push(text("The descriptor:").small().bold()) + .push( + scrollable( + Column::new() + .push(text(descriptor.to_owned()).small()) + .push(Space::with_height(Length::Fixed(5.0))), + ) + .direction(scrollable::Direction::Horizontal( + scrollable::Scrollbar::new().width(5).scroller_width(5), + )), + ) + .push( + Row::new().push(Column::new().width(Length::Fill)).push( + button::secondary(Some(icon::clipboard_icon()), "Copy") + .on_press(Message::Clibpboard(descriptor)), + ), + ) + .spacing(10), + )) + }; layout( progress, email, @@ -697,22 +696,22 @@ pub fn backup_descriptor<'a>( || { Button::new( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) .push(text("Learn more").small().bold()) .push(icon::collapse_icon()), ) - .style(theme::Button::Transparent) + .style(theme::button::transparent) }, || { Button::new( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) .push(text("Learn more").small().bold()) .push(icon::collapsed_icon()), ) - .style(theme::Button::Transparent) + .style(theme::button::transparent) }, help_backup, )) @@ -730,7 +729,7 @@ pub fn backup_descriptor<'a>( ) .direction( scrollable::Direction::Horizontal( - scrollable::Properties::new().width(5).scroller_width(5), + scrollable::Scrollbar::new().width(5).scroller_width(5), ), ), ) @@ -803,7 +802,7 @@ fn display_policy( text(k.to_string()), iced_tooltip::Position::Bottom, ) - .style(theme::Container::Card(theme::Card::Simple)), + .style(theme::card::simple), ) } else { Container::new(text(format!("[{}]", k)).bold()) @@ -850,7 +849,7 @@ fn display_policy( text(k.to_string()), iced_tooltip::Position::Bottom, ) - .style(theme::Container::Card(theme::Card::Simple)), + .style(theme::card::simple), ) } else { Container::new(text(format!("[{}]", k)).bold()) @@ -880,7 +879,7 @@ fn display_policy( .spacing(10) .push(text("The wallet policy:").bold()) .push(scrollable(col).direction(scrollable::Direction::Horizontal( - scrollable::Properties::new().width(5).scroller_width(5), + scrollable::Scrollbar::new().width(5).scroller_width(5), ))) .into() } @@ -957,7 +956,7 @@ pub fn define_bitcoin_node<'a>( }, )) .spacing(30) - .align_items(Alignment::Center) + .align_y(Alignment::Center) }, ), ) @@ -966,7 +965,7 @@ pub fn define_bitcoin_node<'a>( Some(Container::new( Row::new() .spacing(10) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push(text("Checking connection...")), )) } else if is_running.is_some() { @@ -975,17 +974,17 @@ pub fn define_bitcoin_node<'a>( Container::new( Row::new() .spacing(10) - .align_items(Alignment::Center) - .push(icon::circle_check_icon().style(color::GREEN)) - .push(text("Connection checked").style(color::GREEN)), + .align_y(Alignment::Center) + .push(icon::circle_check_icon().color(color::GREEN)) + .push(text("Connection checked").color(color::GREEN)), ) } else { Container::new( Row::new() .spacing(10) - .align_items(Alignment::Center) - .push(icon::circle_cross_icon().style(color::RED)) - .push(text("Connection failed").style(color::RED)), + .align_y(Alignment::Center) + .push(icon::circle_cross_icon().color(color::RED)) + .push(text("Connection failed").color(color::RED)), ) } }) @@ -1059,7 +1058,7 @@ pub fn define_bitcoind<'a>( is not supported. Insert an IP address bound to the same machine \ running Liana (ignore this warning if that's already the case)", ) - .style(color::ORANGE) + .color(color::ORANGE) .size(text::CAPTION_SIZE), ) } else { @@ -1087,7 +1086,7 @@ pub fn define_bitcoind<'a>( }, )) .spacing(30) - .align_items(Alignment::Center) + .align_y(Alignment::Center) }, ), ) @@ -1164,7 +1163,7 @@ pub fn select_bitcoind_type<'a>(progress: (usize, usize)) -> Element<'a, Message Column::new() .push( Row::new() - .align_items(Alignment::Start) + .align_y(Alignment::Start) .spacing(20) .push( Container::new( @@ -1190,14 +1189,14 @@ pub fn select_bitcoind_type<'a>(progress: (usize, usize)) -> Element<'a, Message ) .push( Row::new() - .align_items(Alignment::Start) + .align_y(Alignment::Start) .spacing(20) .push( Container::new( Column::new() .spacing(20) .width(Length::Fixed(300.0)) - .align_items(Alignment::Start) + .align_x(Alignment::Start) .push(text( "Select this option if you already have \ a Bitcoin node running locally or remotely. \ @@ -1211,7 +1210,7 @@ pub fn select_bitcoind_type<'a>(progress: (usize, usize)) -> Element<'a, Message Column::new() .spacing(20) .width(Length::Fixed(300.0)) - .align_items(Alignment::Start) + .align_x(Alignment::Start) .push(text( "Liana will install a pruned node \ on your computer. You won't need to do anything \ @@ -1227,14 +1226,14 @@ pub fn select_bitcoind_type<'a>(progress: (usize, usize)) -> Element<'a, Message ) .push( Row::new() - .align_items(Alignment::End) + .align_y(Alignment::End) .spacing(20) .push( Container::new( Column::new() .spacing(20) .width(Length::Fixed(300.0)) - .align_items(Alignment::Center) + .align_x(Alignment::Center) .push( button::secondary(None, "Select") .width(Length::Fixed(300.0)) @@ -1250,7 +1249,7 @@ pub fn select_bitcoind_type<'a>(progress: (usize, usize)) -> Element<'a, Message Column::new() .spacing(20) .width(Length::Fixed(300.0)) - .align_items(Alignment::Center) + .align_x(Alignment::Center) .push( button::secondary(None, "Select") .width(Length::Fixed(300.0)) @@ -1285,53 +1284,53 @@ pub fn start_internal_bitcoind<'a>( match s { DownloadState::Finished(_) => Row::new() .spacing(10) - .align_items(Alignment::Center) - .push(icon::circle_check_icon().style(color::GREEN)) - .push(text("Download complete").style(color::GREEN)), + .align_y(Alignment::Center) + .push(icon::circle_check_icon().color(color::GREEN)) + .push(text("Download complete").color(color::GREEN)), DownloadState::Downloading { progress } => Row::new() .spacing(10) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push(text(format!( "Downloading Bitcoin Core {version}... {progress:.2}%" ))), DownloadState::Errored(e) => Row::new() .spacing(10) - .align_items(Alignment::Center) - .push(icon::circle_cross_icon().style(color::RED)) - .push(text(format!("Download failed: '{}'.", e)).style(color::RED)), - _ => Row::new().spacing(10).align_items(Alignment::Center), + .align_y(Alignment::Center) + .push(icon::circle_cross_icon().color(color::RED)) + .push(text(format!("Download failed: '{}'.", e)).color(color::RED)), + _ => Row::new().spacing(10).align_y(Alignment::Center), } })) .push(Container::new(if let Some(state) = install_state { match state { InstallState::InProgress => Row::new() .spacing(10) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push("Installing bitcoind..."), InstallState::Finished => Row::new() .spacing(10) - .align_items(Alignment::Center) - .push(icon::circle_check_icon().style(color::GREEN)) - .push(text("Installation complete").style(color::GREEN)), + .align_y(Alignment::Center) + .push(icon::circle_check_icon().color(color::GREEN)) + .push(text("Installation complete").color(color::GREEN)), InstallState::Errored(e) => Row::new() .spacing(10) - .align_items(Alignment::Center) - .push(icon::circle_cross_icon().style(color::RED)) - .push(text(format!("Installation failed: '{}'.", e)).style(color::RED)), + .align_y(Alignment::Center) + .push(icon::circle_cross_icon().color(color::RED)) + .push(text(format!("Installation failed: '{}'.", e)).color(color::RED)), } } else if exe_path.is_some() { Row::new() .spacing(10) - .align_items(Alignment::Center) - .push(icon::circle_check_icon().style(color::GREEN)) - .push(text("Liana-managed bitcoind already installed").style(color::GREEN)) + .align_y(Alignment::Center) + .push(icon::circle_check_icon().color(color::GREEN)) + .push(text("Liana-managed bitcoind already installed").color(color::GREEN)) } else if let Some(DownloadState::Downloading { progress }) = download_state { Row::new() .spacing(10) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push(progress_bar(0.0..=100.0, *progress)) } else { - Row::new().spacing(10).align_items(Alignment::Center) + Row::new().spacing(10).align_y(Alignment::Center) })) .push_maybe(if started.is_some() { started.map(|res| { @@ -1339,18 +1338,18 @@ pub fn start_internal_bitcoind<'a>( Container::new( Row::new() .spacing(10) - .align_items(Alignment::Center) - .push(icon::circle_check_icon().style(color::GREEN)) - .push(text("Started").style(color::GREEN)), + .align_y(Alignment::Center) + .push(icon::circle_check_icon().color(color::GREEN)) + .push(text("Started").color(color::GREEN)), ) } else { Container::new( Row::new() .spacing(10) - .align_items(Alignment::Center) - .push(icon::circle_cross_icon().style(color::RED)) + .align_y(Alignment::Center) + .push(icon::circle_cross_icon().color(color::RED)) .push( - text(res.as_ref().err().unwrap().to_string()).style(color::RED), + text(res.as_ref().err().unwrap().to_string()).color(color::RED), ), ) } @@ -1361,7 +1360,7 @@ pub fn start_internal_bitcoind<'a>( (Some(InstallState::Finished), _) | (None, Some(_)) => Some(Container::new( Row::new() .spacing(10) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push(text("Starting...")), )), _ => Some(Container::new(Space::with_height(Length::Fixed(25.0)))), @@ -1411,9 +1410,9 @@ pub fn install<'a>( Container::new( Row::new() .spacing(10) - .align_items(Alignment::Center) - .push(icon::circle_check_icon().style(color::GREEN)) - .push(text("Installed").style(color::GREEN)), + .align_y(Alignment::Center) + .push(icon::circle_check_icon().color(color::GREEN)) + .push(text("Installed").color(color::GREEN)), ) } else { Container::new(Space::with_height(Length::Fixed(25.0))) @@ -1436,7 +1435,7 @@ pub fn defined_threshold<'a>( .spacing(10) .push((0..threshold.1).fold(Row::new(), |row, i| { if i < threshold.0 { - row.push(icon::round_key_icon().style(color)) + row.push(icon::round_key_icon().color(color)) } else { row.push(icon::round_key_icon()) } @@ -1451,7 +1450,7 @@ pub fn defined_threshold<'a>( ) .padding(10) .on_press(message::DefinePath::EditThreshold) - .style(theme::Button::Secondary) + .style(theme::button::secondary) .into() } else { card::simple( @@ -1459,7 +1458,7 @@ pub fn defined_threshold<'a>( .spacing(10) .push((0..threshold.1).fold(Row::new(), |row, i| { if i < threshold.0 { - row.push(icon::round_key_icon().style(color)) + row.push(icon::round_key_icon().color(color)) } else { row.push(icon::round_key_icon()) } @@ -1485,21 +1484,21 @@ pub fn defined_sequence<'a>( Column::new() .spacing(5) .push(if sequence != 0 { - Row::new().align_items(Alignment::Center).push( + Row::new().align_y(Alignment::Center).push( Container::new( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(5) .push( text::p1_regular("Available after inactivity of ~") - .style(color::GREY_2), + .color(color::GREY_2), ) .push( Button::new( Row::new() .padding(5) .spacing(5) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push(text( [ (n_years, "y"), @@ -1521,7 +1520,7 @@ pub fn defined_sequence<'a>( )) .push(icon::pencil_icon()), ) - .style(theme::Button::Secondary) + .style(theme::button::secondary) .on_press(message::DefinePath::EditSequence), ), ) @@ -1531,14 +1530,14 @@ pub fn defined_sequence<'a>( ) } else { Row::new() - .push(p1_regular("Able to move the funds at any time.").style(color::GREY_2)) + .push(p1_regular("Able to move the funds at any time.").color(color::GREY_2)) .padding(5) }) .push_maybe(if duplicate_sequence { Some( text("No two recovery options may become available at the very same date.") .small() - .style(color::RED), + .color(color::RED), ) } else { None @@ -1614,14 +1613,14 @@ pub fn hw_list_view( kind, pairing_code, .. } => hw::locked_hardware_wallet(kind, pairing_code.as_ref()), }) - .style(theme::Button::Border) + .style(theme::button::container_border) .width(Length::Fill); if !processing && hw.is_supported() { bttn = bttn.on_press(Message::Select(i)); } Container::new(bttn) .width(Length::Fill) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) .into() } @@ -1666,14 +1665,14 @@ pub fn key_list_view<'a>( Some(name), ) }) - .style(theme::Button::Border) + .style(theme::button::secondary) .width(Length::Fill) .on_press(Message::DefineDescriptor( message::DefineDescriptor::KeyModal(message::ImportKeyModal::SelectKey(i)), )); Container::new(bttn) .width(Length::Fill) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) .into() } @@ -1696,7 +1695,7 @@ pub fn backup_mnemonic<'a>( .fold(Column::new().spacing(5), |acc, (i, w)| { acc.push( Row::new() - .align_items(Alignment::End) + .align_y(Alignment::End) .push( Container::new(text(format!("#{}", i + 1)).small()) .width(Length::Fixed(50.0)), @@ -1738,13 +1737,13 @@ pub fn recover_mnemonic<'a>( .push_maybe(if recover { Some( Column::new() - .align_items(Alignment::Center) + .align_x(Alignment::Center) .push( Container::new(if !suggestions.is_empty() { suggestions.iter().fold(Row::new().spacing(5), |row, sugg| { row.push( Button::new(text(sugg)) - .style(theme::Button::Secondary) + .style(theme::button::secondary) .on_press(Message::MnemonicWord( current, sugg.to_string(), @@ -1763,7 +1762,7 @@ pub fn recover_mnemonic<'a>( acc.push( Row::new() .spacing(10) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .push( Container::new(text(format!("#{}", i + 1)).small()) .width(Length::Fixed(50.0)), @@ -1775,7 +1774,7 @@ pub fn recover_mnemonic<'a>( .width(Length::Fixed(100.0)), ) .push_maybe(if *valid { - Some(icon::circle_check_icon().style(color::GREEN)) + Some(icon::circle_check_icon().color(color::GREEN)) } else { None }), @@ -1783,7 +1782,7 @@ pub fn recover_mnemonic<'a>( }, )) .push(Space::with_height(Length::Fixed(50.0))) - .push_maybe(error.map(|e| card::invalid(text(e).style(color::RED)))), + .push_maybe(error.map(|e| card::invalid(text(e).color(color::RED)))), ) } else { None @@ -1839,14 +1838,14 @@ pub fn choose_backend(progress: (usize, usize)) -> Element<'static, Message> { .spacing(20) .width(Length::FillPortion(1)) .push(h3("Use your own node")) - .push(text::p2_medium(LOCAL_WALLET_DESC).style(color::GREY_3)), + .push(text::p2_medium(LOCAL_WALLET_DESC).color(color::GREY_3)), ) .push( Column::new() .spacing(20) .width(Length::FillPortion(1)) .push(h3("Use Liana Connect")) - .push(text::p2_medium(REMOTE_BACKEND_DESC).style(color::GREY_3)), + .push(text::p2_medium(REMOTE_BACKEND_DESC).color(color::GREY_3)), ), ) .push( @@ -1888,13 +1887,12 @@ pub fn login(progress: (usize, usize), connection_step: Element) -> Ele Column::new() .spacing(50) .max_width(700) - .align_items(Alignment::Center) + .align_x(Alignment::Center) .width(Length::FillPortion(1)) .push(h2("Liana Connect")) .push(connection_step), ) - .width(Length::Fill) - .center_x(), + .center_x(Length::Fill), true, Some(Message::Previous), ) @@ -1908,8 +1906,8 @@ pub fn connection_step_enter_email<'a>( ) -> Element<'a, Message> { Column::new() .spacing(20) - .push_maybe(connection_error.map(|e| text(e.to_string()).style(color::ORANGE))) - .push_maybe(auth_error.map(|e| text(e.to_string()).style(color::ORANGE))) + .push_maybe(connection_error.map(|e| text(e.to_string()).color(color::ORANGE))) + .push_maybe(auth_error.map(|e| text(e.to_string()).color(color::ORANGE))) .push(text( "Enter the email you want to associate with the wallet:", )) @@ -1942,10 +1940,10 @@ pub fn connection_step_enter_otp<'a>( ) -> Element<'a, Message> { Column::new() .spacing(20) - .push(text(email).style(color::GREEN)) + .push(text(email).color(color::GREEN)) .push(text("An authentication token has been emailed to you")) - .push_maybe(connection_error.map(|e| text(e.to_string()).style(color::ORANGE))) - .push_maybe(auth_error.map(|e| text(e.to_string()).style(color::ORANGE))) + .push_maybe(connection_error.map(|e| text(e.to_string()).color(color::ORANGE))) + .push_maybe(auth_error.map(|e| text(e.to_string()).color(color::ORANGE))) .push( form::Form::new_trimmed("Token", otp, |msg| { Message::SelectBackend(message::SelectBackend::OTPEdited(msg)) @@ -1980,9 +1978,9 @@ pub fn connection_step_connected<'a>( ) -> Element<'a, Message> { Column::new() .spacing(20) - .push(text(email).style(color::GREEN)) - .push_maybe(connection_error.map(|e| text(e.to_string()).style(color::ORANGE))) - .push_maybe(auth_error.map(|e| text(e.to_string()).style(color::ORANGE))) + .push(text(email).color(color::GREEN)) + .push_maybe(connection_error.map(|e| text(e.to_string()).color(color::ORANGE))) + .push_maybe(auth_error.map(|e| text(e.to_string()).color(color::ORANGE))) .push(Container::new( Row::new() .spacing(10) @@ -2021,23 +2019,18 @@ fn layout<'a>( Column::new() .width(Length::Fill) .push(Row::new().push(Space::with_width(Length::Fill)).push_maybe( - email.map(|e| Container::new(p1_regular(e).style(color::GREEN)).padding(20)), + email.map(|e| Container::new(p1_regular(e).color(color::GREEN)).padding(20)), )) .push(Space::with_height(Length::Fixed(100.0))) .push( Row::new() - .align_items(Alignment::Center) - .push( - Container::new(prev_button) - .width(Length::FillPortion(2)) - .center_x(), - ) + .align_y(Alignment::Center) + .push(Container::new(prev_button).center_x(Length::FillPortion(2))) .push(Container::new(h3(title)).width(Length::FillPortion(8))) .push_maybe(if progress.1 > 0 { Some( Container::new(text(format!("{} | {}", progress.0, progress.1))) - .width(Length::FillPortion(2)) - .center_x(), + .center_x(Length::FillPortion(2)), ) } else { None @@ -2065,9 +2058,9 @@ fn layout<'a>( }), ), )) - .center_x() + .center_x(Length::Fill) .height(Length::Fill) .width(Length::Fill) - .style(theme::Container::Background) + .style(theme::container::background) .into() } diff --git a/liana-gui/src/launcher.rs b/liana-gui/src/launcher.rs index c9bbd7b88..a2e20c549 100644 --- a/liana-gui/src/launcher.rs +++ b/liana-gui/src/launcher.rs @@ -3,7 +3,7 @@ use std::path::PathBuf; use iced::{ alignment::Horizontal, widget::{pick_list, scrollable, Button, Space}, - Alignment, Command, Length, Subscription, + Alignment, Length, Subscription, Task, }; use liana::miniscript::bitcoin::Network; @@ -44,7 +44,7 @@ pub struct Launcher { } impl Launcher { - pub fn new(datadir_path: PathBuf, network: Option) -> (Self, Command) { + pub fn new(datadir_path: PathBuf, network: Option) -> (Self, Task) { let network = network.unwrap_or( NETWORKS .iter() @@ -60,7 +60,7 @@ impl Launcher { error: None, delete_wallet_modal: None, }, - Command::perform( + Task::perform( check_network_datadir(datadir_path.clone(), network), Message::Checked, ), @@ -73,26 +73,26 @@ impl Launcher { Subscription::none() } - pub fn update(&mut self, message: Message) -> Command { + pub fn update(&mut self, message: Message) -> Task { match message { Message::View(ViewMessage::ImportWallet) => { let datadir_path = self.datadir_path.clone(); let network = self.network; - Command::perform(async move { (datadir_path, network) }, |(d, n)| { + Task::perform(async move { (datadir_path, network) }, |(d, n)| { Message::Install(d, n, UserFlow::AddWallet) }) } Message::View(ViewMessage::CreateWallet) => { let datadir_path = self.datadir_path.clone(); let network = self.network; - Command::perform(async move { (datadir_path, network) }, |(d, n)| { + Task::perform(async move { (datadir_path, network) }, |(d, n)| { Message::Install(d, n, UserFlow::CreateWallet) }) } Message::View(ViewMessage::ShareXpubs) => { let datadir_path = self.datadir_path.clone(); let network = self.network; - Command::perform(async move { (datadir_path, network) }, |(d, n)| { + Task::perform(async move { (datadir_path, network) }, |(d, n)| { Message::Install(d, n, UserFlow::ShareXpubs) }) } @@ -109,31 +109,31 @@ impl Launcher { wallet_datadir, internal_bitcoind, )); - Command::none() + Task::none() } Message::View(ViewMessage::SelectNetwork(network)) => { self.network = network; - Command::perform( + Task::perform( check_network_datadir(self.datadir_path.clone(), self.network), Message::Checked, ) } Message::View(ViewMessage::DeleteWallet(DeleteWalletMessage::Deleted)) => { self.state = State::NoWallet; - Command::none() + Task::none() } Message::View(ViewMessage::DeleteWallet(DeleteWalletMessage::CloseModal)) => { self.delete_wallet_modal = None; - Command::none() + Task::none() } Message::Checked(res) => match res { Err(e) => { self.error = Some(e); - Command::none() + Task::none() } Ok(state) => { self.state = state; - Command::none() + Task::none() } }, Message::View(ViewMessage::Run) => { @@ -144,18 +144,18 @@ impl Launcher { path.push(app::config::DEFAULT_FILE_NAME); let cfg = app::Config::from_file(&path).expect("Already checked"); let network = self.network; - Command::perform(async move { (datadir_path.clone(), cfg, network) }, |m| { + Task::perform(async move { (datadir_path.clone(), cfg, network) }, |m| { Message::Run(m.0, m.1, m.2) }) } else { - Command::none() + Task::none() } } _ => { if let Some(modal) = &mut self.delete_wallet_modal { return modal.update(message); } - Command::none() + Task::none() } } } @@ -180,16 +180,16 @@ impl Launcher { Some(self.network), ViewMessage::SelectNetwork, ) - .style(theme::PickList::default()) + .style(theme::pick_list::primary) .padding(10), ) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .padding(100), ) .push( Container::new( Column::new() - .align_items(Alignment::Center) + .align_x(Alignment::Center) .spacing(30) .push(if matches!(self.state, State::Wallet { .. }) { text("Welcome back").size(50).bold() @@ -203,7 +203,7 @@ impl Launcher { email, checksum, .. } => Column::new().push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(20) .push( Button::new( @@ -220,25 +220,25 @@ impl Launcher { ))) .push_maybe(checksum.as_ref().map(|checksum| { p1_regular(format!("Liana-{}", checksum)) - .style(color::GREY_3) + .color(color::GREY_3) })) .push_maybe(email.as_ref().map(|email| { Row::new() .push(Space::with_width(Length::Fill)) .push( p1_regular(email) - .style(color::GREEN), + .color(color::GREEN), ) })), ) .on_press(ViewMessage::Run) - .style(theme::Button::Border) + .style(theme::button::container_border) .padding(10) .width(Length::Fill), ) .push( Button::new(icon::trash_icon()) - .style(theme::Button::Secondary) + .style(theme::button::secondary) .padding(10) .on_press(ViewMessage::DeleteWallet( DeleteWalletMessage::ShowModal, @@ -248,20 +248,20 @@ impl Launcher { State::NoWallet => Column::new() .push( Row::new() - .align_items(Alignment::End) + .align_y(Alignment::End) .spacing(20) .push( Container::new( Column::new() .spacing(20) - .align_items(Alignment::Center) + .align_x(Alignment::Center) .push( image::create_new_wallet_icon() .width(Length::Fixed(100.0)), ) .push( p1_regular("Create a new Liana wallet") - .style(color::GREY_3), + .color(color::GREY_3), ) .push( button::secondary(None, "Select") @@ -270,7 +270,7 @@ impl Launcher { ViewMessage::CreateWallet, ), ) - .align_items(Alignment::Center), + .align_x(Alignment::Center), ) .padding(20), ) @@ -278,7 +278,7 @@ impl Launcher { Container::new( Column::new() .spacing(20) - .align_items(Alignment::Center) + .align_x(Alignment::Center) .push( image::restore_wallet_icon() .width(Length::Fixed(100.0)), @@ -287,7 +287,7 @@ impl Launcher { p1_regular( "Add an existing Liana wallet", ) - .style(color::GREY_3), + .color(color::GREY_3), ) .push( button::secondary(None, "Select") @@ -296,17 +296,16 @@ impl Launcher { ViewMessage::ImportWallet, ), ) - .align_items(Alignment::Center), + .align_x(Alignment::Center), ) .padding(20), ), ) - .align_items(Alignment::Center), + .align_x(Alignment::Center), }) .max_width(500), ) - .width(Length::Fill) - .center_x(), + .center_x(Length::Fill), ) .push(Space::with_height(Length::Fixed(100.0))), )) @@ -376,24 +375,24 @@ impl DeleteWalletModal { } } - fn update(&mut self, message: Message) -> Command { + fn update(&mut self, message: Message) -> Task { if let Message::View(ViewMessage::DeleteWallet(DeleteWalletMessage::Confirm)) = message { self.warning = None; if let Err(e) = std::fs::remove_dir_all(&self.wallet_datadir) { self.warning = Some(e); } else { self.deleted = true; - return Command::perform(async {}, |_| { + return Task::perform(async {}, |_| { Message::View(ViewMessage::DeleteWallet(DeleteWalletMessage::Deleted)) }); }; } - Command::none() + Task::none() } fn view(&self) -> Element { let mut confirm_button = button::secondary(None, "Delete wallet") .width(Length::Fixed(200.0)) - .style(theme::Button::Destructive); + .style(theme::button::destructive); if self.warning.is_none() { confirm_button = confirm_button.on_press(ViewMessage::DeleteWallet(DeleteWalletMessage::Confirm)); @@ -416,12 +415,12 @@ impl DeleteWalletModal { .spacing(10) .push(Container::new( h4_bold(format!("Delete configuration for {}", &self.network)) - .style(color::RED) + .color(color::RED) .width(Length::Fill), )) .push(Row::new().push(text(help_text_1))) .push_maybe( - help_text_2.map(|t| Row::new().push(p1_regular(t).style(color::GREY_3))), + help_text_2.map(|t| Row::new().push(p1_regular(t).color(color::GREY_3))), ) .push(Row::new()) .push(Row::new().push(text(help_text_3))) @@ -434,8 +433,8 @@ impl DeleteWalletModal { } else { Row::new() .spacing(10) - .push(icon::circle_check_icon().style(color::GREEN)) - .push(text("Wallet successfully deleted").style(color::GREEN)) + .push(icon::circle_check_icon().color(color::GREEN)) + .push(text("Wallet successfully deleted").color(color::GREEN)) }) .align_x(Horizontal::Center) .width(Length::Fill), diff --git a/liana-gui/src/lianalite/login.rs b/liana-gui/src/lianalite/login.rs index cfb712454..cb91e621d 100644 --- a/liana-gui/src/lianalite/login.rs +++ b/liana-gui/src/lianalite/login.rs @@ -1,6 +1,6 @@ use std::{path::PathBuf, sync::Arc}; -use iced::{Alignment, Command, Length}; +use iced::{Alignment, Length, Task}; use liana::miniscript::bitcoin::Network; use liana_ui::{ @@ -116,7 +116,7 @@ pub enum ConnectionStep { } impl LianaLiteLogin { - pub fn new(datadir: PathBuf, network: Network, settings: Settings) -> (Self, Command) { + pub fn new(datadir: PathBuf, network: Network, settings: Settings) -> (Self, Task) { match settings .wallets .first() @@ -137,7 +137,7 @@ impl LianaLiteLogin { auth_error: None, processing: true, }, - Command::none(), + Task::none(), ), Ok(auth_config) => ( Self { @@ -149,7 +149,7 @@ impl LianaLiteLogin { auth_error: None, processing: true, }, - Command::perform( + Task::perform( async move { let service_config = super::client::get_service_config(network) .await @@ -174,7 +174,7 @@ impl LianaLiteLogin { } } - pub fn update(&mut self, message: Message) -> Command { + pub fn update(&mut self, message: Message) -> Task { match &mut self.step { ConnectionStep::CheckingAuthFile => { if let Message::Connected(res) = message { @@ -184,7 +184,7 @@ impl LianaLiteLogin { self.auth_error = Some("No wallet found for the given email"); } Ok(BackendState::WalletExists(client, wallet)) => { - return Command::perform(async move { (client, wallet) }, |(c, w)| { + return Task::perform(async move { (client, wallet) }, |(c, w)| { Message::Run(Ok((c, w))) }); } @@ -216,7 +216,7 @@ impl LianaLiteLogin { self.processing = true; self.connection_error = None; self.auth_error = None; - return Command::perform( + return Task::perform( async move { let config = super::client::get_service_config(network) .await @@ -279,7 +279,7 @@ impl LianaLiteLogin { self.processing = true; self.connection_error = None; self.auth_error = None; - return Command::perform( + return Task::perform( async move { client.resend_otp().await?; Ok(()) @@ -309,7 +309,7 @@ impl LianaLiteLogin { self.auth_error = None; let wallet_id = self.wallet_id.clone(); let network = self.network; - return Command::perform( + return Task::perform( async move { connect(client, otp, wallet_id, backend_api_url, network).await }, @@ -322,12 +322,12 @@ impl LianaLiteLogin { self.processing = false; match res { Ok(BackendState::NoWallet(client)) => { - return Command::perform(async move { Some(client) }, Message::Install); + return Task::perform(async move { Some(client) }, Message::Install); } Ok(BackendState::WalletExists(client, wallet)) => { let datadir = self.datadir.clone(); let network = self.network; - return Command::perform( + return Task::perform( async move { update_wallet_auth_settings( datadir, @@ -366,7 +366,7 @@ impl LianaLiteLogin { }, } - Command::none() + Task::none() } pub fn view(&self) -> Element { @@ -374,10 +374,10 @@ impl LianaLiteLogin { Container::new( Column::new() .spacing(100) - .align_items(Alignment::Center) + .align_x(Alignment::Center) .push( Column::new() - .align_items(Alignment::Center) + .align_x(Alignment::Center) .spacing(20) .width(Length::Fill) .push(h2("Liana Connect")) @@ -391,7 +391,7 @@ impl LianaLiteLogin { .spacing(20) .push_maybe( self.auth_error - .map(|e| text(e).style(color::ORANGE)), + .map(|e| text(e).color(color::ORANGE)), ) .push( form::Form::new_trimmed("email", email, |msg| { @@ -412,7 +412,7 @@ impl LianaLiteLogin { .push(text("An authentication was send to your email")) .push_maybe( self.auth_error - .map(|e| text(e).style(color::ORANGE)), + .map(|e| text(e).color(color::ORANGE)), ) .spacing(20) .push( @@ -456,10 +456,8 @@ impl LianaLiteLogin { }), ) .padding(50) - .width(Length::Fill) - .height(Length::Fill) - .center_x() - .center_y(), + .center_x(Length::Fill) + .center_y(Length::Fill), ) .map(Message::View); diff --git a/liana-gui/src/loader.rs b/liana-gui/src/loader.rs index 48bc35526..ac6a93a23 100644 --- a/liana-gui/src/loader.rs +++ b/liana-gui/src/loader.rs @@ -5,7 +5,7 @@ use std::path::{Path, PathBuf}; use std::sync::Arc; use std::time::Duration; -use iced::{Alignment, Command, Length, Subscription}; +use iced::{Alignment, Length, Subscription, Task}; use tokio::runtime::Handle; use tracing::{debug, info, warn}; @@ -99,7 +99,7 @@ impl Loader { gui_config: GUIConfig, network: bitcoin::Network, internal_bitcoind: Option, - ) -> (Self, Command) { + ) -> (Self, Task) { let path = gui_config .daemon_rpc_path .clone() @@ -114,7 +114,7 @@ impl Loader { internal_bitcoind, waiting_daemon_bitcoind: false, }, - Command::perform(connect(path), Message::Loaded), + Task::perform(connect(path), Message::Loaded), ) } @@ -122,11 +122,11 @@ impl Loader { &mut self, daemon: Arc, info: GetInfoResult, - ) -> Command { + ) -> Task { // If the wallet was previously synced (blockheight > 0), load the // application directly. if info.block_height > 0 { - return Command::perform( + return Task::perform( load_application( daemon, info, @@ -143,13 +143,13 @@ impl Loader { progress: 0.0, bitcoind_logs: String::new(), }; - Command::perform(sync(daemon, false), Message::Syncing) + Task::perform(sync(daemon, false), Message::Syncing) } fn on_load( &mut self, res: Result<(Arc, GetInfoResult), Error>, - ) -> Command { + ) -> Task { match res { Ok((daemon, info)) => { if self.gui_config.start_internal_bitcoind { @@ -168,7 +168,7 @@ impl Loader { self.step = Step::StartingDaemon; self.daemon_started = true; self.waiting_daemon_bitcoind = true; - return Command::perform( + return Task::perform( start_bitcoind_and_daemon( daemon_config_path, self.datadir_path.clone(), @@ -186,19 +186,19 @@ impl Loader { } }, } - Command::none() + Task::none() } - fn on_log(&mut self, log: Option) -> Command { + fn on_log(&mut self, log: Option) -> Task { if let Step::Syncing { bitcoind_logs, .. } = &mut self.step { if let Some(l) = log { *bitcoind_logs = l; } } - Command::none() + Task::none() } - fn on_start(&mut self, res: StartedResult) -> Command { + fn on_start(&mut self, res: StartedResult) -> Task { match res { Ok((daemon, bitcoind, info)) => { // bitcoind may have been already started and given to the loader @@ -211,12 +211,12 @@ impl Loader { } Err(e) => { self.step = Step::Error(Box::new(e)); - Command::none() + Task::none() } } } - fn on_sync(&mut self, res: Result) -> Command { + fn on_sync(&mut self, res: Result) -> Task { match &mut self.step { Step::Syncing { daemon, progress, .. @@ -224,7 +224,7 @@ impl Loader { match res { Ok(info) => { if (info.sync - 1.0_f64).abs() < f64::EPSILON { - return Command::perform( + return Task::perform( load_application( daemon.clone(), info, @@ -240,12 +240,12 @@ impl Loader { } Err(e) => { self.step = Step::Error(Box::new(e.into())); - return Command::none(); + return Task::none(); } }; - Command::perform(sync(daemon.clone(), true), Message::Syncing) + Task::perform(sync(daemon.clone(), true), Message::Syncing) } - _ => Command::none(), + _ => Task::none(), } } @@ -281,7 +281,7 @@ impl Loader { } } - pub fn update(&mut self, message: Message) -> Command { + pub fn update(&mut self, message: Message) -> Task { match message { Message::View(ViewMessage::Retry) => { let (loader, cmd) = Self::new( @@ -299,21 +299,21 @@ impl Loader { Message::BitcoindLog(log) => self.on_log(log), Message::Synced(Err(e)) => { self.step = Step::Error(Box::new(e)); - Command::none() + Task::none() } Message::Failure(_) => { self.daemon_started = false; - Command::none() + Task::none() } - Message::None => Command::none(), - _ => Command::none(), + Message::None => Task::none(), + _ => Task::none(), } } pub fn subscription(&self) -> Subscription { if self.internal_bitcoind.is_some() { let log_path = internal_bitcoind_debug_log_path(&self.datadir_path, self.network); - iced::subscription::unfold(0, log_path, move |log_path| async move { + iced::Subscription::unfold(0, log_path, move |log_path| async move { // Reduce the io load. tokio::time::sleep(Duration::from_millis(500)).await; @@ -456,14 +456,14 @@ pub fn view(step: &Step) -> Element { } else { SYNCING_PROGRESS_1 })) - .push(p2_regular(bitcoind_logs).style(color::GREY_3)), + .push(p2_regular(bitcoind_logs).color(color::GREY_3)), ), Step::Error(error) => cover( Some(("Error while starting the internal daemon", error)), Column::new() .spacing(20) .width(Length::Fill) - .align_items(Alignment::Center) + .align_x(Alignment::Center) .push(icon::plug_icon().size(100).width(Length::Fixed(300.0))) .push( if matches!( @@ -500,10 +500,8 @@ pub fn cover<'a, T: 'a + Clone, C: Into>>( .push_maybe(warn.map(|w| notification::warning(w.0.to_string(), w.1.to_string()))) .push( Container::new(content) - .width(iced::Length::Fill) - .height(iced::Length::Fill) - .center_x() - .center_y() + .center_x(iced::Length::Fill) + .center_y(iced::Length::Fill) .padding(50), ) .into() diff --git a/liana-gui/src/main.rs b/liana-gui/src/main.rs index b9fb22457..69015661f 100644 --- a/liana-gui/src/main.rs +++ b/liana-gui/src/main.rs @@ -10,7 +10,7 @@ use iced::{ event::{self, Event}, executor, keyboard, widget::{focus_next, focus_previous}, - Application, Command, Settings, Size, Subscription, + Application, Settings, Size, Subscription, Task, }; use tracing::{error, info}; use tracing_subscriber::filter::LevelFilter; @@ -152,10 +152,10 @@ impl Application for GUI { } } - fn new((config, log_level): (Config, Option)) -> (GUI, Command) { + fn new((config, log_level): (Config, Option)) -> (GUI, Task) { let logger = Logger::setup(log_level.unwrap_or(LevelFilter::INFO)); let mut cmds = font::loads(); - cmds.push(Command::perform(ctrl_c(), |_| Message::CtrlC)); + cmds.push(Task::perform(ctrl_c(), |_| Message::CtrlC)); let state = match config { Config::Launcher(datadir_path) => { let (launcher, command) = Launcher::new(datadir_path, None); @@ -179,11 +179,11 @@ impl Application for GUI { logger, log_level, }, - Command::batch(cmds), + Task::batch(cmds), ) } - fn update(&mut self, message: Self::Message) -> Command { + fn update(&mut self, message: Self::Message) -> Task { match (&mut self.state, message) { (_, Message::CtrlC) | (_, Message::Event(iced::Event::Window(_, iced::window::Event::CloseRequested))) => { @@ -374,7 +374,7 @@ impl Application for GUI { (State::App(i), Message::Run(msg)) => { i.update(*msg).map(|msg| Message::Run(Box::new(msg))) } - _ => Command::none(), + _ => Task::none(), } } @@ -433,7 +433,7 @@ pub fn create_app_with_remote_backend( datadir: PathBuf, network: bitcoin::Network, config: app::Config, -) -> (app::App, iced::Command) { +) -> (app::App, iced::Task) { let hws: Vec = wallet .metadata .ledger_hmacs diff --git a/liana-ui/Cargo.toml b/liana-ui/Cargo.toml index 458ac0318..c13b57018 100644 --- a/liana-ui/Cargo.toml +++ b/liana-ui/Cargo.toml @@ -6,6 +6,6 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -iced = { version = "0.12.1", default-features = false, features = ["svg", "image", "lazy", "qr_code", "advanced", "webgl"] } +iced = { version = "0.13.1", default-features = false, features = ["svg", "image", "lazy", "qr_code", "advanced"] } bitcoin = "0.32" chrono = "0.4" diff --git a/liana-ui/src/component/amount.rs b/liana-ui/src/component/amount.rs index 603d32c17..869f2a6f5 100644 --- a/liana-ui/src/component/amount.rs +++ b/liana-ui/src/component/amount.rs @@ -102,18 +102,18 @@ fn render_amount<'a, T: 'a>( let mut child_after = text(after).size(size).bold(); if let Some(color_after) = color_after { - child_after = child_after.style(color_after); + child_after = child_after.color(color_after); } let row = Row::new() - .push(text(before).size(size).style(color_before)) + .push(text(before).size(size).color(color_before)) .push(child_after); Row::with_children(vec![ row.into(), - text("BTC").size(size).style(color_before).into(), + text("BTC").size(size).color(color_before).into(), ]) .spacing(spacing) - .align_items(iced::Alignment::Center) + .align_y(iced::Alignment::Center) } // Build the rendering elements for displaying a Bitcoin amount. @@ -121,11 +121,11 @@ fn render_unconfirmed_amount<'a, T: 'a>(amount: String, size: u16) -> Row<'a, T> let spacing = if size > P1_SIZE { 10 } else { 5 }; Row::with_children(vec![ - text(amount).size(size).style(color::GREY_3).into(), - text("BTC").size(size).style(color::GREY_3).into(), + text(amount).size(size).color(color::GREY_3).into(), + text("BTC").size(size).color(color::GREY_3).into(), ]) .spacing(spacing) - .align_items(iced::Alignment::Center) + .align_y(iced::Alignment::Center) } #[cfg(test)] diff --git a/liana-ui/src/component/badge.rs b/liana-ui/src/component/badge.rs index 1ef6c4476..096b33591 100644 --- a/liana-ui/src/component/badge.rs +++ b/liana-ui/src/component/badge.rs @@ -2,63 +2,33 @@ use iced::{widget::tooltip, Length}; use crate::{component::text, icon, image, theme, widget::*}; -pub struct Badge { - icon: crate::widget::Text<'static>, - style: theme::Badge, -} - -impl Badge { - pub fn new(icon: crate::widget::Text<'static>) -> Self { - Self { - icon, - style: theme::Badge::Standard, - } - } - pub fn style(self, style: theme::Badge) -> Self { - Self { - icon: self.icon, - style, - } - } -} - -impl<'a, Message: 'a> From for Element<'a, Message> { - fn from(badge: Badge) -> Element<'a, Message> { - Container::new(badge.icon.width(Length::Fixed(20.0))) - .width(Length::Fixed(40.0)) - .height(Length::Fixed(40.0)) - .style(theme::Container::Badge(badge.style)) - .center_x() - .center_y() - .into() - } +pub fn badge(icon: crate::widget::Text<'static>) -> Container<'static, T> { + Container::new(icon.width(Length::Fixed(20.0))) + .style(theme::badge::simple) + .center_x(Length::Fixed(40.0)) + .center_y(Length::Fixed(40.0)) } pub fn receive() -> Container<'static, T> { Container::new(icon::receive_icon().width(Length::Fixed(20.0))) - .width(Length::Fixed(40.0)) - .height(Length::Fixed(40.0)) - .style(theme::Container::Badge(theme::Badge::Standard)) - .center_x() - .center_y() + .style(theme::badge::simple) + .style(theme::badge::simple) + .center_x(Length::Fixed(40.0)) + .center_y(Length::Fixed(40.0)) } pub fn cycle() -> Container<'static, T> { Container::new(icon::arrow_repeat().width(Length::Fixed(20.0))) - .width(Length::Fixed(40.0)) - .height(Length::Fixed(40.0)) - .style(theme::Container::Badge(theme::Badge::Standard)) - .center_x() - .center_y() + .style(theme::badge::simple) + .center_x(Length::Fixed(40.0)) + .center_y(Length::Fixed(40.0)) } pub fn spend() -> Container<'static, T> { Container::new(icon::send_icon().width(Length::Fixed(20.0))) - .width(Length::Fixed(40.0)) - .height(Length::Fixed(40.0)) - .style(theme::Container::Badge(theme::Badge::Standard)) - .center_x() - .center_y() + .style(theme::badge::simple) + .center_x(Length::Fixed(40.0)) + .center_y(Length::Fixed(40.0)) } pub fn coin() -> Container<'static, T> { @@ -67,11 +37,9 @@ pub fn coin() -> Container<'static, T> { .height(Length::Fixed(25.0)) .width(Length::Fixed(25.0)), ) - .width(Length::Fixed(40.0)) - .height(Length::Fixed(40.0)) - .style(theme::Container::Badge(theme::Badge::Standard)) - .center_x() - .center_y() + .style(theme::badge::simple) + .center_x(Length::Fixed(40.0)) + .center_y(Length::Fixed(40.0)) } pub fn recovery<'a, T: 'a>() -> Container<'a, T> { @@ -108,11 +76,11 @@ pub fn badge_pill<'a, T: 'a>(label: &'a str, tooltip: &'a str) -> Container<'a, tooltip::Tooltip::new( Container::new(text::p2_regular(label)) .padding(10) - .center_x() - .style(theme::Container::Pill(theme::Pill::Simple)), + .center_x(Length::Shrink) + .style(theme::pill::simple), tooltip, tooltip::Position::Top, ) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) }) } diff --git a/liana-ui/src/component/button.rs b/liana-ui/src/component/button.rs index bf2663049..ef580b4af 100644 --- a/liana-ui/src/component/button.rs +++ b/liana-ui/src/component/button.rs @@ -1,57 +1,55 @@ use crate::{color, theme, widget::*}; +use iced::alignment::{Horizontal, Vertical}; use iced::widget::{button, container, row}; -use iced::Alignment; use super::text::text; pub fn menu<'a, T: 'a>(icon: Option>, t: &'static str) -> Button<'a, T> { - button::Button::new(content_menu(icon.map(|i| i.style(color::GREY_3)), t).padding(10)) - .style(theme::Button::Menu(false)) + button::Button::new(content_menu(icon.map(|i| i.color(color::GREY_3)), t).padding(10)) + .style(theme::button::menu) } pub fn menu_active<'a, T: 'a>(icon: Option>, t: &'static str) -> Button<'a, T> { - button::Button::new(content_menu(icon.map(|i| i.style(color::GREY_3)), t).padding(10)) - .style(theme::Button::Menu(true)) + button::Button::new(content_menu(icon.map(|i| i.color(color::GREY_3)), t).padding(10)) + .style(theme::button::menu_pressed) } fn content_menu<'a, T: 'a>(icon: Option>, t: &'static str) -> Container<'a, T> { match icon { None => container(text(t)).padding(5), - Some(i) => { - container(row![i, text(t)].spacing(10).align_items(Alignment::Center)).padding(5) - } + Some(i) => container(row![i, text(t)].spacing(10).align_y(Vertical::Center)).padding(5), } } pub fn alert<'a, T: 'a>(icon: Option>, t: &'static str) -> Button<'a, T> { - button::Button::new(content(icon, t)).style(theme::Button::Destructive) + button::Button::new(content(icon, t)).style(theme::button::destructive) } pub fn primary<'a, T: 'a>(icon: Option>, t: &'static str) -> Button<'a, T> { - button::Button::new(content(icon, t)).style(theme::Button::Primary) + button::Button::new(content(icon, t)).style(theme::button::primary) } pub fn transparent<'a, T: 'a>(icon: Option>, t: &'static str) -> Button<'a, T> { - button::Button::new(content(icon, t)).style(theme::Button::Transparent) + button::Button::new(content(icon, t)).style(theme::button::container) } pub fn secondary<'a, T: 'a>(icon: Option>, t: &'static str) -> Button<'a, T> { - button::Button::new(content(icon, t)).style(theme::Button::Secondary) + button::Button::new(content(icon, t)).style(theme::button::secondary) } pub fn border<'a, T: 'a>(icon: Option>, t: &'static str) -> Button<'a, T> { - button::Button::new(content(icon, t)).style(theme::Button::Border) + button::Button::new(content(icon, t)).style(theme::button::secondary) } pub fn transparent_border<'a, T: 'a>(icon: Option>, t: &'static str) -> Button<'a, T> { - button(content(icon, t)).style(theme::Button::TransparentBorder) + button(content(icon, t)).style(theme::button::container_border) } fn content<'a, T: 'a>(icon: Option>, t: &'static str) -> Container<'a, T> { match icon { - None => container(text(t)).center_x().padding(5), - Some(i) => container(row![i, text(t)].spacing(10).align_items(Alignment::Center)) - .center_x() + None => container(text(t)).align_x(Horizontal::Center).padding(5), + Some(i) => container(row![i, text(t)].spacing(10).align_y(Vertical::Center)) + .align_x(Horizontal::Center) .padding(5), } } diff --git a/liana-ui/src/component/card.rs b/liana-ui/src/component/card.rs index 2ccf69bde..8ad3f511f 100644 --- a/liana-ui/src/component/card.rs +++ b/liana-ui/src/component/card.rs @@ -3,19 +3,19 @@ use crate::{color, component::text::text, icon, theme, widget::*}; pub fn modal<'a, T: 'a, C: Into>>(content: C) -> Container<'a, T> { Container::new(content) .padding(15) - .style(theme::Container::Card(theme::Card::Modal)) + .style(theme::card::modal) } pub fn simple<'a, T: 'a, C: Into>>(content: C) -> Container<'a, T> { Container::new(content) .padding(15) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) } pub fn invalid<'a, T: 'a, C: Into>>(content: C) -> Container<'a, T> { Container::new(content) .padding(15) - .style(theme::Container::Card(theme::Card::Invalid)) + .style(theme::card::invalid) } /// display an error card with the message and the error in a tooltip. @@ -23,12 +23,12 @@ pub fn warning<'a, T: 'a>(message: String) -> Container<'a, T> { Container::new( Row::new() .spacing(20) - .align_items(iced::Alignment::Center) + .align_y(iced::Alignment::Center) .push(icon::warning_icon()) .push(text(message)), ) .padding(15) - .style(theme::Container::Card(theme::Card::Warning)) + .style(theme::card::warning) } /// display an error card with the message and the error in a tooltip. @@ -37,14 +37,14 @@ pub fn error<'a, T: 'a>(message: &'static str, error: String) -> Container<'a, T iced::widget::tooltip::Tooltip::new( Row::new() .spacing(20) - .align_items(iced::Alignment::Center) - .push(icon::warning_icon().style(color::RED)) - .push(text(message).style(color::RED)), + .align_y(iced::Alignment::Center) + .push(icon::warning_icon().color(color::RED)) + .push(text(message).color(color::RED)), Text::new(error), iced::widget::tooltip::Position::Bottom, ) - .style(theme::Container::Card(theme::Card::Error)), + .style(theme::card::error), ) .padding(15) - .style(theme::Container::Card(theme::Card::Error)) + .style(theme::card::error) } diff --git a/liana-ui/src/component/collapse.rs b/liana-ui/src/component/collapse.rs index e59ee7d43..8fc992fc1 100644 --- a/liana-ui/src/component/collapse.rs +++ b/liana-ui/src/component/collapse.rs @@ -16,7 +16,7 @@ pub struct Collapse<'a, M, H, F, C> { impl<'a, Message, T, H, F, C, Theme, Renderer> Collapse<'a, Message, H, F, C> where Renderer: advanced::Renderer, - Theme: iced::widget::button::StyleSheet, + Theme: iced::widget::button::Catalog, Message: 'a, T: Into + Clone + 'a, H: Fn() -> Button<'a, Event, Theme, Renderer> + 'a, @@ -53,7 +53,7 @@ where F: Fn() -> Button<'a, Event, Theme, Renderer>, C: Fn() -> Element<'a, T, Theme, Renderer>, Renderer: 'a + advanced::Renderer, - Theme: 'a + iced::widget::button::StyleSheet, + Theme: 'a + iced::widget::button::Catalog, { type State = Option; type Event = Event; @@ -96,7 +96,7 @@ impl<'a, Message, T, H: 'a, F: 'a, C: 'a, Theme, Renderer> From + Clone + 'a, H: Fn() -> Button<'a, Event, Theme, Renderer>, F: Fn() -> Button<'a, Event, Theme, Renderer>, diff --git a/liana-ui/src/component/event.rs b/liana-ui/src/component/event.rs index 53e5db999..db5cacf93 100644 --- a/liana-ui/src/component/event.rs +++ b/liana-ui/src/component/event.rs @@ -12,39 +12,39 @@ use iced::{ use chrono::{DateTime, Local, Utc}; -pub fn unconfirmed_outgoing_event<'a, T: Clone + 'a>( - label: Option>, +pub fn unconfirmed_outgoing_event( + label: Option>, amount: &Amount, msg: T, -) -> Container<'a, T> { +) -> Container<'static, T> { Container::new( button( row!( row!(badge::spend(), Column::new().push_maybe(label),) .spacing(10) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill), badge::unconfirmed(), row!(text::p1_regular("-"), amount::amount(amount)) .spacing(5) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .padding(5) .spacing(20), ) .on_press(msg) - .style(theme::Button::TransparentBorder), + .style(theme::button::transparent_border), ) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) } -pub fn confirmed_outgoing_event<'a, T: Clone + 'a>( - label: Option>, +pub fn confirmed_outgoing_event( + label: Option>, date: DateTime, amount: &Amount, msg: T, -) -> Container<'a, T> { +) -> Container<'static, T> { Container::new( button( row!( @@ -56,59 +56,59 @@ pub fn confirmed_outgoing_event<'a, T: Clone + 'a>( .format("%b. %d, %Y - %T") .to_string() ) - .style(color::GREY_3) + .color(color::GREY_3) ) ) .spacing(10) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill), row!(text::p1_regular("-"), amount::amount(amount)) .spacing(5) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .padding(5) .spacing(20), ) .on_press(msg) - .style(theme::Button::TransparentBorder), + .style(theme::button::transparent_border), ) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) } -pub fn unconfirmed_incoming_event<'a, T: Clone + 'a>( - label: Option>, +pub fn unconfirmed_incoming_event( + label: Option>, amount: &Amount, msg: T, -) -> Container<'a, T> { +) -> Container<'static, T> { Container::new( button( row!( row!(badge::receive(), Column::new().push_maybe(label)) .spacing(10) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill), badge::unconfirmed(), row!(text::p1_regular("+"), amount::amount(amount)) .spacing(5) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .padding(5) .spacing(20), ) .on_press(msg) - .style(theme::Button::TransparentBorder), + .style(theme::button::transparent_border), ) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) } -pub fn confirmed_incoming_event<'a, T: Clone + 'a>( - label: Option>, +pub fn confirmed_incoming_event( + label: Option>, date: DateTime, amount: &Amount, msg: T, -) -> Container<'a, T> { +) -> Container<'static, T> { Container::new( button( row!( @@ -120,22 +120,22 @@ pub fn confirmed_incoming_event<'a, T: Clone + 'a>( .format("%b. %d, %Y - %T") .to_string() ) - .style(color::GREY_3) + .color(color::GREY_3) ) ) .spacing(10) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .width(Length::Fill), row!(text::p1_regular("+"), amount::amount(amount)) .spacing(5) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .padding(5) .spacing(20), ) .on_press(msg) - .style(theme::Button::TransparentBorder), + .style(theme::button::transparent_border), ) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) } diff --git a/liana-ui/src/component/form.rs b/liana-ui/src/component/form.rs index b2017be0a..d4ecce955 100644 --- a/liana-ui/src/component/form.rs +++ b/liana-ui/src/component/form.rs @@ -110,13 +110,13 @@ impl<'a, Message: 'a + Clone> From> for Element<'a, Message> { Container::new( Column::new() .push(if !form.valid { - form.input.style(theme::Form::Invalid) + form.input.style(theme::text_input::invalid) } else { form.input }) .push_maybe(if !form.valid { form.warning - .map(|message| text::caption(message).style(color::RED)) + .map(|message| text::caption(message).color(color::RED)) } else { None }) diff --git a/liana-ui/src/component/hw.rs b/liana-ui/src/component/hw.rs index 16c4338fb..d5cf2414d 100644 --- a/liana-ui/src/component/hw.rs +++ b/liana-ui/src/component/hw.rs @@ -8,7 +8,7 @@ use std::fmt::Display; pub fn locked_hardware_wallet<'a, T: 'a, K: Display>( kind: K, - pairing_code: Option>>, + pairing_code: Option> + Display>, ) -> Container<'a, T> { Container::new( column(vec![ @@ -38,7 +38,7 @@ pub fn supported_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display>( kind: K, version: Option, fingerprint: F, - alias: Option>>, + alias: Option> + Display>, ) -> Container<'a, T> { Container::new( column(vec![ @@ -58,12 +58,12 @@ pub fn supported_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display>( .padding(10) } -pub fn warning_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display>( +pub fn warning_hardware_wallet<'a, T: 'static, K: Display, V: Display, F: Display>( kind: K, version: Option, fingerprint: F, - alias: Option>>, - warning: &'static str, + alias: Option> + Display>, + warning: &'a str, ) -> Container<'a, T> { container( row(vec![ @@ -83,14 +83,14 @@ pub fn warning_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display>( .into(), column(vec![tooltip::Tooltip::new( icon::warning_icon(), - warning, + iced::widget::text!("{}", warning), tooltip::Position::Bottom, ) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) .into()]) .into(), ]) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) .padding(10) } @@ -119,7 +119,7 @@ pub fn unimplemented_method_hardware_wallet<'a, T: 'a, K: Display, V: Display, F message, tooltip::Position::Bottom, ) - .style(theme::Container::Card(theme::Card::Simple)), + .style(theme::card::simple), ) .width(Length::Fill) } @@ -147,7 +147,7 @@ pub fn unrelated_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display>( "This signer does not have a key in this wallet.", tooltip::Position::Bottom, ) - .style(theme::Container::Card(theme::Card::Simple)), + .style(theme::card::simple), ) .width(Length::Fill) } @@ -156,7 +156,7 @@ pub fn processing_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display> kind: K, version: Option, fingerprint: F, - alias: Option>>, + alias: Option> + Display>, ) -> Container<'a, T> { container( row(vec![ @@ -180,7 +180,7 @@ pub fn processing_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display> ]) .into(), ]) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) .padding(10) } @@ -189,32 +189,39 @@ pub fn selected_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display>( kind: K, version: Option, fingerprint: F, - alias: Option>>, - warning: Option<&'static str>, + alias: Option> + Display>, + warning: Option> + Display>, ) -> Container<'a, T> { container( - Row::new() - .push( - column(vec![ - Row::new() - .spacing(5) - .push_maybe(alias.map(|a| text::p1_bold(a))) - .push(text::p1_regular(format!("#{}", fingerprint))) - .into(), - Row::new() - .spacing(5) - .push(text::caption(kind.to_string())) - .push_maybe(version.map(|v| text::caption(v.to_string()))) - .into(), - ]) - .width(Length::Fill), - ) - .push_maybe(warning.map(|w| { - tooltip::Tooltip::new(icon::warning_icon(), w, tooltip::Position::Bottom) - .style(theme::Container::Card(theme::Card::Simple)) - })) - .push(image::success_mark_icon().width(Length::Fixed(50.0))) - .align_items(Alignment::Center), + row(vec![ + column(vec![ + Row::new() + .spacing(5) + .push_maybe(alias.map(text::p1_bold)) + .push(text::p1_regular(format!("#{}", fingerprint))) + .into(), + Row::new() + .spacing(5) + .push(text::caption(kind.to_string())) + .push_maybe(version.map(|v| text::caption(v))) + .into(), + ]) + .width(Length::Fill) + .into(), + // if let Some(w) = warning { + // tooltip::Tooltip::new( + // icon::warning_icon(), + // iced::widget::text!("{}", w), + // tooltip::Position::Bottom, + // ) + // .style(theme::card::simple) + // .into() + // } else { + // Row::new().into() + // }, + image::success_mark_icon().width(Length::Fixed(50.0)).into(), + ]) + .align_y(Alignment::Center), ) .padding(10) } @@ -223,7 +230,7 @@ pub fn sign_success_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Displa kind: K, version: Option, fingerprint: F, - alias: Option>>, + alias: Option> + Display>, ) -> Container<'a, T> { container( row(vec![ @@ -242,14 +249,14 @@ pub fn sign_success_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Displa .width(Length::Fill) .into(), row(vec![ - text::p1_regular("Signed").style(color::GREEN).into(), + text::p1_regular("Signed").color(color::GREEN).into(), image::success_mark_icon().width(Length::Fixed(50.0)).into(), ]) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(5) .into(), ]) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) .padding(10) } @@ -258,7 +265,7 @@ pub fn registration_success_hardware_wallet<'a, T: 'a, K: Display, V: Display, F kind: K, version: Option, fingerprint: F, - alias: Option>>, + alias: Option> + Display>, ) -> Container<'a, T> { container( row(vec![ @@ -277,19 +284,19 @@ pub fn registration_success_hardware_wallet<'a, T: 'a, K: Display, V: Display, F .width(Length::Fill) .into(), row(vec![ - text::p1_regular("Registered").style(color::GREEN).into(), + text::p1_regular("Registered").color(color::GREEN).into(), image::success_mark_icon().width(Length::Fixed(50.0)).into(), ]) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(5) .into(), ]) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) .padding(10) } -pub fn wrong_network_hardware_wallet<'a, T: 'a, K: Display, V: Display>( +pub fn wrong_network_hardware_wallet<'a, T: 'static, K: Display, V: Display>( kind: K, version: Option, ) -> Container<'a, T> { @@ -313,15 +320,15 @@ pub fn wrong_network_hardware_wallet<'a, T: 'a, K: Display, V: Display>( "The wrong bitcoin application is open or the device was initialized with the wrong network", tooltip::Position::Bottom, ) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) .into(), ]) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) .padding(10) } -pub fn unsupported_hardware_wallet<'a, T: 'a, K: Display, V: Display>( +pub fn unsupported_hardware_wallet<'a, T: 'static, K: Display, V: Display>( kind: K, version: Option, ) -> Container<'a, T> { @@ -345,15 +352,15 @@ pub fn unsupported_hardware_wallet<'a, T: 'a, K: Display, V: Display>( "Make sure your device is unlocked and a supported Bitcoin application is opened.", tooltip::Position::Bottom, ) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) .into(), ]) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) .padding(10) } -pub fn unsupported_version_hardware_wallet<'a, T: 'a, K: Display, V: Display, S: Display>( +pub fn unsupported_version_hardware_wallet<'a, T: 'static, K: Display, V: Display, S: Display>( kind: K, version: Option, requested_version: S, @@ -376,17 +383,17 @@ pub fn unsupported_version_hardware_wallet<'a, T: 'a, K: Display, V: Display, S: "Please upgrade firmware", tooltip::Position::Bottom, ) - .style(theme::Container::Card(theme::Card::Simple)) + .style(theme::card::simple) .into(), ]) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) .padding(10) } pub fn sign_success_hot_signer<'a, T: 'a, F: Display>( fingerprint: F, - alias: Option>>, + alias: Option> + Display>, ) -> Container<'a, T> { container( row(vec![ @@ -404,21 +411,21 @@ pub fn sign_success_hot_signer<'a, T: 'a, F: Display>( .width(Length::Fill) .into(), row(vec![ - text::p1_regular("Signed").style(color::GREEN).into(), + text::p1_regular("Signed").color(color::GREEN).into(), image::success_mark_icon().width(Length::Fixed(50.0)).into(), ]) - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(5) .into(), ]) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) .padding(10) } pub fn selected_hot_signer<'a, T: 'a, F: Display>( fingerprint: F, - alias: Option>>, + alias: Option> + Display>, ) -> Container<'a, T> { container( row(vec![ @@ -440,14 +447,14 @@ pub fn selected_hot_signer<'a, T: 'a, F: Display>( .into(), image::success_mark_icon().width(Length::Fixed(50.0)).into(), ]) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) .padding(10) } pub fn unselected_hot_signer<'a, T: 'a, F: Display>( fingerprint: F, - alias: Option>>, + alias: Option> + Display>, ) -> Container<'a, T> { Container::new( column(vec![ @@ -471,7 +478,7 @@ pub fn unselected_hot_signer<'a, T: 'a, F: Display>( pub fn hot_signer<'a, T: 'a, F: Display>( fingerprint: F, - alias: Option>>, + alias: Option> + Display>, ) -> Container<'a, T> { Container::new( column(vec![ diff --git a/liana-ui/src/component/mod.rs b/liana-ui/src/component/mod.rs index edce276a8..6b98c5040 100644 --- a/liana-ui/src/component/mod.rs +++ b/liana-ui/src/component/mod.rs @@ -24,7 +24,7 @@ use self::text::Text; pub fn separation<'a, T: 'a>() -> Container<'a, T> { Container::new(Column::new().push(text::text(" "))) - .style(theme::Container::Border) + .style(theme::container::border) .height(Length::Fixed(1.0)) } @@ -44,10 +44,9 @@ pub fn network_banner<'a, T: 'a>(network: Network) -> Container<'a, T> { ) .push(text::text(", COINS HAVE ")) .push(text::text("NO VALUE").bold()) - .align_items(iced::Alignment::Center), + .align_y(iced::Alignment::Center), ) .padding(5) - .width(Length::Fill) - .center_x() - .style(theme::Container::Banner) + .center_x(Length::Fill) + .style(theme::banner::network) } diff --git a/liana-ui/src/component/modal.rs b/liana-ui/src/component/modal.rs index cb0b823e4..e53c076b3 100644 --- a/liana-ui/src/component/modal.rs +++ b/liana-ui/src/component/modal.rs @@ -147,7 +147,7 @@ where state: &mut Tree, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn widget::Operation, + operation: &mut dyn widget::Operation, ) { self.base .as_widget() @@ -249,7 +249,7 @@ where &mut self, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn widget::Operation, + operation: &mut dyn widget::Operation, ) { self.content.as_widget().operate( self.tree, diff --git a/liana-ui/src/component/notification.rs b/liana-ui/src/component/notification.rs index dff32e87e..eebe6679a 100644 --- a/liana-ui/src/component/notification.rs +++ b/liana-ui/src/component/notification.rs @@ -1,4 +1,3 @@ -use std::borrow::Cow; use std::fmt::Display; use crate::{ @@ -20,41 +19,41 @@ pub fn warning<'a, T: 'a + Clone>(message: String, error: String) -> Container<' Row::new() .push( Container::new( - text::p1_bold(message_clone.to_string()).style(color::LIGHT_BLACK), + text::p1_bold(message_clone.to_string()).color(color::LIGHT_BLACK), ) .width(Length::Fill), ) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) - .push(text::p1_bold("Learn more").style(color::LIGHT_BLACK)) - .push(icon::collapse_icon().style(color::LIGHT_BLACK)), + .push(text::p1_bold("Learn more").color(color::LIGHT_BLACK)) + .push(icon::collapse_icon().color(color::LIGHT_BLACK)), ), ) - .style(theme::Button::Transparent) + .style(theme::button::transparent) }, move || { Button::new( Row::new() .push( - Container::new(text::p1_bold(message.to_owned()).style(color::LIGHT_BLACK)) + Container::new(text::p1_bold(message.to_owned()).color(color::LIGHT_BLACK)) .width(Length::Fill), ) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) - .push(text::p1_bold("Learn more").style(color::LIGHT_BLACK)) - .push(icon::collapsed_icon().style(color::LIGHT_BLACK)), + .push(text::p1_bold("Learn more").color(color::LIGHT_BLACK)) + .push(icon::collapsed_icon().color(color::LIGHT_BLACK)), ), ) - .style(theme::Button::Transparent) + .style(theme::button::transparent) }, move || Element::<'a, T>::from(text::p2_regular(error.to_owned())), ))) .padding(15) - .style(theme::Container::Card(theme::Card::Warning)) + .style(theme::card::warning) .width(Length::Fill) } @@ -62,14 +61,14 @@ pub fn processing_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display> kind: K, version: Option, fingerprint: F, - alias: Option>>, + alias: Option<&'a str>, ) -> Container<'a, T> { container( row(vec![ column(vec![ Row::new() .spacing(5) - .push_maybe(alias.map(|a| text::p1_bold(a))) + .push_maybe(alias.map(text::p1_bold)) .push(text::p1_regular(format!("#{}", fingerprint))) .into(), Row::new() @@ -86,9 +85,9 @@ pub fn processing_hardware_wallet<'a, T: 'a, K: Display, V: Display, F: Display> ]) .into(), ]) - .align_items(Alignment::Center), + .align_y(Alignment::Center), ) - .style(theme::Container::Notification(theme::Notification::Pending)) + .style(theme::notification::pending) .padding(10) } @@ -103,40 +102,40 @@ pub fn processing_hardware_wallet_error<'a, T: 'a + Clone>( Row::new() .push( Container::new( - text::p1_bold(message_clone.to_string()).style(color::LIGHT_BLACK), + text::p1_bold(message_clone.to_string()).color(color::LIGHT_BLACK), ) .width(Length::Fill), ) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) - .push(text::p1_bold("Learn more").style(color::LIGHT_BLACK)) - .push(icon::collapse_icon().style(color::LIGHT_BLACK)), + .push(text::p1_bold("Learn more").color(color::LIGHT_BLACK)) + .push(icon::collapse_icon().color(color::LIGHT_BLACK)), ), ) - .style(theme::Button::Transparent) + .style(theme::button::transparent) }, move || { Button::new( Row::new() .push( - Container::new(text::p1_bold(message.to_owned()).style(color::LIGHT_BLACK)) + Container::new(text::p1_bold(message.to_owned()).color(color::LIGHT_BLACK)) .width(Length::Fill), ) .push( Row::new() - .align_items(Alignment::Center) + .align_y(Alignment::Center) .spacing(10) - .push(text::p1_bold("Learn more").style(color::LIGHT_BLACK)) - .push(icon::collapsed_icon().style(color::LIGHT_BLACK)), + .push(text::p1_bold("Learn more").color(color::LIGHT_BLACK)) + .push(icon::collapsed_icon().color(color::LIGHT_BLACK)), ), ) - .style(theme::Button::Transparent) + .style(theme::button::transparent) }, move || Element::<'a, T>::from(text::p2_regular(error.to_owned())), ))) .padding(10) - .style(theme::Container::Notification(theme::Notification::Error)) + .style(theme::notification::error) .width(Length::Fill) } diff --git a/liana-ui/src/component/spinner.rs b/liana-ui/src/component/spinner.rs index 6d061dba8..c9d17d6ec 100644 --- a/liana-ui/src/component/spinner.rs +++ b/liana-ui/src/component/spinner.rs @@ -108,7 +108,7 @@ where _viewport: &Rectangle, ) -> event::Status { let state = tree.state.downcast_mut::(); - if let Event::Window(_, window::Event::RedrawRequested(now)) = event { + if let Event::Window(window::Event::RedrawRequested(now)) = event { if now.duration_since(state.last_transition) > self.interval { state.last_transition = now; state.current = (state.current + 1) % self.children.len(); @@ -172,7 +172,7 @@ pub fn typing_text_carousel<'a, Message, Theme>( text_builder: impl Fn(&'a str) -> iced::widget::Text<'a, Theme, Renderer>, ) -> Carousel<'a, Message, Theme> where - Theme: 'a + iced::widget::text::StyleSheet, + Theme: 'a + iced::widget::text::Catalog, { let mut children = Vec::new(); if show_empty { diff --git a/liana-ui/src/component/text.rs b/liana-ui/src/component/text.rs index 5dcd143fd..178cd715b 100644 --- a/liana-ui/src/component/text.rs +++ b/liana-ui/src/component/text.rs @@ -1,6 +1,6 @@ use crate::{font, theme::Theme}; -use iced::advanced::text::Shaping; -use std::borrow::Cow; +use iced::advanced::text::{IntoFragment, Shaping}; +use std::fmt::Display; pub const H1_SIZE: u16 = 40; pub const H2_SIZE: u16 = 29; @@ -11,98 +11,98 @@ pub const P1_SIZE: u16 = 16; pub const P2_SIZE: u16 = 14; pub const CAPTION_SIZE: u16 = 12; -pub fn h1<'a>(content: impl Into>) -> iced::widget::Text<'a, Theme> { - iced::widget::Text::new(content) +pub fn h1<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> { + iced::widget::text!("{}", content) .shaping(Shaping::Advanced) .font(font::BOLD) .size(H1_SIZE) } -pub fn h2<'a>(content: impl Into>) -> iced::widget::Text<'a, Theme> { - iced::widget::Text::new(content) +pub fn h2<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> { + iced::widget::text!("{}", content) .shaping(Shaping::Advanced) .font(font::BOLD) .size(H2_SIZE) } -pub fn h3<'a>(content: impl Into>) -> iced::widget::Text<'a, Theme> { - iced::widget::Text::new(content) +pub fn h3<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> { + iced::widget::text!("{}", content) .shaping(Shaping::Advanced) .font(font::BOLD) .size(H3_SIZE) } -pub fn h4_bold<'a>(content: impl Into>) -> iced::widget::Text<'a, Theme> { - iced::widget::Text::new(content) +pub fn h4_bold<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> { + iced::widget::text!("{}", content) .shaping(Shaping::Advanced) .font(font::BOLD) .size(H4_SIZE) } -pub fn h4_regular<'a>(content: impl Into>) -> iced::widget::Text<'a, Theme> { - iced::widget::Text::new(content) +pub fn h4_regular<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> { + iced::widget::text!("{}", content) .shaping(Shaping::Advanced) .font(font::REGULAR) .size(H4_SIZE) } -pub fn h5_medium<'a>(content: impl Into>) -> iced::widget::Text<'a, Theme> { - iced::widget::Text::new(content) +pub fn h5_medium<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> { + iced::widget::text!("{}", content) .shaping(Shaping::Advanced) .font(font::MEDIUM) .size(H5_SIZE) } -pub fn h5_regular<'a>(content: impl Into>) -> iced::widget::Text<'a, Theme> { - iced::widget::Text::new(content) +pub fn h5_regular<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> { + iced::widget::text!("{}", content) .shaping(Shaping::Advanced) .font(font::REGULAR) .size(H5_SIZE) } -pub fn p1_bold<'a>(content: impl Into>) -> iced::widget::Text<'a, Theme> { - iced::widget::Text::new(content) +pub fn p1_bold<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> { + iced::widget::text!("{}", content) .shaping(Shaping::Advanced) .font(font::BOLD) .size(P1_SIZE) } -pub fn p1_medium<'a>(content: impl Into>) -> iced::widget::Text<'a, Theme> { - iced::widget::Text::new(content) +pub fn p1_medium<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> { + iced::widget::text!("{}", content) .shaping(Shaping::Advanced) .font(font::MEDIUM) .size(P1_SIZE) } -pub fn p1_regular<'a>(content: impl Into>) -> iced::widget::Text<'a, Theme> { - iced::widget::Text::new(content) +pub fn p1_regular<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> { + iced::widget::text!("{}", content) .shaping(Shaping::Advanced) .font(font::REGULAR) .size(P1_SIZE) } -pub fn p2_medium<'a>(content: impl Into>) -> iced::widget::Text<'a, Theme> { - iced::widget::Text::new(content) +pub fn p2_medium<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> { + iced::widget::text!("{}", content) .shaping(Shaping::Advanced) .font(font::MEDIUM) .size(P2_SIZE) } -pub fn p2_regular<'a>(content: impl Into>) -> iced::widget::Text<'a, Theme> { - iced::widget::Text::new(content) +pub fn p2_regular<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> { + iced::widget::text!("{}", content) .shaping(Shaping::Advanced) .font(font::REGULAR) .size(P2_SIZE) } -pub fn caption<'a>(content: impl Into>) -> iced::widget::Text<'a, Theme> { - iced::widget::Text::new(content) +pub fn caption<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> { + iced::widget::text!("{}", content) .shaping(Shaping::Advanced) .font(font::REGULAR) .size(CAPTION_SIZE) } -pub fn text<'a>(content: impl Into>) -> iced::widget::Text<'a, Theme> { +pub fn text<'a>(content: impl Display) -> iced::widget::Text<'a, Theme> { p1_regular(content) } diff --git a/liana-ui/src/component/toast.rs b/liana-ui/src/component/toast.rs index 26feae4f5..fba07eef7 100644 --- a/liana-ui/src/component/toast.rs +++ b/liana-ui/src/component/toast.rs @@ -96,7 +96,7 @@ where state: &mut Tree, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn Operation, + operation: &mut dyn Operation, ) { operation.container(None, layout.bounds(), &mut |operation| { self.content @@ -303,7 +303,7 @@ where &mut self, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn iced::advanced::widget::Operation, + operation: &mut dyn iced::advanced::widget::Operation, ) { operation.container(None, layout.bounds(), &mut |operation| { self.toasts diff --git a/liana-ui/src/component/tooltip.rs b/liana-ui/src/component/tooltip.rs index a0fefda78..600a83d4e 100644 --- a/liana-ui/src/component/tooltip.rs +++ b/liana-ui/src/component/tooltip.rs @@ -1,12 +1,12 @@ use crate::{icon, theme, widget::*}; -pub fn tooltip<'a, T: 'a>(help: &'static str) -> Container<'a, T> { +pub fn tooltip(help: &'static str) -> Container<'static, T> { Container::new( iced::widget::tooltip::Tooltip::new( icon::tooltip_icon(), help, iced::widget::tooltip::Position::Right, ) - .style(theme::Container::Card(theme::Card::Simple)), + .style(theme::card::simple), ) } diff --git a/liana-ui/src/font.rs b/liana-ui/src/font.rs index c06fd76ea..f22a4ccb6 100644 --- a/liana-ui/src/font.rs +++ b/liana-ui/src/font.rs @@ -1,7 +1,8 @@ use iced::{ font::{Family, Stretch, Weight}, - Command, Font, + Font, Task, }; +use std::borrow::Cow; pub const BOLD: Font = Font { family: Family::Name("IBM Plex Sans"), @@ -26,12 +27,12 @@ pub const REGULAR_BYTES: &[u8] = include_bytes!("../static/fonts/IBMPlexSans-Reg pub const ICONEX_ICONS_BYTES: &[u8] = include_bytes!("../static/icons/iconex/iconex-icons.ttf"); pub const BOOTSTRAP_ICONS_BYTE: &[u8] = include_bytes!("../static/icons/bootstrap-icons.ttf"); -pub fn loads> + 'static>() -> Vec> { +pub fn load() -> Vec> { vec![ - iced::font::load(BOLD_BYTES).map(T::from), - iced::font::load(MEDIUM_BYTES).map(T::from), - iced::font::load(REGULAR_BYTES).map(T::from), - iced::font::load(ICONEX_ICONS_BYTES).map(T::from), - iced::font::load(BOOTSTRAP_ICONS_BYTE).map(T::from), + BOLD_BYTES.into(), + MEDIUM_BYTES.into(), + REGULAR_BYTES.into(), + ICONEX_ICONS_BYTES.into(), + BOOTSTRAP_ICONS_BYTE.into(), ] } diff --git a/liana-ui/src/icon.rs b/liana-ui/src/icon.rs index b09d7dc3f..c733734a9 100644 --- a/liana-ui/src/icon.rs +++ b/liana-ui/src/icon.rs @@ -7,7 +7,7 @@ fn bootstrap_icon(unicode: char) -> Text<'static> { Text::new(unicode.to_string()) .font(BOOTSTRAP_ICONS) .width(Length::Fixed(20.0)) - .horizontal_alignment(alignment::Horizontal::Center) + .align_x(alignment::Horizontal::Center) .size(P1_SIZE) } @@ -129,7 +129,7 @@ fn iconex_icon(unicode: char) -> Text<'static> { Text::new(unicode.to_string()) .font(ICONEX_ICONS) .width(Length::Fixed(20.0)) - .horizontal_alignment(alignment::Horizontal::Center) + .align_x(alignment::Horizontal::Center) .size(P1_SIZE) } diff --git a/liana-ui/src/image.rs b/liana-ui/src/image.rs index a690bbae0..d077928e3 100644 --- a/liana-ui/src/image.rs +++ b/liana-ui/src/image.rs @@ -10,52 +10,52 @@ pub fn liana_app_icon() -> icon::Icon { icon::from_file_data(LIANA_APP_ICON, None).unwrap() } -pub fn liana_grey_logo() -> Svg { +pub fn liana_grey_logo() -> Svg<'static> { let h = Handle::from_memory(LIANA_LOGO_GREY.to_vec()); Svg::new(h) } -pub fn liana_brand_grey() -> Svg { +pub fn liana_brand_grey() -> Svg<'static> { let h = Handle::from_memory(LIANA_BRAND_GREY.to_vec()); Svg::new(h) } -pub fn wizardsardine() -> Svg { +pub fn wizardsardine() -> Svg<'static> { let h = Handle::from_memory(WIZARDSARDINE_LETTERING.to_vec()); Svg::new(h) } const CREATE_NEW_WALLET_ICON: &[u8] = include_bytes!("../static/icons/blueprint.svg"); -pub fn create_new_wallet_icon() -> Svg { +pub fn create_new_wallet_icon() -> Svg<'static> { let h = Handle::from_memory(CREATE_NEW_WALLET_ICON.to_vec()); Svg::new(h) } const PARTICIPATE_IN_NEW_WALLET_ICON: &[u8] = include_bytes!("../static/icons/discussion.svg"); -pub fn participate_in_new_wallet_icon() -> Svg { +pub fn participate_in_new_wallet_icon() -> Svg<'static> { let h = Handle::from_memory(PARTICIPATE_IN_NEW_WALLET_ICON.to_vec()); Svg::new(h) } const RESTORE_WALLET_ICON: &[u8] = include_bytes!("../static/icons/syncdata.svg"); -pub fn restore_wallet_icon() -> Svg { +pub fn restore_wallet_icon() -> Svg<'static> { let h = Handle::from_memory(RESTORE_WALLET_ICON.to_vec()); Svg::new(h) } const SUCCESS_MARK_ICON: &[u8] = include_bytes!("../static/icons/success-mark.svg"); -pub fn success_mark_icon() -> Svg { +pub fn success_mark_icon() -> Svg<'static> { let h = Handle::from_memory(SUCCESS_MARK_ICON.to_vec()); Svg::new(h) } const KEY_MARK_ICON: &[u8] = include_bytes!("../static/icons/key-mark.svg"); -pub fn key_mark_icon() -> Svg { +pub fn key_mark_icon() -> Svg<'static> { let h = Handle::from_memory(KEY_MARK_ICON.to_vec()); Svg::new(h) } @@ -63,7 +63,7 @@ pub fn key_mark_icon() -> Svg { const INHERITANCE_TEMPLATE_DESC: &[u8] = include_bytes!("../static/images/inheritance_template_description.svg"); -pub fn inheritance_template_description() -> Svg { +pub fn inheritance_template_description() -> Svg<'static> { let h = Handle::from_memory(INHERITANCE_TEMPLATE_DESC.to_vec()); Svg::new(h) } @@ -71,7 +71,7 @@ pub fn inheritance_template_description() -> Svg { const CUSTOM_TEMPLATE_DESC: &[u8] = include_bytes!("../static/images/custom_template_description.svg"); -pub fn custom_template_description() -> Svg { +pub fn custom_template_description() -> Svg<'static> { let h = Handle::from_memory(CUSTOM_TEMPLATE_DESC.to_vec()); Svg::new(h) } @@ -79,7 +79,7 @@ pub fn custom_template_description() -> Svg { const MULTISIG_SECURITY_TEMPLATE_DESC: &[u8] = include_bytes!("../static/images/multisig_security_template.svg"); -pub fn multisig_security_template_description() -> Svg { +pub fn multisig_security_template_description() -> Svg<'static> { let h = Handle::from_memory(MULTISIG_SECURITY_TEMPLATE_DESC.to_vec()); Svg::new(h) } diff --git a/liana-ui/src/lib.rs b/liana-ui/src/lib.rs index b6fa8392f..b67278017 100644 --- a/liana-ui/src/lib.rs +++ b/liana-ui/src/lib.rs @@ -19,9 +19,9 @@ pub mod widget { pub type Text<'a> = iced::widget::Text<'a, Theme, Renderer>; pub type TextInput<'a, Message> = iced::widget::TextInput<'a, Message, Theme, Renderer>; pub type Tooltip<'a> = iced::widget::Tooltip<'a, Theme, Renderer>; - pub type ProgressBar = iced::widget::ProgressBar; + pub type ProgressBar<'a> = iced::widget::ProgressBar<'a, Theme>; pub type PickList<'a, T, L, V, Message> = iced::widget::PickList<'a, T, L, V, Message, Theme, Renderer>; pub type Scrollable<'a, Message> = iced::widget::Scrollable<'a, Message, Theme, Renderer>; - pub type Svg = iced::widget::Svg; + pub type Svg<'a> = iced::widget::Svg<'a, Theme>; } diff --git a/liana-ui/src/theme.rs b/liana-ui/src/theme.rs deleted file mode 100644 index bc04e2fab..000000000 --- a/liana-ui/src/theme.rs +++ /dev/null @@ -1,990 +0,0 @@ -use iced::{ - application, - widget::{ - button, checkbox, container, pick_list, progress_bar, qr_code, radio, scrollable, slider, - svg, text, text_input, - }, -}; - -use super::color; - -#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)] -pub enum Theme { - #[default] - Dark, - Light, -} - -impl application::StyleSheet for Theme { - type Style = (); - - fn appearance(&self, _style: &Self::Style) -> application::Appearance { - match self { - Theme::Light => application::Appearance { - background_color: color::GREY_2, - text_color: color::LIGHT_BLACK, - }, - Theme::Dark => application::Appearance { - background_color: color::LIGHT_BLACK, - text_color: color::WHITE, - }, - } - } -} - -#[derive(Clone, Copy, Default)] -pub enum Overlay { - #[default] - Default, -} -impl iced::overlay::menu::StyleSheet for Theme { - type Style = Overlay; - - fn appearance(&self, _style: &Self::Style) -> iced::overlay::menu::Appearance { - iced::overlay::menu::Appearance { - text_color: color::GREY_2, - background: color::GREY_6.into(), - border: iced::Border { - color: color::GREY_2, - width: 0.0, - radius: 25.0.into(), - }, - selected_text_color: color::LIGHT_BLACK, - selected_background: color::GREEN.into(), - } - } -} -impl From for Overlay { - fn from(_p: PickList) -> Overlay { - Overlay::Default - } -} - -#[derive(Clone, Copy, Default)] -pub enum Text { - #[default] - Default, - Color(iced::Color), -} - -impl From for Text { - fn from(color: iced::Color) -> Self { - Text::Color(color) - } -} - -impl text::StyleSheet for Theme { - type Style = Text; - - fn appearance(&self, style: Self::Style) -> text::Appearance { - match style { - Text::Default => Default::default(), - Text::Color(c) => text::Appearance { color: Some(c) }, - } - } -} - -#[derive(Debug, Copy, Clone, Default)] -pub enum Container { - #[default] - Transparent, - Background, - Foreground, - Border, - Banner, - Card(Card), - Badge(Badge), - Pill(Pill), - Custom(iced::Color), - Notification(Notification), - QrCode, -} - -impl container::StyleSheet for Theme { - type Style = Container; - fn appearance(&self, style: &Self::Style) -> iced::widget::container::Appearance { - match self { - Theme::Light => match style { - Container::Transparent => container::Appearance { - background: Some(iced::Color::TRANSPARENT.into()), - ..container::Appearance::default() - }, - Container::Background => container::Appearance { - background: Some(color::GREY_2.into()), - ..container::Appearance::default() - }, - Container::Foreground => container::Appearance { - background: Some(color::GREY_2.into()), - ..container::Appearance::default() - }, - Container::Border => container::Appearance { - background: Some(iced::Color::TRANSPARENT.into()), - border: iced::Border { - color: color::LIGHT_BLACK, - width: 1.0, - radius: 0.0.into(), - }, - ..container::Appearance::default() - }, - Container::Card(c) => c.appearance(self), - Container::Badge(c) => c.appearance(self), - Container::Pill(c) => c.appearance(self), - Container::Notification(c) => c.appearance(self), - Container::Custom(c) => container::Appearance { - background: Some((*c).into()), - ..container::Appearance::default() - }, - Container::QrCode => container::Appearance { - background: Some(color::WHITE.into()), - border: iced::Border { - color: color::TRANSPARENT, - width: 0.0, - radius: 25.0.into(), - }, - ..container::Appearance::default() - }, - Container::Banner => container::Appearance { - background: Some(color::WHITE.into()), - border: iced::Border { - color: color::TRANSPARENT, - width: 0.0, - radius: 0.0.into(), - }, - text_color: color::LIGHT_BLACK.into(), - ..container::Appearance::default() - }, - }, - Theme::Dark => match style { - Container::Transparent => container::Appearance { - background: Some(iced::Color::TRANSPARENT.into()), - ..container::Appearance::default() - }, - Container::Background => container::Appearance { - background: Some(color::LIGHT_BLACK.into()), - ..container::Appearance::default() - }, - Container::Foreground => container::Appearance { - background: Some(color::BLACK.into()), - ..container::Appearance::default() - }, - Container::Border => container::Appearance { - background: Some(iced::Color::TRANSPARENT.into()), - border: iced::Border { - color: color::GREY_3, - width: 1.0, - radius: 0.0.into(), - }, - ..container::Appearance::default() - }, - Container::Card(c) => c.appearance(self), - Container::Badge(c) => c.appearance(self), - Container::Pill(c) => c.appearance(self), - Container::Notification(c) => c.appearance(self), - Container::Custom(c) => container::Appearance { - background: Some((*c).into()), - ..container::Appearance::default() - }, - Container::QrCode => container::Appearance { - background: Some(color::WHITE.into()), - border: iced::Border { - color: color::TRANSPARENT, - width: 0.0, - radius: 25.0.into(), - }, - ..container::Appearance::default() - }, - Container::Banner => container::Appearance { - background: Some(color::BLUE.into()), - border: iced::Border { - color: color::TRANSPARENT, - width: 0.0, - radius: 0.0.into(), - }, - text_color: color::LIGHT_BLACK.into(), - ..container::Appearance::default() - }, - }, - } - } -} - -impl From for Container { - fn from(c: Card) -> Container { - Container::Card(c) - } -} - -impl From for Container { - fn from(c: Badge) -> Container { - Container::Badge(c) - } -} - -impl From for Container { - fn from(c: Pill) -> Container { - Container::Pill(c) - } -} - -#[derive(Debug, Copy, Clone, Default)] -pub enum Notification { - #[default] - Pending, - Error, -} - -impl Notification { - fn appearance(&self, theme: &Theme) -> iced::widget::container::Appearance { - match theme { - Theme::Light => match self { - Self::Pending => container::Appearance { - background: Some(iced::Background::Color(color::GREEN)), - text_color: color::LIGHT_BLACK.into(), - border: iced::Border { - color: color::GREEN, - width: 1.0, - radius: 25.0.into(), - }, - ..container::Appearance::default() - }, - Self::Error => container::Appearance { - background: Some(iced::Background::Color(color::ORANGE)), - text_color: color::LIGHT_BLACK.into(), - border: iced::Border { - color: color::ORANGE, - width: 1.0, - radius: 25.0.into(), - }, - ..container::Appearance::default() - }, - }, - Theme::Dark => match self { - Self::Pending => container::Appearance { - background: Some(iced::Background::Color(color::GREEN)), - text_color: color::LIGHT_BLACK.into(), - border: iced::Border { - color: color::GREEN, - width: 1.0, - radius: 25.0.into(), - }, - ..container::Appearance::default() - }, - Self::Error => container::Appearance { - background: Some(iced::Background::Color(color::ORANGE)), - text_color: color::LIGHT_BLACK.into(), - border: iced::Border { - color: color::ORANGE, - width: 1.0, - radius: 25.0.into(), - }, - ..container::Appearance::default() - }, - }, - } - } -} - -#[derive(Debug, Copy, Clone, Default)] -pub enum Card { - #[default] - Simple, - Modal, - Border, - Invalid, - Warning, - Error, -} - -impl Card { - fn appearance(&self, theme: &Theme) -> iced::widget::container::Appearance { - match theme { - Theme::Light => match self { - Card::Simple => container::Appearance { - background: Some(color::GREY_2.into()), - ..container::Appearance::default() - }, - Card::Modal => container::Appearance { - background: Some(color::GREY_2.into()), - ..container::Appearance::default() - }, - Card::Border => container::Appearance { - background: Some(iced::Color::TRANSPARENT.into()), - border: iced::Border { - color: color::GREY_7, - width: 1.0, - radius: 10.0.into(), - }, - ..container::Appearance::default() - }, - Card::Invalid => container::Appearance { - background: Some(color::GREY_2.into()), - text_color: color::BLACK.into(), - border: iced::Border { - color: color::RED, - width: 1.0, - radius: 0.0.into(), - }, - ..container::Appearance::default() - }, - Card::Error => container::Appearance { - background: Some(color::GREY_2.into()), - text_color: color::RED.into(), - border: iced::Border { - color: color::RED, - width: 1.0, - radius: 0.0.into(), - }, - ..container::Appearance::default() - }, - Card::Warning => container::Appearance { - background: Some(color::ORANGE.into()), - text_color: color::GREY_2.into(), - ..container::Appearance::default() - }, - }, - Theme::Dark => match self { - Card::Simple => container::Appearance { - background: Some(color::GREY_6.into()), - border: iced::Border { - color: color::TRANSPARENT, - width: 0.0, - radius: 25.0.into(), - }, - ..container::Appearance::default() - }, - Card::Modal => container::Appearance { - background: Some(color::LIGHT_BLACK.into()), - border: iced::Border { - color: color::TRANSPARENT, - width: 0.0, - radius: 25.0.into(), - }, - ..container::Appearance::default() - }, - Card::Border => container::Appearance { - background: Some(iced::Color::TRANSPARENT.into()), - border: iced::Border { - color: color::GREY_7, - width: 1.0, - radius: 25.0.into(), - }, - ..container::Appearance::default() - }, - Card::Invalid => container::Appearance { - background: Some(color::LIGHT_BLACK.into()), - text_color: color::RED.into(), - border: iced::Border { - color: color::RED, - width: 1.0, - radius: 25.0.into(), - }, - ..container::Appearance::default() - }, - Card::Error => container::Appearance { - background: Some(color::LIGHT_BLACK.into()), - text_color: color::RED.into(), - border: iced::Border { - color: color::RED, - width: 1.0, - radius: 25.0.into(), - }, - ..container::Appearance::default() - }, - Card::Warning => container::Appearance { - background: Some(color::ORANGE.into()), - text_color: color::LIGHT_BLACK.into(), - ..container::Appearance::default() - }, - }, - } - } -} - -#[derive(Debug, Copy, Clone, Default)] -pub enum Badge { - #[default] - Standard, - Bitcoin, -} - -impl Badge { - fn appearance(&self, _theme: &Theme) -> iced::widget::container::Appearance { - match self { - Self::Standard => container::Appearance { - border: iced::Border { - color: color::TRANSPARENT, - width: 0.0, - radius: 40.0.into(), - }, - background: Some(color::GREY_4.into()), - ..container::Appearance::default() - }, - Self::Bitcoin => container::Appearance { - border: iced::Border { - color: color::TRANSPARENT, - width: 0.0, - radius: 40.0.into(), - }, - background: Some(color::ORANGE.into()), - text_color: iced::Color::WHITE.into(), - ..container::Appearance::default() - }, - } - } -} - -#[derive(Debug, Copy, Clone, Default)] -pub enum Pill { - #[default] - Simple, - Primary, - Success, - Warning, -} - -impl Pill { - fn appearance(&self, _theme: &Theme) -> iced::widget::container::Appearance { - match self { - Self::Primary => container::Appearance { - background: Some(color::GREEN.into()), - border: iced::Border { - color: color::TRANSPARENT, - width: 0.0, - radius: 25.0.into(), - }, - text_color: color::LIGHT_BLACK.into(), - ..container::Appearance::default() - }, - Self::Success => container::Appearance { - background: Some(color::GREEN.into()), - border: iced::Border { - color: color::TRANSPARENT, - width: 0.0, - radius: 25.0.into(), - }, - text_color: color::LIGHT_BLACK.into(), - ..container::Appearance::default() - }, - Self::Simple => container::Appearance { - background: Some(iced::Color::TRANSPARENT.into()), - border: iced::Border { - color: color::GREY_3, - width: 1.0, - radius: 25.0.into(), - }, - text_color: color::GREY_3.into(), - ..container::Appearance::default() - }, - Self::Warning => container::Appearance { - background: Some(iced::Color::TRANSPARENT.into()), - border: iced::Border { - color: color::RED, - width: 1.0, - radius: 25.0.into(), - }, - text_color: color::RED.into(), - ..container::Appearance::default() - }, - } - } -} - -#[derive(Default)] -pub struct Radio {} -impl radio::StyleSheet for Theme { - type Style = Radio; - - fn active(&self, _style: &Self::Style, _is_selected: bool) -> radio::Appearance { - radio::Appearance { - background: iced::Color::TRANSPARENT.into(), - dot_color: color::GREEN, - border_width: 1.0, - border_color: color::GREY_7, - text_color: None, - } - } - - fn hovered(&self, style: &Self::Style, is_selected: bool) -> radio::Appearance { - let active = self.active(style, is_selected); - radio::Appearance { - dot_color: color::GREEN, - border_color: color::GREEN, - background: iced::Color::TRANSPARENT.into(), - ..active - } - } -} - -#[derive(Default, Clone)] -pub struct Scrollable {} -impl scrollable::StyleSheet for Theme { - type Style = Scrollable; - - fn active(&self, _style: &Self::Style) -> scrollable::Appearance { - scrollable::Appearance { - gap: None, - container: container::Appearance::default(), - scrollbar: scrollable::Scrollbar { - background: None, - border: iced::Border { - color: color::GREY_3, - width: 0.0, - radius: 10.0.into(), - }, - scroller: scrollable::Scroller { - color: color::GREY_7, - border: iced::Border { - color: color::TRANSPARENT, - width: 0.0, - radius: 10.0.into(), - }, - }, - }, - } - } - - fn hovered(&self, style: &Self::Style, _is_hovered: bool) -> scrollable::Appearance { - let active = self.active(style); - scrollable::Appearance { ..active } - } -} - -#[derive(Default, Clone)] -pub enum PickList { - #[default] - Secondary, -} -impl pick_list::StyleSheet for Theme { - type Style = PickList; - - fn active(&self, _style: &Self::Style) -> pick_list::Appearance { - pick_list::Appearance { - placeholder_color: color::GREY_6, - handle_color: color::GREY_7, - background: color::GREY_6.into(), - border: iced::Border { - color: color::GREY_7, - width: 1.0, - radius: 25.0.into(), - }, - text_color: color::GREY_2, - } - } - - fn hovered(&self, _style: &Self::Style) -> pick_list::Appearance { - pick_list::Appearance { - placeholder_color: color::GREY_6, - handle_color: color::GREEN, - background: color::GREY_6.into(), - border: iced::Border { - color: color::GREEN, - width: 1.0, - radius: 25.0.into(), - }, - text_color: color::GREEN, - } - } -} - -#[derive(Default)] -pub struct CheckBox {} -impl checkbox::StyleSheet for Theme { - type Style = CheckBox; - - fn active(&self, _style: &Self::Style, is_selected: bool) -> checkbox::Appearance { - if is_selected { - checkbox::Appearance { - background: color::GREEN.into(), - icon_color: color::GREY_4, - text_color: None, - border: iced::Border { - color: color::TRANSPARENT, - width: 1.0, - radius: 4.0.into(), - }, - } - } else { - checkbox::Appearance { - background: color::GREY_4.into(), - icon_color: color::GREEN, - text_color: None, - border: iced::Border { - color: color::TRANSPARENT, - width: 0.0, - radius: 4.0.into(), - }, - } - } - } - - fn hovered(&self, style: &Self::Style, is_selected: bool) -> checkbox::Appearance { - self.active(style, is_selected) - } -} - -#[derive(Default)] -pub enum Button { - #[default] - Primary, - Secondary, - Destructive, - SecondaryDestructive, - Transparent, - TransparentBorder, - Border, - Menu(bool), -} - -impl button::StyleSheet for Theme { - type Style = Button; - - fn active(&self, style: &Self::Style) -> button::Appearance { - match self { - Theme::Light => button::Appearance::default(), - Theme::Dark => match style { - Button::Primary => button::Appearance { - shadow_offset: iced::Vector::default(), - background: Some(color::GREEN.into()), - text_color: color::LIGHT_BLACK, - border: iced::Border { - color: color::GREEN, - width: 1.0, - radius: 25.0.into(), - }, - ..button::Appearance::default() - }, - Button::Secondary | Button::SecondaryDestructive | Button::Border => { - button::Appearance { - shadow_offset: iced::Vector::default(), - background: Some(color::GREY_6.into()), - text_color: color::GREY_2, - border: iced::Border { - color: color::GREY_7, - width: 1.0, - radius: 25.0.into(), - }, - ..button::Appearance::default() - } - } - Button::Destructive => button::Appearance { - shadow_offset: iced::Vector::default(), - background: Some(color::GREY_6.into()), - text_color: color::RED, - border: iced::Border { - color: color::RED, - width: 1.0, - radius: 25.0.into(), - }, - ..button::Appearance::default() - }, - Button::Transparent => button::Appearance { - shadow_offset: iced::Vector::default(), - background: Some(iced::Color::TRANSPARENT.into()), - text_color: color::GREY_2, - border: iced::Border { - color: color::TRANSPARENT, - width: 0.0, - radius: 25.0.into(), - }, - ..button::Appearance::default() - }, - Button::TransparentBorder => button::Appearance { - shadow_offset: iced::Vector::default(), - background: Some(iced::Color::TRANSPARENT.into()), - text_color: color::WHITE, - border: iced::Border { - color: color::TRANSPARENT, - width: 0.0, - radius: 25.0.into(), - }, - ..button::Appearance::default() - }, - Button::Menu(active) => { - if *active { - button::Appearance { - shadow_offset: iced::Vector::default(), - background: Some(color::LIGHT_BLACK.into()), - text_color: color::WHITE, - border: iced::Border { - color: color::TRANSPARENT, - width: 0.0, - radius: 25.0.into(), - }, - ..button::Appearance::default() - } - } else { - button::Appearance { - shadow_offset: iced::Vector::default(), - background: Some(iced::Color::TRANSPARENT.into()), - text_color: color::WHITE, - border: iced::Border { - color: color::TRANSPARENT, - width: 0.0, - radius: 25.0.into(), - }, - ..button::Appearance::default() - } - } - } - }, - } - } - - fn hovered(&self, style: &Self::Style) -> button::Appearance { - match self { - Theme::Light => button::Appearance::default(), - Theme::Dark => match style { - Button::Primary => button::Appearance { - shadow_offset: iced::Vector::default(), - background: Some(color::GREEN.into()), - text_color: color::LIGHT_BLACK, - border: iced::Border { - color: color::TRANSPARENT, - width: 0.0, - radius: 25.0.into(), - }, - ..button::Appearance::default() - }, - Button::Secondary => button::Appearance { - shadow_offset: iced::Vector::default(), - background: Some(color::GREY_6.into()), - text_color: color::GREEN, - border: iced::Border { - color: color::GREEN, - width: 1.0, - radius: 25.0.into(), - }, - ..button::Appearance::default() - }, - Button::Destructive | Button::SecondaryDestructive => button::Appearance { - shadow_offset: iced::Vector::default(), - background: Some(color::RED.into()), - text_color: color::LIGHT_BLACK, - border: iced::Border { - color: color::TRANSPARENT, - width: 0.0, - radius: 25.0.into(), - }, - ..button::Appearance::default() - }, - Button::Transparent => button::Appearance { - shadow_offset: iced::Vector::default(), - background: Some(iced::Color::TRANSPARENT.into()), - text_color: color::GREY_2, - border: iced::Border { - color: color::TRANSPARENT, - width: 0.0, - radius: 25.0.into(), - }, - ..button::Appearance::default() - }, - Button::TransparentBorder | Button::Border => button::Appearance { - shadow_offset: iced::Vector::default(), - background: Some(color::GREY_6.into()), - text_color: color::WHITE, - border: iced::Border { - color: color::GREEN, - width: 1.0, - radius: 25.0.into(), - }, - ..button::Appearance::default() - }, - Button::Menu(_) => button::Appearance { - shadow_offset: iced::Vector::default(), - background: Some(color::LIGHT_BLACK.into()), - text_color: color::WHITE, - border: iced::Border { - color: color::TRANSPARENT, - width: 0.0, - radius: 25.0.into(), - }, - ..button::Appearance::default() - }, - }, - } - } - fn disabled(&self, style: &Self::Style) -> button::Appearance { - let active = if let Button::Primary = style { - self.active(&Button::Secondary) - } else { - self.active(style) - }; - button::Appearance { - shadow_offset: iced::Vector::default(), - background: Some(color::TRANSPARENT.into()), - text_color: iced::Color { - a: active.text_color.a * 0.5, - ..active.text_color - }, - ..active - } - } -} - -#[derive(Debug, Copy, Clone, Default)] -pub enum Form { - #[default] - Simple, - Invalid, -} - -impl text_input::StyleSheet for Theme { - type Style = Form; - fn active(&self, style: &Self::Style) -> text_input::Appearance { - match style { - Form::Simple => text_input::Appearance { - icon_color: color::GREY_7, - background: iced::Background::Color(iced::Color::TRANSPARENT), - border: iced::Border { - color: color::GREY_7, - width: 1.0, - radius: 25.0.into(), - }, - }, - Form::Invalid => text_input::Appearance { - icon_color: color::GREY_7, - background: iced::Background::Color(iced::Color::TRANSPARENT), - border: iced::Border { - color: color::RED, - width: 1.0, - radius: 25.0.into(), - }, - }, - } - } - - fn disabled(&self, style: &Self::Style) -> text_input::Appearance { - text_input::Appearance { - ..self.active(style) - } - } - - fn focused(&self, style: &Self::Style) -> text_input::Appearance { - text_input::Appearance { - ..self.active(style) - } - } - - fn disabled_color(&self, _style: &Self::Style) -> iced::Color { - color::GREY_7 - } - - fn placeholder_color(&self, _style: &Self::Style) -> iced::Color { - color::GREY_7 - } - - fn value_color(&self, _style: &Self::Style) -> iced::Color { - color::GREY_2 - } - - fn selection_color(&self, _style: &Self::Style) -> iced::Color { - color::GREEN - } -} - -#[derive(Debug, Copy, Clone, Default)] -pub enum ProgressBar { - #[default] - Simple, -} - -impl progress_bar::StyleSheet for Theme { - type Style = ProgressBar; - fn appearance(&self, _style: &Self::Style) -> progress_bar::Appearance { - progress_bar::Appearance { - background: color::GREY_6.into(), - bar: color::GREEN.into(), - border_radius: 10.0.into(), - } - } -} - -#[derive(Debug, Copy, Clone, Default)] -pub enum Slider { - #[default] - Simple, -} - -impl slider::StyleSheet for Theme { - type Style = Slider; - fn active(&self, _style: &Self::Style) -> slider::Appearance { - let handle = slider::Handle { - shape: slider::HandleShape::Rectangle { - width: 8, - border_radius: 4.0.into(), - }, - color: color::BLACK, - border_color: color::GREEN, - border_width: 1.0, - }; - slider::Appearance { - rail: slider::Rail { - colors: (color::GREEN, iced::Color::TRANSPARENT), - border_radius: 4.0.into(), - width: 2.0, - }, - handle, - } - } - fn hovered(&self, _style: &Self::Style) -> slider::Appearance { - let handle = slider::Handle { - shape: slider::HandleShape::Rectangle { - width: 8, - border_radius: 4.0.into(), - }, - color: color::GREEN, - border_color: color::GREEN, - border_width: 1.0, - }; - slider::Appearance { - rail: slider::Rail { - colors: (color::GREEN, iced::Color::TRANSPARENT), - border_radius: 4.0.into(), - width: 2.0, - }, - handle, - } - } - fn dragging(&self, _style: &Self::Style) -> slider::Appearance { - let handle = slider::Handle { - shape: slider::HandleShape::Rectangle { - width: 8, - border_radius: 4.0.into(), - }, - color: color::GREEN, - border_color: color::GREEN, - border_width: 1.0, - }; - slider::Appearance { - rail: slider::Rail { - colors: (color::GREEN, iced::Color::TRANSPARENT), - border_radius: 4.0.into(), - width: 2.0, - }, - handle, - } - } -} - -#[derive(Debug, Copy, Clone, Default)] -pub enum Svg { - #[default] - Simple, -} - -impl svg::StyleSheet for Theme { - type Style = ProgressBar; - fn appearance(&self, _style: &Self::Style) -> svg::Appearance { - svg::Appearance::default() - } -} - -impl qr_code::StyleSheet for Theme { - type Style = (); - fn appearance(&self, _style: &Self::Style) -> qr_code::Appearance { - qr_code::Appearance { - cell: color::BLACK, - background: color::WHITE, - } - } -} diff --git a/liana-ui/src/theme/badge.rs b/liana-ui/src/theme/badge.rs new file mode 100644 index 000000000..0093aad4d --- /dev/null +++ b/liana-ui/src/theme/badge.rs @@ -0,0 +1,27 @@ +use iced::widget::container::Style; +use iced::{Background, Border}; + +use super::palette::ContainerPalette; +use super::Theme; + +fn badge(palette: &ContainerPalette) -> Style { + Style { + background: Some(Background::Color(palette.background)), + text_color: palette.text, + border: Border { + radius: 25.0.into(), + width: 1.0, + color: iced::Color::TRANSPARENT.into(), + ..Default::default() + }, + ..Default::default() + } +} + +pub fn simple(theme: &Theme) -> Style { + badge(&theme.colors.badges.simple) +} + +pub fn bitcoin(theme: &Theme) -> Style { + badge(&theme.colors.badges.bitcoin) +} diff --git a/liana-ui/src/theme/banner.rs b/liana-ui/src/theme/banner.rs new file mode 100644 index 000000000..f2798b589 --- /dev/null +++ b/liana-ui/src/theme/banner.rs @@ -0,0 +1,28 @@ +use iced::widget::container::Style; +use iced::{Background, Border}; + +use super::palette::ContainerPalette; +use super::Theme; + +fn banner(palette: &ContainerPalette) -> Style { + Style { + background: Some(Background::Color(palette.background)), + text_color: palette.text, + border: if let Some(color) = palette.border { + Border { + width: 1.0, + color, + ..Default::default() + } + } else { + Border { + ..Default::default() + } + }, + ..Default::default() + } +} + +pub fn network(theme: &Theme) -> Style { + banner(&theme.colors.banners.network) +} diff --git a/liana-ui/src/theme/button.rs b/liana-ui/src/theme/button.rs new file mode 100644 index 000000000..85710a27d --- /dev/null +++ b/liana-ui/src/theme/button.rs @@ -0,0 +1,146 @@ +use iced::widget::button::{Catalog, Status, Style, StyleFn}; +use iced::{Background, Border, Color}; + +use super::palette::Button; +use super::Theme; + +impl Catalog for Theme { + type Class<'a> = StyleFn<'a, Self>; + + fn default<'a>() -> Self::Class<'a> { + Box::new(primary) + } + + fn style(&self, class: &Self::Class<'_>, status: Status) -> Style { + class(self, status) + } +} + +pub fn primary(theme: &Theme, status: Status) -> Style { + button(&theme.colors.buttons.primary, status) +} + +pub fn secondary(theme: &Theme, status: Status) -> Style { + button(&theme.colors.buttons.secondary, status) +} + +pub fn destructive(theme: &Theme, status: Status) -> Style { + button(&theme.colors.buttons.destructive, status) +} + +pub fn container(theme: &Theme, status: Status) -> Style { + button(&theme.colors.buttons.container, status) +} + +pub fn container_border(theme: &Theme, status: Status) -> Style { + button(&theme.colors.buttons.container_border, status) +} + +pub fn menu(theme: &Theme, status: Status) -> Style { + button(&theme.colors.buttons.menu, status) +} + +pub fn menu_pressed(theme: &Theme, _status: Status) -> Style { + button(&theme.colors.buttons.menu, Status::Pressed) +} + +pub fn transparent(theme: &Theme, status: Status) -> Style { + button(&theme.colors.buttons.transparent, status) +} + +pub fn transparent_border(theme: &Theme, status: Status) -> Style { + button(&theme.colors.buttons.transparent_border, status) +} + +fn button(p: &Button, status: Status) -> Style { + match status { + Status::Active => Style { + background: Some(Background::Color(p.active.background)), + text_color: p.active.text, + border: if let Some(color) = p.active.border { + Border { + radius: 25.0.into(), + width: 1.0, + color, + ..Default::default() + } + } else { + Border { + ..Default::default() + } + }, + ..Default::default() + }, + Status::Pressed => { + if let Some(pressed) = p.pressed { + Style { + background: Some(Background::Color(pressed.background)), + text_color: pressed.text, + border: if let Some(color) = pressed.border { + Border { + radius: 25.0.into(), + width: 1.0, + color, + ..Default::default() + } + } else { + Border { + ..Default::default() + } + }, + ..Default::default() + } + } else { + button(p, Status::Active) + } + } + Status::Hovered => Style { + background: Some(Background::Color(p.hovered.background)), + text_color: p.hovered.text, + border: if let Some(color) = p.hovered.border { + Border { + radius: 25.0.into(), + width: 1.0, + color, + ..Default::default() + } + } else { + Border { + ..Default::default() + } + }, + ..Default::default() + }, + Status::Disabled => { + if let Some(disabled) = p.disabled { + Style { + background: Some(Background::Color(disabled.background)), + text_color: disabled.text, + border: if let Some(color) = disabled.border { + Border { + radius: 25.0.into(), + width: 1.0, + color, + ..Default::default() + } + } else { + Border { + ..Default::default() + } + }, + ..Default::default() + } + } else { + let active: Style = button(p, Status::Active); + + Style { + text_color: Color { + a: 0.2, + ..active.text_color + }, + ..active + } + } + } + } +} diff --git a/liana-ui/src/theme/card.rs b/liana-ui/src/theme/card.rs new file mode 100644 index 000000000..9fad0a3a7 --- /dev/null +++ b/liana-ui/src/theme/card.rs @@ -0,0 +1,49 @@ +use iced::widget::container::Style; +use iced::{Background, Border}; + +use super::palette::ContainerPalette; +use super::Theme; + +fn card(palette: &ContainerPalette) -> Style { + Style { + background: Some(Background::Color(palette.background)), + text_color: palette.text, + border: if let Some(color) = palette.border { + Border { + radius: 25.0.into(), + width: 1.0, + color, + ..Default::default() + } + } else { + Border { + ..Default::default() + } + }, + ..Default::default() + } +} + +pub fn simple(theme: &Theme) -> Style { + card(&theme.colors.cards.simple) +} + +pub fn modal(theme: &Theme) -> Style { + card(&theme.colors.cards.modal) +} + +pub fn border(theme: &Theme) -> Style { + card(&theme.colors.cards.border) +} + +pub fn invalid(theme: &Theme) -> Style { + card(&theme.colors.cards.invalid) +} + +pub fn warning(theme: &Theme) -> Style { + card(&theme.colors.cards.warning) +} + +pub fn error(theme: &Theme) -> Style { + card(&theme.colors.cards.error) +} diff --git a/liana-ui/src/theme/checkbox.rs b/liana-ui/src/theme/checkbox.rs new file mode 100644 index 000000000..d4977784b --- /dev/null +++ b/liana-ui/src/theme/checkbox.rs @@ -0,0 +1,37 @@ +use iced::{ + widget::checkbox::{Catalog, Status, Style, StyleFn}, + Border, +}; + +use super::Theme; + +impl Catalog for Theme { + type Class<'a> = StyleFn<'a, Self>; + + fn default<'a>() -> ::Class<'a> { + Box::new(primary) + } + + fn style(&self, class: &::Class<'_>, status: Status) -> Style { + class(self, status) + } +} + +pub fn primary(theme: &Theme, _status: Status) -> Style { + Style { + icon_color: theme.colors.checkboxes.icon, + text_color: theme.colors.checkboxes.text.into(), + background: theme.colors.cards.simple.background.into(), + border: if let Some(color) = theme.colors.checkboxes.border { + Border { + radius: 25.0.into(), + width: 1.0, + color, + } + } else { + Border { + ..Default::default() + } + }, + } +} diff --git a/liana-ui/src/theme/container.rs b/liana-ui/src/theme/container.rs new file mode 100644 index 000000000..326dee0be --- /dev/null +++ b/liana-ui/src/theme/container.rs @@ -0,0 +1,44 @@ +use iced::widget::container::{transparent, Catalog, Style, StyleFn}; +use iced::Background; + +use super::Theme; + +impl Catalog for Theme { + type Class<'a> = StyleFn<'a, Self>; + + fn default<'a>() -> Self::Class<'a> { + Box::new(transparent) + } + + fn style(&self, class: &Self::Class<'_>) -> Style { + class(self) + } +} + +pub fn background(theme: &Theme) -> Style { + Style { + background: Some(Background::Color(theme.colors.general.background)), + ..Default::default() + } +} + +pub fn foreground(theme: &Theme) -> Style { + Style { + background: Some(Background::Color(theme.colors.general.foreground)), + ..Default::default() + } +} + +pub fn border(theme: &Theme) -> Style { + Style { + background: Some(Background::Color(theme.colors.general.background)), + ..Default::default() + } +} + +pub fn custom(color: iced::Color) -> Box Style> { + Box::new(move |_theme: &Theme| Style { + background: Some(Background::Color(color)), + ..Default::default() + }) +} diff --git a/liana-ui/src/theme/mod.rs b/liana-ui/src/theme/mod.rs new file mode 100644 index 000000000..1626b835e --- /dev/null +++ b/liana-ui/src/theme/mod.rs @@ -0,0 +1,33 @@ +pub mod badge; +pub mod banner; +pub mod button; +pub mod card; +pub mod checkbox; +pub mod container; +pub mod notification; +pub mod overlay; +pub mod palette; +pub mod pick_list; +pub mod pill; +pub mod progress_bar; +pub mod qr_code; +pub mod radio; +pub mod scrollable; +pub mod slider; +pub mod svg; +pub mod text; +pub mod text_input; + +#[derive(Debug, Copy, Clone, PartialEq, Default)] +pub struct Theme { + colors: palette::Palette, +} + +impl iced::application::DefaultStyle for Theme { + fn default_style(&self) -> iced::application::Appearance { + iced::application::Appearance { + background_color: self.colors.general.background, + text_color: self.colors.text.primary, + } + } +} diff --git a/liana-ui/src/theme/notification.rs b/liana-ui/src/theme/notification.rs new file mode 100644 index 000000000..cda95f714 --- /dev/null +++ b/liana-ui/src/theme/notification.rs @@ -0,0 +1,33 @@ +use iced::widget::container::Style; +use iced::{Background, Border}; + +use super::palette::ContainerPalette; +use super::Theme; + +fn notification(palette: &ContainerPalette) -> Style { + Style { + background: Some(Background::Color(palette.background)), + text_color: palette.text, + border: if let Some(color) = palette.border { + Border { + width: 1.0, + color, + radius: 25.0.into(), + ..Default::default() + } + } else { + Border { + ..Default::default() + } + }, + ..Default::default() + } +} + +pub fn pending(theme: &Theme) -> Style { + notification(&theme.colors.notifications.pending) +} + +pub fn error(theme: &Theme) -> Style { + notification(&theme.colors.notifications.error) +} diff --git a/liana-ui/src/theme/overlay.rs b/liana-ui/src/theme/overlay.rs new file mode 100644 index 000000000..c4c7befb5 --- /dev/null +++ b/liana-ui/src/theme/overlay.rs @@ -0,0 +1,48 @@ +use iced::{ + widget::overlay::menu::{Catalog, Style, StyleFn}, + Border, +}; + +use super::Theme; + +impl Catalog for Theme { + type Class<'a> = StyleFn<'a, Self>; + + fn default<'a>() -> ::Class<'a> { + Box::new(primary) + } + + fn style(&self, class: &::Class<'_>) -> Style { + class(self) + } +} + +pub fn primary(theme: &Theme) -> Style { + Style { + text_color: theme + .colors + .cards + .simple + .text + .unwrap_or(theme.colors.text.primary), + selected_text_color: theme + .colors + .cards + .simple + .text + .unwrap_or(theme.colors.text.secondary), + background: theme.colors.cards.simple.background.into(), + selected_background: theme.colors.cards.simple.background.into(), + border: if let Some(color) = theme.colors.cards.simple.border { + Border { + radius: 25.0.into(), + width: 1.0, + color, + } + } else { + Border { + ..Default::default() + } + }, + } +} diff --git a/liana-ui/src/theme/palette.rs b/liana-ui/src/theme/palette.rs new file mode 100644 index 000000000..58af6a14d --- /dev/null +++ b/liana-ui/src/theme/palette.rs @@ -0,0 +1,156 @@ +#[derive(Debug, Copy, Clone, PartialEq, Default)] +pub struct Palette { + pub general: General, + pub text: Text, + pub buttons: Buttons, + pub cards: Cards, + pub banners: Banners, + pub badges: Badges, + pub pills: Pills, + pub notifications: Notifications, + pub text_inputs: TextInputs, + pub svgs: SVGs, + pub checkboxes: Checkboxes, + pub radio_buttons: RadioButtons, + pub sliders: Sliders, +} + +#[derive(Debug, Copy, Clone, PartialEq, Default)] +pub struct Text { + pub primary: iced::Color, + pub secondary: iced::Color, + pub warning: iced::Color, + pub error: iced::Color, +} + +#[derive(Debug, Copy, Clone, PartialEq, Default)] +pub struct General { + pub background: iced::Color, + pub foreground: iced::Color, + pub scrollable: iced::Color, +} + +#[derive(Debug, Copy, Clone, PartialEq, Default)] +pub struct Buttons { + pub transparent: Button, + pub transparent_border: Button, + pub primary: Button, + pub secondary: Button, + pub destructive: Button, + pub container: Button, + pub container_border: Button, + pub menu: Button, +} + +#[derive(Debug, Copy, Clone, PartialEq, Default)] +pub struct Button { + pub active: ButtonPalette, + pub hovered: ButtonPalette, + pub pressed: Option, + pub disabled: Option, +} + +#[derive(Debug, Copy, Clone, PartialEq, Default)] +pub struct ButtonPalette { + pub background: iced::Color, + pub text: iced::Color, + pub border: Option, +} + +#[derive(Debug, Copy, Clone, PartialEq, Default)] +pub struct Containers { + pub border: ContainerPalette, +} + +#[derive(Debug, Copy, Clone, PartialEq, Default)] +pub struct ContainerPalette { + pub background: iced::Color, + pub text: Option, + pub border: Option, +} + +#[derive(Debug, Copy, Clone, PartialEq, Default)] +pub struct Cards { + pub transparent: ContainerPalette, + pub simple: ContainerPalette, + pub modal: ContainerPalette, + pub border: ContainerPalette, + pub invalid: ContainerPalette, + pub warning: ContainerPalette, + pub error: ContainerPalette, +} + +#[derive(Debug, Copy, Clone, PartialEq, Default)] +pub struct Banners { + pub network: ContainerPalette, + pub warning: ContainerPalette, +} + +#[derive(Debug, Copy, Clone, PartialEq, Default)] +pub struct Badges { + pub simple: ContainerPalette, + pub bitcoin: ContainerPalette, +} + +#[derive(Debug, Copy, Clone, PartialEq, Default)] +pub struct Pills { + pub simple: ContainerPalette, + pub primary: ContainerPalette, + pub success: ContainerPalette, + pub warning: ContainerPalette, +} + +#[derive(Debug, Copy, Clone, PartialEq, Default)] +pub struct Notifications { + pub pending: ContainerPalette, + pub error: ContainerPalette, +} + +#[derive(Debug, Copy, Clone, PartialEq, Default)] +pub struct TextInputs { + pub primary: TextInput, + pub invalid: TextInput, +} + +#[derive(Debug, Copy, Clone, PartialEq, Default)] +pub struct TextInput { + pub active: TextInputPalette, + pub disabled: TextInputPalette, +} + +#[derive(Debug, Copy, Clone, PartialEq, Default)] +pub struct TextInputPalette { + pub background: iced::Color, + pub text: iced::Color, + pub placeholder: iced::Color, + pub value: iced::Color, + pub selection: iced::Color, + pub border: Option, +} + +#[derive(Debug, Copy, Clone, PartialEq, Default)] +pub struct SVGs { + pub primary: iced::Color, +} + +#[derive(Debug, Copy, Clone, PartialEq, Default)] +pub struct Checkboxes { + pub icon: iced::Color, + pub text: iced::Color, + pub border: Option, +} + +#[derive(Debug, Copy, Clone, PartialEq, Default)] +pub struct RadioButtons { + pub dot: iced::Color, + pub text: iced::Color, + pub border: iced::Color, +} + +#[derive(Debug, Copy, Clone, PartialEq, Default)] +pub struct Sliders { + pub background: iced::Color, + pub border: iced::Color, + pub rail_border: Option, + pub rail_backgrounds: (iced::Color, iced::Color), +} diff --git a/liana-ui/src/theme/pick_list.rs b/liana-ui/src/theme/pick_list.rs new file mode 100644 index 000000000..77cef7142 --- /dev/null +++ b/liana-ui/src/theme/pick_list.rs @@ -0,0 +1,48 @@ +use iced::{ + widget::pick_list::{Catalog, Status, Style, StyleFn}, + Border, +}; + +use super::Theme; + +impl Catalog for Theme { + type Class<'a> = StyleFn<'a, Self>; + + fn default<'a>() -> ::Class<'a> { + Box::new(primary) + } + + fn style(&self, class: &::Class<'_>, status: Status) -> Style { + class(self, status) + } +} + +pub fn primary(theme: &Theme, _status: Status) -> Style { + Style { + text_color: theme + .colors + .cards + .simple + .text + .unwrap_or(theme.colors.text.primary), + placeholder_color: theme.colors.cards.simple.background, + background: theme.colors.cards.simple.background.into(), + border: if let Some(color) = theme.colors.cards.simple.border { + Border { + radius: 25.0.into(), + width: 1.0, + color, + } + } else { + Border { + ..Default::default() + } + }, + handle_color: theme + .colors + .cards + .simple + .text + .unwrap_or(theme.colors.text.primary), + } +} diff --git a/liana-ui/src/theme/pill.rs b/liana-ui/src/theme/pill.rs new file mode 100644 index 000000000..e14652d2d --- /dev/null +++ b/liana-ui/src/theme/pill.rs @@ -0,0 +1,35 @@ +use iced::widget::container::Style; +use iced::{Background, Border}; + +use super::palette::ContainerPalette; +use super::Theme; + +fn pill(palette: &ContainerPalette) -> Style { + Style { + background: Some(Background::Color(palette.background)), + text_color: palette.text, + border: Border { + radius: 25.0.into(), + width: 0.0, + color: palette.border.unwrap_or_default(), + ..Default::default() + }, + ..Default::default() + } +} + +pub fn simple(theme: &Theme) -> Style { + pill(&theme.colors.pills.simple) +} + +pub fn primary(theme: &Theme) -> Style { + pill(&theme.colors.pills.primary) +} + +pub fn success(theme: &Theme) -> Style { + pill(&theme.colors.pills.success) +} + +pub fn warning(theme: &Theme) -> Style { + pill(&theme.colors.pills.warning) +} diff --git a/liana-ui/src/theme/progress_bar.rs b/liana-ui/src/theme/progress_bar.rs new file mode 100644 index 000000000..753267c0f --- /dev/null +++ b/liana-ui/src/theme/progress_bar.rs @@ -0,0 +1,36 @@ +use iced::{ + widget::progress_bar::{Catalog, Style, StyleFn}, + Border, +}; + +use super::Theme; + +impl Catalog for Theme { + type Class<'a> = StyleFn<'a, Self>; + + fn default<'a>() -> ::Class<'a> { + Box::new(primary) + } + + fn style(&self, class: &::Class<'_>) -> Style { + class(self) + } +} + +pub fn primary(theme: &Theme) -> Style { + Style { + background: theme.colors.cards.simple.background.into(), + bar: theme.colors.cards.simple.background.into(), + border: if let Some(color) = theme.colors.cards.simple.border { + Border { + radius: 25.0.into(), + width: 1.0, + color, + } + } else { + Border { + ..Default::default() + } + }, + } +} diff --git a/liana-ui/src/theme/qr_code.rs b/liana-ui/src/theme/qr_code.rs new file mode 100644 index 000000000..72bc25527 --- /dev/null +++ b/liana-ui/src/theme/qr_code.rs @@ -0,0 +1,22 @@ +use iced::widget::qr_code::{Catalog, Style, StyleFn}; + +use super::Theme; + +impl Catalog for Theme { + type Class<'a> = StyleFn<'a, Self>; + + fn default<'a>() -> Self::Class<'a> { + Box::new(qr_code) + } + + fn style(&self, class: &Self::Class<'_>) -> Style { + class(self) + } +} + +pub fn qr_code(_theme: &Theme) -> Style { + Style { + background: iced::Color::WHITE, + cell: iced::Color::BLACK, + } +} diff --git a/liana-ui/src/theme/radio.rs b/liana-ui/src/theme/radio.rs new file mode 100644 index 000000000..647268fd2 --- /dev/null +++ b/liana-ui/src/theme/radio.rs @@ -0,0 +1,25 @@ +use iced::widget::radio::{Catalog, Status, Style, StyleFn}; + +use super::Theme; + +impl Catalog for Theme { + type Class<'a> = StyleFn<'a, Self>; + + fn default<'a>() -> ::Class<'a> { + Box::new(primary) + } + + fn style(&self, class: &::Class<'_>, status: Status) -> Style { + class(self, status) + } +} + +pub fn primary(theme: &Theme, _status: Status) -> Style { + Style { + dot_color: theme.colors.radio_buttons.dot, + text_color: theme.colors.radio_buttons.text.into(), + background: theme.colors.cards.simple.background.into(), + border_width: 1.0, + border_color: theme.colors.radio_buttons.border, + } +} diff --git a/liana-ui/src/theme/scrollable.rs b/liana-ui/src/theme/scrollable.rs new file mode 100644 index 000000000..c8455c49d --- /dev/null +++ b/liana-ui/src/theme/scrollable.rs @@ -0,0 +1,54 @@ +use iced::{ + widget::{ + container, + scrollable::{Catalog, Rail, Scroller, Status, Style, StyleFn}, + }, + Border, Color, Shadow, +}; + +use super::Theme; + +impl Catalog for Theme { + type Class<'a> = StyleFn<'a, Self>; + + fn default<'a>() -> Self::Class<'a> { + Box::new(primary) + } + + fn style(&self, class: &Self::Class<'_>, status: Status) -> Style { + class(self, status) + } +} + +pub fn primary(theme: &Theme, status: Status) -> Style { + let rail = Rail { + background: None, + border: Border::default(), + scroller: Scroller { + color: theme.colors.general.scrollable, + border: Border { + radius: 8.0.into(), + width: 0.0, + color: Color::TRANSPARENT, + }, + }, + }; + + match status { + Status::Active { .. } | Status::Hovered { .. } | Status::Dragged { .. } => Style { + container: container::Style { + text_color: None, + background: None, + border: Border { + radius: 8.0.into(), + width: 1.0, + color: Color::TRANSPARENT, + }, + shadow: Shadow::default(), + }, + vertical_rail: rail, + horizontal_rail: rail, + gap: None, + }, + } +} diff --git a/liana-ui/src/theme/slider.rs b/liana-ui/src/theme/slider.rs new file mode 100644 index 000000000..a71f14958 --- /dev/null +++ b/liana-ui/src/theme/slider.rs @@ -0,0 +1,50 @@ +use iced::{ + widget::slider::{Catalog, Handle, HandleShape, Rail, Status, Style, StyleFn}, + Border, +}; + +use super::Theme; + +impl Catalog for Theme { + type Class<'a> = StyleFn<'a, Self>; + + fn default<'a>() -> Self::Class<'a> { + Box::new(slider) + } + + fn style(&self, class: &Self::Class<'_>, status: Status) -> Style { + class(self, status) + } +} + +pub fn slider(theme: &Theme, _status: Status) -> Style { + Style { + rail: Rail { + backgrounds: ( + theme.colors.sliders.rail_backgrounds.0.into(), + theme.colors.sliders.rail_backgrounds.1.into(), + ), + border: if let Some(color) = theme.colors.sliders.rail_border { + Border { + color, + width: 1.0, + radius: 4.0.into(), + } + } else { + Border { + ..Default::default() + } + }, + width: 2.0, + }, + handle: Handle { + shape: HandleShape::Rectangle { + width: 8, + border_radius: 4.0.into(), + }, + background: theme.colors.sliders.background.into(), + border_color: theme.colors.sliders.border, + border_width: 1.0, + }, + } +} diff --git a/liana-ui/src/theme/svg.rs b/liana-ui/src/theme/svg.rs new file mode 100644 index 000000000..161d159ef --- /dev/null +++ b/liana-ui/src/theme/svg.rs @@ -0,0 +1,21 @@ +use iced::widget::svg::{Catalog, Status, Style, StyleFn}; + +use super::Theme; + +impl Catalog for Theme { + type Class<'a> = StyleFn<'a, Self>; + + fn default<'a>() -> Self::Class<'a> { + Box::new(default) + } + + fn style(&self, class: &Self::Class<'_>, status: Status) -> Style { + class(self, status) + } +} + +pub fn default(theme: &Theme, _status: Status) -> Style { + Style { + color: Some(theme.colors.svgs.primary), + } +} diff --git a/liana-ui/src/theme/text.rs b/liana-ui/src/theme/text.rs new file mode 100644 index 000000000..2d61d6811 --- /dev/null +++ b/liana-ui/src/theme/text.rs @@ -0,0 +1,27 @@ +use iced::widget::text::{Catalog, Style, StyleFn}; + +use super::Theme; + +impl Catalog for Theme { + type Class<'a> = StyleFn<'a, Self>; + + fn default<'a>() -> Self::Class<'a> { + Box::new(primary) + } + + fn style(&self, class: &Self::Class<'_>) -> Style { + class(self) + } +} + +pub fn primary(theme: &Theme) -> Style { + Style { + color: Some(theme.colors.text.primary), + } +} + +pub fn secondary(theme: &Theme) -> Style { + Style { + color: Some(theme.colors.text.primary), + } +} diff --git a/liana-ui/src/theme/text_input.rs b/liana-ui/src/theme/text_input.rs new file mode 100644 index 000000000..18a21e7f1 --- /dev/null +++ b/liana-ui/src/theme/text_input.rs @@ -0,0 +1,65 @@ +use iced::{ + widget::text_input::{Catalog, Status, Style, StyleFn}, + Background, Border, +}; + +use super::{palette::TextInput, Theme}; + +impl Catalog for Theme { + type Class<'a> = StyleFn<'a, Self>; + + fn default<'a>() -> Self::Class<'a> { + Box::new(primary) + } + + fn style(&self, class: &Self::Class<'_>, status: Status) -> Style { + class(self, status) + } +} + +pub fn primary(theme: &Theme, status: Status) -> Style { + text_input(&theme.colors.text_inputs.primary, status) +} + +pub fn invalid(theme: &Theme, status: Status) -> Style { + text_input(&theme.colors.text_inputs.invalid, status) +} + +fn text_input(c: &TextInput, status: Status) -> Style { + let active = Style { + background: Background::Color(c.active.background), + border: if let Some(color) = c.active.border { + Border { + radius: 25.0.into(), + width: 1.0, + color, + } + } else { + Border::default() + }, + icon: c.active.text, + placeholder: c.active.placeholder, + value: c.active.value, + selection: c.active.selection, + }; + + match status { + Status::Active | Status::Hovered | Status::Focused { .. } => active, + Status::Disabled => Style { + background: Background::Color(c.disabled.background), + border: if let Some(color) = c.disabled.border { + Border { + radius: 25.0.into(), + width: 1.0, + color, + } + } else { + Border::default() + }, + icon: c.disabled.text, + placeholder: c.disabled.placeholder, + value: c.disabled.value, + selection: c.disabled.selection, + }, + } +}