From 8dcac818efbf18bbbabf59679855ba71fe1d755b Mon Sep 17 00:00:00 2001 From: Suyog Tandel Date: Sat, 21 Feb 2026 22:46:22 +0530 Subject: [PATCH] feat(ui): extract dialogs into a custom component --- Cargo.lock | 186 +++++++++++++++++------------------ Cargo.toml | 2 +- flake.lock | 6 +- src/ui/components/dialog.rs | 185 ++++++++++++++++++++++++++++++++++ src/ui/components/mod.rs | 1 + src/ui/views/config.rs | 70 ++++--------- src/ui/views/passkeys.rs | 191 ++++++++---------------------------- 7 files changed, 343 insertions(+), 298 deletions(-) create mode 100644 src/ui/components/dialog.rs diff --git a/Cargo.lock b/Cargo.lock index 5c323e6..6e8ffe0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -71,9 +71,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.101" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "ar_archive_writer" @@ -107,7 +107,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -180,9 +180,9 @@ dependencies = [ [[package]] name = "ashpd" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "522dc9bec59923af17c43c5911cdabbacdb32ed4f955e83ecf592855618b20b5" +checksum = "33a3c86f3fd70c0ffa500ed189abfa90b5a52398a45d5dc372fcc38ebeb7a645" dependencies = [ "async-fs", "async-net", @@ -220,7 +220,7 @@ checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", "synstructure", ] @@ -232,7 +232,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -272,9 +272,9 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.39" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68650b7df54f0293fd061972a0fb05aaf4fc0879d3b3d21a638a182c5c543b9f" +checksum = "7d67d43201f4d20c78bcda740c142ca52482d81da80681533d33bf3f0596c8e2" dependencies = [ "compression-codecs", "compression-core", @@ -388,7 +388,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -450,7 +450,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -556,7 +556,7 @@ dependencies = [ "regex", "rustc-hash 2.1.1", "shlex", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -644,7 +644,7 @@ checksum = "27142319e2f4c264581067eaccb9f80acccdde60d8b4bf57cc50cd3152f109ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -723,9 +723,9 @@ checksum = "f4ad8f11f288f48ca24471bbd51ac257aaeaaa07adae295591266b792902ae64" [[package]] name = "bumpalo" -version = "3.19.1" +version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" [[package]] name = "bytemuck" @@ -744,7 +744,7 @@ checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -813,7 +813,7 @@ dependencies = [ "quote", "serde", "serde_json", - "syn 2.0.116", + "syn 2.0.117", "tempfile", "toml 0.8.23", ] @@ -1022,9 +1022,9 @@ dependencies = [ [[package]] name = "compression-codecs" -version = "0.4.36" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00828ba6fd27b45a448e57dbfe84f1029d4c9f26b368157e9a448a5f49a2ec2a" +checksum = "eb7b51a7d9c967fc26773061ba86150f19c50c0d65c887cb1fbe295fd16619b7" dependencies = [ "compression-core", "deflate64", @@ -1391,9 +1391,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.5.6" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc3dc5ad92c2e2d1c193bbbbdf2ea477cb81331de4f3103f267ca18368b988c4" +checksum = "2163a0e204a148662b6b6816d4b5d5668a5f2f8df498ccbd5cd0e864e78fecba" dependencies = [ "powerfmt", ] @@ -1408,7 +1408,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -1429,7 +1429,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.116", + "syn 2.0.117", "unicode-xid", ] @@ -1536,7 +1536,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -1645,7 +1645,7 @@ checksum = "685adfa4d6f3d765a26bc5dbc936577de9abf756c1feeb3089b01dd395034842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -1666,7 +1666,7 @@ checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -1686,7 +1686,7 @@ checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -1809,7 +1809,7 @@ checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -1974,7 +1974,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -2106,7 +2106,7 @@ checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -2435,7 +2435,7 @@ source = "git+https://github.com/librekeys/gpui-component?branch=fix%2Fclient-wi dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -2447,7 +2447,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -2468,7 +2468,7 @@ checksum = "644de174341a87b3478bd65b66bca38af868bcf2b2e865700523734f83cfc664" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -2598,7 +2598,7 @@ checksum = "2c28f65ef47fb97e21e82fd4dd75ccc2506eda010c846dc8054015ea234f1a22" dependencies = [ "gpui_perf", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -2751,7 +2751,7 @@ dependencies = [ "markup5ever", "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -3111,14 +3111,14 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] name = "inventory" -version = "0.3.21" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc61209c082fbeb19919bee74b176221b27223e27b65d781eb91af24eb1fb46e" +checksum = "009ae045c87e7082cb72dab0ccd01ae075dd00141ddc108f43a0ea150a9e7227" dependencies = [ "rustversion", ] @@ -3205,9 +3205,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.85" +version = "0.3.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +checksum = "93f0862381daaec758576dcc22eb7bbf4d7efd67328553f3b45a412a51a3fb21" dependencies = [ "once_cell", "wasm-bindgen", @@ -3868,7 +3868,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -4080,7 +4080,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3299dd401feaf1d45afd8fd1c0586f10fcfb22f244bb9afa942cec73503b89d" dependencies = [ "aes", - "ashpd 0.12.2", + "ashpd 0.12.3", "async-fs", "async-io", "async-lock", @@ -4346,7 +4346,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -4478,7 +4478,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -4509,7 +4509,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -4537,7 +4537,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b" dependencies = [ "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -4908,7 +4908,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -5012,7 +5012,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.116", + "syn 2.0.117", "walkdir", ] @@ -5055,7 +5055,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -5281,7 +5281,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -5327,9 +5327,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "security-framework" -version = "3.6.0" +version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d17b898a6d6948c3a8ee4372c17cb384f90d2e6e912ef00895b14fd7ab54ec38" +checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ "bitflags 2.11.0", "core-foundation 0.10.0", @@ -5340,9 +5340,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.16.0" +version = "2.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "321c8673b092a9a42605034a9879d73cb79101ed5fd117bc9a597b89b4e9e61a" +checksum = "6ce2691df843ecc5d231c0b14ece2acc3efb62c0a398c7e1d875f3983ce020e3" dependencies = [ "core-foundation-sys", "libc", @@ -5407,7 +5407,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -5418,7 +5418,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -5465,7 +5465,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -5693,7 +5693,7 @@ checksum = "172175341049678163e979d9107ca3508046d4d2a7c6682bee46ac541b17db69" dependencies = [ "proc-macro-error2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -5776,7 +5776,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -5788,7 +5788,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -5915,9 +5915,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.116" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3df424c70518695237746f84cede799c9c58fcb37450d7b23716568cc8bc69cb" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -5941,7 +5941,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -6077,7 +6077,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -6088,7 +6088,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -6393,7 +6393,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -6811,9 +6811,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.108" +version = "0.2.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" +checksum = "1de241cdc66a9d91bd84f097039eb140cdc6eec47e0cdbaf9d932a1dd6c35866" dependencies = [ "cfg-if", "once_cell", @@ -6824,9 +6824,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.58" +version = "0.4.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" +checksum = "a42e96ea38f49b191e08a1bab66c7ffdba24b06f9995b39a9dd60222e5b6f1da" dependencies = [ "cfg-if", "futures-util", @@ -6838,9 +6838,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.108" +version = "0.2.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" +checksum = "e12fdf6649048f2e3de6d7d5ff3ced779cdedee0e0baffd7dff5cdfa3abc8a52" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6848,22 +6848,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.108" +version = "0.2.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" +checksum = "0e63d1795c565ac3462334c1e396fd46dbf481c40f51f5072c310717bc4fb309" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.108" +version = "0.2.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +checksum = "e9f9cdac23a5ce71f6bf9f8824898a501e511892791ea2a0c6b8568c68b9cb53" dependencies = [ "unicode-ident", ] @@ -7014,9 +7014,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.85" +version = "0.3.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" +checksum = "f2c7c5718134e770ee62af3b6b4a84518ec10101aad610c024b64d6ff29bb1ff" dependencies = [ "js-sys", "wasm-bindgen", @@ -7183,7 +7183,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -7194,7 +7194,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -7205,7 +7205,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -7216,7 +7216,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -7621,7 +7621,7 @@ dependencies = [ "heck 0.5.0", "indexmap", "prettyplease", - "syn 2.0.116", + "syn 2.0.117", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -7637,7 +7637,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -7870,7 +7870,7 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", "synstructure", ] @@ -7918,7 +7918,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", "zbus_names", "zvariant", "zvariant_utils", @@ -8095,7 +8095,7 @@ checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -8115,7 +8115,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", "synstructure", ] @@ -8136,7 +8136,7 @@ checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -8169,7 +8169,7 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", ] [[package]] @@ -8241,7 +8241,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.116", + "syn 2.0.117", "zvariant_utils", ] @@ -8254,6 +8254,6 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.116", + "syn 2.0.117", "winnow", ] diff --git a/Cargo.toml b/Cargo.toml index db6712a..eb89f36 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ directories = "6" # For Applcation config/data dir handling # For device management backend: pcsc = "2" # Standard Smart Card API (connect to the key) -hex = "0.4" # For parsing "CAFE:4242" VID/PID strings +hex = "0.4" # For parsing VID/PID strings byteorder = "1.5" # Required for writing Big-Endian numbers (firmware requirement) thiserror = "2" # Makes custom error handling much easier anyhow = "1" # For easy error propagation diff --git a/flake.lock b/flake.lock index a24d615..7225bec 100644 --- a/flake.lock +++ b/flake.lock @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1771008912, - "narHash": "sha256-gf2AmWVTs8lEq7z/3ZAsgnZDhWIckkb+ZnAo5RzSxJg=", + "lastModified": 1771369470, + "narHash": "sha256-0NBlEBKkN3lufyvFegY4TYv5mCNHbi5OmBDrzihbBMQ=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "a82ccc39b39b621151d6732718e3e250109076fa", + "rev": "0182a361324364ae3f436a63005877674cf45efb", "type": "github" }, "original": { diff --git a/src/ui/components/dialog.rs b/src/ui/components/dialog.rs new file mode 100644 index 0000000..c590fc2 --- /dev/null +++ b/src/ui/components/dialog.rs @@ -0,0 +1,185 @@ +use gpui::*; +use gpui_component::{ + WindowExt, + button::{Button, ButtonVariant, ButtonVariants}, + dialog::DialogButtonProps, + input::{Input, InputState}, + v_flex, +}; + +pub fn open_pin_prompt( + title: &str, + description: &str, + confirm_label: &str, + window: &mut Window, + cx: &mut App, + on_confirm: impl Fn(String, &mut Window, &mut App) + 'static, +) { + let title = SharedString::from(title.to_string()); + let description = SharedString::from(description.to_string()); + let confirm_label = SharedString::from(confirm_label.to_string()); + + let pin_input = cx.new(|cx| { + InputState::new(window, cx) + .placeholder("Enter FIDO PIN") + .masked(true) + }); + + let on_confirm = std::rc::Rc::new(on_confirm); + + window.open_dialog(cx, move |dialog, _, _| { + let pin_input_for_footer = pin_input.clone(); + let confirm_label = confirm_label.clone(); + let on_confirm = on_confirm.clone(); + + dialog + .title(title.clone()) + .child( + v_flex() + .gap_4() + .pb_4() + .child(description.clone()) + .child(Input::new(&pin_input)), + ) + .footer(move |_, _, _, _| { + let input = pin_input_for_footer.clone(); + let on_confirm = on_confirm.clone(); + + vec![ + Button::new("cancel") + .label("Cancel") + .on_click(|_, window, cx| { + window.close_dialog(cx); + }), + Button::new("confirm") + .primary() + .label(confirm_label.clone()) + .on_click(move |_, window, cx| { + let pin = input.read(cx).text().to_string(); + if !pin.is_empty() { + window.close_dialog(cx); + on_confirm(pin, window, cx); + } + }), + ] + }) + }); +} + +pub fn open_confirm( + title: &str, + message: String, + ok_label: &str, + ok_variant: ButtonVariant, + window: &mut Window, + cx: &mut App, + on_ok: impl Fn(&mut Window, &mut App) + 'static, +) { + let title = SharedString::from(title.to_string()); + let ok_label = SharedString::from(ok_label.to_string()); + let on_ok = std::rc::Rc::new(on_ok); + + window.open_dialog(cx, move |dialog, _, _| { + let on_ok = on_ok.clone(); + + dialog + .confirm() + .title(title.clone()) + .child(div().pb_4().child(message.clone())) + .on_ok(move |_, window, cx| { + on_ok(window, cx); + false + }) + .on_cancel(|_, _, _| true) + .button_props( + DialogButtonProps::default() + .ok_text(ok_label.clone()) + .ok_variant(ok_variant), + ) + }); +} + +pub fn open_change_pin( + window: &mut Window, + cx: &mut App, + on_error: impl Fn(&str, &mut App) + 'static + Clone, + on_confirm: impl Fn(String, String, &mut App) + 'static, +) { + let current_pin = cx.new(|cx| { + InputState::new(window, cx) + .placeholder("Enter current PIN") + .masked(true) + }); + let new_pin = cx.new(|cx| { + InputState::new(window, cx) + .placeholder("Enter new PIN") + .masked(true) + }); + let confirm_pin = cx.new(|cx| { + InputState::new(window, cx) + .placeholder("Confirm new PIN") + .masked(true) + }); + + let on_confirm = std::rc::Rc::new(on_confirm); + + window.open_dialog(cx, move |dialog, _, _| { + let current = current_pin.clone(); + let new = new_pin.clone(); + let confirm = confirm_pin.clone(); + let on_error = on_error.clone(); + let on_confirm = on_confirm.clone(); + + dialog + .title("Change PIN") + .child("Enter your current PIN and choose a new one.") + .child( + v_flex() + .gap_4() + .pb_4() + .child("Current PIN") + .child(Input::new(¤t)) + .child("New PIN") + .child(Input::new(&new)) + .child("Confirm New PIN") + .child(Input::new(&confirm)), + ) + .footer(move |_, _window, _cx, _| { + let current = current.clone(); + let new = new.clone(); + let confirm = confirm.clone(); + let on_error = on_error.clone(); + let on_confirm = on_confirm.clone(); + + vec![ + Button::new("cancel") + .label("Cancel") + .on_click(|_, window, cx| window.close_dialog(cx)), + Button::new("confirm") + .primary() + .label("Confirm") + .on_click(move |_, _, cx| { + let current_val = current.read(cx).text().to_string(); + let new_val = new.read(cx).text().to_string(); + let confirm_val = confirm.read(cx).text().to_string(); + + if current_val.is_empty() { + return; + } + + if new_val != confirm_val { + on_error("PINs do not match", cx); + return; + } + + if new_val.len() < 4 { + on_error("PIN too short", cx); + return; + } + + on_confirm(current_val, new_val, cx); + }), + ] + }) + }); +} diff --git a/src/ui/components/mod.rs b/src/ui/components/mod.rs index 4f4ac29..debf487 100644 --- a/src/ui/components/mod.rs +++ b/src/ui/components/mod.rs @@ -1,4 +1,5 @@ pub mod button; pub mod card; +pub mod dialog; pub mod page_view; pub mod sidebar; diff --git a/src/ui/views/config.rs b/src/ui/views/config.rs index c8a7fb3..1119aed 100644 --- a/src/ui/views/config.rs +++ b/src/ui/views/config.rs @@ -1,11 +1,11 @@ use crate::device::io; use crate::device::types::{AppConfigInput, FullDeviceStatus}; -use crate::ui::components::{card::Card, page_view::PageView}; +use crate::ui::components::{card::Card, dialog, page_view::PageView}; use crate::ui::types::{LedDriverType, UsbIdentityPreset}; use gpui::*; use gpui_component::button::{ButtonCustomVariant, ButtonVariants}; use gpui_component::{ - ActiveTheme, Disableable, Icon, Theme, WindowExt, + ActiveTheme, Disableable, Icon, Theme, button::Button, input::{Input, InputState}, select::{Select, SelectItem, SelectState}, @@ -274,57 +274,25 @@ impl ConfigView { window: &mut Window, cx: &mut Context, ) { - let pin_input = cx.new(|cx| { - InputState::new(window, cx) - .placeholder("Enter FIDO PIN") - .masked(true) - }); let view_handle = cx.entity().downgrade(); - window.open_dialog(cx, move |dialog, _, _| { - let view_handle_for_footer = view_handle.clone(); - let pin_input_for_footer = pin_input.clone(); - let changes = changes.clone(); - - dialog - .title("Authentication Required") - .child( - v_flex() - .gap_4() - .pb_4() - .child("Enter your device PIN to apply changes.") - .child(Input::new(&pin_input)), - ) - .footer(move |_, _, _, _| { - let view = view_handle_for_footer.clone(); - let input = pin_input_for_footer.clone(); - let changes = changes.clone(); - - vec![ - Button::new("cancel") - .label("Cancel") - .on_click(|_, window, cx| { - window.close_dialog(cx); - }), - Button::new("confirm").primary().label("Confirm").on_click( - move |_, window, cx| { - let pin = input.read(cx).text().to_string(); - if !pin.is_empty() { - window.close_dialog(cx); - let _ = view.update(cx, |this, cx| { - this.write_config_to_device( - changes.clone(), - crate::device::types::DeviceMethod::Fido, - Some(pin), - cx, - ); - }); - } - }, - ), - ] - }) - }); + dialog::open_pin_prompt( + "Authentication Required", + "Enter your device PIN to apply changes.", + "Confirm", + window, + cx, + move |pin, _, cx| { + let _ = view_handle.update(cx, |this, cx| { + this.write_config_to_device( + changes.clone(), + crate::device::types::DeviceMethod::Fido, + Some(pin), + cx, + ); + }); + }, + ); } fn apply_changes(&mut self, window: &mut Window, cx: &mut Context) { diff --git a/src/ui/views/passkeys.rs b/src/ui/views/passkeys.rs index 190b88b..d80dbd8 100644 --- a/src/ui/views/passkeys.rs +++ b/src/ui/views/passkeys.rs @@ -3,6 +3,7 @@ use crate::device::types::{FidoDeviceInfo, FullDeviceStatus, StoredCredential}; use crate::ui::components::{ button::{PFButton, PFIconButton}, card::Card, + dialog, page_view::PageView, }; use gpui::*; @@ -172,49 +173,20 @@ impl PasskeysView { } fn open_unlock_dialog(&mut self, window: &mut Window, cx: &mut Context) { - let pin_input = cx.new(|cx| { - InputState::new(window, cx) - .placeholder("Enter FIDO PIN") - .masked(true) - }); let view_handle = cx.entity().downgrade(); - window.open_dialog(cx, move |dialog, _, _| { - let view_handle_for_footer = view_handle.clone(); - let pin_input_for_footer = pin_input.clone(); - - dialog - .title("Unlock Storage") - .child( - v_flex() - .gap_4() - .pb_4() - .child("Enter your device PIN to view saved passkeys") - .child(Input::new(&pin_input)), - ) - .footer(move |_, _, _, _| { - let view = view_handle_for_footer.clone(); - let input = pin_input_for_footer.clone(); - - vec![ - Button::new("cancel") - .label("Cancel") - .on_click(|_, window, cx| { - window.close_dialog(cx); - }), - Button::new("unlock").primary().label("Unlock").on_click( - move |_, _window, cx| { - let pin = input.read(cx).text().to_string(); - if !pin.is_empty() { - let _ = view.update(cx, |this, cx| { - this.unlock_storage(pin, cx); - }); - } - }, - ), - ] - }) - }); + dialog::open_pin_prompt( + "Unlock Storage", + "Enter your device PIN to view saved passkeys", + "Unlock", + window, + cx, + move |pin, _, cx| { + let _ = view_handle.update(cx, |this, cx| { + this.unlock_storage(pin, cx); + }); + }, + ); } fn open_delete_dialog( @@ -229,120 +201,39 @@ impl PasskeysView { let name = cred.rp_id.clone(); let view_handle = cx.entity().downgrade(); - window.open_dialog(cx, move |dialog, _, _| { - let view_handle = view_handle.clone(); - let cred_id = cred_id.clone(); - let pin_str = pin_str.clone(); - - dialog - .confirm() - .title("Delete Passkey") - .child(div().pb_4().child(format!( - "Are you sure you want to delete the passkey for {}?", - name - ))) - .on_ok(move |_, _, cx| { - let _ = view_handle.update(cx, |this, cx| { - this.execute_delete(cred_id.clone(), pin_str.clone(), cx); - }); - false - }) - .on_cancel(|_, _, _| true) - .button_props( - gpui_component::dialog::DialogButtonProps::default() - .ok_text("Delete") - .ok_variant(ButtonVariant::Danger), - ) - }); + dialog::open_confirm( + "Delete Passkey", + format!("Are you sure you want to delete the passkey for {}?", name), + "Delete", + ButtonVariant::Danger, + window, + cx, + move |_, cx| { + let _ = view_handle.update(cx, |this, cx| { + this.execute_delete(cred_id.clone(), pin_str.clone(), cx); + }); + }, + ); } fn open_change_pin_dialog(&mut self, window: &mut Window, cx: &mut Context) { - let current_pin = cx.new(|cx| { - InputState::new(window, cx) - .placeholder("Enter current PIN") - .masked(true) - }); - let new_pin = cx.new(|cx| { - InputState::new(window, cx) - .placeholder("Enter new PIN") - .masked(true) - }); - let confirm_pin = cx.new(|cx| { - InputState::new(window, cx) - .placeholder("Confirm new PIN") - .masked(true) - }); - let view_handle = cx.entity().downgrade(); + let view_for_error = cx.entity().downgrade(); - window.open_dialog(cx, move |dialog, _, _| { - let view = view_handle.clone(); - let current = current_pin.clone(); - let new = new_pin.clone(); - let confirm = confirm_pin.clone(); - - dialog - .title("Change PIN") - .child("Enter your current PIN and choose a new one.") - .child( - v_flex() - .gap_4() - .pb_4() - .child("Current PIN") - .child(Input::new(¤t)) - .child("New PIN") - .child(Input::new(&new)) - .child("Confirm New PIN") - .child(Input::new(&confirm)), - ) - .footer(move |_, _window, _cx, _| { - let view = view.clone(); - let current = current.clone(); - let new = new.clone(); - let confirm = confirm.clone(); - - vec![ - Button::new("cancel") - .label("Cancel") - .on_click(|_, window, cx| window.close_dialog(cx)), - Button::new("confirm").primary().label("Confirm").on_click( - move |_, _, cx| { - let current_val = current.read(cx).text().to_string(); - let new_val = new.read(cx).text().to_string(); - let confirm_val = confirm.read(cx).text().to_string(); - - if current_val.is_empty() { - return; - // Todo: show error - } - - if new_val != confirm_val { - // Todo: show validation error (toast) - let _ = view.update(cx, |_, cx| { - cx.emit(PasskeysEvent::Notification( - "PINs do not match".to_string(), - )); - }); - return; - } - - if new_val.len() < 4 { - let _ = view.update(cx, |_, cx| { - cx.emit(PasskeysEvent::Notification( - "PIN too short".to_string(), - )); - }); - return; - } - - let _ = view.update(cx, |this, cx| { - this.change_pin(current_val, new_val, cx); - }); - }, - ), - ] - }) - }); + dialog::open_change_pin( + window, + cx, + move |msg, cx| { + let _ = view_for_error.update(cx, |_, cx| { + cx.emit(PasskeysEvent::Notification(msg.to_string())); + }); + }, + move |current, new, cx| { + let _ = view_handle.update(cx, |this, cx| { + this.change_pin(current, new, cx); + }); + }, + ); } fn open_min_pin_length_dialog(&mut self, window: &mut Window, cx: &mut Context) {