From 99086207c9831e758fe2735fd44c737a97a9718a Mon Sep 17 00:00:00 2001 From: Sridhar Ratnakumar <3998+srid@users.noreply.github.com> Date: Thu, 12 Oct 2023 17:56:09 -0400 Subject: [PATCH] Leptos -> Dioxus Desktop (#79) Switch from Leptos to Dioxus, and convert this to be a desktop. Consequently, the following changes have been made: - Remove e2e testing (we may have to probably reintroduce this latter after figuring out how to test desktop apps; the code exists in `leptos` branch) - Remove bunch of server/cli code that are no longer necessary - Remove `leptos_extra` crate - `nix_rs`: no longer needs "ssr" feature flags --- .envrc | 2 +- .gitattributes | 2 + .github/workflows/ci.yaml | 18 - .vscode/settings.json | 3 + Cargo.lock | 3688 +++++++++++------ Cargo.toml | 86 +- Dioxus.toml | 45 + README.md | 16 +- assets/images/128x128.png | Bin 0 -> 8817 bytes assets/tailwind.css | 1155 ++++++ crates/leptos_extra/Cargo.toml | 19 - crates/leptos_extra/src/lib.rs | 3 - crates/leptos_extra/src/query.rs | 104 - crates/leptos_extra/src/signal.rs | 78 - crates/nix_health/Cargo.toml | 21 +- crates/nix_health/src/check/caches.rs | 3 - crates/nix_health/src/check/direnv.rs | 12 +- crates/nix_health/src/check/flake_enabled.rs | 3 - crates/nix_health/src/check/max_jobs.rs | 3 - .../nix_health/src/check/min_nix_version.rs | 4 +- crates/nix_health/src/check/rosetta.rs | 5 +- crates/nix_health/src/check/system.rs | 2 - crates/nix_health/src/check/trusted_users.rs | 2 - crates/nix_health/src/lib.rs | 2 - crates/nix_health/src/traits.rs | 3 +- crates/nix_rs/Cargo.toml | 11 +- crates/nix_rs/src/command.rs | 15 +- crates/nix_rs/src/config.rs | 5 +- crates/nix_rs/src/env.rs | 42 +- crates/nix_rs/src/flake/mod.rs | 8 +- crates/nix_rs/src/flake/outputs.rs | 13 +- crates/nix_rs/src/info.rs | 2 +- crates/nix_rs/src/version.rs | 8 +- css/input.css | 4 - e2e/.gitignore | 4 - e2e/README.md | 6 - e2e/flake-module.nix | 52 - e2e/node_modules | 1 + e2e/playwright.config.ts | 68 - e2e/tests/nix-version.spec.ts | 7 - flake.lock | 34 +- flake.nix | 9 +- justfile | 28 +- rust.nix | 117 +- src/app/flake.rs | 360 +- src/app/health.rs | 133 +- src/app/info.rs | 188 +- src/app/mod.rs | 226 +- src/app/state.rs | 161 + src/app/state/datum.rs | 109 + src/app/widget.rs | 45 + src/cli.rs | 21 - src/lib.rs | 27 - src/logging.rs | 47 +- src/main.rs | 26 +- src/server.rs | 87 - src/widget.rs | 176 - tailwind.config.js | 2 +- 58 files changed, 4425 insertions(+), 2896 deletions(-) create mode 100644 .gitattributes delete mode 100644 .github/workflows/ci.yaml create mode 100644 Dioxus.toml create mode 100644 assets/images/128x128.png create mode 100644 assets/tailwind.css delete mode 100644 crates/leptos_extra/Cargo.toml delete mode 100644 crates/leptos_extra/src/lib.rs delete mode 100644 crates/leptos_extra/src/query.rs delete mode 100644 crates/leptos_extra/src/signal.rs delete mode 100644 e2e/.gitignore delete mode 100644 e2e/README.md delete mode 100644 e2e/flake-module.nix create mode 120000 e2e/node_modules delete mode 100644 e2e/playwright.config.ts delete mode 100644 e2e/tests/nix-version.spec.ts create mode 100644 src/app/state.rs create mode 100644 src/app/state/datum.rs create mode 100644 src/app/widget.rs delete mode 100644 src/lib.rs delete mode 100644 src/server.rs delete mode 100644 src/widget.rs diff --git a/.envrc b/.envrc index 1281b8e..d538f7b 100644 --- a/.envrc +++ b/.envrc @@ -1,2 +1,2 @@ -use flake nix_direnv_watch_file */*.nix *.nix +use flake diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..ac157b4 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +flake.lock linguist-generated=true +assets/tailwind.css linguist-generated=true diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml deleted file mode 100644 index d09a97d..0000000 --- a/.github/workflows/ci.yaml +++ /dev/null @@ -1,18 +0,0 @@ -name: "CI" -on: - # Run only when pushing to master branch, and making PRs - push: - branches: - - main - pull_request: -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Install Nix - uses: DeterminateSystems/nix-installer-action@main - - uses: DeterminateSystems/magic-nix-cache-action@main - - run: nix --accept-flake-config build --no-link --print-out-paths .#e2e-playwright-test - - name: E2E tests - run: nix --accept-flake-config run .#e2e-playwright-test diff --git a/.vscode/settings.json b/.vscode/settings.json index a55310b..1dc1b5e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,6 +13,9 @@ "rust": "html", "*.rs": "html" }, + "tailwindCSS.experimental.classRegex": [ + "class: \"(.*)\"" + ], "files.associations": { "*.css": "tailwindcss" } diff --git a/Cargo.lock b/Cargo.lock index 9e72855..6342f4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,28 +17,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "ahash" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - -[[package]] -name = "ahash" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", -] - [[package]] name = "aho-corasick" version = "1.0.5" @@ -48,21 +26,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - [[package]] name = "android-tzdata" version = "0.1.1" @@ -113,7 +76,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -123,7 +86,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" dependencies = [ "anstyle", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -139,32 +102,61 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c" [[package]] -name = "async-compression" -version = "0.4.2" +name = "async-broadcast" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d495b6dc0184693324491a5ac05f559acc97bf937ab31d7a1c33dd0016be6d2b" +checksum = "7c48ccdbf6ca6b121e0f586cbc0e73ae440e56c67c30fa0873b4e110d9c26d2b" dependencies = [ - "brotli", - "flate2", + "event-listener", "futures-core", - "memchr", - "pin-project-lite", - "tokio", - "zstd", - "zstd-safe", ] [[package]] -name = "async-recursion" -version = "1.0.4" +name = "async-channel" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.29", + "concurrent-queue", + "event-listener", + "futures-core", ] +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock", + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-lite", + "log", + "parking", + "polling", + "rustix 0.37.24", + "slab", + "socket2 0.4.9", + "waker-fn", +] + +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-task" +version = "4.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9441c6b2fe128a7c2bf680a44c34d0df31ce09e5b7e401fcca3faa483dbc921" + [[package]] name = "async-trait" version = "0.1.73" @@ -177,101 +169,41 @@ dependencies = [ ] [[package]] -name = "attribute-derive" -version = "0.6.1" +name = "atk" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c124f12ade4e670107b132722d0ad1a5c9790bcbc1b265336369ea05626b4498" +checksum = "39991bc421ddf72f70159011b323ff49b0f783cc676a7287c59453da2e2531cf" dependencies = [ - "attribute-derive-macro", - "proc-macro2", - "quote", - "syn 2.0.29", + "atk-sys", + "bitflags 1.3.2", + "glib", + "libc", ] [[package]] -name = "attribute-derive-macro" -version = "0.6.1" +name = "atk-sys" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b217a07446e0fb086f83401a98297e2d81492122f5874db5391bd270a185f88" +checksum = "11ad703eb64dc058024f0e57ccfa069e15a413b98dbd50a1a950e743b7f11148" dependencies = [ - "collection_literals", - "interpolator", - "proc-macro-error", - "proc-macro-utils", - "proc-macro2", - "quote", - "quote-use", - "syn 2.0.29", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "axum" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" -dependencies = [ - "async-trait", - "axum-core", - "axum-macros", - "bitflags 1.3.2", - "bytes", - "futures-util", - "http", - "http-body", - "hyper", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "serde_json", - "serde_path_to_error", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-core" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http", - "http-body", - "mime", - "rustversion", - "tower-layer", - "tower-service", -] - -[[package]] -name = "axum-macros" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdca6a10ecad987bda04e95606ef85a5417dcaac1a78455242d72e031e2b6b62" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.29", -] - [[package]] name = "backtrace" version = "0.3.69" @@ -319,18 +251,15 @@ name = "bitflags" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +dependencies = [ + "serde", +] [[package]] -name = "bitvec" -version = "1.0.1" +name = "block" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" [[package]] name = "block-buffer" @@ -342,24 +271,19 @@ dependencies = [ ] [[package]] -name = "brotli" -version = "3.3.4" +name = "blocking" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" +checksum = "94c4ef1f913d78636d78d538eec1f18de81e481f44b1be0a81060090530846e1" dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "2.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", + "async-channel", + "async-lock", + "async-task", + "fastrand 2.0.1", + "futures-io", + "futures-lite", + "piper", + "tracing", ] [[package]] @@ -369,27 +293,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] -name = "bytecheck" -version = "0.6.11" +name = "bytemuck" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" -dependencies = [ - "bytecheck_derive", - "ptr_meta", - "simdutf8", - "uuid", -] +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" [[package]] -name = "bytecheck_derive" -version = "0.6.11" +name = "byteorder" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" @@ -407,57 +320,66 @@ dependencies = [ ] [[package]] -name = "cached" -version = "0.44.0" +name = "cairo-rs" +version = "0.16.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b195e4fbc4b6862bbd065b991a34750399c119797efff72492f28a5864de8700" +checksum = "f3125b15ec28b84c238f6f476c6034016a5f6cc0221cb514ca46c532139fc97d" dependencies = [ - "async-trait", - "cached_proc_macro", - "cached_proc_macro_types", - "futures", - "hashbrown 0.13.2", - "instant", + "bitflags 1.3.2", + "cairo-sys-rs", + "glib", + "libc", "once_cell", "thiserror", - "tokio", ] [[package]] -name = "cached_proc_macro" -version = "0.17.0" +name = "cairo-sys-rs" +version = "0.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b48814962d2fd604c50d2b9433c2a41a0ab567779ee2c02f7fba6eca1221f082" +checksum = "7c48f4af05fabdcfa9658178e1326efa061853f040ce7d72e33af6885196f421" dependencies = [ - "cached_proc_macro_types", - "darling 0.14.4", - "proc-macro2", - "quote", - "syn 1.0.109", + "glib-sys", + "libc", + "system-deps", ] -[[package]] -name = "cached_proc_macro_types" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a4f925191b4367301851c6d99b09890311d74b0d43f274c0b34c86d308a3663" - -[[package]] -name = "camino" -version = "1.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" - [[package]] name = "cc" version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ - "jobserver", "libc", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfb" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" +dependencies = [ + "byteorder", + "fnv", + "uuid", +] + +[[package]] +name = "cfg-expr" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03915af431787e6ffdcc74c645077518c6b6e01f80b761e0fbbfa288536311b3" +dependencies = [ + "smallvec", + "target-lexicon", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -474,34 +396,7 @@ dependencies = [ "iana-time-zone", "num-traits", "serde", - "windows-targets", -] - -[[package]] -name = "ciborium" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" -dependencies = [ - "ciborium-io", - "ciborium-ll", - "serde", -] - -[[package]] -name = "ciborium-io" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" - -[[package]] -name = "ciborium-ll" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" -dependencies = [ - "ciborium-io", - "half", + "windows-targets 0.48.5", ] [[package]] @@ -545,10 +440,50 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" [[package]] -name = "collection_literals" -version = "1.0.1" +name = "clipboard-win" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186dce98367766de751c42c4f03970fc60fc012296e706ccbb9d5df9b6c1e271" +checksum = "9fdf5e01086b6be750428ba4a40619f847eb2e95756eee84b18e06e5f0b50342" +dependencies = [ + "lazy-bytes-cast", + "winapi", +] + +[[package]] +name = "cocoa" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" +dependencies = [ + "bitflags 1.3.2", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" +dependencies = [ + "bitflags 1.3.2", + "block", + "core-foundation", + "core-graphics-types", + "libc", + "objc", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "colorchoice" @@ -564,32 +499,26 @@ checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" dependencies = [ "is-terminal", "lazy_static", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] -name = "common_macros" -version = "0.1.1" +name = "combine" +version = "4.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3f6d59c71e7dc3af60f0af9db32364d96a16e9310f3f5db2b55ed642162dd35" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "memchr", +] [[package]] -name = "config" -version = "0.13.3" +name = "concurrent-queue" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7" +checksum = "f057a694a54f12365049b0958a1685bb52d567f5593b355fbf685838e873d400" dependencies = [ - "async-trait", - "json5", - "lazy_static", - "nom", - "pathdiff", - "ron", - "rust-ini", - "serde", - "serde_json", - "toml 0.5.11", - "yaml-rust", + "crossbeam-utils", ] [[package]] @@ -613,32 +542,39 @@ dependencies = [ ] [[package]] -name = "const_format" -version = "0.2.31" +name = "constcat" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c990efc7a285731f9a4378d81aff2f0e85a2c8781a05ef0f8baa8dac54d0ff48" -dependencies = [ - "const_format_proc_macros", -] - -[[package]] -name = "const_format_proc_macros" -version = "0.2.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e026b6ce194a874cb9cf32cd5772d1ef9767cc8fcb5765948d74f37a9d8b2bf6" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] +checksum = "f272d0c4cf831b4fa80ee529c7707f76585986e910e1fbce1d7921970bc1a241" [[package]] name = "convert_case" -version = "0.6.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "copypasta" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "133fc8675ee3a4ec9aa513584deda9aa0faeda3586b87f7f0f2ba082c66fb172" dependencies = [ - "unicode-segmentation", + "clipboard-win", + "objc", + "objc-foundation", + "objc_id", + "smithay-clipboard", + "x11-clipboard", +] + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", ] [[package]] @@ -647,6 +583,30 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +[[package]] +name = "core-graphics" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bb142d41022986c1d8ff29103a1411c8a3dfad3552f87a4f8dc50d61d4f4e33" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + [[package]] name = "cpufeatures" version = "0.2.9" @@ -665,6 +625,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + [[package]] name = "crossbeam-deque" version = "0.8.3" @@ -685,7 +655,7 @@ dependencies = [ "autocfg", "cfg-if", "crossbeam-utils", - "memoffset", + "memoffset 0.9.0", "scopeguard", ] @@ -709,13 +679,30 @@ dependencies = [ ] [[package]] -name = "darling" -version = "0.14.4" +name = "cssparser" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" dependencies = [ - "darling_core 0.14.4", - "darling_macro 0.14.4", + "cssparser-macros", + "dtoa-short", + "itoa 0.4.8", + "matches", + "phf", + "proc-macro2", + "quote", + "smallvec", + "syn 1.0.109", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +dependencies = [ + "quote", + "syn 2.0.29", ] [[package]] @@ -724,22 +711,8 @@ version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ - "darling_core 0.20.3", - "darling_macro 0.20.3", -] - -[[package]] -name = "darling_core" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 1.0.109", + "darling_core", + "darling_macro", ] [[package]] @@ -756,24 +729,13 @@ dependencies = [ "syn 2.0.29", ] -[[package]] -name = "darling_macro" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" -dependencies = [ - "darling_core 0.14.4", - "quote", - "syn 1.0.109", -] - [[package]] name = "darling_macro" version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ - "darling_core 0.20.3", + "darling_core", "quote", "syn 2.0.29", ] @@ -788,14 +750,16 @@ dependencies = [ ] [[package]] -name = "derive-where" -version = "1.2.3" +name = "derive_more" +version = "0.99.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875a0460143f2dbcc71fd8a63f34b7c83ac66f14bead94054e7cd619c57bbb27" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ + "convert_case", "proc-macro2", "quote", - "syn 2.0.29", + "rustc_version", + "syn 1.0.109", ] [[package]] @@ -809,29 +773,343 @@ dependencies = [ ] [[package]] -name = "dlv-list" -version = "0.3.0" +name = "dioxus" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257" - -[[package]] -name = "drain_filter_polyfill" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "669a445ee724c5c69b1b06fe0b63e70a1c84bc9bb7d9696cd4f4e3ec45050408" - -[[package]] -name = "educe" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "079044df30bb07de7d846d41a184c4b00e66ebdac93ee459253474f3a47e50ae" +checksum = "734b13d4894daf5cee7d4a1d7960da207acd7d4b4e427c05c201a2ba87a5c032" dependencies = [ - "enum-ordinalize", + "dioxus-core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-core-macro 0.4.0", + "dioxus-hooks 0.4.0", + "dioxus-hot-reload 0.4.0", + "dioxus-html 0.4.0", + "dioxus-rsx 0.4.0", +] + +[[package]] +name = "dioxus" +version = "0.4.2" +source = "git+https://github.com/DioxusLabs/dioxus.git?rev=459f24d5e9ef0e03a3bbd037342c60bbde409dbf#459f24d5e9ef0e03a3bbd037342c60bbde409dbf" +dependencies = [ + "dioxus-core 0.4.2 (git+https://github.com/DioxusLabs/dioxus.git?rev=459f24d5e9ef0e03a3bbd037342c60bbde409dbf)", + "dioxus-core-macro 0.4.2", + "dioxus-hooks 0.4.2", + "dioxus-hot-reload 0.4.2", + "dioxus-html 0.4.2", + "dioxus-rsx 0.4.2", +] + +[[package]] +name = "dioxus-core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9980d48779193a6fb30fb43cdb06cdcc6ada2173a73579bf92dec81607a7ed5e" +dependencies = [ + "bumpalo", + "futures-channel", + "futures-util", + "log", + "longest-increasing-subsequence", + "rustc-hash", + "serde", + "slab", + "smallbox", +] + +[[package]] +name = "dioxus-core" +version = "0.4.2" +source = "git+https://github.com/DioxusLabs/dioxus.git?rev=459f24d5e9ef0e03a3bbd037342c60bbde409dbf#459f24d5e9ef0e03a3bbd037342c60bbde409dbf" +dependencies = [ + "bumpalo", + "futures-channel", + "futures-util", + "longest-increasing-subsequence", + "rustc-hash", + "serde", + "slab", + "smallbox", + "tracing", +] + +[[package]] +name = "dioxus-core-macro" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e98f3e3fc1fb1f8796e30a5eaa6e037ca44105bdee3a70ed66721ac8b720c931" +dependencies = [ + "dioxus-rsx 0.4.0", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.29", ] +[[package]] +name = "dioxus-core-macro" +version = "0.4.2" +source = "git+https://github.com/DioxusLabs/dioxus.git?rev=459f24d5e9ef0e03a3bbd037342c60bbde409dbf#459f24d5e9ef0e03a3bbd037342c60bbde409dbf" +dependencies = [ + "constcat", + "dioxus-core 0.4.2 (git+https://github.com/DioxusLabs/dioxus.git?rev=459f24d5e9ef0e03a3bbd037342c60bbde409dbf)", + "dioxus-rsx 0.4.2", + "proc-macro2", + "quote", + "syn 2.0.29", +] + +[[package]] +name = "dioxus-debug-cell" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ea539174bb236e0e7dc9c12b19b88eae3cb574dedbd0252a2d43ea7e6de13e2" + +[[package]] +name = "dioxus-desktop" +version = "0.4.2" +source = "git+https://github.com/DioxusLabs/dioxus.git?rev=459f24d5e9ef0e03a3bbd037342c60bbde409dbf#459f24d5e9ef0e03a3bbd037342c60bbde409dbf" +dependencies = [ + "async-trait", + "core-foundation", + "dioxus-core 0.4.2 (git+https://github.com/DioxusLabs/dioxus.git?rev=459f24d5e9ef0e03a3bbd037342c60bbde409dbf)", + "dioxus-hot-reload 0.4.2", + "dioxus-html 0.4.2", + "dioxus-interpreter-js", + "dunce", + "futures-channel", + "futures-util", + "infer", + "objc", + "objc_id", + "rfd", + "serde", + "serde_json", + "slab", + "thiserror", + "tokio", + "tracing", + "urlencoding", + "webbrowser", + "wry", +] + +[[package]] +name = "dioxus-hooks" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808e553203e4c2534e186a8a9da0f4032027ff5413067307ea8ecbd793e37f57" +dependencies = [ + "dioxus-core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-debug-cell", + "futures-channel", + "log", + "slab", + "thiserror", +] + +[[package]] +name = "dioxus-hooks" +version = "0.4.2" +source = "git+https://github.com/DioxusLabs/dioxus.git?rev=459f24d5e9ef0e03a3bbd037342c60bbde409dbf#459f24d5e9ef0e03a3bbd037342c60bbde409dbf" +dependencies = [ + "dioxus-core 0.4.2 (git+https://github.com/DioxusLabs/dioxus.git?rev=459f24d5e9ef0e03a3bbd037342c60bbde409dbf)", + "dioxus-debug-cell", + "futures-channel", + "slab", + "thiserror", + "tracing", +] + +[[package]] +name = "dioxus-hot-reload" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ceb8aca167a64e4b0afaff447b13052402a9ade3f21b9e7d031b6b72669994a" +dependencies = [ + "dioxus-core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "dioxus-html 0.4.0", + "dioxus-rsx 0.4.0", + "interprocess-docfix", + "serde", + "serde_json", +] + +[[package]] +name = "dioxus-hot-reload" +version = "0.4.2" +source = "git+https://github.com/DioxusLabs/dioxus.git?rev=459f24d5e9ef0e03a3bbd037342c60bbde409dbf#459f24d5e9ef0e03a3bbd037342c60bbde409dbf" +dependencies = [ + "dioxus-core 0.4.2 (git+https://github.com/DioxusLabs/dioxus.git?rev=459f24d5e9ef0e03a3bbd037342c60bbde409dbf)", + "dioxus-html 0.4.2", + "dioxus-rsx 0.4.2", + "interprocess-docfix", + "serde", + "serde_json", +] + +[[package]] +name = "dioxus-html" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb712fe56650dafddb626f8aed3d6ae194706c0299e175e99b45464add8b7af1" +dependencies = [ + "async-channel", + "async-trait", + "dioxus-core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "enumset", + "euclid", + "keyboard-types 0.6.2", + "serde", + "serde-value", + "serde_json", + "serde_repr", + "web-sys", +] + +[[package]] +name = "dioxus-html" +version = "0.4.2" +source = "git+https://github.com/DioxusLabs/dioxus.git?rev=459f24d5e9ef0e03a3bbd037342c60bbde409dbf#459f24d5e9ef0e03a3bbd037342c60bbde409dbf" +dependencies = [ + "async-channel", + "async-trait", + "dioxus-core 0.4.2 (git+https://github.com/DioxusLabs/dioxus.git?rev=459f24d5e9ef0e03a3bbd037342c60bbde409dbf)", + "enumset", + "euclid", + "keyboard-types 0.7.0", + "serde", + "serde-value", + "serde_json", + "serde_repr", + "tokio", + "web-sys", +] + +[[package]] +name = "dioxus-interpreter-js" +version = "0.4.2" +source = "git+https://github.com/DioxusLabs/dioxus.git?rev=459f24d5e9ef0e03a3bbd037342c60bbde409dbf#459f24d5e9ef0e03a3bbd037342c60bbde409dbf" + +[[package]] +name = "dioxus-router" +version = "0.4.2" +source = "git+https://github.com/DioxusLabs/dioxus.git?rev=459f24d5e9ef0e03a3bbd037342c60bbde409dbf#459f24d5e9ef0e03a3bbd037342c60bbde409dbf" +dependencies = [ + "anyhow", + "dioxus 0.4.2", + "dioxus-router-macro", + "futures-util", + "gloo", + "gloo-utils", + "js-sys", + "thiserror", + "tracing", + "url", + "urlencoding", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "dioxus-router-macro" +version = "0.4.2" +source = "git+https://github.com/DioxusLabs/dioxus.git?rev=459f24d5e9ef0e03a3bbd037342c60bbde409dbf#459f24d5e9ef0e03a3bbd037342c60bbde409dbf" +dependencies = [ + "proc-macro2", + "quote", + "slab", + "syn 2.0.29", +] + +[[package]] +name = "dioxus-rsx" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "531a6b418fb75d08389920c024d1c082b500844cf50ccb16ad8d9ee33a1907a1" +dependencies = [ + "dioxus-core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn 2.0.29", +] + +[[package]] +name = "dioxus-rsx" +version = "0.4.2" +source = "git+https://github.com/DioxusLabs/dioxus.git?rev=459f24d5e9ef0e03a3bbd037342c60bbde409dbf#459f24d5e9ef0e03a3bbd037342c60bbde409dbf" +dependencies = [ + "dioxus-core 0.4.2 (git+https://github.com/DioxusLabs/dioxus.git?rev=459f24d5e9ef0e03a3bbd037342c60bbde409dbf)", + "proc-macro2", + "quote", + "syn 2.0.29", +] + +[[package]] +name = "dioxus-signals" +version = "0.0.0" +source = "git+https://github.com/DioxusLabs/dioxus.git?rev=459f24d5e9ef0e03a3bbd037342c60bbde409dbf#459f24d5e9ef0e03a3bbd037342c60bbde409dbf" +dependencies = [ + "dioxus-core 0.4.2 (git+https://github.com/DioxusLabs/dioxus.git?rev=459f24d5e9ef0e03a3bbd037342c60bbde409dbf)", + "generational-box", + "simple_logger", + "tracing", +] + +[[package]] +name = "dioxus-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537b5edb67884c6dcc65a067b5425fd44a9bcb754d3c232f90d54fd4a468ad9e" +dependencies = [ + "async-broadcast", + "cfg-if", + "copypasta", + "dioxus 0.4.0", + "js-sys", + "uuid", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +dependencies = [ + "libloading", +] + +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + +[[package]] +name = "dtoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" + +[[package]] +name = "dtoa-short" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbaceec3c6e4211c79e7b1800fb9680527106beb2f9c51904a3210c03a448c74" +dependencies = [ + "dtoa", +] + +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + [[package]] name = "either" version = "1.9.0" @@ -839,22 +1117,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] -name = "encoding_rs" -version = "0.8.33" +name = "enumset" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "e875f1719c16de097dee81ed675e2d9bb63096823ed3f0ca827b7dea3028bbbb" dependencies = [ - "cfg-if", + "enumset_derive", ] [[package]] -name = "enum-ordinalize" -version = "3.1.13" +name = "enumset_derive" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4f76552f53cefc9a7f64987c3701b99d982f7690606fd67de1d09712fbf52f1" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" dependencies = [ - "num-bigint", - "num-traits", + "darling", "proc-macro2", "quote", "syn 2.0.29", @@ -874,7 +1151,7 @@ checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ "errno-dragonfly", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -887,6 +1164,56 @@ dependencies = [ "libc", ] +[[package]] +name = "euclid" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f253bc5c813ca05792837a0ff4b3a580336b224512d48f7eda1d7dd9210787" +dependencies = [ + "num-traits", + "serde", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fdeflate" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset 0.9.0", + "rustc_version", +] + [[package]] name = "flate2" version = "1.0.27" @@ -903,6 +1230,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.0" @@ -913,24 +1255,13 @@ dependencies = [ ] [[package]] -name = "funty" -version = "2.0.0" +name = "futf" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "futures" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", + "mac", + "new_debug_unreachable", ] [[package]] @@ -940,7 +1271,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", - "futures-sink", ] [[package]] @@ -966,6 +1296,21 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + [[package]] name = "futures-macro" version = "0.3.28" @@ -995,11 +1340,9 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ - "futures-channel", "futures-core", "futures-io", "futures-macro", - "futures-sink", "futures-task", "memchr", "pin-project-lite", @@ -1007,6 +1350,109 @@ dependencies = [ "slab", ] +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "gdk" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9cb33da481c6c040404a11f8212d193889e9b435db2c14fd86987f630d3ce1" +dependencies = [ + "bitflags 1.3.2", + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.16.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3578c60dee9d029ad86593ed88cb40f35c1b83360e12498d055022385dd9a05" +dependencies = [ + "bitflags 1.3.2", + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3092cf797a5f1210479ea38070d9ae8a5b8e9f8f1be9f32f4643c529c7d70016" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk-sys" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76354f97a913e55b984759a997b693aa7dc71068c9e98bcce51aa167a0a5c5a" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gdkwayland-sys" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4511710212ed3020b61a8622a37aa6f0dd2a84516575da92e9b96928dcbe83ba" +dependencies = [ + "gdk-sys", + "glib-sys", + "gobject-sys", + "libc", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gdkx11-sys" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa2bf8b5b8c414bc5d05e48b271896d0fd3ddb57464a3108438082da61de6af" +dependencies = [ + "gdk-sys", + "glib-sys", + "libc", + "system-deps", + "x11", +] + +[[package]] +name = "generational-box" +version = "0.0.0" +source = "git+https://github.com/DioxusLabs/dioxus.git?rev=459f24d5e9ef0e03a3bbd037342c60bbde409dbf#459f24d5e9ef0e03a3bbd037342c60bbde409dbf" +dependencies = [ + "bumpalo", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -1017,6 +1463,27 @@ dependencies = [ "version_check", ] +[[package]] +name = "gethostname" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + [[package]] name = "getrandom" version = "0.2.10" @@ -1026,7 +1493,7 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", ] @@ -1036,6 +1503,86 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +[[package]] +name = "gio" +version = "0.16.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a1c84b4534a290a29160ef5c6eff2a9c95833111472e824fc5cb78b513dd092" +dependencies = [ + "bitflags 1.3.2", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "once_cell", + "pin-project-lite", + "smallvec", + "thiserror", +] + +[[package]] +name = "gio-sys" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9b693b8e39d042a95547fc258a7b07349b1f0b48f4b2fa3108ba3c51c0b5229" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "winapi", +] + +[[package]] +name = "glib" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16aa2475c9debed5a32832cb5ff2af5a3f9e1ab9e69df58eaadc1ab2004d6eba" +dependencies = [ + "bitflags 1.3.2", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "once_cell", + "smallvec", + "thiserror", +] + +[[package]] +name = "glib-macros" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb1a9325847aa46f1e96ffea37611b9d51fc4827e67f79e7de502a297560a67b" +dependencies = [ + "anyhow", + "heck", + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "glib-sys" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61a4f46316d06bfa33a7ac22df6f0524c8be58e3db2d9ca99ccb1f357b62a65" +dependencies = [ + "libc", + "system-deps", +] + [[package]] name = "gloo" version = "0.8.1" @@ -1047,7 +1594,7 @@ dependencies = [ "gloo-events", "gloo-file", "gloo-history", - "gloo-net 0.3.1", + "gloo-net", "gloo-render", "gloo-storage", "gloo-timers", @@ -1116,26 +1663,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "gloo-net" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9902a044653b26b99f7e3693a42f171312d9be8b26b5697bd1e43ad1f8a35e10" -dependencies = [ - "futures-channel", - "futures-core", - "futures-sink", - "gloo-utils", - "js-sys", - "pin-project", - "serde", - "serde_json", - "thiserror", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - [[package]] name = "gloo-net" version = "0.3.1" @@ -1188,8 +1715,6 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" dependencies = [ - "futures-channel", - "futures-core", "js-sys", "wasm-bindgen", ] @@ -1225,47 +1750,76 @@ dependencies = [ ] [[package]] -name = "h2" -version = "0.3.21" +name = "gobject-sys" +version = "0.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "3520bb9c07ae2a12c7f2fbb24d4efc11231c8146a86956413fb1a79bb760a0f1" dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap 1.9.3", - "slab", - "tokio", - "tokio-util", - "tracing", + "glib-sys", + "libc", + "system-deps", ] [[package]] -name = "half" -version = "1.8.2" +name = "gtk" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +checksum = "e4d3507d43908c866c805f74c9dd593c0ce7ba5c38e576e41846639cdcd4bee6" +dependencies = [ + "atk", + "bitflags 1.3.2", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk", + "gdk-pixbuf", + "gio", + "glib", + "gtk-sys", + "gtk3-macros", + "libc", + "once_cell", + "pango", + "pkg-config", +] + +[[package]] +name = "gtk-sys" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b5f8946685d5fe44497007786600c2f368ff6b1e61a16251c89f72a97520a3" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk3-macros" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "096eb63c6fedf03bafe65e5924595785eaf1bcb7200dac0f2cbe9c9738f05ad8" +dependencies = [ + "anyhow", + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" -dependencies = [ - "ahash 0.7.6", -] - -[[package]] -name = "hashbrown" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" -dependencies = [ - "ahash 0.8.3", -] [[package]] name = "hashbrown" @@ -1297,16 +1851,21 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] -name = "html-escape" -version = "0.2.13" +name = "html5ever" +version = "0.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476" +checksum = "e5c13fb08e5d4dfc151ee5e88bae63f7773d61852f3bdc73c9f4b9e1bde03148" dependencies = [ - "utf8-width", + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -1317,38 +1876,9 @@ checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ "bytes", "fnv", - "itoa", + "itoa 1.0.9", ] -[[package]] -name = "http-body" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "http-range-header" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" - -[[package]] -name = "httparse" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - [[package]] name = "human-panic" version = "1.2.0" @@ -1365,30 +1895,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "hyper" -version = "0.14.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2 0.4.9", - "tokio", - "tower-service", - "tracing", - "want", -] - [[package]] name = "iana-time-zone" version = "0.1.57" @@ -1400,7 +1906,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows", + "windows 0.48.0", ] [[package]] @@ -1428,6 +1934,19 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "image" +version = "0.24.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "num-rational", + "num-traits", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -1450,6 +1969,15 @@ dependencies = [ "serde", ] +[[package]] +name = "infer" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6c16b11a665b26aeeb9b1d7f954cdeb034be38dd00adab4f2ae921a8fee804" +dependencies = [ + "cfb", +] + [[package]] name = "instant" version = "0.1.12" @@ -1460,40 +1988,40 @@ dependencies = [ ] [[package]] -name = "interpolator" -version = "0.5.0" +name = "interprocess-docfix" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71dd52191aae121e8611f1e8dc3e324dd0dd1dee1e6dd91d10ee07a3cfb4d9d8" - -[[package]] -name = "inventory" -version = "0.3.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1be380c410bf0595e94992a648ea89db4dd3f3354ba54af206fd2a68cf5ac8e" - -[[package]] -name = "ipnet" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" - -[[package]] -name = "iri-string" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21859b667d66a4c1dacd9df0863b3efb65785474255face87f5bca39dd8407c0" +checksum = "4b84ee245c606aeb0841649a9288e3eae8c61b853a8cd5c0e14450e96d53d28f" dependencies = [ - "memchr", - "serde", + "blocking", + "cfg-if", + "futures-core", + "futures-io", + "intmap", + "libc", + "once_cell", + "rustc_version", + "spinning", + "thiserror", + "to_method", + "winapi", ] [[package]] -name = "is-docker" -version = "0.2.0" +name = "intmap" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" +checksum = "ae52f28f45ac2bc96edb7714de995cffc174a395fb0abf5bff453587c980d7b9" + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "once_cell", + "hermit-abi", + "libc", + "windows-sys 0.48.0", ] [[package]] @@ -1503,18 +2031,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix", - "windows-sys", -] - -[[package]] -name = "is-wsl" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" -dependencies = [ - "is-docker", - "once_cell", + "rustix 0.38.11", + "windows-sys 0.48.0", ] [[package]] @@ -1527,13 +2045,10 @@ dependencies = [ ] [[package]] -name = "itertools" -version = "0.10.5" +name = "itoa" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "itoa" @@ -1542,14 +2057,64 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" [[package]] -name = "jobserver" -version = "0.1.26" +name = "javascriptcore-rs" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" +checksum = "110b9902c80c12bf113c432d0b71c7a94490b294a8234f326fd0abca2fac0b00" dependencies = [ - "libc", + "bitflags 1.3.2", + "glib", + "javascriptcore-rs-sys", ] +[[package]] +name = "javascriptcore-rs-sys" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98a216519a52cd941a733a0ad3f1023cfdb1cd47f3955e8e863ed56f558f916c" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "jni" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "039022cdf4d7b1cf548d31f60ae783138e5fd42013f6271049d7df7afadef96c" +dependencies = [ + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", +] + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + [[package]] name = "js-sys" version = "0.3.64" @@ -1560,269 +2125,51 @@ dependencies = [ ] [[package]] -name = "json5" -version = "0.4.1" +name = "keyboard-types" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +checksum = "0b7668b7cff6a51fe61cdde64cd27c8a220786f399501b57ebe36f7d8112fd68" dependencies = [ - "pest", - "pest_derive", + "bitflags 1.3.2", "serde", + "unicode-segmentation", ] +[[package]] +name = "keyboard-types" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" +dependencies = [ + "bitflags 2.4.0", + "serde", + "unicode-segmentation", +] + +[[package]] +name = "kuchiki" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ea8e9c6e031377cff82ee3001dc8026cdf431ed4e2e6b51f98ab8c73484a358" +dependencies = [ + "cssparser", + "html5ever", + "matches", + "selectors", +] + +[[package]] +name = "lazy-bytes-cast" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10257499f089cd156ad82d0a9cd57d9501fa2c989068992a97eb3c27836f206b" + [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "leptos" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65154cd0fc2f505a1676b870d5c055dec9dafe4d6081358ef1d7e357d6f222c5" -dependencies = [ - "cfg-if", - "leptos_config", - "leptos_dom", - "leptos_macro", - "leptos_reactive", - "leptos_server", - "server_fn", - "tracing", - "typed-builder", -] - -[[package]] -name = "leptos_axum" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "309af4ea2fd7e9769f1f10d7e356fcb4e7d2bb1c21588dc73151feca415fd45a" -dependencies = [ - "axum", - "futures", - "http", - "hyper", - "leptos", - "leptos_integration_utils", - "leptos_meta", - "leptos_router", - "once_cell", - "parking_lot", - "serde_json", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "leptos_config" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0108f6c8409c99fcf25f4c55a56b4bf9afeeb58f643879bb115d4258b9e22979" -dependencies = [ - "config", - "regex", - "serde", - "thiserror", - "typed-builder", -] - -[[package]] -name = "leptos_dom" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5a92b7a30d6e1363233211babdd59fdd983f28dc3aa6aebbd7bfbdd15630c73" -dependencies = [ - "async-recursion", - "cfg-if", - "drain_filter_polyfill", - "educe", - "futures", - "getrandom", - "html-escape", - "indexmap 2.0.0", - "itertools", - "js-sys", - "leptos_reactive", - "once_cell", - "pad-adapter", - "paste", - "rustc-hash", - "serde", - "serde_json", - "server_fn", - "smallvec", - "tracing", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "leptos_extra" -version = "0.1.0" -dependencies = [ - "cfg-if", - "leptos", - "leptos_query", - "tracing", -] - -[[package]] -name = "leptos_hot_reload" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ef84aede40b027d1a4addd9bd54c89de722272429f7b21da40b04f9ebe5e3b2" -dependencies = [ - "anyhow", - "camino", - "indexmap 2.0.0", - "parking_lot", - "proc-macro2", - "quote", - "rstml", - "serde", - "syn 2.0.29", - "walkdir", -] - -[[package]] -name = "leptos_integration_utils" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bdd4411a987054b1bce1f89c888ea1bfde50f9c956ce7edc0bb5b54deaf1621" -dependencies = [ - "futures", - "leptos", - "leptos_config", - "leptos_hot_reload", - "leptos_meta", - "tracing", -] - -[[package]] -name = "leptos_macro" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cc27567e059d8ab630a33bf782a81bb2e10178011b8c97c080aafcf09c4e5e0" -dependencies = [ - "attribute-derive", - "cfg-if", - "convert_case", - "html-escape", - "itertools", - "leptos_hot_reload", - "prettyplease", - "proc-macro-error", - "proc-macro2", - "quote", - "rstml", - "server_fn_macro", - "syn 2.0.29", - "tracing", - "uuid", -] - -[[package]] -name = "leptos_meta" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "329c4bbe4191a0bef6514bab827f2ff1a1e69bc2b431e78ac9799e2bdc26ae33" -dependencies = [ - "cfg-if", - "indexmap 2.0.0", - "leptos", - "tracing", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "leptos_query" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e49b2c3d199c091071e14071d9f0c9d87399e00040183234affefa1a4832d7bb" -dependencies = [ - "cfg-if", - "gloo-timers", - "js-sys", - "leptos", - "tokio", -] - -[[package]] -name = "leptos_reactive" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b4fc821e6a8646635b721dd58b5604b5c447eb3b21c464b3837cd2063a6b209" -dependencies = [ - "base64 0.21.3", - "cfg-if", - "futures", - "indexmap 2.0.0", - "js-sys", - "rkyv", - "rustc-hash", - "self_cell", - "serde", - "serde-wasm-bindgen", - "serde_json", - "slotmap", - "thiserror", - "tokio", - "tracing", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "leptos_router" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f02384aaeff09ba17093305a0dfe8713fb171f7227a8543992a9ce44c75cd" -dependencies = [ - "cached", - "cfg-if", - "common_macros", - "gloo-net 0.2.6", - "js-sys", - "lazy_static", - "leptos", - "linear-map", - "log", - "lru", - "once_cell", - "percent-encoding", - "regex", - "serde", - "serde_json", - "serde_qs", - "thiserror", - "tracing", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "leptos_server" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc28e6ae7ca7bd36fc865fb844ecb27ddf72a0eb9514b7ee45d0cad6cf930c7d" -dependencies = [ - "inventory", - "lazy_static", - "leptos_macro", - "leptos_reactive", - "serde", - "server_fn", - "thiserror", - "tracing", -] - [[package]] name = "libc" version = "0.2.147" @@ -1830,20 +2177,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] -name = "linear-map" -version = "1.2.0" +name = "libloading" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfae20f6b19ad527b550c223fddc3077a547fc70cda94b9b566575423fd303ee" +checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" dependencies = [ - "serde", - "serde_test", + "cfg-if", + "windows-sys 0.48.0", ] [[package]] -name = "linked-hash-map" -version = "0.5.6" +name = "linux-raw-sys" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" @@ -1868,12 +2215,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] -name = "lru" +name = "longest-increasing-subsequence" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3bd0dd2cd90571056fdb71f6275fada10131182f84899f4b2a916e565d81d86" + +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "markup5ever" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670" +checksum = "a24f40fb03852d1cdd84330cddcaf98e9ec08a7b7768e952fad3b4cf048ec8fd" dependencies = [ - "hashbrown 0.13.2", + "log", + "phf", + "phf_codegen", + "string_cache", + "string_cache_codegen", + "tendril", ] [[package]] @@ -1886,10 +2259,10 @@ dependencies = [ ] [[package]] -name = "matchit" -version = "0.7.2" +name = "matches" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed1202b2a6f884ae56f04cff409ab315c5ce26b5e58d7412e484f01fd52f52ef" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] name = "memchr" @@ -1897,6 +2270,24 @@ version = "2.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5486aed0026218e61b8a01d5fbd5a0a134649abb71a0e53b7bc088529dced86e" +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + [[package]] name = "memoffset" version = "0.9.0" @@ -1906,22 +2297,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "mime_guess" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" -dependencies = [ - "mime", - "unicase", -] - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -1935,6 +2310,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", + "simd-adler32", ] [[package]] @@ -1944,45 +2320,83 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "wasi", - "windows-sys", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.48.0", +] + +[[package]] +name = "ndk" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2032c77e030ddee34a6787a64166008da93f6a352b629261d0fee232b8742dd4" +dependencies = [ + "bitflags 1.3.2", + "jni-sys", + "ndk-sys", + "num_enum", + "thiserror", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5a6ae77c8ee183dcbbba6150e2e6b9f3f4196a7666c02a715a95692ec1fa97" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" + +[[package]] +name = "nix" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.6.5", ] [[package]] name = "nix-browser" version = "0.1.0" dependencies = [ - "axum", - "axum-macros", + "anyhow", "cfg-if", "clap", "console_error_panic_hook", "console_log", + "dioxus 0.4.2", + "dioxus-desktop", + "dioxus-router", + "dioxus-signals", + "dioxus-std", "http", "human-panic", - "hyper", - "leptos", - "leptos_axum", - "leptos_extra", - "leptos_meta", - "leptos_query", - "leptos_router", "nix_health", "nix_rs", - "open", "regex", "serde", "serde_json", "serde_with", "thiserror", "tokio", - "tower", - "tower-http", "tracing", "tracing-subscriber", - "tracing-subscriber-wasm", "uuid", - "wasm-bindgen", ] [[package]] @@ -2027,6 +2441,12 @@ dependencies = [ "url", ] +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + [[package]] name = "nom" version = "7.1.3" @@ -2056,17 +2476,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "num-bigint" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-integer" version = "0.1.45" @@ -2077,6 +2486,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.16" @@ -2096,6 +2516,75 @@ dependencies = [ "libc", ] +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + [[package]] name = "object" version = "0.32.0" @@ -2112,24 +2601,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] -name = "open" -version = "5.0.0" +name = "ordered-float" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfabf1927dce4d6fdf563d63328a0a506101ced3ec780ca2135747336c98cef8" +checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87" dependencies = [ - "is-wsl", - "libc", - "pathdiff", -] - -[[package]] -name = "ordered-multimap" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a" -dependencies = [ - "dlv-list", - "hashbrown 0.12.3", + "num-traits", ] [[package]] @@ -2150,10 +2627,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] -name = "pad-adapter" -version = "0.1.1" +name = "pango" +version = "0.16.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56d80efc4b6721e8be2a10a5df21a30fa0b470f1539e53d8b4e6e75faf938b63" +checksum = "cdff66b271861037b89d028656184059e03b0b6ccb36003820be19f7200b1e94" +dependencies = [ + "bitflags 1.3.2", + "gio", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e134909a9a293e04d2cc31928aa95679c5e4df954d0b85483159bd20d8f047f" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "parking" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e52c774a4c39359c1d1c52e43f73dd91a75a614652c825408eec30c95a9b2067" [[package]] name = "parking_lot" @@ -2175,21 +2678,9 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.48.5", ] -[[package]] -name = "paste" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" - -[[package]] -name = "pathdiff" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" - [[package]] name = "percent-encoding" version = "2.3.0" @@ -2197,48 +2688,76 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] -name = "pest" -version = "2.7.3" +name = "phf" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a4d085fd991ac8d5b05a147b437791b4260b76326baf0fc60cf7c9c27ecd33" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" dependencies = [ - "memchr", - "thiserror", - "ucd-trie", + "phf_macros", + "phf_shared 0.8.0", + "proc-macro-hack", ] [[package]] -name = "pest_derive" -version = "2.7.3" +name = "phf_codegen" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bee7be22ce7918f641a33f08e3f43388c7656772244e2bbb2477f44cc9021a" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" dependencies = [ - "pest", - "pest_generator", + "phf_generator 0.8.0", + "phf_shared 0.8.0", ] [[package]] -name = "pest_generator" -version = "2.7.3" +name = "phf_generator" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1511785c5e98d79a05e8a6bc34b4ac2168a0e3e92161862030ad84daa223141" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" dependencies = [ - "pest", - "pest_meta", + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", "proc-macro2", "quote", - "syn 2.0.29", + "syn 1.0.109", ] [[package]] -name = "pest_meta" -version = "2.7.3" +name = "phf_shared" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42f0394d3123e33353ca5e1e89092e533d2cc490389f2bd6131c43c634ebc5f" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" dependencies = [ - "once_cell", - "pest", - "sha2", + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", ] [[package]] @@ -2273,6 +2792,17 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "piper" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +dependencies = [ + "atomic-waker", + "fastrand 2.0.1", + "futures-io", +] + [[package]] name = "pkg-config" version = "0.3.27" @@ -2280,13 +2810,54 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] -name = "prettyplease" -version = "0.2.12" +name = "png" +version = "0.17.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64d9ba0963cdcea2e1b2230fbae2bab30eb25a174be395c41e764bfb65dd62" +checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" dependencies = [ - "proc-macro2", - "syn 2.0.29", + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.14", ] [[package]] @@ -2314,15 +2885,10 @@ dependencies = [ ] [[package]] -name = "proc-macro-utils" -version = "0.8.0" +name = "proc-macro-hack" +version = "0.5.20+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f59e109e2f795a5070e69578c4dc101068139f74616778025ae1011d4cd41a8" -dependencies = [ - "proc-macro2", - "quote", - "smallvec", -] +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" @@ -2333,39 +2899,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "proc-macro2-diagnostics" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.29", - "version_check", - "yansi", -] - -[[package]] -name = "ptr_meta" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" -dependencies = [ - "ptr_meta_derive", -] - -[[package]] -name = "ptr_meta_derive" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "quote" version = "1.0.33" @@ -2376,22 +2909,91 @@ dependencies = [ ] [[package]] -name = "quote-use" -version = "0.7.1" +name = "rand" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58e9a38ef862d7fec635661503289062bc5b3035e61859a8de3d3f81823accd2" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "derive-where", - "proc-macro2", - "quote", - "syn 2.0.29", + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", ] [[package]] -name = "radium" -version = "0.7.0" +name = "rand" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.10", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "raw-window-handle" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" [[package]] name = "rayon" @@ -2467,109 +3069,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] -name = "rend" -version = "0.4.0" +name = "rfd" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581008d2099240d37fb08d77ad713bcaec2c4d89d50b5b21a8bb1996bbab68ab" +checksum = "4fe664af397d2b6a13a8ba1d172a2b5c87c6c5149039edbf8fa122b98c9ed96f" dependencies = [ - "bytecheck", -] - -[[package]] -name = "reqwest" -version = "0.11.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" -dependencies = [ - "base64 0.21.3", - "bytes", - "encoding_rs", - "futures-core", + "async-io", + "block", + "dispatch", "futures-util", - "h2", - "http", - "http-body", - "hyper", - "ipnet", + "glib-sys", + "gobject-sys", + "gtk-sys", "js-sys", "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tower-service", - "url", + "objc", + "objc-foundation", + "objc_id", + "raw-window-handle", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg", -] - -[[package]] -name = "rkyv" -version = "0.7.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" -dependencies = [ - "bitvec", - "bytecheck", - "hashbrown 0.12.3", - "ptr_meta", - "rend", - "rkyv_derive", - "seahash", - "tinyvec", - "uuid", -] - -[[package]] -name = "rkyv_derive" -version = "0.7.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ron" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a" -dependencies = [ - "base64 0.13.1", - "bitflags 1.3.2", - "serde", -] - -[[package]] -name = "rstml" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe542870b8f59dd45ad11d382e5339c9a1047cde059be136a7016095bbdefa77" -dependencies = [ - "proc-macro2", - "proc-macro2-diagnostics", - "quote", - "syn 2.0.29", - "syn_derive", - "thiserror", -] - -[[package]] -name = "rust-ini" -version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df" -dependencies = [ - "cfg-if", - "ordered-multimap", + "windows 0.44.0", ] [[package]] @@ -2584,6 +3105,29 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.37.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4279d76516df406a8bd37e7dff53fd37d1a093f997a3c34a5c21658c126db06d" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + [[package]] name = "rustix" version = "0.38.11" @@ -2593,16 +3137,10 @@ dependencies = [ "bitflags 2.4.0", "errno", "libc", - "linux-raw-sys", - "windows-sys", + "linux-raw-sys 0.4.5", + "windows-sys 0.48.0", ] -[[package]] -name = "rustversion" -version = "1.0.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" - [[package]] name = "ryu" version = "1.0.15" @@ -2618,6 +3156,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" @@ -2625,16 +3169,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] -name = "seahash" -version = "4.1.0" +name = "selectors" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" +checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" +dependencies = [ + "bitflags 1.3.2", + "cssparser", + "derive_more", + "fxhash", + "log", + "matches", + "phf", + "phf_codegen", + "precomputed-hash", + "servo_arc", + "smallvec", + "thin-slice", +] [[package]] -name = "self_cell" -version = "1.0.1" +name = "semver" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c309e515543e67811222dbc9e3dd7e1056279b782e1dacffe4242b718734fb6" +checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0" [[package]] name = "serde" @@ -2645,6 +3203,16 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +dependencies = [ + "ordered-float", + "serde", +] + [[package]] name = "serde-wasm-bindgen" version = "0.5.0" @@ -2673,30 +3241,20 @@ version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" dependencies = [ - "itoa", + "itoa 1.0.9", "ryu", "serde", ] [[package]] -name = "serde_path_to_error" -version = "0.1.14" +name = "serde_repr" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4beec8bce849d58d06238cb50db2e1c417cfeafa4c63f692b15c82b7c80f8335" +checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ - "itoa", - "serde", -] - -[[package]] -name = "serde_qs" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0431a35568651e363364210c91983c1da5eb29404d9f0928b67d4ebcfa7d330c" -dependencies = [ - "percent-encoding", - "serde", - "thiserror", + "proc-macro2", + "quote", + "syn 2.0.29", ] [[package]] @@ -2708,15 +3266,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_test" -version = "1.0.176" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a2f49ace1498612d14f7e0b8245519584db8299541dfe31a06374a828d620ab" -dependencies = [ - "serde", -] - [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -2724,7 +3273,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa", + "itoa 1.0.9", "ryu", "serde", ] @@ -2752,60 +3301,20 @@ version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e6be15c453eb305019bfa438b1593c731f36a289a7853f7707ee29e870b3b3c" dependencies = [ - "darling 0.20.3", + "darling", "proc-macro2", "quote", "syn 2.0.29", ] [[package]] -name = "server_fn" -version = "0.4.10" +name = "servo_arc" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fcddd58a35e4fd00f15dac8f2fc08deed175d8178b2c3e615f59a7e7be6fed7" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" dependencies = [ - "ciborium", - "const_format", - "gloo-net 0.2.6", - "inventory", - "js-sys", - "lazy_static", - "once_cell", - "proc-macro2", - "quote", - "reqwest", - "serde", - "serde_json", - "serde_qs", - "server_fn_macro_default", - "syn 2.0.29", - "thiserror", - "xxhash-rust", -] - -[[package]] -name = "server_fn_macro" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9083155d5a075eda2d08f18663e4789e0d447a1000b225bc4e1746e849c95c8e" -dependencies = [ - "const_format", - "proc-macro-error", - "proc-macro2", - "quote", - "serde", - "syn 2.0.29", - "xxhash-rust", -] - -[[package]] -name = "server_fn_macro_default" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dba6c99de6539ec3193130f764427ead9d784a76ca3126f38e56a6a0b7a2f3d" -dependencies = [ - "server_fn_macro", - "syn 2.0.29", + "nodrop", + "stable_deref_trait", ] [[package]] @@ -2844,10 +3353,28 @@ dependencies = [ ] [[package]] -name = "simdutf8" -version = "0.1.4" +name = "simd-adler32" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "simple_logger" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2230cd5c29b815c9b699fb610b49a5ed65588f3509d9f0108be3a885da629333" +dependencies = [ + "colored", + "log", + "time", + "windows-sys 0.42.0", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "slab" @@ -2859,14 +3386,10 @@ dependencies = [ ] [[package]] -name = "slotmap" -version = "1.0.6" +name = "smallbox" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" -dependencies = [ - "serde", - "version_check", -] +checksum = "d92359f97e6b417da4328a970cf04a044db104fbd57f7d72cb7ff665bb8806af" [[package]] name = "smallvec" @@ -2874,6 +3397,34 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +[[package]] +name = "smithay-client-toolkit" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "870427e30b8f2cbe64bf43ec4b86e88fe39b0a84b3f15efd9c9c2d020bc86eb9" +dependencies = [ + "bitflags 1.3.2", + "dlib", + "lazy_static", + "log", + "memmap2", + "nix", + "pkg-config", + "wayland-client", + "wayland-cursor", + "wayland-protocols", +] + +[[package]] +name = "smithay-clipboard" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a345c870a1fae0b1b779085e81b51e614767c239e93503588e54c5b17f4b0e8" +dependencies = [ + "smithay-client-toolkit", + "wayland-client", +] + [[package]] name = "socket2" version = "0.4.9" @@ -2891,7 +3442,76 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2538b18701741680e0322a2302176d3253a35388e2e62f172f64f4f16605f877" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "soup3" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82bc46048125fefd69d30b32b9d263d6556c9ffe82a7a7df181a86d912da5616" +dependencies = [ + "bitflags 1.3.2", + "futures-channel", + "gio", + "glib", + "libc", + "once_cell", + "soup3-sys", +] + +[[package]] +name = "soup3-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "014bbeb1c4cdb30739dc181e8d98b7908f124d9555843afa89b5570aaf4ec62b" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "spinning" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d4f0e86297cad2658d92a707320d87bf4e6ae1050287f51d19b67ef3f153a7b" +dependencies = [ + "lock_api", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "string_cache" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +dependencies = [ + "new_debug_unreachable", + "once_cell", + "parking_lot", + "phf_shared 0.10.0", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", + "proc-macro2", + "quote", ] [[package]] @@ -2922,24 +3542,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "syn_derive" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8128874d02f9a114ade6d9ad252078cb32d3cb240e26477ac73d7e9c495c605e" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.29", -] - -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - [[package]] name = "sysinfo" version = "0.29.10" @@ -2956,10 +3558,98 @@ dependencies = [ ] [[package]] -name = "tap" -version = "1.0.1" +name = "system-deps" +version = "6.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +checksum = "94af52f9402f94aac4948a2518b43359be8d9ce6cd9efc1c4de3b2f7b7e897d6" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml 0.8.2", + "version-compare", +] + +[[package]] +name = "tao" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "746ae5d0ca57ae275a792f109f6e992e0b41a443abdf3f5c6eff179ef5b3443a" +dependencies = [ + "bitflags 1.3.2", + "cairo-rs", + "cc", + "cocoa", + "core-foundation", + "core-graphics", + "crossbeam-channel", + "dispatch", + "gdk", + "gdk-pixbuf", + "gdk-sys", + "gdkwayland-sys", + "gdkx11-sys", + "gio", + "glib", + "glib-sys", + "gtk", + "image", + "instant", + "jni 0.20.0", + "lazy_static", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "objc", + "once_cell", + "parking_lot", + "png", + "raw-window-handle", + "scopeguard", + "serde", + "tao-macros", + "unicode-segmentation", + "uuid", + "windows 0.44.0", + "windows-implement", + "x11-dl", +] + +[[package]] +name = "tao-macros" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec114582505d158b669b136e6851f85840c109819d77c42bb7c0709f727d18c2" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "target-lexicon" +version = "0.12.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" + +[[package]] +name = "tendril" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" +dependencies = [ + "futf", + "mac", + "utf-8", +] + +[[package]] +name = "thin-slice" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" [[package]] name = "thiserror" @@ -2998,7 +3688,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" dependencies = [ "deranged", - "itoa", + "itoa 1.0.9", + "libc", + "num_threads", "serde", "time-core", "time-macros", @@ -3034,6 +3726,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "to_method" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c4ceeeca15c8384bbc3e011dbd8fccb7f068a440b752b7d9b32ceb0ca0e2e8" + [[package]] name = "tokio" version = "1.32.0" @@ -3050,7 +3748,7 @@ dependencies = [ "signal-hook-registry", "socket2 0.5.3", "tokio-macros", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -3064,31 +3762,6 @@ dependencies = [ "syn 2.0.29", ] -[[package]] -name = "tokio-util" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "futures-util", - "hashbrown 0.12.3", - "pin-project-lite", - "tokio", - "tracing", -] - -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - [[package]] name = "toml" version = "0.7.6" @@ -3098,7 +3771,19 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.19.14", +] + +[[package]] +name = "toml" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.20.2", ] [[package]] @@ -3124,63 +3809,18 @@ dependencies = [ ] [[package]] -name = "tower" -version = "0.4.13" +name = "toml_edit" +version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" dependencies = [ - "futures-core", - "futures-util", - "pin-project", - "pin-project-lite", - "tokio", - "tower-layer", - "tower-service", - "tracing", + "indexmap 2.0.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", ] -[[package]] -name = "tower-http" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ae70283aba8d2a8b411c695c437fe25b8b5e44e23e780662002fc72fb47a82" -dependencies = [ - "async-compression", - "base64 0.21.3", - "bitflags 2.4.0", - "bytes", - "futures-core", - "futures-util", - "http", - "http-body", - "http-range-header", - "httpdate", - "iri-string", - "mime", - "mime_guess", - "percent-encoding", - "pin-project-lite", - "tokio", - "tokio-util", - "tower", - "tower-layer", - "tower-service", - "tracing", - "uuid", -] - -[[package]] -name = "tower-layer" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - [[package]] name = "tracing" version = "0.1.37" @@ -3188,7 +3828,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -3244,55 +3883,12 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "tracing-subscriber-wasm" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79804e80980173c6c8e53d98508eb24a2dbc4ee17a3e8d2ca8e5bad6bf13a898" -dependencies = [ - "gloo", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "try-lock" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" - -[[package]] -name = "typed-builder" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64cba322cb9b7bc6ca048de49e83918223f35e7a86311267013afff257004870" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "typenum" version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" -[[package]] -name = "ucd-trie" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" - -[[package]] -name = "unicase" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] - [[package]] name = "unicode-bidi" version = "0.3.13" @@ -3320,12 +3916,6 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" -[[package]] -name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" - [[package]] name = "url" version = "2.4.1" @@ -3339,10 +3929,16 @@ dependencies = [ ] [[package]] -name = "utf8-width" -version = "0.1.6" +name = "urlencoding" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5190c9442dcdaf0ddd50f37420417d219ae5261bbf5db120d0f9bab996c9cba1" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "utf8parse" @@ -3356,7 +3952,7 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" dependencies = [ - "getrandom", + "getrandom 0.2.10", "serde", "wasm-bindgen", ] @@ -3367,12 +3963,24 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "version-compare" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" + [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "waker-fn" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" + [[package]] name = "walkdir" version = "2.3.3" @@ -3384,13 +3992,10 @@ dependencies = [ ] [[package]] -name = "want" -version = "0.3.1" +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasi" @@ -3464,6 +4069,79 @@ version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +[[package]] +name = "wayland-client" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715" +dependencies = [ + "bitflags 1.3.2", + "downcast-rs", + "libc", + "nix", + "scoped-tls", + "wayland-commons", + "wayland-scanner", + "wayland-sys", +] + +[[package]] +name = "wayland-commons" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" +dependencies = [ + "nix", + "once_cell", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-cursor" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" +dependencies = [ + "nix", + "wayland-client", + "xcursor", +] + +[[package]] +name = "wayland-protocols" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" +dependencies = [ + "bitflags 1.3.2", + "wayland-client", + "wayland-commons", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53" +dependencies = [ + "proc-macro2", + "quote", + "xml-rs", +] + +[[package]] +name = "wayland-sys" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4" +dependencies = [ + "dlib", + "lazy_static", + "pkg-config", +] + [[package]] name = "web-sys" version = "0.3.64" @@ -3474,6 +4152,105 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webbrowser" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2c79b77f525a2d670cb40619d7d9c673d09e0666f72c591ebd7861f84a87e57" +dependencies = [ + "core-foundation", + "home", + "jni 0.21.1", + "log", + "ndk-context", + "objc", + "raw-window-handle", + "url", + "web-sys", +] + +[[package]] +name = "webkit2gtk" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8eea819afe15eb8dcdff4f19d8bfda540bae84d874c10e6f4b8faf2d6704bd1" +dependencies = [ + "bitflags 1.3.2", + "cairo-rs", + "gdk", + "gdk-sys", + "gio", + "gio-sys", + "glib", + "glib-sys", + "gobject-sys", + "gtk", + "gtk-sys", + "javascriptcore-rs", + "libc", + "once_cell", + "soup3", + "webkit2gtk-sys", +] + +[[package]] +name = "webkit2gtk-sys" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0ac7a95ddd3fdfcaf83d8e513b4b1ad101b95b413b6aa6662ed95f284fc3d5b" +dependencies = [ + "bitflags 1.3.2", + "cairo-sys-rs", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk-sys", + "javascriptcore-rs-sys", + "libc", + "pkg-config", + "soup3-sys", + "system-deps", +] + +[[package]] +name = "webview2-com" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11296e5daf3a653b79bf47d66c380e4143d5b9c975818871179a3bda79499562" +dependencies = [ + "webview2-com-macros", + "webview2-com-sys", + "windows 0.44.0", + "windows-implement", +] + +[[package]] +name = "webview2-com-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaebe196c01691db62e9e4ca52c5ef1e4fd837dcae27dae3ada599b5a8fd05ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "webview2-com-sys" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cde542bed28058a5b028d459689ee57f1d06685bb6c266da3b91b1be6703952f" +dependencies = [ + "regex", + "serde", + "serde_json", + "thiserror", + "windows 0.44.0", + "windows-bindgen", + "windows-metadata", +] + [[package]] name = "which" version = "4.4.2" @@ -3483,7 +4260,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix", + "rustix 0.38.11", ] [[package]] @@ -3511,19 +4288,101 @@ dependencies = [ "winapi", ] +[[package]] +name = "winapi-wsapoll" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c17110f57155602a80dca10be03852116403c9ff3cd25b079d666f2aa3df6e" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-targets 0.42.2", +] + [[package]] name = "windows" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-bindgen" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222204ecf46521382a4d88b4a1bbefca9f8855697b4ab7d20803901425e061a3" +dependencies = [ + "windows-metadata", + "windows-tokens", +] + +[[package]] +name = "windows-implement" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce87ca8e3417b02dc2a8a22769306658670ec92d78f1bd420d6310a67c245c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "windows-interface" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "853f69a591ecd4f810d29f17e902d40e349fb05b0b11fff63b08b826bfe39c7f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "windows-metadata" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee78911e3f4ce32c1ad9d3c7b0bd95389662ad8d8f1a3155688fed70bd96e2b6" + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", ] [[package]] @@ -3532,7 +4391,22 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] @@ -3541,51 +4415,99 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows-tokens" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4251900975a0d10841c5d4bde79c56681543367ef811f3fabb8d1803b0959b" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -3602,71 +4524,107 @@ dependencies = [ ] [[package]] -name = "winreg" -version = "0.50.0" +name = "wry" +version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys", -] - -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "xxhash-rust" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "735a71d46c4d68d71d4b24d03fdc2b98e38cea81730595801db779c04fe80d70" - -[[package]] -name = "yaml-rust" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "yansi" -version = "1.0.0-rc.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1367295b8f788d371ce2dbc842c7b709c73ee1364d30351dd300ec2203b12377" - -[[package]] -name = "zstd" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "6.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" +checksum = "7d15f9f827d537cefe6d047be3930f5d89b238dfb85e08ba6a319153217635aa" dependencies = [ + "base64 0.13.1", + "block", + "cocoa", + "core-graphics", + "crossbeam-channel", + "dunce", + "gdk", + "gio", + "glib", + "gtk", + "html5ever", + "http", + "javascriptcore-rs", + "kuchiki", "libc", - "zstd-sys", + "log", + "objc", + "objc_id", + "once_cell", + "serde", + "serde_json", + "sha2", + "soup3", + "tao", + "thiserror", + "url", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows 0.44.0", + "windows-implement", ] [[package]] -name = "zstd-sys" -version = "2.0.8+zstd.1.5.5" +name = "x11" +version = "2.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" +checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" dependencies = [ - "cc", "libc", "pkg-config", ] + +[[package]] +name = "x11-clipboard" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "980b9aa9226c3b7de8e2adb11bf20124327c054e0e5812d2aac0b5b5a87e7464" +dependencies = [ + "x11rb", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "x11rb" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "592b4883219f345e712b3209c62654ebda0bb50887f330cbd018d0f654bfd507" +dependencies = [ + "gethostname", + "nix", + "winapi", + "winapi-wsapoll", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56b245751c0ac9db0e006dc812031482784e434630205a93c73cfefcaabeac67" +dependencies = [ + "nix", +] + +[[package]] +name = "xcursor" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7" +dependencies = [ + "nom", +] + +[[package]] +name = "xml-rs" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" diff --git a/Cargo.toml b/Cargo.toml index fc4a6f1..d57f458 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,22 +10,16 @@ repository = "https://github.com/juspay/nix-browser" cfg-if = "1" clap = { version = "4.3", features = ["derive", "env"] } human-panic = "1.1.5" -leptos = { version = "0.4", features = ["serde", "nightly"] } -leptos_meta = { version = "0.4", features = ["nightly"] } -leptos_router = { version = "0.4", features = ["nightly"] } -leptos_query = "0.2" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } -tracing-subscriber-wasm = "0.1" -wasm-bindgen = "=0.2.87" # The version here must match the pinned stuff in Nix flakes. nix_rs = { version = "0.2", path = "./crates/nix_rs" } nix_health = { path = "./crates/nix_health" } -leptos_extra = { path = "./crates/leptos_extra" } thiserror = "1.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" serde_with = { version = "3.2", features = ["json"] } bytesize = { version = "1.3.0", features = ["serde"] } +anyhow = "1.0.75" [package] edition = "2021" @@ -37,89 +31,29 @@ homepage = "https://github.com/juspay/nix-browser" [package.metadata.docs.rs] all-features = true -[lib] -crate-type = ["cdylib", "rlib"] - # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -axum = { version = "0.6", features = ["json", "tokio"], optional = true } -axum-macros = { version = "0.3", optional = true } +anyhow.workspace = true cfg-if.workspace = true clap.workspace = true console_error_panic_hook = "0.1" -console_log = { version = "1" } -http = { version = "0.2", optional = true } +console_log = "1" +http = "0.2" human-panic.workspace = true -hyper = { version = "0.14", features = ["server"], optional = true } -leptos.workspace = true -leptos_axum = { version = "0.4", optional = true } -leptos_meta.workspace = true -leptos_router.workspace = true -leptos_query.workspace = true regex = "1.9.3" -open = { version = "5.0", optional = true } serde.workspace = true serde_json.workspace = true serde_with.workspace = true thiserror.workspace = true -tokio = { version = "1.29", features = ["full"], optional = true } -tower = { version = "0.4", optional = true } -tower-http = { version = "0.4", features = ["full"], optional = true } +tokio = { version = "1", features = ["full"] } tracing.workspace = true tracing-subscriber.workspace = true -tracing-subscriber-wasm.workspace = true uuid = { version = "1.3.0", features = ["serde", "v4", "js"] } -wasm-bindgen.workspace = true nix_rs.workspace = true nix_health.workspace = true -leptos_extra.workspace = true - -[features] -default = [ - "ssr", -] # Unfortunately, leptos_query won't compile (in `nix build`) without this -hydrate = [ - "leptos/hydrate", - "leptos_meta/hydrate", - "leptos_query/hydrate", - "leptos_router/hydrate", - "leptos_extra/hydrate", -] -ssr = [ - "dep:axum-macros", - "dep:axum", - "dep:http", - "dep:hyper", - "dep:leptos_axum", - "dep:open", - "dep:tokio", - "dep:tower-http", - "dep:tower", - "leptos/ssr", - "leptos_meta/ssr", - "leptos_query/ssr", - "leptos_router/ssr", - "leptos_extra/ssr", - "nix_rs/ssr", - "nix_health/ssr", -] - -# Defines a size-optimized profile for the WASM bundle in release mode -[profile.wasm-release] -inherits = "release" -opt-level = 'z' -lto = true -codegen-units = 1 -panic = "abort" - -[package.metadata.leptos] -site-addr = "127.0.0.1:3000" -tailwind-input-file = "css/input.css" -assets-dir = "assets" -bin-features = ["ssr"] -lib-features = ["hydrate"] -# The profile to use for the lib target when compiling for release -# -# Optional. Defaults to "release". -lib-profile-release = "wasm-release" +dioxus = { git = "https://github.com/DioxusLabs/dioxus.git", rev = "459f24d5e9ef0e03a3bbd037342c60bbde409dbf" } +dioxus-desktop = { git = "https://github.com/DioxusLabs/dioxus.git", rev = "459f24d5e9ef0e03a3bbd037342c60bbde409dbf" } +dioxus-router = { git = "https://github.com/DioxusLabs/dioxus.git", rev = "459f24d5e9ef0e03a3bbd037342c60bbde409dbf" } +dioxus-signals = { git = "https://github.com/DioxusLabs/dioxus.git", rev = "459f24d5e9ef0e03a3bbd037342c60bbde409dbf" } +dioxus-std = { version = "0.4.0", features = ["clipboard", "utils"] } diff --git a/Dioxus.toml b/Dioxus.toml new file mode 100644 index 0000000..31662a7 --- /dev/null +++ b/Dioxus.toml @@ -0,0 +1,45 @@ +[application] +name = "nix-browser" +default_platform = "desktop" +out_dir = "dist" +asset_dir = "assets" + +[web.app] +title = "nix-browser | 🌍" + +[web.watcher] +# when watcher trigger, regenerate the `index.html` +reload_html = true +# which files or dirs will be watcher monitoring +watch_path = ["src", "assets"] + +[web.resource] +# CSS style file +style = ["tailwind.css"] +# Javascript code file +script = [] + +[web.resource.dev] +# CSS style file +style = [] +# Javascript code file +script = [] + +# FIXME: Need to `cd assets` before running `dx bundle` due to https://github.com/DioxusLabs/dioxus/issues/1283 +[bundle] +name = "Nix Browser" +identifier = "in.juspay.nix-browser" +icon = ["images/128x128.png"] # ["32x32.png", "128x128.png", "128x128@2x.png"] +version = "1.0.0" +# TODO: Must add these files +resources = ["**/tailwind.css", "images/**/*.png"] # , "secrets/public_key.txt"] +copyright = "Copyright (c) Juspay 2023. All rights reserved." +category = "Developer Tool" +short_description = "WIP: nix-browser" +long_description = """ +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do +eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut +enim ad minim veniam, quis nostrud exercitation ullamco laboris +nisi ut aliquip ex ea commodo consequat. +""" +osx_frameworks = [] diff --git a/README.md b/README.md index 88535cf..bd0a032 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # nix-browser -🚧 This project is a work in progress. The ultimate goal is to create something that inspires people towards [Nix](https://zero-to-flakes.com/). +🚧 This project is a work in progress. The ultimate goal is to create a GUI app that inspires people towards using [Nix](https://zero-to-flakes.com/). ## Getting Started @@ -15,12 +15,17 @@ This will automatically activate the nix develop shell. Open VSCode and install ## Running locally -In nix shell, +We should run two watchers: one for generating Tailwind CSS (`just tw`) and another running the cargo package (`just watch`). In nix shell, ``` +# In one terminal, just watch +# In another, +just tw ``` +`just watch` runs `dx serve` (with hot reload disabled) that will restart the desktop app after compilation. + ## Nix workflows Inside the nix develop shell (activated by direnv) you can use any of the `cargo` or `rustc` commands, as well as [`just`](https://just.systems/) workflows. Nix specific commands can also be used to work with the project: @@ -38,14 +43,13 @@ nix run - When you are done with your changes, run `just fmt` to **autoformat** the source tree; the CI checks for this. - Add tests if relevant, and run them: - Run `just test` to run the **unit tests**. - - Run `just e2e` (requires `just watch` to be running) or `just e2e-release` to run the **end-to-end tests** - Add documentation wherever useful. To preview the **docs**, run `just doc`. -## Frontend tech +## Tech -### Rust wasm +### Rust desktop app -We use [Leptos](https://leptos.dev/). With sufficient knowledge of Rust, you can 🎓 read the [Leptos Book](https://leptos-rs.github.io/leptos/) to get familiar with reactive frontend programming in Rust. +We use [Dioxus](https://dioxuslabs.com/) to build the desktop app using web technologies. The yet to be released [dioxus-signals](https://github.com/DioxusLabs/dioxus/tree/master/packages/signals) package is also used for data reactivity. ### Styling diff --git a/assets/images/128x128.png b/assets/images/128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..2850afcc5b816a0cc8df30a30b41ed0ee2555eea GIT binary patch literal 8817 zcmZX4WmFwY)9!5C*;sJfkl<`2_{ItDE(sbmSdifEf#AX2-Q696I{|`AAV6?}bIJRj zd%o|k+p}t_y5^~;s`}5Yo}MseMJY@)5;On+FlD4ARG+o)UqL~7zV`|ljXW!mqpFk` zP%%!n|2zpa)s`_+PyiU8Z4>|zgbTp`g*;yXhy+0Vj|~8_Aku$rRS^9@7&rh3u>=tQ z!RS8gzeD<2o}>TK@L8b$Va$U27www`|3CKMu+}fUpEv& z^&g1S2SJFof-;r3or5VAH!B+}8$<|=ii!&6@ZOAHRYLNg@aLHz#KOtRo*xQzadBaF z;bgUQFo&}9@$o^~IG`LHEYAoQM>kt1BUct%N1FeV{9hgkQ%4gAOM53vJ6o#1yhg@$ z&Q5|5$lpZ&j{nx_WNG$4nQR^ZY3sQ`=-($$c2+j%zueEEu)kh@B?n8>=gfckh1g;L zLH<9!fAYYff0O^OV*cCdf4tAF3ZcQE|1O&l8nONcG5}Cf%Sec-yMm71p{9{(BtPkE zP;$z=T8LH)l-M2uvD1Y*yvG6OR-h~9R7jz)q3WE3bou8*V^I{L9H33nLX3=Vh&jkw z?_rwprqT4Yw0`s(C|Yc!a2PVX(q;v%rN54zJSwdU21lJVlw36a?7{Z-70Hji2A{l+ zJ=R)7k!G?GkY2LU`-!4r$Qmlc1>h3Jcm3gqA@~KU~j*agbgbIr-G8R|foBq+)ee;&w6^O1_C)jD09lU&bjFqeH$t-g& z&9RSydvzL|C*!&!7=1j)#6r8SiHfRr$FTKPe*=_CPvQ$f^$C+z!q zWYr%?X1mUyTb#w7w^dR?cP$^PDKet*xZc+j$92H>16yIdeG7tCV{1wbq2;uu?@HdJl*EE+4+BTT}(9q3orP^Q!XX^-;F)+PXmK8E}I@vk3;F#tMWZd zXmQ+T?-y@cq;ZDN8Z>>B;*pJqfQ0 zTE}d|%wns#SjvAEZEP=G!e4vrny~Yqe+*G&z;=7r$hbdfBvwqc*)&k;3km$N3l-wU z;=Uu}*bWK8FN`716f=t*`ehjOR3DuTHCR0ZvUu3p=pB6h?#BYD;5A=)RAKhp#7*C@ zP%K&~+|A*=`&_vUgexQ8I;57a)<7q?45;5IzGyr>CsnXYvtw}N|23%&x${)-a8xce z7u%m3P7`=h(yWT2H6nuc^g$mDq068Xi_N~ZM0Q3()h5fVdwLu9s)tLKC#T_* z%tzYziSa`))dt*KH+q%EOFgH@D;h2u<^c8P3uS&slDA9|u8M}9rvh8WjBcpj?+~Nh z5vbYlOwktMF2+B9hKj6ByG?^RzIND+)BF-e5+!blc*#@R?s%lHA&R?zr$5hu{kand z4AZ(?BcF}OZ8&z@x3^0`1X`@a%tWQ>&bf_=OIh^Fa)Naf_(SvH-ep{(_eiQtNSM3B zb_(A|uv&IV@NQCn#^fVpfu-&2eKm-m{p_RD#pe_l`UMZt43Ttj&aoW{>s#q-!L+7; zlqO99B8cK$Ki;t9TH1{?t`n~KFA2pQVvX1YLQI-mSH3bMiz8MYD(Vpp+z@$ao3k!` zqTph#V<$p%lYsX>0d*--aMqVS2v)h58eLV25*8z2(VPR|NsmN$ zX(W;8gr253t5O}APN5gw(I+BcMHY20Pib4XWqkT4Zi#d4n+*Dqa!-^+i6^pbJ%M&g z3Ae0^J*J;LDe$~~!7&o+=PB9>=Nj)$W1~|7rkQ%ruMV&?=mWiY;-5e$Eoowx!)9;9 zn^0$~oCIJel*wbQ`ZR@(T=L9}VlOvY?V%$*mo&a*hU;7JVVDDdAJ=$XF7j=$j3B6Y~?$&Rr+fq zWz%Gl0i_$lhA-?AS0Pm1puloO1LGX@5v&!ZP&J07YM-!;rHPqeDO`-$mN|r~GF+X= z=2=%2QS*xUx-k(@V^DAt5W zcNNXcK=y;At!QgWkOdLN7sU6(`?-MM7vC6mv+|$f4%OJbrKjpG<4`EGg*dcw!n&+N7LjfV=He%MD}4*BIrQ+aloSqE9h19#OrCB9Y&Y&^4Zy^mwd z8LST6$&hX(2WfVY6!4o-U7qiMra6%Ir3Zq-3?`gErE94+m)&O3?p zv5X6I3)_f~;mXxJ(Zn7;KiDer`zIop=h5&%faYDtMpfxT*F}`(!+Z?`r48*PGJ>7U zk^r=@Ui{A|smU`GEobaS>h~8V#pd_#_E95Qa!SPX!N*lE2;{7VLF@C6@`qwz`W$>EFp9tYR!3W?-FiJ87wd^3Ydadh*4RF=PP0^lHD^eG+ z$EFKL+W1@owNAm%y-UA+E=b7gX?om*y5972v^Sx_cDR)wrIv}Cz_*lxJ?^Pr<0Vro zu*^et!hFJmAKzd#|LJz9EGE4{Q^{6`ROS1Cb{Ad{KrZ%p{u#bT+JW)>jjR z^ke|TLNDR|$ht;mH0RJ3&2Ki_+*LWv4lkN=g2naW1*~ihje42yo3(p&vohkIOCQse zV&-b_53p^!t1iu`N)gpbfdINfv|5xB%sXq(sd+W^{6i`0tSVb7kNY-ByL~@muo3wy z_Pxc{sZ^gbu(V+lwIh_V2kmxo@5S71A==^A8s`@H@FBc;QoSHx3sE40B0PA5$l}py zbmfj7!4u6ldeXNNOm@;k%lQ$%?0ctgNMX?_29lNNe2MQT(pSMZ`eC53c7tX_{!THT zq; zJ>md+3>V@7C6-C@;c6Y^i~@x-|6)%yo_l2~(BOC8k8*ae<8oOi17-Y40sYxf$mb@G zB;$An7vb<0HT=YAhi(r9^%iJi_K4T;_vvz`Ue^EG?(^FefEFZH0*a1%<7yK2J6vC; zFwhQ6P-JS(7AYjYyT@BID17Pb(@HQ@i)?-bHIO>ffvMLJGCMCVf_ViyEM_oF+kcV39dLaQutsvLxAmGqu(-!d8Xt?ONe)8-T3QDc zz{=)tl|F<#X%W*Ny+A$iCFo2J=Hu~y;J-%j0Z?Fk2_S^5LD5PLBDx%{RuMcMLTwnu z#*M-E4aOz;Q7Ju-9Nqj8bgo?4GI!1}vq*}ZI;1X1G2(XR>e4H#JnV}A8U^T%H# z?jgKk*tr;$91@sttb}o-r6RufC|;*Qx?Ha-x3?ymg@Nzgo7ImmYmgpy7LykBF!kMH zg9fX782SaX(}haU3F2LuR=7%Zjyk#nluhLTkbo{AdMj++_TDsv1w=pJh3~-;MucDw zXRRM7UyDb6RLE3)608l16$aYmjag9cCt*i7@c2`-um8a0=4DM(`$#YjY&E^SY$F+| z8NgW|?kD5D7R%0^5#r`^9b9X|zzCDb4Rn5X++=HoC1^SBaF6b1$i55hxVtbaPsSzE z3O9;4qf*ePV43(RBgtm&2U4_ypTP=Qt!d~~ylw{bv0BEc*U(7;U(crEQ08hOWgTDm zI7K-{GCrNJWQJJT*uYx^7H@LQ2*Je7!~0@GIRwD>eijM6P4S10f-q^d!JIdCbj&wy z5z&m7uJ+^l(Jt`c4o4U@RScD1iO9H7_+7C}2M+b&4-Yf^5}hL-Jx80A@B zWaGZQDTvU{VR$6aJMZkVfYhwh|2JPtkOflCHoyW(@iVcMO1Hb)!Uk}U-?&)AB`|ZM z8^QaIuuU!xi5dEo&5jYkiz$2?j(6fID9V*Z@+_r|V$d+k5Roc3`1A-wpIKa3elc_NX=f*5ny=Y#f#jg)WYS@&((*nO)nJc>Q?H{2X zK+>WISSMuAJl}#YH2(sKG zBQFj5Szm0i9jB%{=`hMfBlP9 z7`SGB7du6^l`Y-hqgHE$5**-Z@|~dUvRB6Ac#l?-J!+1})7jzr?xCfpBmm~6>J3=X zSyz72Z)+H(8#J~(CqYPvijPz0{t82`0t?y10OojTZuw2-i`kl~1#L%(O5Q-;cZ)EW zi$J7>w40spPj?w-#LY8d6Ns8&?R%h%=_4s$)N9~y`;!Y|&lVa-uLC=o&C<4(q&JXt z2WLtZNSux3%8fpyUQ&Mf#rTF@>+x>MY9OLdLOqk+7D{Jb(^OzA7CmDt$G@$Wgbg%t z@Cz)aNo;l*(u%M+(T2@*kqb7ai}H5ieX8L_%E~|ix)3A`r@r5#TXE#=ka}Gp0#_A2 z3g0rt>y7BC1yS^C_63RTf8?3qE_f9qPi%{0^?Vtrf$O?&b{Z`{!gmf;E zeQoX$^`cL*+wZNfsSJPNfO|57+A!1Q+=j#s)P(wfOukksEARgO)!ax3I5Sow`DFay zh|%>uPAI8=Kg@b7C?_K3rp*_|kpaB*X&e-*5mDX~avH`2p^w!R-L`$ubvtae&0 zKiRXB`{^xLuJlQ6p6eHWekW-`rI<&6jg8wbbOo(V&{A|cVDg#q}+$cOC49sPFiX7~3?h}eo0 zRe(XofU1X(_C9u}gom;hTF-kjc%Yl8ZfLoVAaa@p8ER%tFIflGLRKu%=)OrVCiAr5 zH{oyuy$Ynr_v(}`+5*5Wz=d&xYzIMJ-#xI-=a-gOP28&Ne1=^&P-24~>ozq}ML@;u z6cJw9a$e#DX7ehdcTOENQ42?BCntl~iwTQxQ4#-WOk-;0NiLF5j16d73~yn*dd;5- zF8mppf@bc_L_2CgMqn&5((kmNeO_l6aO_L)%G7K3U7;xnr-_08YLte8P9}EZ1=0ap zYZ3JoP5Sdzhops^mFOHljuOxZo6VhgsgiVl)IyO$GM^ml07SrcN7BhJsvC^RV=@6F+gX8*%UB|`f?^qw>u9HmMHOW zjA^5A=R)m5#3wl~VCkI?((2))v8roH<(Bf6wG#4z{}o_JD#kE}-j#E9*?C5rexs5Qb?jAb!cyGPM=SmC{4sMBH6 zm3M%Dy27X1aStor@q}9*6i*o}(A4AhKH~QnT*FS-GMh_z$pfNdUQiyIjK~Alkxeh2 z-qHJIVc)%Vl*SL*(vsAI;j%-1JVM>-q14LPi#^p7lC?ijl?`WPesUSTbm6nBKgu>` zNk1`ME#T_4)2in~c|*1@*G;WS;dAFqe<;=#&eMFBNbRRpXBDNZ?$yb-;y8~^6;ynz zgj=Wm>Wjqkigtj0;X}sbd%Rx)Wdur`7I}swyu7(r0%D`VE);tfi!5{zN%%t~MQqT9 z(8|P9?el~Ks-^=YovKt*+Enw)mqm&a!_X?qq&uc6v{?Vf2mRpgbdh7s2bO(S5YO9H zxSh^&vYw1TOdAFmw!2E_p$$L`M`}$7^M!HE?9{+Jy+iS;=}b-TJ1gT2l@qsMI;wC-$kC+^y;MDpC$fSct=lpN6$N78XE9J zR`2IED{#a_)1eQ8S2SaRu}0tP5V* z(pGrGShSfLxg<4VlOXx-2%^+1Eu?2?N~?71xk7ZVQDGvdJ}71W4~iEtRP>P*r=IOG zG~N(B-9i+aYVD}N;;U-;o?mowC8>oQbtEAb!@VO2c3jR6~IsNAisl_dYW}I-)BTwoOXd1t4w&tY8%~?;f z?}cqM$&qv^2VbwB;Burngd1ySQkX`W5fFo$l*OIxqP{-x|oNgnyQgwnj*-Eh#4W3jAy z)5wI&SBzMBSx_6h#59QOpdDyPF>y4XuL5N%mvTE8WMeWTco#+XicB$1-TM5__F_V9DI`s8KB4TS(T;9L7iv`eCM?i1HQNvEG0%ZDG__4j6TJNkyW`HKyt z9KMSs7;%+{bXG!L`!KoSc3zLQZ_BOQ`x6{`u*BgYZx$YhEn^Fh z+2)3*Drly4)TB5@6p%Bvx#}41fM;?wp zV;;&Xgt3ilap%8%-k<}l3+dX!GbI)mG3cUQTI*!v&)<7obl761)G2^2_JNjkEormJ@8ii1hd8fL4~lJ zQ%Lhj%CNM+Z>p;#q_2duj<>Bam35njio6f{ec{1B>(NJ?gK%51&=ULSDpAN)rd%AWSohS z&zn;WNOq%X@PN0J%b2z10@I$-lo-a>#PGFrf0J!tWQZ`D#c08{y`N5dbS+82CE0-Y z9|~CjC;-W7eVf$Vqnb8yHV&}4$ukN0k0@6(O8`+i27cp_kSf3vVG zRBdyI9Dp2mU?c18W1HjTvw{&?lt9z4s$bb}STpKo|I5QMbL=xt==wQ^>}~EwsMPh) zbw$V=GmU;BWxLDTn}CU^-oVXsPh#6#r2P2vK|E?F8}sgYZ%>#R1v#?6Sr=p!o~Et* zaBBE;lZs}*%}ELFOv^;@HVO{W(Qo-3V93QN_<)K0Ih`W4~=W7+!c4>^{t zo3OF5-lAS2_<%3OGJ)skv_gcn??-&%tAXdz;#6Q8zG@ z%LJ1+v!yz-Krl8q_8sTCOo+j$D%8of5vj8`0f2|&iYBj^#7oQ`4$CT=OeSXj|4!Zi g_d)z)2kptzE2J%wwY|0MzyDpxyit^>5Hs}uKh+%<*#H0l literal 0 HcmV?d00001 diff --git a/assets/tailwind.css b/assets/tailwind.css new file mode 100644 index 0000000..eac326b --- /dev/null +++ b/assets/tailwind.css @@ -0,0 +1,1155 @@ +/* +! tailwindcss v3.3.3 | MIT License | https://tailwindcss.com +*/ + +/* +1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) +2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) +*/ + +*, +::before, +::after { + box-sizing: border-box; + /* 1 */ + border-width: 0; + /* 2 */ + border-style: solid; + /* 2 */ + border-color: #e5e7eb; + /* 2 */ +} + +::before, +::after { + --tw-content: ''; +} + +/* +1. Use a consistent sensible line-height in all browsers. +2. Prevent adjustments of font size after orientation changes in iOS. +3. Use a more readable tab size. +4. Use the user's configured `sans` font-family by default. +5. Use the user's configured `sans` font-feature-settings by default. +6. Use the user's configured `sans` font-variation-settings by default. +*/ + +html { + line-height: 1.5; + /* 1 */ + -webkit-text-size-adjust: 100%; + /* 2 */ + -moz-tab-size: 4; + /* 3 */ + -o-tab-size: 4; + tab-size: 4; + /* 3 */ + font-family: Proxima Nova, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + /* 4 */ + font-feature-settings: normal; + /* 5 */ + font-variation-settings: normal; + /* 6 */ +} + +/* +1. Remove the margin in all browsers. +2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. +*/ + +body { + margin: 0; + /* 1 */ + line-height: inherit; + /* 2 */ +} + +/* +1. Add the correct height in Firefox. +2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) +3. Ensure horizontal rules are visible by default. +*/ + +hr { + height: 0; + /* 1 */ + color: inherit; + /* 2 */ + border-top-width: 1px; + /* 3 */ +} + +/* +Add the correct text decoration in Chrome, Edge, and Safari. +*/ + +abbr:where([title]) { + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; +} + +/* +Remove the default font size and weight for headings. +*/ + +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: inherit; + font-weight: inherit; +} + +/* +Reset links to optimize for opt-in styling instead of opt-out. +*/ + +a { + color: inherit; + text-decoration: inherit; +} + +/* +Add the correct font weight in Edge and Safari. +*/ + +b, +strong { + font-weight: bolder; +} + +/* +1. Use the user's configured `mono` font family by default. +2. Correct the odd `em` font sizing in all browsers. +*/ + +code, +kbd, +samp, +pre { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + /* 1 */ + font-size: 1em; + /* 2 */ +} + +/* +Add the correct font size in all browsers. +*/ + +small { + font-size: 80%; +} + +/* +Prevent `sub` and `sup` elements from affecting the line height in all browsers. +*/ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* +1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) +2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) +3. Remove gaps between table borders by default. +*/ + +table { + text-indent: 0; + /* 1 */ + border-color: inherit; + /* 2 */ + border-collapse: collapse; + /* 3 */ +} + +/* +1. Change the font styles in all browsers. +2. Remove the margin in Firefox and Safari. +3. Remove default padding in all browsers. +*/ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; + /* 1 */ + font-feature-settings: inherit; + /* 1 */ + font-variation-settings: inherit; + /* 1 */ + font-size: 100%; + /* 1 */ + font-weight: inherit; + /* 1 */ + line-height: inherit; + /* 1 */ + color: inherit; + /* 1 */ + margin: 0; + /* 2 */ + padding: 0; + /* 3 */ +} + +/* +Remove the inheritance of text transform in Edge and Firefox. +*/ + +button, +select { + text-transform: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Remove default button styles. +*/ + +button, +[type='button'], +[type='reset'], +[type='submit'] { + -webkit-appearance: button; + /* 1 */ + background-color: transparent; + /* 2 */ + background-image: none; + /* 2 */ +} + +/* +Use the modern Firefox focus style for all focusable elements. +*/ + +:-moz-focusring { + outline: auto; +} + +/* +Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) +*/ + +:-moz-ui-invalid { + box-shadow: none; +} + +/* +Add the correct vertical alignment in Chrome and Firefox. +*/ + +progress { + vertical-align: baseline; +} + +/* +Correct the cursor style of increment and decrement buttons in Safari. +*/ + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} + +/* +1. Correct the odd appearance in Chrome and Safari. +2. Correct the outline style in Safari. +*/ + +[type='search'] { + -webkit-appearance: textfield; + /* 1 */ + outline-offset: -2px; + /* 2 */ +} + +/* +Remove the inner padding in Chrome and Safari on macOS. +*/ + +::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Change font properties to `inherit` in Safari. +*/ + +::-webkit-file-upload-button { + -webkit-appearance: button; + /* 1 */ + font: inherit; + /* 2 */ +} + +/* +Add the correct display in Chrome and Safari. +*/ + +summary { + display: list-item; +} + +/* +Removes the default spacing and border for appropriate elements. +*/ + +blockquote, +dl, +dd, +h1, +h2, +h3, +h4, +h5, +h6, +hr, +figure, +p, +pre { + margin: 0; +} + +fieldset { + margin: 0; + padding: 0; +} + +legend { + padding: 0; +} + +ol, +ul, +menu { + list-style: none; + margin: 0; + padding: 0; +} + +/* +Reset default styling for dialogs. +*/ + +dialog { + padding: 0; +} + +/* +Prevent resizing textareas horizontally by default. +*/ + +textarea { + resize: vertical; +} + +/* +1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) +2. Set the default placeholder color to the user's configured gray 400 color. +*/ + +input::-moz-placeholder, textarea::-moz-placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +input::placeholder, +textarea::placeholder { + opacity: 1; + /* 1 */ + color: #9ca3af; + /* 2 */ +} + +/* +Set the default cursor for buttons. +*/ + +button, +[role="button"] { + cursor: pointer; +} + +/* +Make sure disabled buttons don't get the pointer cursor. +*/ + +:disabled { + cursor: default; +} + +/* +1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) +2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) + This can trigger a poorly considered lint error in some tools but is included by design. +*/ + +img, +svg, +video, +canvas, +audio, +iframe, +embed, +object { + display: block; + /* 1 */ + vertical-align: middle; + /* 2 */ +} + +/* +Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) +*/ + +img, +video { + max-width: 100%; + height: auto; +} + +/* Make elements with the HTML hidden attribute stay hidden by default */ + +[hidden] { + display: none; +} + +*, ::before, ::after { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; +} + +::backdrop { + --tw-border-spacing-x: 0; + --tw-border-spacing-y: 0; + --tw-translate-x: 0; + --tw-translate-y: 0; + --tw-rotate: 0; + --tw-skew-x: 0; + --tw-skew-y: 0; + --tw-scale-x: 1; + --tw-scale-y: 1; + --tw-pan-x: ; + --tw-pan-y: ; + --tw-pinch-zoom: ; + --tw-scroll-snap-strictness: proximity; + --tw-gradient-from-position: ; + --tw-gradient-via-position: ; + --tw-gradient-to-position: ; + --tw-ordinal: ; + --tw-slashed-zero: ; + --tw-numeric-figure: ; + --tw-numeric-spacing: ; + --tw-numeric-fraction: ; + --tw-ring-inset: ; + --tw-ring-offset-width: 0px; + --tw-ring-offset-color: #fff; + --tw-ring-color: rgb(59 130 246 / 0.5); + --tw-ring-offset-shadow: 0 0 #0000; + --tw-ring-shadow: 0 0 #0000; + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + --tw-blur: ; + --tw-brightness: ; + --tw-contrast: ; + --tw-grayscale: ; + --tw-hue-rotate: ; + --tw-invert: ; + --tw-saturate: ; + --tw-sepia: ; + --tw-drop-shadow: ; + --tw-backdrop-blur: ; + --tw-backdrop-brightness: ; + --tw-backdrop-contrast: ; + --tw-backdrop-grayscale: ; + --tw-backdrop-hue-rotate: ; + --tw-backdrop-invert: ; + --tw-backdrop-opacity: ; + --tw-backdrop-saturate: ; + --tw-backdrop-sepia: ; +} + +.container { + width: 100%; +} + +@media (min-width: 640px) { + .container { + max-width: 640px; + } +} + +@media (min-width: 768px) { + .container { + max-width: 768px; + } +} + +@media (min-width: 1024px) { + .container { + max-width: 1024px; + } +} + +@media (min-width: 1280px) { + .container { + max-width: 1280px; + } +} + +@media (min-width: 1536px) { + .container { + max-width: 1536px; + } +} + +.static { + position: static; +} + +.m-2 { + margin: 0.5rem; +} + +.mx-auto { + margin-left: auto; + margin-right: auto; +} + +.my-1 { + margin-top: 0.25rem; + margin-bottom: 0.25rem; +} + +.my-2 { + margin-top: 0.5rem; + margin-bottom: 0.5rem; +} + +.my-4 { + margin-top: 1rem; + margin-bottom: 1rem; +} + +.mb-2 { + margin-bottom: 0.5rem; +} + +.mb-4 { + margin-bottom: 1rem; +} + +.mb-8 { + margin-bottom: 2rem; +} + +.ml-4 { + margin-left: 1rem; +} + +.mr-2 { + margin-right: 0.5rem; +} + +.mt-4 { + margin-top: 1rem; +} + +.flex { + display: flex; +} + +.table { + display: table; +} + +.contents { + display: contents; +} + +.h-16 { + height: 4rem; +} + +.h-48 { + height: 12rem; +} + +.min-h-screen { + min-height: 100vh; +} + +.w-16 { + width: 4rem; +} + +.w-48 { + width: 12rem; +} + +.w-full { + width: 100%; +} + +.flex-grow { + flex-grow: 1; +} + +@keyframes spin { + to { + transform: rotate(360deg); + } +} + +.animate-spin { + animation: spin 1s linear infinite; +} + +.cursor-pointer { + cursor: pointer; +} + +.list-disc { + list-style-type: disc; +} + +.flex-row { + flex-direction: row; +} + +.flex-col { + flex-direction: column; +} + +.flex-wrap { + flex-wrap: wrap; +} + +.items-center { + align-items: center; +} + +.items-stretch { + align-items: stretch; +} + +.justify-start { + justify-content: flex-start; +} + +.justify-center { + justify-content: center; +} + +.space-x-2 > :not([hidden]) ~ :not([hidden]) { + --tw-space-x-reverse: 0; + margin-right: calc(0.5rem * var(--tw-space-x-reverse)); + margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse))); +} + +.space-y-2 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)); +} + +.space-y-3 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)); +} + +.space-y-4 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(1rem * var(--tw-space-y-reverse)); +} + +.space-y-8 > :not([hidden]) ~ :not([hidden]) { + --tw-space-y-reverse: 0; + margin-top: calc(2rem * calc(1 - var(--tw-space-y-reverse))); + margin-bottom: calc(2rem * var(--tw-space-y-reverse)); +} + +.overflow-y-auto { + overflow-y: auto; +} + +.overflow-y-scroll { + overflow-y: scroll; +} + +.rounded { + border-radius: 0.25rem; +} + +.rounded-full { + border-radius: 9999px; +} + +.rounded-lg { + border-radius: 0.5rem; +} + +.rounded-md { + border-radius: 0.375rem; +} + +.border-2 { + border-width: 2px; +} + +.border-4 { + border-width: 4px; +} + +.border-b-2 { + border-bottom-width: 2px; +} + +.border-l-2 { + border-left-width: 2px; +} + +.border-t-2 { + border-top-width: 2px; +} + +.border-base-300 { + --tw-border-opacity: 1; + border-color: rgb(209 213 219 / var(--tw-border-opacity)); +} + +.border-base-400 { + --tw-border-opacity: 1; + border-color: rgb(156 163 175 / var(--tw-border-opacity)); +} + +.border-black { + --tw-border-opacity: 1; + border-color: rgb(0 0 0 / var(--tw-border-opacity)); +} + +.border-gray-300 { + --tw-border-opacity: 1; + border-color: rgb(209 213 219 / var(--tw-border-opacity)); +} + +.border-purple-500 { + --tw-border-opacity: 1; + border-color: rgb(168 85 247 / var(--tw-border-opacity)); +} + +.border-base-700 { + --tw-border-opacity: 1; + border-color: rgb(55 65 81 / var(--tw-border-opacity)); +} + +.bg-base-100 { + --tw-bg-opacity: 1; + background-color: rgb(243 244 246 / var(--tw-bg-opacity)); +} + +.bg-base-200 { + --tw-bg-opacity: 1; + background-color: rgb(229 231 235 / var(--tw-bg-opacity)); +} + +.bg-black { + --tw-bg-opacity: 1; + background-color: rgb(0 0 0 / var(--tw-bg-opacity)); +} + +.bg-blue-400 { + --tw-bg-opacity: 1; + background-color: rgb(96 165 250 / var(--tw-bg-opacity)); +} + +.bg-blue-700 { + --tw-bg-opacity: 1; + background-color: rgb(29 78 216 / var(--tw-bg-opacity)); +} + +.bg-gray-300 { + --tw-bg-opacity: 1; + background-color: rgb(209 213 219 / var(--tw-bg-opacity)); +} + +.bg-gray-400 { + --tw-bg-opacity: 1; + background-color: rgb(156 163 175 / var(--tw-bg-opacity)); +} + +.bg-primary-50 { + --tw-bg-opacity: 1; + background-color: rgb(239 246 255 / var(--tw-bg-opacity)); +} + +.bg-primary-800 { + --tw-bg-opacity: 1; + background-color: rgb(30 64 175 / var(--tw-bg-opacity)); +} + +.bg-red-400 { + --tw-bg-opacity: 1; + background-color: rgb(248 113 113 / var(--tw-bg-opacity)); +} + +.bg-red-500 { + --tw-bg-opacity: 1; + background-color: rgb(239 68 68 / var(--tw-bg-opacity)); +} + +.bg-white { + --tw-bg-opacity: 1; + background-color: rgb(255 255 255 / var(--tw-bg-opacity)); +} + +.bg-base-50 { + --tw-bg-opacity: 1; + background-color: rgb(249 250 251 / var(--tw-bg-opacity)); +} + +.bg-base-700 { + --tw-bg-opacity: 1; + background-color: rgb(55 65 81 / var(--tw-bg-opacity)); +} + +.bg-red-200 { + --tw-bg-opacity: 1; + background-color: rgb(254 202 202 / var(--tw-bg-opacity)); +} + +.bg-cover { + background-size: cover; +} + +.bg-center { + background-position: center; +} + +.p-1 { + padding: 0.25rem; +} + +.p-2 { + padding: 0.5rem; +} + +.p-4 { + padding: 1rem; +} + +.px-2 { + padding-left: 0.5rem; + padding-right: 0.5rem; +} + +.px-3 { + padding-left: 0.75rem; + padding-right: 0.75rem; +} + +.px-4 { + padding-left: 1rem; + padding-right: 1rem; +} + +.py-1 { + padding-top: 0.25rem; + padding-bottom: 0.25rem; +} + +.py-2 { + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.text-left { + text-align: left; +} + +.text-center { + text-align: center; +} + +.text-right { + text-align: right; +} + +.text-end { + text-align: end; +} + +.font-mono { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; +} + +.text-3xl { + font-size: 1.875rem; + line-height: 2.25rem; +} + +.text-5xl { + font-size: 3rem; + line-height: 1; +} + +.text-lg { + font-size: 1.125rem; + line-height: 1.75rem; +} + +.text-sm { + font-size: 0.875rem; + line-height: 1.25rem; +} + +.text-xl { + font-size: 1.25rem; + line-height: 1.75rem; +} + +.text-xs { + font-size: 0.75rem; + line-height: 1rem; +} + +.font-bold { + font-weight: 700; +} + +.font-light { + font-weight: 300; +} + +.font-semibold { + font-weight: 600; +} + +.italic { + font-style: italic; +} + +.text-base-100 { + --tw-text-opacity: 1; + color: rgb(243 244 246 / var(--tw-text-opacity)); +} + +.text-base-700 { + --tw-text-opacity: 1; + color: rgb(55 65 81 / var(--tw-text-opacity)); +} + +.text-base-800 { + --tw-text-opacity: 1; + color: rgb(31 41 55 / var(--tw-text-opacity)); +} + +.text-gray-500 { + --tw-text-opacity: 1; + color: rgb(107 114 128 / var(--tw-text-opacity)); +} + +.text-gray-600 { + --tw-text-opacity: 1; + color: rgb(75 85 99 / var(--tw-text-opacity)); +} + +.text-green-500 { + --tw-text-opacity: 1; + color: rgb(34 197 94 / var(--tw-text-opacity)); +} + +.text-primary-500 { + --tw-text-opacity: 1; + color: rgb(59 130 246 / var(--tw-text-opacity)); +} + +.text-primary-600 { + --tw-text-opacity: 1; + color: rgb(37 99 235 / var(--tw-text-opacity)); +} + +.text-primary-800 { + --tw-text-opacity: 1; + color: rgb(30 64 175 / var(--tw-text-opacity)); +} + +.text-red-500 { + --tw-text-opacity: 1; + color: rgb(239 68 68 / var(--tw-text-opacity)); +} + +.text-white { + --tw-text-opacity: 1; + color: rgb(255 255 255 / var(--tw-text-opacity)); +} + +.underline { + text-decoration-line: underline; +} + +.shadow { + --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.shadow-lg { + --tw-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); + --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color); + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.filter { + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); +} + +@media (min-width: 640px) { + .sm\:container { + width: 100%; + } + + @media (min-width: 640px) { + .sm\:container { + max-width: 640px; + } + } + + @media (min-width: 768px) { + .sm\:container { + max-width: 768px; + } + } + + @media (min-width: 1024px) { + .sm\:container { + max-width: 1024px; + } + } + + @media (min-width: 1280px) { + .sm\:container { + max-width: 1280px; + } + } + + @media (min-width: 1536px) { + .sm\:container { + max-width: 1536px; + } + } +} + +.hover\:border-gray-400:hover { + --tw-border-opacity: 1; + border-color: rgb(156 163 175 / var(--tw-border-opacity)); +} + +.hover\:bg-blue-800:hover { + --tw-bg-opacity: 1; + background-color: rgb(30 64 175 / var(--tw-bg-opacity)); +} + +.hover\:bg-primary-100:hover { + --tw-bg-opacity: 1; + background-color: rgb(219 234 254 / var(--tw-bg-opacity)); +} + +.hover\:bg-primary-200:hover { + --tw-bg-opacity: 1; + background-color: rgb(191 219 254 / var(--tw-bg-opacity)); +} + +.hover\:underline:hover { + text-decoration-line: underline; +} + +.hover\:no-underline:hover { + text-decoration-line: none; +} + +.active\:shadow-none:active { + --tw-shadow: 0 0 #0000; + --tw-shadow-colored: 0 0 #0000; + box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +@media (min-width: 640px) { + .sm\:max-w-screen-md { + max-width: 768px; + } +} + +@media (min-width: 768px) { + .md\:rounded-b { + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; + } +} diff --git a/crates/leptos_extra/Cargo.toml b/crates/leptos_extra/Cargo.toml deleted file mode 100644 index 77d472f..0000000 --- a/crates/leptos_extra/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -edition = "2021" -name = "leptos_extra" -version = "0.1.0" - -[lib] -crate-type = ["cdylib", "rlib"] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -cfg-if.workspace = true -leptos.workspace = true -leptos_query.workspace = true -tracing.workspace = true - -[features] -hydrate = ["leptos/hydrate", "leptos_query/hydrate"] -ssr = ["leptos/ssr", "leptos_query/ssr"] diff --git a/crates/leptos_extra/src/lib.rs b/crates/leptos_extra/src/lib.rs deleted file mode 100644 index 42747ee..0000000 --- a/crates/leptos_extra/src/lib.rs +++ /dev/null @@ -1,3 +0,0 @@ -//! Extra modules for [leptos] -pub mod query; -pub mod signal; diff --git a/crates/leptos_extra/src/query.rs b/crates/leptos_extra/src/query.rs deleted file mode 100644 index e42bc87..0000000 --- a/crates/leptos_extra/src/query.rs +++ /dev/null @@ -1,104 +0,0 @@ -//! [leptos_query] helpers for working with [server] fns, and useful widgets. -use cfg_if::cfg_if; -use leptos::*; -use leptos_query::*; -use std::{future::Future, hash::Hash}; -use tracing::instrument; - -/// The result type of Leptos [server] function returning a `T` -pub type ServerFnResult = Result; - -/// Sensible [QueryOptions] defaults for an app -pub fn query_options() -> QueryOptions { - QueryOptions { - // Disable staleness so the query is not refetched on every route switch. - stale_time: None, - ..Default::default() - } -} - -/// Like [use_query] but specifically meant for server functions, does logging -/// via [tracing] and uses [query_options] always. -/// -/// In order to be able to log the name of the server fns, we unfortunately must -/// require them to be 1-ary functions taking tuples, due to a limitation with -/// Rust type system around Fn trait. -/// -/// Arguments -/// * `k`: The argument to the server fn -/// * `fetcher`: The server fn to call -#[instrument( - name = "use_server_query", - skip(cx, k, fetcher), - fields( - fetcher = std::any::type_name::(), - render_mode=LEPTOS_MODE - ) -)] -pub fn use_server_query( - cx: Scope, - k: impl Fn() -> K + 'static, - fetcher: F, -) -> QueryResult, impl RefetchFn> -where - K: Hash + Eq + Clone + std::fmt::Debug + 'static, - ServerFnResult: Clone + Serializable + 'static, - Fu: Future> + 'static, - F: Fn(K) -> Fu + 'static, -{ - let span = tracing::Span::current(); - tracing::debug!("use_query"); - leptos_query::use_query( - cx, - k, - move |k| { - let _enter = span.enter(); - tracing::info!("calling server fn"); - fetcher(k) - }, - query_options::>(), - ) -} - -const LEPTOS_MODE: &str = { - cfg_if! { if #[cfg(feature="ssr")] { - "ssr" - } else if #[cfg(feature="hydrate")] { - "hydrate" - } else { - compile_error!("Either ssr or hydrate feature must be enabled"); - }} -}; - -/// Button component to refresh the given [leptos_query] query. -/// -/// Arguments -/// * `result`: The query result to refresh -/// * `query`: The value to pass to [invalidate_query] -#[component] -pub fn RefetchQueryButton( - cx: Scope, - result: QueryResult, R>, - query: F, -) -> impl IntoView -where - K: Hash + Eq + Clone + std::fmt::Debug + 'static, - ServerFnResult: Clone + Serializable + 'static, - R: RefetchFn, - F: Fn() -> K + 'static, -{ - view! { cx, - - } -} diff --git a/crates/leptos_extra/src/signal.rs b/crates/leptos_extra/src/signal.rs deleted file mode 100644 index 7de0a71..0000000 --- a/crates/leptos_extra/src/signal.rs +++ /dev/null @@ -1,78 +0,0 @@ -//! [Signal] related helpers for Leptos -use leptos::*; -use tracing::instrument; - -/// [provide_context] a new signal of type `T` in the current scope -pub fn provide_signal(cx: Scope, default: T) { - let sig = create_rw_signal(cx, default); - provide_context(cx, sig); -} - -/// [use_context] the signal of type `T` in the current scope -/// -/// If the signal was not provided in a top-level scope (via [provide_signal]) -/// this method will panic after tracing an error. -#[instrument(name = "use_signal")] -pub fn use_signal(cx: Scope) -> RwSignal { - use_context(cx) - .ok_or_else(|| { - // This happens if the dev forgets to call `provide_signal::` in - // the parent scope - let msg = format!( - "no signal provided for type: {}", - std::any::type_name::() - ); - tracing::error!(msg); - msg - }) - .unwrap() -} - -/// Extends [SignalWith] to add a `with_result` method that operates on the -/// inner value, avoiding the need to clone it. -pub trait SignalWithResult: SignalWith>> { - /// Like [SignalWith::with] but operates on the inner [Result] value without cloning it. - fn with_result(&self, f: impl Fn(&T) -> U + 'static) -> Option> - where - E: Clone, - { - self.with(move |d| d.map_option_result(f)) - } -} - -impl SignalWithResult for Signal>> {} - -/// Functions unique to [Option] of [Result] values -pub trait OptionResult { - /// Map the value inside a nested [Option]-of-[Result] - /// - /// This function is efficient in that the inner value is not cloned. - fn map_option_result(&self, f: impl Fn(&T) -> U + 'static) -> Option> - where - E: Clone; - - /// Like [[Option::unwrap_or]] but unwraps the nested value - fn unwrap_option_result_value_or(&self, default: T) -> T - where - T: Clone; -} - -impl OptionResult for Option> { - fn map_option_result(&self, f: impl Fn(&T) -> U + 'static) -> Option> - where - E: Clone, - { - self.as_ref() - .map(|r| r.as_ref().map(f).map_err(Clone::clone)) - } - - fn unwrap_option_result_value_or(&self, default: T) -> T - where - T: Clone, - { - self.as_ref() - .and_then(|r| r.as_ref().ok()) - .cloned() - .unwrap_or(default) - } -} diff --git a/crates/nix_health/Cargo.toml b/crates/nix_health/Cargo.toml index cfe6859..58225b2 100644 --- a/crates/nix_health/Cargo.toml +++ b/crates/nix_health/Cargo.toml @@ -12,33 +12,22 @@ crate-type = ["cdylib", "rlib"] [[bin]] name = "nix-health" path = "src/main.rs" -required-features = ["ssr"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] cfg-if.workspace = true -clap = { workspace = true, optional = true } +clap = { workspace = true } regex = "1.9.3" thiserror.workspace = true serde.workspace = true serde_json.workspace = true serde_with.workspace = true -tokio = { version = "1.29", features = ["full"], optional = true } +tokio = { version = "1.29", features = ["full"] } url = { version = "2.4", features = ["serde"] } nix_rs.workspace = true human-panic.workspace = true -anyhow = { version = "1.0.75", optional = true } -colored = { version = "2.0", optional = true } -which = { version = "4.4.2", optional = true } +anyhow = { version = "1.0.75" } +colored = { version = "2.0" } +which = { version = "4.4.2" } bytesize.workspace = true - -[features] -ssr = [ - "dep:clap", - "dep:tokio", - "dep:anyhow", - "dep:colored", - "dep:which", - "nix_rs/ssr", -] diff --git a/crates/nix_health/src/check/caches.rs b/crates/nix_health/src/check/caches.rs index 85ca4d4..34039df 100644 --- a/crates/nix_health/src/check/caches.rs +++ b/crates/nix_health/src/check/caches.rs @@ -1,9 +1,7 @@ -#[cfg(feature = "ssr")] use nix_rs::{env, info}; use serde::{Deserialize, Serialize}; use url::Url; -#[cfg(feature = "ssr")] use crate::traits::*; /// Check that [nix_rs::config::NixConfig::substituters] is set to a good value. @@ -22,7 +20,6 @@ impl Default for Caches { } } -#[cfg(feature = "ssr")] impl Checkable for Caches { fn check(&self, nix_info: &info::NixInfo, nix_env: &env::NixEnv) -> Vec { let val = &nix_info.nix_config.substituters.value; diff --git a/crates/nix_health/src/check/direnv.rs b/crates/nix_health/src/check/direnv.rs index 606f07d..d7bdb18 100644 --- a/crates/nix_health/src/check/direnv.rs +++ b/crates/nix_health/src/check/direnv.rs @@ -2,9 +2,8 @@ use std::path::PathBuf; use serde::{Deserialize, Serialize}; -#[cfg(feature = "ssr")] use crate::traits::{Check, CheckResult, Checkable}; -#[cfg(feature = "ssr")] + use nix_rs::{env, info}; /// Check if direnv is installed @@ -25,7 +24,6 @@ impl Default for Direnv { } } -#[cfg(feature = "ssr")] impl Checkable for Direnv { fn check(&self, _nix_info: &info::NixInfo, nix_env: &env::NixEnv) -> Vec { let mut checks = vec![]; @@ -47,7 +45,7 @@ impl Checkable for Direnv { } /// [Check] that direnv was installed. -#[cfg(feature = "ssr")] + fn install_check(required: bool) -> Check { let suggestion = "Install direnv ".to_string(); let direnv_install = DirenvInstall::detect(); @@ -67,7 +65,7 @@ fn install_check(required: bool) -> Check { } /// [Check] that direnv was activated on the local flake -#[cfg(feature = "ssr")] + fn activation_check(local_flake: &std::path::Path, required: bool) -> Check { let suggestion = format!("Run `direnv allow` under `{}`", local_flake.display()); Check { @@ -103,7 +101,7 @@ pub struct DirenvInstall { impl DirenvInstall { /// Detect user's direnv installation - #[cfg(feature = "ssr")] + pub fn detect() -> anyhow::Result { let bin_path = which::which("direnv")?; let output = std::process::Command::new(&bin_path) @@ -136,7 +134,7 @@ impl DirenvInstall { } /// Check if direnv was already activated in [project_dir] -#[cfg(feature = "ssr")] + pub fn is_direnv_active_on(project_dir: &std::path::Path) -> anyhow::Result { let output = std::process::Command::new("direnv") .arg("status") diff --git a/crates/nix_health/src/check/flake_enabled.rs b/crates/nix_health/src/check/flake_enabled.rs index 91ceded..44ad8f3 100644 --- a/crates/nix_health/src/check/flake_enabled.rs +++ b/crates/nix_health/src/check/flake_enabled.rs @@ -1,8 +1,6 @@ -#[cfg(feature = "ssr")] use nix_rs::{env, info}; use serde::{Deserialize, Serialize}; -#[cfg(feature = "ssr")] use crate::traits::*; /// Check that [nix_rs::config::NixConfig::experimental_features] is set to a good value. @@ -10,7 +8,6 @@ use crate::traits::*; #[serde(default)] pub struct FlakeEnabled {} -#[cfg(feature = "ssr")] impl Checkable for FlakeEnabled { fn check(&self, nix_info: &info::NixInfo, _nix_env: &env::NixEnv) -> Vec { let val = &nix_info.nix_config.experimental_features.value; diff --git a/crates/nix_health/src/check/max_jobs.rs b/crates/nix_health/src/check/max_jobs.rs index 883d48a..5ce0a49 100644 --- a/crates/nix_health/src/check/max_jobs.rs +++ b/crates/nix_health/src/check/max_jobs.rs @@ -1,8 +1,6 @@ -#[cfg(feature = "ssr")] use nix_rs::{env, info}; use serde::{Deserialize, Serialize}; -#[cfg(feature = "ssr")] use crate::traits::*; /// Check that [nix_rs::config::NixConfig::max_jobs] is set to a good value. @@ -10,7 +8,6 @@ use crate::traits::*; #[serde(default)] pub struct MaxJobs {} -#[cfg(feature = "ssr")] impl Checkable for MaxJobs { fn check(&self, nix_info: &info::NixInfo, nix_env: &env::NixEnv) -> Vec { let max_jobs = nix_info.nix_config.max_jobs.value; diff --git a/crates/nix_health/src/check/min_nix_version.rs b/crates/nix_health/src/check/min_nix_version.rs index 820371d..3935404 100644 --- a/crates/nix_health/src/check/min_nix_version.rs +++ b/crates/nix_health/src/check/min_nix_version.rs @@ -1,9 +1,8 @@ use nix_rs::version::NixVersion; -#[cfg(feature = "ssr")] + use nix_rs::{env, info}; use serde::{Deserialize, Serialize}; -#[cfg(feature = "ssr")] use crate::traits::*; /// Check that [nix_rs::version::NixVersion] is set to a good value. @@ -25,7 +24,6 @@ impl Default for MinNixVersion { } } -#[cfg(feature = "ssr")] impl Checkable for MinNixVersion { fn check(&self, nix_info: &info::NixInfo, _nix_env: &env::NixEnv) -> Vec { let val = &nix_info.nix_version; diff --git a/crates/nix_health/src/check/rosetta.rs b/crates/nix_health/src/check/rosetta.rs index da178c2..2ab2891 100644 --- a/crates/nix_health/src/check/rosetta.rs +++ b/crates/nix_health/src/check/rosetta.rs @@ -1,11 +1,9 @@ -#[cfg(feature = "ssr")] use nix_rs::{ env::{self, AppleEmulation, MacOSArch, OS}, info, }; use serde::{Deserialize, Serialize}; -#[cfg(feature = "ssr")] use crate::traits::{Check, CheckResult, Checkable}; /// Check if Nix is being run under rosetta emulation @@ -27,7 +25,6 @@ impl Default for Rosetta { } } -#[cfg(feature = "ssr")] impl Checkable for Rosetta { fn check(&self, _nix_info: &info::NixInfo, nix_env: &env::NixEnv) -> Vec { let mut checks = vec![]; @@ -52,7 +49,7 @@ impl Checkable for Rosetta { } /// Return [AppleEmulation]. Return None if not an ARM mac. -#[cfg(feature = "ssr")] + fn get_apple_emulation(system: &OS) -> Option { match system { OS::MacOS { diff --git a/crates/nix_health/src/check/system.rs b/crates/nix_health/src/check/system.rs index 1b5bbe8..097e574 100644 --- a/crates/nix_health/src/check/system.rs +++ b/crates/nix_health/src/check/system.rs @@ -1,7 +1,6 @@ use bytesize::ByteSize; use serde::{Deserialize, Serialize}; -#[cfg(feature = "ssr")] use crate::traits::{Check, CheckResult, Checkable}; /// Check if the system has enough resources @@ -29,7 +28,6 @@ impl Default for System { } } -#[cfg(feature = "ssr")] impl Checkable for System { fn check( &self, diff --git a/crates/nix_health/src/check/trusted_users.rs b/crates/nix_health/src/check/trusted_users.rs index 97d3bbd..9e64555 100644 --- a/crates/nix_health/src/check/trusted_users.rs +++ b/crates/nix_health/src/check/trusted_users.rs @@ -1,6 +1,5 @@ use serde::{Deserialize, Serialize}; -#[cfg(feature = "ssr")] use crate::traits::*; /// Check that [crate::nix::config::NixConfig::trusted_users] is set to a good value. @@ -8,7 +7,6 @@ use crate::traits::*; #[serde(default)] pub struct TrustedUsers {} -#[cfg(feature = "ssr")] impl Checkable for TrustedUsers { fn check(&self, nix_info: &nix_rs::info::NixInfo, nix_env: &nix_rs::env::NixEnv) -> Vec { let val = &nix_info.nix_config.trusted_users.value; diff --git a/crates/nix_health/src/lib.rs b/crates/nix_health/src/lib.rs index 9a6d50a..95d21d5 100644 --- a/crates/nix_health/src/lib.rs +++ b/crates/nix_health/src/lib.rs @@ -30,7 +30,6 @@ pub struct NixHealth { pub direnv: Direnv, } -#[cfg(feature = "ssr")] impl<'a> IntoIterator for &'a NixHealth { type Item = &'a dyn traits::Checkable; type IntoIter = std::vec::IntoIter; @@ -51,7 +50,6 @@ impl<'a> IntoIterator for &'a NixHealth { } } -#[cfg(feature = "ssr")] impl NixHealth { /// Create [NixHealth] using configuration from the given flake /// diff --git a/crates/nix_health/src/traits.rs b/crates/nix_health/src/traits.rs index c891d0b..f946d43 100644 --- a/crates/nix_health/src/traits.rs +++ b/crates/nix_health/src/traits.rs @@ -1,12 +1,13 @@ use serde::{Deserialize, Serialize}; /// Types that can do specific "health check" for Nix -#[cfg(feature = "ssr")] + pub trait Checkable { /// Run and create the health check /// /// NOTE: Some checks may perform impure actions (IO, etc.). Returning an /// empty vector indicates that the check is skipped on this environment. + /// TODO: This should be async! fn check(&self, nix_info: &nix_rs::info::NixInfo, nix_env: &nix_rs::env::NixEnv) -> Vec; } diff --git a/crates/nix_rs/Cargo.toml b/crates/nix_rs/Cargo.toml index 1c505a7..18dc14a 100644 --- a/crates/nix_rs/Cargo.toml +++ b/crates/nix_rs/Cargo.toml @@ -20,14 +20,11 @@ thiserror.workspace = true serde.workspace = true serde_json.workspace = true serde_with.workspace = true -tokio = { version = "1.29", features = ["full"], optional = true } +tokio = { version = "1.29", features = ["full"] } tracing.workspace = true url = { version = "2.4", features = ["serde"] } -colored = { version = "2.0", optional = true } -shell-words = { version = "1.1.0", optional = true } -is_proc_translated = { version = "0.1.1", optional = true } +colored = { version = "2.0" } +shell-words = { version = "1.1.0" } +is_proc_translated = { version = "0.1.1" } sysinfo.version = "0.29.10" bytesize.workspace = true - -[features] -ssr = ["dep:tokio", "dep:colored", "dep:shell-words", "dep:is_proc_translated"] diff --git a/crates/nix_rs/src/command.rs b/crates/nix_rs/src/command.rs index 42b32a9..2a0c4b2 100644 --- a/crates/nix_rs/src/command.rs +++ b/crates/nix_rs/src/command.rs @@ -12,9 +12,9 @@ use std::fmt::{self, Display}; use serde::{Deserialize, Serialize}; use thiserror::Error; -#[cfg(feature = "ssr")] + use tokio::process::Command; -#[cfg(feature = "ssr")] + use tracing::instrument; /// The `nix` command's global options. @@ -54,14 +54,13 @@ impl Default for NixCmd { /// /// The command will be highlighted to distinguish it (for copying) from the /// rest of the instrumentation parameters. -#[cfg(feature = "ssr")] + #[instrument(name = "command")] pub fn trace_cmd(cmd: &tokio::process::Command) { use colored::Colorize; tracing::info!("🐚 {}ī¸", to_cli(cmd).bright_blue()); } -#[cfg(feature = "ssr")] impl NixCmd { /// Return a [Command] for this [NixCmd] configuration pub fn command(&self) -> Command { @@ -72,7 +71,7 @@ impl NixCmd { } /// Run nix with given args, interpreting stdout as JSON, parsing into `T` - #[cfg(feature = "ssr")] + pub async fn run_with_args_expecting_json(&self, args: &[&str]) -> Result where T: serde::de::DeserializeOwned, @@ -83,7 +82,7 @@ impl NixCmd { } /// Run nix with given args, interpreting parsing stdout, via [std::str::FromStr], into `T` - #[cfg(feature = "ssr")] + pub async fn run_with_args_expecting_fromstr(&self, args: &[&str]) -> Result where T: std::str::FromStr, @@ -96,7 +95,7 @@ impl NixCmd { } /// Run nix with given args, returning stdout. - #[cfg(feature = "ssr")] + pub async fn run_with_args_returning_stdout( &self, args: &[&str], @@ -132,7 +131,7 @@ impl NixCmd { } /// Convert a Command to user-copyable CLI string -#[cfg(feature = "ssr")] + fn to_cli(cmd: &tokio::process::Command) -> String { use std::ffi::OsStr; let program = cmd.as_std().get_program().to_string_lossy().to_string(); diff --git a/crates/nix_rs/src/config.rs b/crates/nix_rs/src/config.rs index bdfba2e..dbb3a8b 100644 --- a/crates/nix_rs/src/config.rs +++ b/crates/nix_rs/src/config.rs @@ -1,7 +1,7 @@ //! Rust module for `nix show-config` use serde::{Deserialize, Serialize}; -#[cfg(feature = "ssr")] + use tracing::instrument; use url::Url; @@ -35,7 +35,7 @@ pub struct ConfigVal { impl NixConfig { /// Get the output of `nix show-config` - #[cfg(feature = "ssr")] + #[instrument(name = "show-config")] pub async fn from_nix( nix_cmd: &super::command::NixCmd, @@ -47,7 +47,6 @@ impl NixConfig { } } -#[cfg(feature = "ssr")] #[tokio::test] async fn test_nix_config() -> Result<(), crate::command::NixCmdError> { let v = NixConfig::from_nix(&crate::command::NixCmd::default()).await?; diff --git a/crates/nix_rs/src/env.rs b/crates/nix_rs/src/env.rs index 5cd8ac8..11e9b4d 100644 --- a/crates/nix_rs/src/env.rs +++ b/crates/nix_rs/src/env.rs @@ -26,23 +26,27 @@ pub struct NixEnv { impl NixEnv { /// Determine [NixEnv] on the user's system - #[cfg(feature = "ssr")] + pub async fn detect(current_flake: Option) -> Result { use sysinfo::{DiskExt, SystemExt}; - let current_user = std::env::var("USER")?; let os = OS::detect().await; - let sys = sysinfo::System::new_with_specifics( - sysinfo::RefreshKind::new().with_disks_list().with_memory(), - ); - let total_disk_space = to_bytesize(get_nix_disk(&sys)?.total_space()); - let total_memory = to_bytesize(sys.total_memory()); - Ok(NixEnv { - current_user, - current_flake, - os, - total_disk_space, - total_memory, + tokio::task::spawn_blocking(|| { + let current_user = std::env::var("USER")?; + let sys = sysinfo::System::new_with_specifics( + sysinfo::RefreshKind::new().with_disks_list().with_memory(), + ); + let total_disk_space = to_bytesize(get_nix_disk(&sys)?.total_space()); + let total_memory = to_bytesize(sys.total_memory()); + Ok(NixEnv { + current_user, + current_flake, + os, + total_disk_space, + total_memory, + }) }) + .await + .unwrap() } /// Return [NixEnv::current_flake] as a local path if it is one @@ -54,7 +58,7 @@ impl NixEnv { } /// Get the disk where /nix exists -#[cfg(feature = "ssr")] + fn get_nix_disk(sys: &sysinfo::System) -> Result<&sysinfo::Disk, NixEnvError> { use sysinfo::{DiskExt, SystemExt}; let by_mount_point: std::collections::HashMap<&Path, &sysinfo::Disk> = sys @@ -98,7 +102,6 @@ pub enum AppleEmulation { } impl AppleEmulation { - #[cfg(feature = "ssr")] pub fn new() -> Self { use is_proc_translated::is_proc_translated; if is_proc_translated() { @@ -109,7 +112,6 @@ impl AppleEmulation { } } -#[cfg(feature = "ssr")] impl Default for AppleEmulation { fn default() -> Self { Self::new() @@ -117,7 +119,6 @@ impl Default for AppleEmulation { } impl MacOSArch { - #[cfg(feature = "ssr")] pub fn from(os_arch: Option<&str>) -> MacOSArch { match os_arch { Some("arm64") => MacOSArch::Arm64(AppleEmulation::new()), @@ -146,7 +147,6 @@ impl Display for OS { } impl OS { - #[cfg(feature = "ssr")] pub async fn detect() -> Self { let os_info = tokio::task::spawn_blocking(os_info::get).await.unwrap(); let os_type = os_info.os_type(); @@ -188,7 +188,7 @@ impl OS { } /// Errors while trying to fetch [NixEnv] -#[cfg(feature = "ssr")] + #[derive(thiserror::Error, Debug)] pub enum NixEnvError { #[error("Failed to fetch ENV: {0}")] @@ -201,7 +201,7 @@ pub enum NixEnvError { /// Convert bytes to a closest [ByteSize] /// /// Useful for displaying disk space and memory which are typically in GBs / TBs -#[cfg(feature = "ssr")] + fn to_bytesize(bytes: u64) -> ByteSize { let kb = bytes / 1024; let mb = kb / 1024; @@ -218,7 +218,7 @@ fn to_bytesize(bytes: u64) -> ByteSize { } /// Test for [to_bytesize] -#[cfg(feature = "ssr")] + #[test] fn test_to_bytesize() { assert_eq!(to_bytesize(0), ByteSize::b(0)); diff --git a/crates/nix_rs/src/flake/mod.rs b/crates/nix_rs/src/flake/mod.rs index b7f5c19..574a184 100644 --- a/crates/nix_rs/src/flake/mod.rs +++ b/crates/nix_rs/src/flake/mod.rs @@ -1,5 +1,5 @@ //! Rust module for Nix flakes -#[cfg(feature = "ssr")] + pub mod eval; pub mod outputs; pub mod schema; @@ -7,11 +7,11 @@ pub mod system; pub mod url; use serde::{Deserialize, Serialize}; -#[cfg(feature = "ssr")] + use tracing::instrument; use self::{outputs::FlakeOutputs, schema::FlakeSchema, system::System, url::FlakeUrl}; -#[cfg(feature = "ssr")] + use crate::command::NixCmdError; /// All the information about a Nix flake @@ -28,7 +28,7 @@ pub struct Flake { impl Flake { /// Get [Flake] info for the given flake url - #[cfg(feature = "ssr")] + #[instrument(name = "flake", skip(nix_cmd))] pub async fn from_nix( nix_cmd: &crate::command::NixCmd, diff --git a/crates/nix_rs/src/flake/outputs.rs b/crates/nix_rs/src/flake/outputs.rs index 6c00cea..37720c7 100644 --- a/crates/nix_rs/src/flake/outputs.rs +++ b/crates/nix_rs/src/flake/outputs.rs @@ -1,7 +1,10 @@ //! Nix flake outputs use serde::{Deserialize, Serialize}; -use std::collections::{btree_map::Entry, BTreeMap}; +use std::{ + collections::{btree_map::Entry, BTreeMap}, + fmt::Display, +}; /// Represents the "outputs" of a flake /// @@ -15,7 +18,7 @@ pub enum FlakeOutputs { impl FlakeOutputs { /// Run `nix flake show` on the given flake url - #[cfg(feature = "ssr")] + #[tracing::instrument(name = "flake-show")] pub async fn from_nix( nix_cmd: &crate::command::NixCmd, @@ -113,3 +116,9 @@ impl Type { } } } + +impl Display for Type { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&format!("{:?}", self)) + } +} diff --git a/crates/nix_rs/src/info.rs b/crates/nix_rs/src/info.rs index 5d6875d..8fcf1d2 100644 --- a/crates/nix_rs/src/info.rs +++ b/crates/nix_rs/src/info.rs @@ -13,7 +13,7 @@ pub struct NixInfo { impl NixInfo { /// Determine [NixInfo] on the user's system - #[cfg(feature = "ssr")] + pub async fn from_nix( nix_cmd: &crate::command::NixCmd, ) -> Result { diff --git a/crates/nix_rs/src/version.rs b/crates/nix_rs/src/version.rs index 6084c82..631acbf 100644 --- a/crates/nix_rs/src/version.rs +++ b/crates/nix_rs/src/version.rs @@ -3,11 +3,11 @@ use regex::Regex; use serde_with::{DeserializeFromStr, SerializeDisplay}; use std::{fmt, str::FromStr}; use thiserror::Error; -#[cfg(feature = "ssr")] + use tracing::instrument; /// Nix version as parsed from `nix --version` -#[derive(Clone, PartialOrd, PartialEq, Eq, Debug, SerializeDisplay, DeserializeFromStr)] +#[derive(Clone, Copy, PartialOrd, PartialEq, Eq, Debug, SerializeDisplay, DeserializeFromStr)] pub struct NixVersion { pub major: u32, pub minor: u32, @@ -48,7 +48,7 @@ impl FromStr for NixVersion { impl NixVersion { /// Get the output of `nix --version` - #[cfg(feature = "ssr")] + #[instrument(name = "version")] pub async fn from_nix( nix_cmd: &super::command::NixCmd, @@ -66,7 +66,6 @@ impl fmt::Display for NixVersion { } } -#[cfg(feature = "ssr")] #[tokio::test] async fn test_run_nix_version() { let nix_version = NixVersion::from_nix(&crate::command::NixCmd::default()) @@ -75,7 +74,6 @@ async fn test_run_nix_version() { println!("Nix version: {}", nix_version); } -#[cfg(feature = "ssr")] #[tokio::test] async fn test_parse_nix_version() { assert_eq!( diff --git a/css/input.css b/css/input.css index a31f067..b5c61c9 100644 --- a/css/input.css +++ b/css/input.css @@ -1,7 +1,3 @@ @tailwind base; @tailwind components; @tailwind utilities; - -a[aria-current="page"] { - @apply font-bold bg-white text-primary-600; -} \ No newline at end of file diff --git a/e2e/.gitignore b/e2e/.gitignore deleted file mode 100644 index 3c0d3a0..0000000 --- a/e2e/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -node_modules -/test-results/ -/playwright-report/ -/playwright/.cache/ diff --git a/e2e/README.md b/e2e/README.md deleted file mode 100644 index bbc6ab3..0000000 --- a/e2e/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Playwright end-to-end tests - -We use [Playwright](https://playwright.dev/dotnet/) to test our application. - -- All e2e test are nixified, simply run `nix run .#e2e-playwright-test` from project root (there are `just` targets as well) -- The nix shell creates a `node_modules` symlink which in turn provide IDE support in VSCode for editing `tests/*` diff --git a/e2e/flake-module.nix b/e2e/flake-module.nix deleted file mode 100644 index 16e16e1..0000000 --- a/e2e/flake-module.nix +++ /dev/null @@ -1,52 +0,0 @@ -{ lib, ... }: -{ - perSystem = { config, self', pkgs, system, ... }: { - # e2e test service using playwright - process-compose.e2e-playwright-test = - let - TEST_PORT = "5000"; - in - { - tui = false; - settings.processes = { - start-app = { - command = "${lib.getExe self'.packages.default} --site-addr=127.0.0.1:${TEST_PORT} --no-open"; - readiness_probe = { - exec.command = "${lib.getExe pkgs.curl} --fail 127.0.0.1:${TEST_PORT}"; - initial_delay_seconds = 2; - period_seconds = 10; - timeout_seconds = 4; - }; - }; - test = { - environment = { - inherit TEST_PORT; - }; - command = pkgs.writeShellApplication { - name = "e2e-playwright"; - runtimeInputs = with pkgs; [ nodejs playwright-test ]; - text = '' - cd e2e - playwright test --project chromium - ''; - }; - depends_on."start-app".condition = "process_healthy"; - availability.exit_on_end = true; - }; - }; - }; - - devShells.e2e-playwright = pkgs.mkShell { - buildInputs = with pkgs; [ - nodejs - playwright-test - ]; - shellHook = '' - export NODE_PATH=${pkgs.playwright-test}/lib/node_modules - # VSCode disrespects NODE_PATH https://github.com/microsoft/TypeScript/issues/8760 - # So we must manually create ./node_modules - just node_modules NODE_PATH=$NODE_PATH - ''; - }; - }; -} diff --git a/e2e/node_modules b/e2e/node_modules new file mode 120000 index 0000000..93e4870 --- /dev/null +++ b/e2e/node_modules @@ -0,0 +1 @@ +/nix/store/ffsk31ifmhjxzf5nvagljxhqylsqzfxv-_at_playwright_slash_test-1.38.0/lib/node_modules \ No newline at end of file diff --git a/e2e/playwright.config.ts b/e2e/playwright.config.ts deleted file mode 100644 index c1734aa..0000000 --- a/e2e/playwright.config.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { defineConfig, devices } from '@playwright/test'; - -/** - * Read environment variables from file. - * https://github.com/motdotla/dotenv - */ -// require('dotenv').config(); - -/** - * @see https://playwright.dev/docs/test-configuration - */ -export default defineConfig({ - testDir: './tests', - /* Run tests in files in parallel */ - fullyParallel: true, - /* Fail the build on CI if you accidentally left test.only in the source code. */ - forbidOnly: !!process.env.CI, - /* Retry on CI only */ - retries: process.env.CI ? 2 : 0, - /* Opt out of parallel tests on CI. */ - workers: process.env.CI ? 1 : undefined, - /* Reporter to use. See https://playwright.dev/docs/test-reporters */ - reporter: 'line', - /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ - use: { - /* Base URL to use in actions like `await page.goto('/')`. */ - baseURL: `http://127.0.0.1:${process.env.TEST_PORT}`, - - /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ - trace: 'on-first-retry', - }, - - /* Configure projects for major browsers */ - projects: [ - { - name: 'chromium', - use: { ...devices['Desktop Chrome'] }, - } - - /* Test against mobile viewports. */ - // { - // name: 'Mobile Chrome', - // use: { ...devices['Pixel 5'] }, - // }, - // { - // name: 'Mobile Safari', - // use: { ...devices['iPhone 12'] }, - // }, - - /* Test against branded browsers. */ - // { - // name: 'Microsoft Edge', - // use: { ...devices['Desktop Edge'], channel: 'msedge' }, - // }, - // { - // name: 'Google Chrome', - // use: { ...devices['Desktop Chrome'], channel: 'chrome' }, - // }, - ], - - /* Run your local dev server before starting the tests */ - // webServer: { - // command: 'npm run start', - // url: 'http://127.0.0.1:3000', - // reuseExistingServer: !process.env.CI, - // }, -}); - diff --git a/e2e/tests/nix-version.spec.ts b/e2e/tests/nix-version.spec.ts deleted file mode 100644 index 6799d97..0000000 --- a/e2e/tests/nix-version.spec.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { test, expect } from "@playwright/test"; - -test('check nix version', async ({ page }) => { - await page.goto('/info'); - const nixVersion = await page.locator(":text('Nix Version') + div").textContent(); - await expect(nixVersion).toBeTruthy(); -}); diff --git a/flake.lock b/flake.lock index a2c5d35..16d8a38 100644 --- a/flake.lock +++ b/flake.lock @@ -38,6 +38,22 @@ "type": "github" } }, + "dioxus-desktop-template": { + "flake": false, + "locked": { + "lastModified": 1696953583, + "narHash": "sha256-g+8wFUOSVLVN63DAlcj1OhYjOD3pkSFH5BCt6Gs0y6I=", + "owner": "srid", + "repo": "dioxus-desktop-template", + "rev": "a3c76b656c9fbddbde423c800bcab46876b5026e", + "type": "github" + }, + "original": { + "owner": "srid", + "repo": "dioxus-desktop-template", + "type": "github" + } + }, "flake-compat": { "flake": false, "locked": { @@ -108,22 +124,6 @@ "type": "github" } }, - "leptos-fullstack": { - "flake": false, - "locked": { - "lastModified": 1694027158, - "narHash": "sha256-XzDBUA5jzTFDiLJtgvknAb9MuXwEGXmAd/ZoTqVUg+o=", - "owner": "srid", - "repo": "leptos-fullstack", - "rev": "4203055c17476616bec375cd7e471e91f70d26d0", - "type": "github" - }, - "original": { - "owner": "srid", - "repo": "leptos-fullstack", - "type": "github" - } - }, "nixpkgs": { "locked": { "lastModified": 1696234590, @@ -193,8 +193,8 @@ "inputs": { "cargo-doc-live": "cargo-doc-live", "crane": "crane", + "dioxus-desktop-template": "dioxus-desktop-template", "flake-parts": "flake-parts", - "leptos-fullstack": "leptos-fullstack", "nixpkgs": "nixpkgs", "process-compose-flake": "process-compose-flake", "rust-overlay": "rust-overlay_2", diff --git a/flake.nix b/flake.nix index 47c4772..6b48c64 100644 --- a/flake.nix +++ b/flake.nix @@ -18,8 +18,8 @@ process-compose-flake.url = "github:Platonic-Systems/process-compose-flake"; cargo-doc-live.url = "github:srid/cargo-doc-live"; - leptos-fullstack.url = "github:srid/leptos-fullstack"; - leptos-fullstack.flake = false; + dioxus-desktop-template.url = "github:srid/dioxus-desktop-template"; + dioxus-desktop-template.flake = false; }; outputs = inputs: @@ -30,9 +30,8 @@ inputs.treefmt-nix.flakeModule inputs.process-compose-flake.flakeModule inputs.cargo-doc-live.flakeModule - (inputs.leptos-fullstack + /nix/flake-module.nix) + (inputs.dioxus-desktop-template + /nix/flake-module.nix) ./rust.nix - ./e2e/flake-module.nix ]; flake = { @@ -63,7 +62,6 @@ programs = { nixpkgs-fmt.enable = true; rustfmt.enable = true; - leptosfmt.enable = true; }; }; @@ -72,7 +70,6 @@ inputsFrom = [ config.treefmt.build.devShell self'.devShells.rust - self'.devShells.e2e-playwright ]; packages = with pkgs; [ just diff --git a/justfile b/justfile index 89bfbae..4e73f68 100644 --- a/justfile +++ b/justfile @@ -6,33 +6,37 @@ default: # Auto-format the source tree fmt: treefmt + # Due a bug in dx fmt, we cannot run it on files using macros + find src/app/ -name \*.rs | grep -v state.rs | grep -v state/ | xargs -n1 sh -c 'echo "📔 $1"; dx fmt -f $1' sh alias f := fmt +# CI=true for https://github.com/tauri-apps/tauri/issues/3055#issuecomment-1624389208) +bundle $CI="true": + # HACK (change PWD): Until https://github.com/DioxusLabs/dioxus/issues/1283 + cd assets && dx bundle + nix run nixpkgs#eza -- -T ./dist/bundle/macos/nix-browser.app + # Run the project locally watch $RUST_BACKTRACE="1": - cargo leptos watch + # XXX: hot reload doesn't work with tailwind + # dx serve --hot-reload + dx serve alias w := watch +tw: + tailwind -i ./css/input.css -o ./assets/tailwind.css --watch + # Run 'cargo run' for nix-health CLI in watch mode. Example: just watch-nix-health github:nammayatri/nammayatri watch-nix-health *ARGS: - cargo watch -- cargo run --bin nix-health --features=ssr -- {{ARGS}} + cargo watch -- cargo run --bin nix-health -- {{ARGS}} alias wh := watch-nix-health -# Run tests (backend & frontend) +# Run tests test: cargo test - cargo leptos test - -# Run end-to-end tests against release server -e2e-release: - nix run .#e2e-playwright-test - -# Run end-to-end tests against `just watch` server -e2e: - cd e2e && TEST_PORT=3000 playwright test --project chromium # Run docs server (live reloading) doc: diff --git a/rust.nix b/rust.nix index 54b34ed..b3bc1f3 100644 --- a/rust.nix +++ b/rust.nix @@ -1,83 +1,48 @@ # Nix module for the Rust part of the project # -# This uses https://github.com/srid/leptos-fullstack/blob/master/nix/flake-module.nix +# This uses https://github.com/srid/dioxus-desktop-template/blob/master/nix/flake-module.nix { - perSystem = { config, self', pkgs, lib, system, ... }: - let - rustBuildInputs = lib.optionals pkgs.stdenv.isDarwin (with pkgs.darwin.apple_sdk.frameworks; [ - IOKit - # For when we start using Tauri - Carbon - WebKit - ]); - in - { - leptos-fullstack.overrideCraneArgs = oa: - let - # 'cargo leptos test' doesn't run tests for all crates in the - # workspace. We do it here. - run-test = pkgs.writeShellApplication { - name = "run-test"; - text = '' - set -xe - - ${oa.cargoTestCommand} - - # Disable tests on macOS for https://github.com/garnix-io/issues/issues/69 - # If/when we move to Jenkins, this won't be necessary. - ${if !pkgs.stdenv.isDarwin - then '' - # Run `cargo test` using the same settings as `cargo leptos test` - # In particular: target-dir and features - cargo test --target-dir=target/server --no-default-features --features=ssr - cargo test --target-dir=target/front --no-default-features --features=hydrate - '' - else "" - } - ''; - }; - in - { - nativeBuildInputs = (oa.nativeBuildInputs or [ ]) ++ [ - pkgs.nix # cargo tests need nix - ]; - buildInputs = (oa.buildInputs or [ ]) ++ rustBuildInputs; - cargoTestCommand = lib.getExe run-test; - meta.description = "WIP: nix-browser"; - }; - - packages = { - default = self'.packages.nix-browser; - nix-health = config.leptos-fullstack.craneLib.buildPackage { - inherit (config.leptos-fullstack) src; - pname = "nix-health"; - nativeBuildInputs = [ - pkgs.nix # cargo tests need nix - ]; - buildInputs = rustBuildInputs; - cargoExtraArgs = "-p nix_health --features ssr"; - # Disable tests on macOS for https://github.com/garnix-io/issues/issues/69 - # If/when we move to Jenkins, this won't be necessary. - doCheck = !pkgs.stdenv.isDarwin; - }; - }; - - devShells.rust = pkgs.mkShell { - inputsFrom = [ - self'.devShells.nix-browser + perSystem = { config, self', pkgs, lib, system, ... }: { + dioxus-desktop = { + overrideCraneArgs = oa: { + nativeBuildInputs = (oa.nativeBuildInputs or [ ]) ++ [ + pkgs.nix # cargo tests need nix ]; - packages = with pkgs; [ - cargo-watch - cargo-expand - cargo-nextest - config.process-compose.cargo-doc-live.outputs.package - ]; - buildInputs = rustBuildInputs; - shellHook = '' - echo - echo "🍎🍎 Run 'just ' to get started" - just - ''; + meta.description = "WIP: nix-browser"; }; }; + + packages = { + default = self'.packages.nix-browser; + nix-health = config.dioxus-desktop.craneLib.buildPackage { + inherit (config.dioxus-desktop) src; + pname = "nix-health"; + nativeBuildInputs = [ + pkgs.nix # cargo tests need nix + ]; + buildInputs = config.dioxus-desktop.rustBuildInputs; + cargoExtraArgs = "-p nix_health"; + # Disable tests on macOS for https://github.com/garnix-io/issues/issues/69 + # If/when we move to Jenkins, this won't be necessary. + doCheck = !pkgs.stdenv.isDarwin; + }; + }; + + devShells.rust = pkgs.mkShell { + inputsFrom = [ + self'.devShells.nix-browser + ]; + packages = with pkgs; [ + cargo-watch + cargo-expand + cargo-nextest + config.process-compose.cargo-doc-live.outputs.package + ]; + shellHook = '' + echo + echo "🍎🍎 Run 'just ' to get started" + just + ''; + }; + }; } diff --git a/src/app/flake.rs b/src/app/flake.rs index 290bc68..a564c93 100644 --- a/src/app/flake.rs +++ b/src/app/flake.rs @@ -2,203 +2,162 @@ use std::collections::BTreeMap; -use leptos::*; -use leptos_extra::{ - query::{self, RefetchQueryButton}, - signal::{use_signal, SignalWithResult}, -}; -use leptos_meta::*; -use leptos_router::*; -use nix_rs::{ - command::Refresh, - flake::{ - outputs::{FlakeOutputs, Type, Val}, - schema::FlakeSchema, - url::FlakeUrl, - Flake, - }, +use dioxus::prelude::*; +use dioxus_router::prelude::Link; +use nix_rs::flake::{ + outputs::{FlakeOutputs, Type, Val}, + schema::FlakeSchema, + url::FlakeUrl, + Flake, }; -use crate::widget::*; +use crate::{ + app::widget::RefreshButton, + app::{state::AppState, Route}, +}; -/// Nix flake dashboard #[component] -pub fn NixFlakeRoute(cx: Scope) -> impl IntoView { - let suggestions = FlakeUrl::suggestions(); - let url = use_signal::(cx); - let refresh = use_signal::(cx); - let query = move || (url(), refresh()); - let result = query::use_server_query(cx, query, get_flake); - view! { cx, - - <h1 class="text-5xl font-bold">{"Nix Flake"}</h1> - <TextInput id="nix-flake-input" label="Load a Nix Flake" val=url suggestions/> - <RefetchQueryButton result query/> - <Outlet/> +pub fn Flake(cx: Scope) -> Element { + let state = AppState::use_state(cx); + let fut = use_future(cx, (), |_| async move { state.update_flake().await }); + let flake = state.flake.read(); + let busy = (*flake).is_loading_or_refreshing(); + render! { + h1 { class: "text-5xl font-bold", "Flake dashboard" } + div { class: "p-2 my-1", + input { + class: "w-full p-1 mb-4 font-mono", + id: "nix-flake-input", + "type": "text", + value: "{state.flake_url}", + disabled: busy, + onchange: move |ev| { + let url: FlakeUrl = ev.value.clone().into(); + tracing::info!("setting flake url set to {}", & url); + state.flake_url.set(url); + fut.restart(); + } + } + RefreshButton { busy: busy, handler: move |_| { fut.restart() } } + flake.render_with(cx, |v| render! { FlakeView { flake: v.clone() } }) + } } } #[component] -pub fn NixFlakeHomeRoute(cx: Scope) -> impl IntoView { - let url = use_signal::<FlakeUrl>(cx); - let refresh = use_signal::<Refresh>(cx); - let query = move || (url(), refresh()); - let result = query::use_server_query(cx, query, get_flake); - let data = result.data; - view! { cx, - <div class="p-2 my-1"> - <SuspenseWithErrorHandling> - {move || { - data.with_result(move |flake| { - view! { cx, <FlakeView flake/> } - }) - }} - - </SuspenseWithErrorHandling> - </div> +pub fn FlakeRaw(cx: Scope) -> Element { + let state = AppState::use_state(cx); + use_future(cx, (), |_| async move { state.update_flake().await }); + let flake = state.flake.read(); + render! { + div { + Link { to: Route::Flake {}, "âŦ… Back" } + div { class: "px-4 py-2 font-mono text-xs text-left text-gray-500 border-2 border-black", + flake.render_with(cx, |v| render! { FlakeOutputsRawView { outs: v.output.clone() } } ) + } + } } } #[component] -pub fn NixFlakeRawRoute(cx: Scope) -> impl IntoView { - let url = use_signal::<FlakeUrl>(cx); - let refresh = use_signal::<Refresh>(cx); - let query = move || (url(), refresh()); - let result = query::use_server_query(cx, query, get_flake); - let data = result.data; - view! { cx, - <div> - <A href="/flake">"< Back"</A> - </div> - <div class="px-4 py-2 font-mono text-xs text-left text-gray-500 border-2 border-black"> - <SuspenseWithErrorHandling> - {move || { - data.with_result(move |r| { - view! { cx, <FlakeOutputsRawView outs=&r.output/> } - }) - }} - - </SuspenseWithErrorHandling> - </div> +pub fn FlakeView(cx: Scope, flake: Flake) -> Element { + render! { + div { class: "flex flex-col my-4", + h3 { class: "text-lg font-bold", flake.url.to_string() } + div { class: "text-sm italic text-gray-600", + Link { to: Route::FlakeRaw {}, "View raw output" } + } + div { FlakeSchemaView { schema: &flake.schema } } + } } } #[component] -fn FlakeView<'a>(cx: Scope, flake: &'a Flake) -> impl IntoView { - view! { cx, - <div class="flex flex-col my-4"> - <h3 class="text-lg font-bold">{flake.url.to_string()}</h3> - <div class="text-sm italic text-gray-600"> - <A href="/flake/raw" exact=true> - "View raw output" - </A> - </div> - <div> - <FlakeSchemaView schema=&flake.schema/> - </div> - </div> +pub fn SectionHeading(cx: Scope, title: &'static str) -> Element { + render! { + h3 { class: "p-2 mt-4 mb-2 font-bold bg-gray-300 border-b-2 border-l-2 border-black text-l", + "{title}" + } } } #[component] -fn SectionHeading(cx: Scope, title: &'static str) -> impl IntoView { - view! { cx, - <h3 class="p-2 mt-4 mb-2 font-bold bg-gray-300 border-b-2 border-l-2 border-black text-l"> - {title} - </h3> +pub fn FlakeSchemaView<'a>(cx: Scope, schema: &'a FlakeSchema) -> Element { + let system = schema.system.clone(); + render! { + div { + h2 { class: "my-2", + div { class: "text-xl font-bold text-primary-600", "{system.human_readable()}" } + span { class: "font-mono text-xs text-gray-500", "(", "{system }", ")" } + } + div { class: "text-left", + BtreeMapView { title: "Packages", tree: &schema.packages } + BtreeMapView { title: "Legacy Packages", tree: &schema.legacy_packages } + BtreeMapView { title: "Dev Shells", tree: &schema.devshells } + BtreeMapView { title: "Checks", tree: &schema.checks } + BtreeMapView { title: "Apps", tree: &schema.apps } + SectionHeading { title: "Formatter" } + match schema.formatter.as_ref() { + Some(v) => { + let k = v.name.clone().unwrap_or("formatter".to_string()); + render! { FlakeValView { k: k.clone(), v: v.clone() } } + }, + None => render! { "" } + }, + SectionHeading { title: "Other" } + match &schema.other { + Some(v) => render! { FlakeOutputsRawView { outs: FlakeOutputs::Attrset(v.clone()) } }, + None => render! { "" } + } + } + } } } #[component] -fn FlakeSchemaView<'a>(cx: Scope, schema: &'a FlakeSchema) -> impl IntoView { - let system = &schema.system.clone(); - view! { cx, - <div> - <h2 class="my-2 "> - <div class="text-xl font-bold text-primary-600">{system.human_readable()}</div> - " " - <span class="font-mono text-xs text-gray-500">"(" {system.to_string()} ")"</span> - </h2> - - <div class="text-left"> - <BTreeMapView title="Packages" tree=&schema.packages/> - <BTreeMapView title="Legacy Packages" tree=&schema.legacy_packages/> - <BTreeMapView title="Dev Shells" tree=&schema.devshells/> - <BTreeMapView title="Checks" tree=&schema.checks/> - <BTreeMapView title="Apps" tree=&schema.apps/> - <SectionHeading title="Formatter"/> - {schema - .formatter - .as_ref() - .map(|v| { - let default = "formatter".to_string(); - let k = v.name.as_ref().unwrap_or(&default); - view! { cx, <FlakeValView k v/> } - })} - - <SectionHeading title="Other"/> - {schema - .other - .as_ref() - .map(|v| { - // TODO: Use a non-recursive rendering component? - view! { cx, <FlakeOutputsRawView outs=&FlakeOutputs::Attrset(v.clone())/> } - })} - - </div> - </div> - } -} - -#[component] -fn BTreeMapView<'a>( +pub fn BtreeMapView<'a>( cx: Scope, title: &'static str, tree: &'a BTreeMap<String, Val>, -) -> impl IntoView { - (!tree.is_empty()).then(move || { - view! { cx, - <SectionHeading title/> - <BTreeMapBodyView tree/> +) -> Element { + render! { + div { + SectionHeading { title: title } + BtreeMapBodyView { tree: tree } } - }) -} - -#[component] -fn BTreeMapBodyView<'a>(cx: Scope, tree: &'a BTreeMap<String, Val>) -> impl IntoView { - view! { cx, - <div class="flex flex-wrap justify-start"> - {tree.iter().map(|(k, v)| view! { cx, <FlakeValView k v/> }).collect_view(cx)} - </div> } } #[component] -fn FlakeValView<'a>(cx: Scope, k: &'a String, v: &'a Val) -> impl IntoView { - view! { cx, - <div - title=format!("{:?}", v.type_) - class="flex flex-col p-2 my-2 mr-2 space-y-2 bg-white border-4 border-gray-300 rounded hover:border-gray-400" - > - <div class="flex flex-row justify-start space-x-2 font-bold text-primary-500"> - <div>{v.type_.to_icon()}</div> - <div>{k}</div> - </div> - {v - .name - .as_ref() - .map(|v| { - view! { cx, <div class="font-mono text-xs text-gray-500">{v}</div> } - })} +pub fn BtreeMapBodyView<'a>(cx: Scope, tree: &'a BTreeMap<String, Val>) -> Element { + render! { + div { class: "flex flex-wrap justify-start", + for (k , v) in tree.iter() { + FlakeValView { k: k.clone(), v: v.clone() } + } + } + } +} - {v - .description - .as_ref() - .map(|v| { - view! { cx, <div class="font-light">{v}</div> } - })} - - </div> +#[component] +pub fn FlakeValView(cx: Scope, k: String, v: Val) -> Element { + render! { + div { + title: "{v.type_}", + class: "flex flex-col p-2 my-2 mr-2 space-y-2 bg-white border-4 border-gray-300 rounded hover:border-gray-400", + div { class: "flex flex-row justify-start space-x-2 font-bold text-primary-500", + div { v.type_.to_icon() } + div { "{k}" } + } + match &v.name { + Some(name_val) => render! { div { class: "font-mono text-xs text-gray-500", "{name_val}" } }, + None => render! { "" } // No-op for None + }, + match &v.description { + Some(desc_val) => render! { div { class: "font-light", "{desc_val}" } }, + None => render! { "" } // No-op for None + } + } } } @@ -207,65 +166,46 @@ fn FlakeValView<'a>(cx: Scope, k: &'a String, v: &'a Val) -> impl IntoView { /// /// WARNING: This may cause performance problems if the tree is large. #[component] -fn FlakeOutputsRawView<'a>(cx: Scope, outs: &'a FlakeOutputs) -> impl IntoView { - fn view_val<'b>(cx: Scope, val: &'b Val) -> View { - view! { cx, - <span> - <b>{val.name.clone()}</b> +pub fn FlakeOutputsRawView(cx: Scope, outs: FlakeOutputs) -> Element { + #[component] + fn ValView<'a>(cx: Scope, val: &'a Val) -> Element { + render! { + span { + b { val.name.clone() } " (" - <TypeView type_=&val.type_/> + TypeView { type_: &val.type_ } ") " - <em>{val.description.clone()}</em> - </span> + em { val.description.clone() } + } } - .into_view(cx) } #[component] - fn TypeView<'b>(cx: Scope, type_: &'b Type) -> impl IntoView { - view! { cx, - <span> - {match type_ { + pub fn TypeView<'a>(cx: Scope, type_: &'a Type) -> Element { + render! { + span { + match type_ { Type::NixosModule => "nixosModule ❄ī¸", Type::Derivation => "derivation đŸ“Ļ", Type::App => "app 📱", Type::Template => "template 🏗ī¸", Type::Unknown => "unknown ❓", - }} - - </span> + } + } } } + match outs { - FlakeOutputs::Val(v) => view_val(cx, v), - FlakeOutputs::Attrset(v) => view! { cx, - <ul class="list-disc"> - {v - .iter() - .map(|(k, v)| { - view! { cx, - <li class="ml-4"> - <span class="px-2 py-1 font-bold text-primary-500">{k}</span> - <FlakeOutputsRawView outs=v/> - </li> - } - }) - .collect_view(cx)} - </ul> - } - .into_view(cx), + FlakeOutputs::Val(v) => render! { ValView { val: v } }, + FlakeOutputs::Attrset(v) => render! { + ul { class: "list-disc", + for (k , v) in v.iter() { + li { class: "ml-4", + span { class: "px-2 py-1 font-bold text-primary-500", "{k}" } + FlakeOutputsRawView { outs: v.clone() } + } + } + } + }, } } - -/// Get [Flake] info for the given flake url -#[server(GetFlake, "/api")] -pub async fn get_flake(args: (FlakeUrl, Refresh)) -> Result<Flake, ServerFnError> { - use nix_rs::command::NixCmd; - let (url, refresh) = args; - let nix_cmd = &NixCmd { - refresh, - ..NixCmd::default() - }; - let v = Flake::from_nix(nix_cmd, url).await?; - Ok(v) -} diff --git a/src/app/health.rs b/src/app/health.rs index 4748ede..de37c40 100644 --- a/src/app/health.rs +++ b/src/app/health.rs @@ -1,100 +1,71 @@ //! Nix health check UI -use leptos::*; -use leptos_extra::query::{self, RefetchQueryButton}; -use leptos_meta::*; +use dioxus::prelude::*; use nix_health::traits::{Check, CheckResult}; -use tracing::instrument; -use crate::widget::*; +use crate::{app::state::AppState, app::widget::RefreshButton}; /// Nix health checks -#[component] -pub fn NixHealthRoute(cx: Scope) -> impl IntoView { +pub fn Health(cx: Scope) -> Element { + let state = AppState::use_state(cx); + let health_checks = state.health_checks.read(); let title = "Nix Health"; - let result = query::use_server_query(cx, || (), get_nix_health); - let data = result.data; - view! { cx, - <Title text=title/> - <h1 class="text-5xl font-bold">{title}</h1> - <RefetchQueryButton result query=|| ()/> - <div class="my-1"> - <SuspenseWithErrorHandling> - <div class="flex flex-col items-stretch justify-start space-y-8 text-left"> - <For - each=move || data.get().unwrap_or(Ok(vec![])).unwrap_or(vec![]) - key=|check| check.title.clone() - view=move |cx, check| { - view! { cx, <ViewCheck check/> } - } - /> - - </div> - - </SuspenseWithErrorHandling> - </div> + render! { + h1 { class: "text-5xl font-bold", title } + RefreshButton { + busy: (*health_checks).is_loading_or_refreshing(), + handler: move |_event| { + cx.spawn(async move { + state.update_health_checks().await; + }); + } + } + health_checks.render_with(cx, |checks| render! { + div { class: "flex flex-col items-stretch justify-start space-y-8 text-left", + for check in checks { + ViewCheck { check: check.clone() } + } + } + }) } } #[component] -fn ViewCheck(cx: Scope, check: Check) -> impl IntoView { - view! { cx, - <div class="contents"> - <details - open=check.result != CheckResult::Green - class="my-2 bg-white border-2 rounded-lg cursor-pointer hover:bg-primary-100 border-base-300" - > - <summary class="p-4 text-xl font-bold"> - <CheckResultSummaryView green=check.result.green()/> - {" "} - {check.title} - </summary> - <div class="p-4"> - <div class="p-2 my-2 font-mono text-sm bg-black text-base-100"> - {check.info} - </div> - <div class="flex flex-col justify-start space-y-4"> - {match check.result { - CheckResult::Green => view! { cx, "" }.into_view(cx), - CheckResult::Red { msg, suggestion } => { - view! { cx, - <h3 class="my-2 font-bold text-l"></h3> - <div class="p-2 bg-red-400 rounded bg-border">{msg}</div> - <h3 class="my-2 font-bold text-l"></h3> - <div class="p-2 bg-blue-400 rounded bg-border"> - {suggestion} - </div> - } - .into_view(cx) +fn ViewCheck(cx: Scope, check: Check) -> Element { + render! { + div { class: "contents", + details { + open: check.result != CheckResult::Green, + class: "my-2 bg-white border-2 rounded-lg cursor-pointer hover:bg-primary-100 border-base-300", + summary { class: "p-4 text-xl font-bold", + CheckResultSummaryView { green: check.result.green() } + " " + check.title.clone() + } + div { class: "p-4", + div { class: "p-2 my-2 font-mono text-sm bg-black text-base-100", check.info.clone() } + div { class: "flex flex-col justify-start space-y-4", + match check.result.clone() { + CheckResult::Green => render! { "" }, + CheckResult::Red { msg, suggestion } => render! { + h3 { class: "my-2 font-bold text-l" } + div { class: "p-2 bg-red-400 rounded bg-border", msg } + h3 { class: "my-2 font-bold text-l" } + div { class: "p-2 bg-blue-400 rounded bg-border", suggestion } } - }} - - </div> - </div> - </details> - </div> + } + } + } + } + } } } #[component] -pub fn CheckResultSummaryView(cx: Scope, green: bool) -> impl IntoView { - if green { - view! { cx, <span class="text-green-500">{"✓"}</span> } +pub fn CheckResultSummaryView(cx: Scope, green: bool) -> Element { + if *green { + render! { span { class: "text-green-500", "✓" } } } else { - view! { cx, <span class="text-red-500">{"✗"}</span> } + render! { span { class: "text-red-500", "✗" } } } } - -/// Get [NixHealth] information -#[instrument(name = "nix-health")] -#[server(GetNixHealth, "/api")] -pub async fn get_nix_health(_unit: ()) -> Result<Vec<nix_health::traits::Check>, ServerFnError> { - use nix_health::NixHealth; - use nix_rs::{env, info}; - let nix_info = info::NixInfo::from_nix(&nix_rs::command::NixCmd::default()).await?; - // TODO: Use Some(flake_url)? With what UX? - let nix_env = env::NixEnv::detect(None).await?; - let health = NixHealth::default(); - let checks = health.run_checks(&nix_info, &nix_env); - Ok(checks) -} diff --git a/src/app/info.rs b/src/app/info.rs index 29f0b95..dc9a9f5 100644 --- a/src/app/info.rs +++ b/src/app/info.rs @@ -2,128 +2,104 @@ use std::fmt::Display; -use leptos::*; -use leptos_extra::query::{self, RefetchQueryButton}; -use leptos_extra::signal::SignalWithResult; -use leptos_meta::*; -use nix_rs::{ - config::{ConfigVal, NixConfig}, - info::NixInfo, - version::NixVersion, -}; +use dioxus::prelude::*; +use nix_rs::{config::NixConfig, info::NixInfo, version::NixVersion}; -use crate::widget::*; +use crate::{app::state::AppState, app::widget::RefreshButton}; /// Nix information #[component] -pub fn NixInfoRoute(cx: Scope) -> impl IntoView { +pub fn Info(cx: Scope) -> Element { let title = "Nix Info"; - let result = query::use_server_query(cx, || (), get_nix_info); - let data = result.data; - view! { cx, - <Title text=title/> - <h1 class="text-5xl font-bold">{title}</h1> - <RefetchQueryButton result query=|| ()/> - <div class="my-1 text-left"> - <SuspenseWithErrorHandling> - {move || { - data.with_result(move |info| { - view! { cx, <NixInfoView info/> } - }) - }} - - </SuspenseWithErrorHandling> - </div> + let state = AppState::use_state(cx); + let nix_info = state.nix_info.read(); + render! { + h1 { class: "text-5xl font-bold", title } + RefreshButton { + busy: (*nix_info).is_loading_or_refreshing(), + handler: move |_event| { + cx.spawn(async move { + state.update_nix_info().await; + }); + } + } + nix_info.render_with(cx, |v| render! { NixInfoView { info: v.clone() } }) } } #[component] -fn NixInfoView<'a>(cx: Scope, info: &'a NixInfo) -> impl IntoView { - view! { cx, - <div class="flex flex-col p-4 space-y-8 bg-white border-2 rounded border-base-400"> - <div> - <b>Nix Version</b> - <div class="p-1 my-1 rounded bg-primary-50"> - <NixVersionView version=&info.nix_version/> - </div> - </div> - <div> - <b>Nix Config</b> - <NixConfigView config=info.nix_config.clone()/> - </div> - </div> - } -} - -#[component] -fn NixVersionView<'a>(cx: Scope, version: &'a NixVersion) -> impl IntoView { - view! { cx, - <a href=nix_rs::refs::RELEASE_HISTORY class="font-mono hover:underline" target="_blank"> - {format!("{}", version)} - </a> - } -} - -#[component] -fn NixConfigView(cx: Scope, config: NixConfig) -> impl IntoView { - #[component] - fn ConfigRow(cx: Scope, key: &'static str, title: String, children: Children) -> impl IntoView { - view! { cx, - // TODO: Use a nice Tailwind tooltip here, instead of "title" - // attribute. - <tr title=title> - <td class="px-4 py-2 font-semibold text-base-700">{key}</td> - <td class="px-4 py-2 text-left"> - <code>{children(cx)}</code> - </td> - </tr> +fn NixInfoView(cx: Scope, info: NixInfo) -> Element { + render! { + div { class: "flex flex-col p-4 space-y-8 bg-white border-2 rounded border-base-400", + div { + b { "Nix Version" } + div { class: "p-1 my-1 rounded bg-primary-50", NixVersionView { version: info.nix_version } } + } + div { + b { "Nix Config" } + NixConfigView { config: info.nix_config.clone() } + } } } - view! { cx, - <div class="py-1 my-1 rounded bg-primary-50"> - <table class="text-right"> - // FIXME: so many clones - <tbody> - <ConfigRow key="Local System" title=config.system.description> - {config.system.value.to_string()} - </ConfigRow> - <ConfigRow key="Max Jobs" title=config.max_jobs.description.clone()> - {config.max_jobs.value} - </ConfigRow> - <ConfigRow key="Cores per build" title=config.cores.description> - {config.cores.value} - </ConfigRow> - <ConfigRow key="Nix Caches" title=config.substituters.clone().description> - <ConfigValListView cfg=config.substituters.clone()/> - </ConfigRow> - </tbody> - </table> - </div> - } - .into_view(cx) } #[component] -pub fn ConfigValListView<T>(cx: Scope, cfg: ConfigVal<Vec<T>>) -> impl IntoView +fn NixVersionView(cx: Scope, version: NixVersion) -> Element { + render! {a { href: nix_rs::refs::RELEASE_HISTORY, class: "font-mono hover:underline", target: "_blank", "{version}" }} +} + +#[component] +fn NixConfigView(cx: Scope, config: NixConfig) -> Element { + let config_row = |key: &'static str, title: String, children: Element<'a>| { + render! { + tr { title: "{title}", + td { class: "px-4 py-2 font-semibold text-base-700", "{key}" } + td { class: "px-4 py-2 text-left", + code { children } + } + } + } + }; + render! { + div { class: "py-1 my-1 rounded bg-primary-50", + table { class: "text-right", + tbody { + config_row ( + "Local System", + config.system.description.clone(), + render! { "{config.system.value}" } + ), + config_row ( + "Max Jobs", + config.max_jobs.description.clone(), + render! {"{config.max_jobs.value}"} + ), + config_row ( + "Cores per build", + config.cores.description.clone(), + render! { "{config.cores.value}" } + ), + config_row ( + "Nix Caches", + config.substituters.clone().description, + render! { ConfigValList { items: &config.substituters.value } } + ) + } + } + } + } +} + +#[component] +fn ConfigValList<T, 'a>(cx: Scope, items: &'a Vec<T>) -> Element where T: Display, { - view! { cx, - // Render a list of T items in the list 'self' - <div class="flex flex-col space-y-4"> - {cfg - .value - .into_iter() - .map(|item| view! { cx, <li class="list-disc">{item.to_string()}</li> }) - .collect_view(cx)} - </div> + render! { + div { class: "flex flex-col space-y-4", + for item in items { + li { class: "list-disc", "{item}" } + } + } } - .into_view(cx) -} - -/// Determine [NixInfo] on the user's system -#[server(GetNixInfo, "/api")] -pub async fn get_nix_info(_unit: ()) -> Result<NixInfo, ServerFnError> { - let v = NixInfo::from_nix(&nix_rs::command::NixCmd::default()).await?; - Ok(v) } diff --git a/src/app/mod.rs b/src/app/mod.rs index 1cd44fc..36e394d 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -6,141 +6,139 @@ mod flake; mod health; mod info; +mod state; +mod widget; -use leptos::*; -use leptos_extra::{ - query::{self}, - signal::{provide_signal, SignalWithResult}, +use dioxus::prelude::*; +use dioxus_router::prelude::*; +use nix_rs::flake::url::FlakeUrl; + +use crate::app::{ + flake::{Flake, FlakeRaw}, + health::Health, + info::Info, + state::AppState, + widget::Loader, }; -use leptos_meta::*; -use leptos_query::*; -use leptos_router::*; -use nix_rs::{command::Refresh, flake::url::FlakeUrl}; -use crate::{app::flake::*, app::health::*, app::info::*, widget::*}; +#[derive(Routable, PartialEq, Debug, Clone)] +#[rustfmt::skip] +enum Route { + #[layout(Wrapper)] + #[route("/")] + Dashboard {}, + #[route("/about")] + About {}, + #[route("/flake")] + Flake {}, + #[route("/flake/raw")] + FlakeRaw {}, + #[route("/health")] + Health {}, + #[route("/info")] + Info {}, +} + +fn Wrapper(cx: Scope) -> Element { + render! { + Nav {} + Outlet::<Route> {} + footer { class: "flex flex-row justify-center w-full p-4", img { src: "images/128x128.png", width: "32", height: "32" } } + } +} /// Main frontend application container -#[component] -pub fn App(cx: Scope) -> impl IntoView { - provide_meta_context(cx); - provide_query_client(cx); - provide_signal::<FlakeUrl>( - cx, +pub fn App(cx: Scope) -> Element { + AppState::provide_state(cx); + use_shared_state_provider(cx, || { FlakeUrl::suggestions() .first() .map(Clone::clone) - .unwrap_or_default(), - ); - provide_signal::<Refresh>(cx, false.into()); // refresh flag is unused, but we may add it to UI later. + .unwrap_or_default() + }); + render! { + body { + // Can't do this, because Tauri window has its own scrollbar. :-/ + // class: "overflow-y-scroll", + div { class: "flex justify-center w-full min-h-screen bg-center bg-cover bg-base-200", + div { class: "flex flex-col items-stretch mx-auto sm:container sm:max-w-screen-md", + main { class: "flex flex-col px-2 mb-8 space-y-3 text-center", Router::<Route> {} } + } + } + } + } +} - view! { cx, - <Stylesheet id="leptos" href="/pkg/nix-browser.css"/> - <Title formatter=|s| format!("{s} ― nix-browser")/> - <Router fallback=|cx| { - view! { cx, <NotFound/> } - }> - <Body class="overflow-y-scroll"/> - <div class="flex justify-center w-full min-h-screen bg-center bg-cover bg-base-200"> - <div class="flex flex-col items-stretch mx-auto sm:container sm:max-w-screen-md"> - <Nav/> - <main class="flex flex-col px-2 mb-8 space-y-3 text-center"> - <Routes> - <Route path="" view=Dashboard/> - <Route path="/flake" view=NixFlakeRoute> - <Route path="" view=NixFlakeHomeRoute/> - <Route path="raw" view=NixFlakeRawRoute/> - </Route> - <Route path="/health" view=NixHealthRoute/> - <Route path="/info" view=NixInfoRoute/> - <Route path="/about" view=About/> - </Routes> - </main> - </div> - </div> - </Router> +// Home page +fn Dashboard(cx: Scope) -> Element { + tracing::debug!("Rendering Dashboard page"); + let state = AppState::use_state(cx); + let health_checks = state.health_checks.read(); + // A Card component + #[component] + fn Card<'a>(cx: Scope, href: Route, children: Element<'a>) -> Element<'a> { + render! { + Link { + to: "{href}", + class: "flex items-center justify-center w-48 h-48 p-2 m-2 border-2 rounded-lg shadow border-base-400 active:shadow-none bg-base-100 hover:bg-primary-200", + span { class: "text-3xl text-base-800", children } + } + } + } + render! { + h1 { class: "text-5xl font-bold", "Dashboard" } + div { id: "cards", class: "flex flex-row flex-wrap", + Card { href: Route::Health {}, + "Nix Health Check " + match (*health_checks).current_value() { + Some(Ok(checks)) => render! { + if checks.iter().all(|check| check.result.green()) { + "✅" + } else { + "❌" + } + }, + Some(Err(err)) => render! { "{err}" }, + None => render! { Loader {} }, + } + } + Card { href: Route::Info {}, "Nix Info ℹī¸" } + Card { href: Route::Flake {}, "Flake Dashboard ❄ī¸ī¸" } + } } } /// Navigation bar /// /// TODO Switch to breadcrumbs, as it simplifes the design overall. -#[component] -fn Nav(cx: Scope) -> impl IntoView { +fn Nav(cx: Scope) -> Element { let class = "px-3 py-2"; - view! { cx, - <nav class="flex flex-row w-full mb-8 text-white md:rounded-b bg-primary-800"> - <A exact=true href="/" class=class> - "Dashboard" - </A> - <A exact=false href="/flake" class=class> - "Flake" - </A> - <A exact=true href="/health" class=class> - "Nix Health" - </A> - <A exact=true href="/info" class=class> - "Nix Info" - </A> - <A exact=true href="/about" class=class> - "About" - </A> - <div class=format!("flex-grow font-bold text-end {}", class)>"🌍 nix-browser"</div> - </nav> - } -} - -/// Home page -#[component] -fn Dashboard(cx: Scope) -> impl IntoView { - tracing::debug!("Rendering Dashboard page"); - let result = query::use_server_query(cx, || (), get_nix_health); - let data = result.data; - let healthy = Signal::derive(cx, move || { - data.with_result(|checks| checks.iter().all(|check| check.result.green())) - }); - // A Card component - #[component] - fn Card(cx: Scope, href: &'static str, children: Children) -> impl IntoView { - view! { cx, - <A - href=href - class="flex items-center justify-center w-48 h-48 p-2 m-2 border-2 rounded-lg shadow border-base-400 active:shadow-none bg-base-100 hover:bg-primary-200" - > - <span class="text-3xl text-base-800">{children(cx)}</span> - </A> + let active_class = "bg-white text-primary-800 font-bold"; + render! { + nav { class: "flex flex-row w-full mb-8 text-white md:rounded-b bg-primary-800", + Link { to: Route::Dashboard {}, class: class, active_class: active_class, "Dashboard" } + Link { to: Route::Flake {}, class: class, active_class: active_class, "Flake" } + Link { to: Route::Health {}, class: class, active_class: active_class, "Nix Health" } + Link { to: Route::Info {}, class: class, active_class: active_class, "Nix Info" } + Link { to: Route::About {}, class: class, active_class: active_class, "About" } + div { class: "flex-grow font-bold text-end {class}", "🌍 nix-browser" } } } - view! { cx, - <Title text="Dashboard"/> - <h1 class="text-5xl font-bold">"Dashboard"</h1> - <div id="cards" class="flex flex-row flex-wrap"> - <SuspenseWithErrorHandling> - <Card href="/health"> - "Nix Health Check " - {move || { - healthy - .with_result(move |green| { - view! { cx, <CheckResultSummaryView green=*green/> } - }) - }} - - </Card> - </SuspenseWithErrorHandling> - <Card href="/info">"Nix Info ℹī¸"</Card> - <Card href="/flake">"Flake Overview ❄ī¸ī¸"</Card> - </div> - } } /// About page -#[component] -fn About(cx: Scope) -> impl IntoView { - view! { cx, - <Title text="About"/> - <h1 class="text-5xl font-bold">"About"</h1> - <p> +fn About(cx: Scope) -> Element { + render! { + h1 { class: "text-5xl font-bold", "About" } + p { "nix-browser is still work in progress. Track its development " - <LinkExternal link="https://github.com/juspay/nix-browser" text="on Github"/> - </p> + a { + href: "https://github.com/juspay/nix-browser", + class: "underline text-primary-500 hover:no-underline", + rel: "external", + target: "_blank", + "on Github" + } + } } } diff --git a/src/app/state.rs b/src/app/state.rs new file mode 100644 index 0000000..407982a --- /dev/null +++ b/src/app/state.rs @@ -0,0 +1,161 @@ +//! Application state + +mod datum; + +use std::fmt::Display; + +use dioxus::prelude::{use_context, use_context_provider, use_future, Scope}; +use dioxus_signals::Signal; +use nix_health::NixHealth; +use nix_rs::{ + command::NixCmdError, + flake::{url::FlakeUrl, Flake}, +}; +use tracing::instrument; + +use self::datum::Datum; + +/// Our dioxus application state is a struct of [Signal] +/// +/// They use [Datum] which is a glorified [Option] to distinguis between initial +/// loading and subsequent refreshing. +#[derive(Default, Clone, Copy, Debug)] +pub struct AppState { + pub nix_info: Signal<Datum<Result<nix_rs::info::NixInfo, SystemError>>>, + pub nix_env: Signal<Datum<Result<nix_rs::env::NixEnv, SystemError>>>, + pub health_checks: Signal<Datum<Result<Vec<nix_health::traits::Check>, SystemError>>>, + + pub flake_url: Signal<FlakeUrl>, + pub flake: Signal<Datum<Result<Flake, NixCmdError>>>, +} + +impl AppState { + pub async fn initialize(&self) { + tracing::info!("Initializing app state"); + // Initializing health checks automatially initializes other signals. + self.update_health_checks().await; + } + + #[instrument(name = "update-nix-info", skip(self))] + pub async fn update_nix_info(&self) { + tracing::debug!("Updating nix info ..."); + Datum::refresh_with(self.nix_info, async { + // NOTE: Without tokio::spawn, this will run in main desktop thread, + // and will hang at some point. + let nix_info = tokio::spawn(async move { + nix_rs::info::NixInfo::from_nix(&nix_rs::command::NixCmd::default()) + .await + .map_err(|e| SystemError { + message: format!("Error getting nix info: {:?}", e), + }) + }) + .await + .unwrap(); + tracing::debug!("Got nix info, about to mut"); + nix_info + }) + .await; + } + + #[instrument(name = "update-nix-env", skip(self))] + pub async fn update_nix_env(&self) { + tracing::debug!("Updating nix env ..."); + Datum::refresh_with(self.nix_env, async { + let nix_env = tokio::spawn(async move { + nix_rs::env::NixEnv::detect(None) + .await + .map_err(|e| e.to_string().into()) + }) + .await + .unwrap(); + tracing::debug!("Got nix env, about to mut"); + nix_env + }) + .await; + } + + #[instrument(name = "update-health-checks", skip(self))] + pub async fn update_health_checks(&self) { + tracing::debug!("Updating health checks ..."); + Datum::refresh_with(self.health_checks, async { + // Update depenencies + self.update_nix_info().await; + self.update_nix_env().await; + let get_nix_health = move || -> Result<Vec<nix_health::traits::Check>, SystemError> { + let nix_env = self.nix_env.read(); + let nix_env: &nix_rs::env::NixEnv = nix_env + .current_value() + .unwrap() + .as_ref() + .map_err(|e| Into::<SystemError>::into(e.to_string()))?; + let nix_info = self.nix_info.read(); + let nix_info: &nix_rs::info::NixInfo = + nix_info + .current_value() + .unwrap() + .as_ref() + .map_err(|e| Into::<SystemError>::into(e.to_string()))?; + let health_checks = NixHealth::default().run_checks(nix_info, nix_env); + Ok(health_checks) + }; + let health_checks = get_nix_health(); + tracing::debug!("Got health checks, about to mut"); + health_checks + }) + .await; + } + + #[instrument(name = "set-flake-url", skip(self))] + pub async fn set_flake_url(&self, url: &FlakeUrl) { + // TODO: Can we use derived signals here? + self.flake_url.set(url.clone()); + self.update_flake().await; + } + + #[instrument(name = "update-flake", skip(self))] + pub async fn update_flake(&self) { + tracing::debug!("Updating flake ..."); + Datum::refresh_with(self.flake, async { + let flake_url = self.flake_url.read().clone(); + let flake = tokio::spawn(async move { + Flake::from_nix(&nix_rs::command::NixCmd::default(), flake_url.clone()).await + }) + .await + .unwrap(); + tracing::debug!("Got flake, about to mut"); + flake + }) + .await; + } + + /// Get the [AppState] from context + pub fn use_state(cx: Scope) -> Self { + *use_context(cx).unwrap() + } + + pub fn provide_state(cx: Scope) { + use_context_provider(cx, AppState::default); + let state = AppState::use_state(cx); + use_future(cx, (), |_| async move { + state.initialize().await; + }); + } +} + +/// Catch all error to use in UI components +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct SystemError { + pub message: String, +} + +impl Display for SystemError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.message) + } +} + +impl From<String> for SystemError { + fn from(message: String) -> Self { + Self { message } + } +} diff --git a/src/app/state/datum.rs b/src/app/state/datum.rs new file mode 100644 index 0000000..90c8f26 --- /dev/null +++ b/src/app/state/datum.rs @@ -0,0 +1,109 @@ +use std::{fmt::Display, future::Future}; + +use dioxus::prelude::*; +use dioxus_signals::Signal; + +/// Represent loading/refreshing state of UI data +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] +pub enum Datum<T> { + #[default] + Loading, + Available { + value: T, + refreshing: bool, + }, +} + +impl<T> Datum<T> { + pub fn is_loading_or_refreshing(&self) -> bool { + matches!( + self, + Datum::Loading + | Datum::Available { + value: _, + refreshing: true + } + ) + } + + /// Get the inner value if available + pub fn current_value(&self) -> Option<&T> { + match self { + Datum::Loading => None, + Datum::Available { + value: x, + refreshing: _, + } => Some(x), + } + } + + /// Set the datum value + /// + /// Use [refresh_with] if the value is produced by a long-running task. + fn set_value(&mut self, value: T) { + tracing::debug!("🍒 Setting {} datum value", std::any::type_name::<T>()); + *self = Datum::Available { + value, + refreshing: false, + } + } + + /// Mark the datum is being-refreshed + /// + /// Do this just prior to doing a long-running task that will provide a + /// value to be set using [set_value] + fn mark_refreshing(&mut self) { + if let Datum::Available { + value: _, + refreshing, + } = self + { + if *refreshing { + panic!("Cannot refresh already refreshing data"); + } + tracing::debug!( + "🍒 Marking {} datum as refreshing", + std::any::type_name::<T>() + ); + *refreshing = true; + } + } + + /// Refresh the datum [Signal] using the given function + /// + /// Refresh state is automatically set. + pub async fn refresh_with<F>(signal: Signal<Self>, f: F) + where + F: Future<Output = T>, + { + signal.with_mut(move |x| { + x.mark_refreshing(); + }); + let val = f.await; + signal.with_mut(move |x| { + x.set_value(val); + }); + } +} + +impl<T, E: Display> Datum<Result<T, E>> { + /// Render the result datum with the given component + /// + /// The error message will be rendered appropriately. If the datum is + /// unavailable, nothing will be rendered (loading state is rendered + /// differently) + pub fn render_with<'a, F>(&self, cx: &'a Scoped<'a, ()>, component: F) -> Element<'a> + where + F: FnOnce(&T) -> Element<'a>, + { + match self.current_value()? { + Ok(value) => component(value), + Err(err) => render! { + div { + class: "p-4 my-1 text-left text-sm font-mono text-white bg-red-500 rounded", + "Error: {err}" + } + }, + } + } +} diff --git a/src/app/widget.rs b/src/app/widget.rs new file mode 100644 index 0000000..eb71a0c --- /dev/null +++ b/src/app/widget.rs @@ -0,0 +1,45 @@ +//! Various widgets + +use dioxus::prelude::*; + +/// A refresh button with a busy indicator +/// +/// You want to use [crate::state::datum] for this. +#[component] +pub fn RefreshButton<F>(cx: Scope, busy: bool, handler: F) -> Element +where + F: Fn(Event<MouseData>), +{ + let button_cls = if *busy { + "bg-gray-400 text-white" + } else { + "bg-blue-700 text-white hover:bg-blue-800" + }; + render! { + div { class: "flex-col items-center justify-center space-y-2 mb-4", + button { + class: "py-1 px-2 shadow-lg border-1 {button_cls} rounded-md", + disabled: *busy, + onclick: handler, + "Refresh " + if *busy { + render! { "âŗ" } + } else { + render! { "🔄" } + } + } + if *busy { + render! { Loader {} } + } + } + } +} + +#[component] +pub fn Loader(cx: Scope) -> Element { + render! { + div { class: "flex justify-center items-center", + div { class: "animate-spin rounded-full h-16 w-16 border-t-2 border-b-2 border-purple-500" } + } + } +} diff --git a/src/cli.rs b/src/cli.rs index cdc711f..239b0a4 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,31 +1,10 @@ //! Command-line interface use clap::Parser; -use std::net::SocketAddr; use crate::logging; #[derive(Parser, Debug)] pub struct Args { - /// Do not automatically open the application in the local browser - /// - /// Enabled by default if the app is running under `cargo leptos ...` - #[arg(short = 'n', long = "no-open", env = "NIX_BROWSER_NO_OPEN")] - pub no_open: bool, - - /// The address to serve the application on - /// - /// Format: `IP_ADDRESS:PORT` - /// - /// Uses localhost and random port by default. To use a different port, pass - /// `127.0.0.1:8080` - #[arg( - short = 's', - long = "site-addr", - default_value = "127.0.0.1:0", - env = "LEPTOS_SITE_ADDR" - )] - pub site_addr: Option<SocketAddr>, - #[command(flatten)] pub verbosity: logging::Verbosity, } diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index 03b330d..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,27 +0,0 @@ -#![feature(associated_type_defaults)] -//! nix-browser crate; see GitHub [README] for details. -//! -//! [README]: https://github.com/juspay/nix-browser -pub mod app; -pub mod logging; -pub mod widget; -#[cfg(feature = "hydrate")] -use wasm_bindgen::prelude::wasm_bindgen; -#[cfg(feature = "ssr")] -pub mod cli; -#[cfg(feature = "ssr")] -pub mod server; - -/// Main entry point for the WASM frontend -#[cfg(feature = "hydrate")] -#[wasm_bindgen] -pub fn hydrate() { - use crate::app::*; - use leptos::*; - - logging::setup_client_logging(); - tracing::info!("Hydrating app"); - leptos::mount_to_body(move |cx| { - view! { cx, <App/> } - }); -} diff --git a/src/logging.rs b/src/logging.rs index 96d08a5..783128b 100644 --- a/src/logging.rs +++ b/src/logging.rs @@ -1,52 +1,15 @@ //! Logging setup for the server and client -#[cfg(feature = "ssr")] -use tower_http::{ - classify::{ServerErrorsAsFailures, SharedClassifier}, - trace::TraceLayer, -}; -#[cfg(feature = "ssr")] use tracing_subscriber::filter::{Directive, LevelFilter}; -#[cfg(feature = "ssr")] use tracing_subscriber::EnvFilter; -/// Setup server-side logging using [tracing_subscriber] -#[cfg(feature = "ssr")] -pub fn setup_server_logging(verbosity: &Verbosity) { +pub fn setup_logging(verbosity: &Verbosity) { tracing_subscriber::fmt() .with_env_filter(verbosity.log_filter()) .compact() .init(); } -/// Setup browser console logging using [tracing_subscriber_wasm] -#[cfg(feature = "hydrate")] -pub fn setup_client_logging() { - tracing_subscriber::fmt() - .with_writer( - // To avoide trace events in the browser from showing their - // JS backtrace, which is very annoying, in my opinion - tracing_subscriber_wasm::MakeConsoleWriter::default() - .map_trace_level_to(tracing::Level::DEBUG), - ) - .with_max_level(tracing::Level::INFO) - // For some reason, if we don't do this in the browser, we get - // a runtime error. - .without_time() - .init(); -} - -/// Setup HTTP request logging -#[cfg(feature = "ssr")] -pub fn http_trace_layer() -> TraceLayer<SharedClassifier<ServerErrorsAsFailures>> { - use tower_http::trace; - use tracing::Level; - - TraceLayer::new_for_http() - .make_span_with(trace::DefaultMakeSpan::new().level(Level::INFO)) - .on_response(trace::DefaultOnResponse::new().level(Level::INFO)) -} - #[derive(clap::Args, Debug, Clone)] pub struct Verbosity { /// Server logging level @@ -56,7 +19,6 @@ pub struct Verbosity { pub verbose: u8, } -#[cfg(feature = "ssr")] impl Verbosity { /// Return the log filter for CLI flag. fn log_filter(&self) -> EnvFilter { @@ -74,25 +36,18 @@ impl Verbosity { LevelFilter::WARN.into(), "nix_browser=info".parse().unwrap(), "nix_rs=info".parse().unwrap(), - "leptos_extra=info".parse().unwrap(), ], // -v: log app DEBUG level, as well as http requests 1 => vec![ LevelFilter::WARN.into(), "nix_browser=debug".parse().unwrap(), "nix_rs=debug".parse().unwrap(), - "leptos_extra=debug".parse().unwrap(), - // 3rd-party libraries - "tower_http=info".parse().unwrap(), ], // -vv: log app TRACE level, as well as http requests 2 => vec![ LevelFilter::WARN.into(), "nix_browser=trace".parse().unwrap(), "nix_rs=trace".parse().unwrap(), - "leptos_extra=trace".parse().unwrap(), - // 3rd-party libraries - "tower_http=info".parse().unwrap(), ], // -vvv: log DEBUG level of app and libraries 3 => vec![LevelFilter::DEBUG.into()], diff --git a/src/main.rs b/src/main.rs index f46ae7b..e5d7169 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,23 @@ -#[cfg(feature = "ssr")] +use dioxus_desktop::{LogicalSize, WindowBuilder}; + +mod app; +mod cli; +mod logging; + #[tokio::main] async fn main() { use clap::Parser; - human_panic::setup_panic!(); - let args = nix_browser::cli::Args::parse(); - nix_browser::server::main(args).await -} + let args = crate::cli::Args::parse(); + crate::logging::setup_logging(&args.verbosity); -#[cfg(not(feature = "ssr"))] -fn main() { - // No main entry point for wasm + dioxus_desktop::launch_cfg( + app::App, + dioxus_desktop::Config::new() + .with_custom_head(r#" <link rel="stylesheet" href="tailwind.css"> "#.to_string()) + .with_window( + WindowBuilder::new() + .with_title("nix-browser") + .with_inner_size(LogicalSize::new(900, 600)), + ), + ) } diff --git a/src/server.rs b/src/server.rs deleted file mode 100644 index fbf2555..0000000 --- a/src/server.rs +++ /dev/null @@ -1,87 +0,0 @@ -//! Axum server -use std::convert::Infallible; - -use crate::app::App; -use axum::response::Response as AxumResponse; -use axum::routing::IntoMakeService; -use axum::{body::Body, http::Request, response::IntoResponse}; -use axum::{routing::post, Router}; -use hyper::server::conn::AddrIncoming; -use leptos::*; -use leptos_axum::{generate_route_list, LeptosRoutes}; -use std::net::SocketAddr; -use tower_http::services::ServeDir; -use tracing::instrument; - -use crate::cli; - -/// Axum server main entry point -pub async fn main(args: cli::Args) { - crate::logging::setup_server_logging(&args.verbosity); - let leptos_options = get_leptos_options(&args).await; - let server = create_server(leptos_options).await; - if !args.no_open { - open_http_app(server.local_addr()).await; - } - server.await.unwrap() -} - -/// Create an Axum server for the Leptos app -#[instrument(name = "server")] -#[allow(clippy::async_yields_async)] -async fn create_server( - leptos_options: leptos_config::LeptosOptions, -) -> axum::Server<AddrIncoming, IntoMakeService<axum::Router>> { - tracing::debug!("Firing up Leptos app with config: {:?}", leptos_options); - leptos_query::suppress_query_load(true); // https://github.com/nicoburniske/leptos_query/issues/6 - let routes = generate_route_list(|cx| view! { cx, <App/> }).await; - leptos_query::suppress_query_load(false); - let client_dist = ServeDir::new(leptos_options.site_root.clone()); - let leptos_options_clone = leptos_options.clone(); // A copy to move to the closure below. - let not_found_service = - tower::service_fn(move |req| not_found_handler(leptos_options_clone.to_owned(), req)); - let app = Router::new() - // server functions API routes - .route("/api/*fn_name", post(leptos_axum::handle_server_fns)) - // application routes - .leptos_routes(&leptos_options, routes, |cx| view! { cx, <App/> }) - // static files are served as fallback (but *before* falling back to - // error handler) - .fallback_service(client_dist.clone().not_found_service(not_found_service)) - // enable HTTP request logging - .layer(crate::logging::http_trace_layer()) - .with_state(leptos_options.clone()); - - let server = axum::Server::bind(&leptos_options.site_addr).serve(app.into_make_service()); - tracing::info!("nix-browser web 🌀ī¸ http://{}", server.local_addr()); - server -} - -async fn get_leptos_options(args: &cli::Args) -> leptos_config::LeptosOptions { - let conf_file = get_configuration(None).await.unwrap(); - leptos_config::LeptosOptions { - site_addr: args.site_addr.unwrap_or(conf_file.leptos_options.site_addr), - ..conf_file.leptos_options - } -} - -/// Handler for missing routes -/// -/// On missing routes, just delegate to the leptos app, which has a route -/// fallback rendering 404 response. -async fn not_found_handler( - options: LeptosOptions, - req: Request<Body>, -) -> Result<AxumResponse, Infallible> { - let handler = - leptos_axum::render_app_to_stream(options.to_owned(), move |cx| view! { cx, <App/> }); - Ok(handler(req).await.into_response()) -} - -/// Open a http address in the user's web browser -async fn open_http_app(addr: SocketAddr) { - let url = format!("http://{}", &addr); - if let Err(err) = open::that(url) { - tracing::warn!("Unable to open in web browser: {}", err) - } -} diff --git a/src/widget.rs b/src/widget.rs deleted file mode 100644 index 852a57d..0000000 --- a/src/widget.rs +++ /dev/null @@ -1,176 +0,0 @@ -//! Various Leptos widgets - -use std::{fmt::Display, hash::Hash, str::FromStr}; - -use cfg_if::cfg_if; -#[cfg(feature = "ssr")] -use http::status::StatusCode; -use leptos::*; -#[cfg(feature = "ssr")] -use leptos_axum::ResponseOptions; -use leptos_router::*; - -// A loading spinner -#[component] -pub fn Spinner(cx: Scope) -> impl IntoView { - view! { cx, - <div - class="animate-spin inline-block w-6 h-6 border-[3px] border-current border-t-transparent text-blue-600 rounded-full" - role="status" - aria-label="loading" - > - <span class="sr-only">"Loading..."</span> - </div> - } -} - -/// A `<a>` link -#[component] -pub fn Link(cx: Scope, link: &'static str, text: &'static str) -> impl IntoView { - view! { cx, - <A href=link class="text-primary-100 hover:no-underline"> - {text} - </A> - } -} - -/// A `<a>` link that links to an external site -#[component] -pub fn LinkExternal(cx: Scope, link: &'static str, text: &'static str) -> impl IntoView { - view! { cx, - <a - href=link - class="underline text-primary-500 hover:no-underline" - rel="external" - target="_blank" - > - {text} - </a> - } -} - -/// 404 page -#[component] -pub fn NotFound(cx: Scope) -> impl IntoView { - cfg_if! { if #[cfg(feature="ssr")] { - if let Some(response) = use_context::<ResponseOptions>(cx) { - response.set_status(StatusCode::NOT_FOUND); - } - }} - view! { cx, - // The HTML for 404 not found - <div class="grid w-full min-h-screen bg-center bg-cover bg-base-100 place-items-center"> - <div class="z-0 flex items-center justify-center col-start-1 row-start-1 text-center"> - <div class="flex flex-col space-y-3"> - <h1 class="text-5xl font-bold">"404"</h1> - <p class="py-6"> - <h2 class="text-3xl font-bold text-gray-500">"Page not found"</h2> - <p class="my-1">"The page you are looking for does not exist."</p> - </p> - <Link link="/" text="Go to home page"/> - </div> - </div> - </div> - } -} - -/// Display errors to the user -#[component] -pub fn Errors(cx: Scope, errors: Errors) -> impl IntoView { - tracing::error!("Errors: {:?}", errors); - view! { cx, - <div class="flex flex-col justify-center overflow-auto"> - <header class="p-2 text-xl font-bold text-white bg-error-500">"đŸ’Ŗ ERROR đŸ’Ŗ"</header> - <div class="p-2 font-mono text-sm text-left whitespace-pre-wrap bg-black"> - <ul> - {errors - .into_iter() - .map(|(k, e)| { - view! { cx, - <li class="mb-4"> - <header class="px-2 mb-2 font-bold text-gray-100"> - {format!("{:?}", k)} - </header> - <div class="px-2 text-gray-400 hover:text-gray-100"> - {e.to_string()} - </div> - </li> - } - }) - .collect_view(cx)} - </ul> - </div> - </div> - } -} - -/// Like [Suspense] but also handles errors using [ErrorBoundary] -#[component(transparent)] -pub fn SuspenseWithErrorHandling(cx: Scope, children: ChildrenFn) -> impl IntoView { - let children = store_value(cx, children); - view! { cx, - <Suspense fallback=move || view! { cx, <Spinner/> }> - <ErrorBoundary fallback=|cx, errors| { - view! { cx, <Errors errors=errors.get()/> } - }>{children.with_value(|c| c(cx))}</ErrorBoundary> - </Suspense> - } -} - -/// An input element component with suggestions. -/// -/// A label, input element, and datalist are rendered, as well as error div. -/// [FromStr::from_str] is used to parse the input value into `K`. -/// -/// Arguments: -/// * `id`: The id of the input element -/// * `label`: The label string -/// * `suggestions`: The initial suggestions to show in the datalist -/// * `val`: The [RwSignal] mirror'ing the input element value -#[component] -pub fn TextInput<K>( - cx: Scope, - id: &'static str, - label: &'static str, - /// Initial suggestions to show in the datalist - suggestions: Vec<K>, - val: RwSignal<K>, -) -> impl IntoView -where - K: ToString + FromStr + Hash + Eq + Clone + Display + 'static, - <K as std::str::FromStr>::Err: Display, -{ - let datalist_id = &format!("{}-datalist", id); - // Input query to the server fn - // Errors in input element (based on [FromStr::from_str]) - let (input_err, set_input_err) = create_signal(cx, None::<String>); - view! { cx, - <label for=id>{label}</label> - <input - list=datalist_id - id=id.to_string() - type="text" - class="w-full p-1 font-mono" - on:change=move |ev| { - match FromStr::from_str(&event_target_value(&ev)) { - Ok(s) => { - val.set(s); - set_input_err(None) - } - Err(e) => set_input_err(Some(e.to_string())), - } - } - - prop:value=move || val.get().to_string() - /> - <span class="text-red-500">{input_err}</span> - // TODO: use local storage, and cache user's inputs - <datalist id=datalist_id> - {suggestions - .iter() - .map(|s| view! { cx, <option value=s.to_string()></option> }) - .collect_view(cx)} - - </datalist> - } -} diff --git a/tailwind.config.js b/tailwind.config.js index c64d01f..85a93f5 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -4,7 +4,7 @@ const defaultTheme = require('tailwindcss/defaultTheme') module.exports = { content: [ "./src/**/*.rs", - "./crates/leptos_extra/**/*.rs" + "./dist/**/*.html" ], theme: { fontFamily: {