diff --git a/Cargo.lock b/Cargo.lock index 5d958b1..1816c2e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,6 +27,17 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "ahash" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +dependencies = [ + "getrandom 0.2.10", + "once_cell", + "version_check 0.9.4", +] + [[package]] name = "aho-corasick" version = "1.0.5" @@ -79,6 +90,12 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +[[package]] +name = "anymap" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33954243bd79057c2de7338850b85983a44588021f8a5fee574a8888c6de4344" + [[package]] name = "ascii" version = "0.9.3" @@ -133,7 +150,7 @@ checksum = "c7f329c7eb9b646a72f70c9c4b516c70867d356ec46cb00dcac8ad343fd006b0" dependencies = [ "Inflector", "async-graphql-parser", - "darling", + "darling 0.20.3", "proc-macro-crate", "proc-macro2 1.0.66", "quote 1.0.33", @@ -218,6 +235,31 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" +[[package]] +name = "atomic_hooks" +version = "0.1.6" +source = "git+https://github.com/seed-rs/styles_hooks?branch=main#056367c663230defe991b36b35a92e4663b7a2f0" +dependencies = [ + "anymap", + "atomic_hooks_macros", + "illicit", + "slotmap", + "topo", + "typemap", +] + +[[package]] +name = "atomic_hooks_macros" +version = "0.1.6" +source = "git+https://github.com/seed-rs/styles_hooks?branch=main#056367c663230defe991b36b35a92e4663b7a2f0" +dependencies = [ + "darling 0.10.2", + "illicit", + "proc-macro2 1.0.66", + "quote 1.0.33", + "syn 1.0.109", +] + [[package]] name = "attohttpc" version = "0.26.1" @@ -584,14 +626,38 @@ dependencies = [ "syn 2.0.29", ] +[[package]] +name = "darling" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +dependencies = [ + "darling_core 0.10.2", + "darling_macro 0.10.2", +] + [[package]] name = "darling" version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ - "darling_core", - "darling_macro", + "darling_core 0.20.3", + "darling_macro 0.20.3", +] + +[[package]] +name = "darling_core" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2 1.0.66", + "quote 1.0.33", + "strsim 0.9.3", + "syn 1.0.109", ] [[package]] @@ -604,17 +670,28 @@ dependencies = [ "ident_case", "proc-macro2 1.0.66", "quote 1.0.33", - "strsim", + "strsim 0.10.0", "syn 2.0.29", ] +[[package]] +name = "darling_macro" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +dependencies = [ + "darling_core 0.10.2", + "quote 1.0.33", + "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", + "darling_core 0.20.3", "quote 1.0.33", "syn 2.0.29", ] @@ -734,6 +811,12 @@ dependencies = [ "crypto-common", ] +[[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" @@ -749,6 +832,20 @@ dependencies = [ "dtoa", ] +[[package]] +name = "dyn-cache" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "515b3a396334e2b513a534f07cc4452709e6014ec00f1b28aa35e7acaddda6a9" +dependencies = [ + "downcast-rs", + "hash_hasher", + "hashbrown 0.11.2", + "illicit", + "parking_lot 0.11.2", + "paste", +] + [[package]] name = "either" version = "1.9.0" @@ -1233,6 +1330,21 @@ dependencies = [ "thiserror", ] +[[package]] +name = "hash_hasher" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74721d007512d0cb3338cd20f0654ac913920061a4c4d0d8708edb3f2a698c0c" + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1427,6 +1539,28 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "472c8093cbd4f6e9e42238219c630735871563d23b2a830f5eaa5424a0f298ce" +[[package]] +name = "illicit" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8b336d323555c6ca57e96f90df894ce3f621a25c3862a9d2d8e67caa31710d3" +dependencies = [ + "illicit-macro", + "owning_ref", + "scopeguard", +] + +[[package]] +name = "illicit-macro" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e735fac4fa42c34ce6d7fb2f5a729bf1e5db239f3b09aa7bf36f2068147d7d96" +dependencies = [ + "proc-macro-error", + "quote 1.0.33", + "syn 1.0.109", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -1481,6 +1615,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", ] [[package]] @@ -1585,7 +1722,8 @@ dependencies = [ "itertools", "log 0.4.20", "notmuch", - "seed", + "seed 0.9.2", + "seed_hooks", "serde", "serde_json", "shared", @@ -1946,6 +2084,15 @@ version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "owning_ref" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ff55baddef9e4ad00f88b6c743a2a8062d4c6ade126c2a528644b8e444d52ce" +dependencies = [ + "stable_deref_trait", +] + [[package]] name = "parking_lot" version = "0.11.2" @@ -1994,6 +2141,12 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + [[package]] name = "pear" version = "0.1.5" @@ -2254,6 +2407,30 @@ dependencies = [ "toml_edit", ] +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2 1.0.66", + "quote 1.0.33", + "syn 1.0.109", + "version_check 0.9.4", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2 1.0.66", + "quote 1.0.33", + "version_check 0.9.4", +] + [[package]] name = "proc-macro-hack" version = "0.5.20+deprecated" @@ -2811,6 +2988,41 @@ dependencies = [ "web-sys", ] +[[package]] +name = "seed" +version = "0.10.0" +source = "git+https://github.com/seed-rs/seed.git?branch=master#f0fdb7005816f367a066c68e0dd4475adfd545e1" +dependencies = [ + "enclose", + "futures", + "getrandom 0.2.10", + "gloo-file", + "gloo-timers", + "gloo-utils", + "indexmap 1.9.3", + "js-sys", + "rand 0.8.5", + "uuid", + "version_check 0.9.4", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "seed_hooks" +version = "0.1.5" +source = "git+https://github.com/seed-rs/styles_hooks?branch=main#056367c663230defe991b36b35a92e4663b7a2f0" +dependencies = [ + "atomic_hooks", + "derive_more", + "gloo-timers", + "lazy_static", + "seed 0.10.0", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "selectors" version = "0.22.0" @@ -2975,6 +3187,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "slotmap" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" +dependencies = [ + "version_check 0.9.4", +] + [[package]] name = "smallvec" version = "1.11.0" @@ -3075,6 +3296,12 @@ dependencies = [ "quote 1.0.33", ] +[[package]] +name = "strsim" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" + [[package]] name = "strsim" version = "0.10.0" @@ -3356,6 +3583,29 @@ dependencies = [ "winnow", ] +[[package]] +name = "topo" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3b2366045f6c12eef44a8396a272b2064a8a8ac996c415add2fce4304f355f9" +dependencies = [ + "dyn-cache", + "illicit", + "once_cell", + "parking_lot 0.11.2", + "topo-macro", +] + +[[package]] +name = "topo-macro" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b420cb55838be8020a93bdb628c171339fc945c0be4eb8cd1432186a9030b8f2" +dependencies = [ + "quote 1.0.33", + "syn 1.0.109", +] + [[package]] name = "tower-service" version = "0.3.2" @@ -3442,6 +3692,15 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" +[[package]] +name = "typemap" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "653be63c80a3296da5551e1bfd2cca35227e13cdd08c6668903ae2f4f77aa1f6" +dependencies = [ + "unsafe-any", +] + [[package]] name = "typenum" version = "1.17.0" @@ -3543,6 +3802,15 @@ dependencies = [ "void", ] +[[package]] +name = "unsafe-any" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30360d7979f5e9c6e6cea48af192ea8fab4afb3cf72597154b8f08935bc9c7f" +dependencies = [ + "traitobject", +] + [[package]] name = "untrusted" version = "0.7.1" diff --git a/web/Cargo.toml b/web/Cargo.toml index 2d69c03..68766bf 100644 --- a/web/Cargo.toml +++ b/web/Cargo.toml @@ -30,6 +30,8 @@ css-inline = "0.8.5" chrono = "0.4.31" graphql_client = "0.13.0" thiserror = "1.0.50" +seed_hooks = { git = "https://github.com/seed-rs/styles_hooks", package = "seed_hooks", branch = "main" } + [package.metadata.wasm-pack.profile.release] wasm-opt = ['-Os'] diff --git a/web/src/lib.rs b/web/src/lib.rs index ac40128..4c329f8 100644 --- a/web/src/lib.rs +++ b/web/src/lib.rs @@ -13,6 +13,7 @@ use itertools::Itertools; use log::{debug, error, info, Level}; use notmuch::{Content, Part, Thread, ThreadNode, ThreadSet}; use seed::{prelude::*, *}; +use seed_hooks::{state_access::CloneState, topo, use_state, StateAccessEventHandlers}; use serde::de::Deserialize; use thiserror::Error; use wasm_timer::Instant; @@ -1201,6 +1202,7 @@ fn view_footer(render_time_ms: u128) -> Node { ] } +#[topo::nested] fn view_desktop(model: &Model) -> Node { // Do two queries, one without `unread` so it loads fast, then a second with unread. let content = match &model.context { @@ -1255,8 +1257,8 @@ fn view_desktop(model: &Model) -> Node { n, &Tag { name: parts[..i + 1].join("/"), - bg_color: "#000".to_string(), - fg_color: "#fff".to_string(), + bg_color: "#fff".to_string(), + fg_color: "#000".to_string(), unread: 0, }, )); @@ -1278,16 +1280,31 @@ fn view_desktop(model: &Model) -> Node { .tags .as_ref() .map(|tags| tags.iter().filter(|t| t.unread == 0)); + let tags_open = use_state(|| false); div![ C!["desktop-main-content"], aside![ C!["tags-menu", "menu"], IF!(unread.is_some() => p![C!["menu-label"], "Unread"]), IF!(unread.is_some() => ul![C!["menu-list"], unread.map(view_tag_list)]), - p![C!["menu-label"], "Tags"], + p![ + C!["menu-label"], + i![C![ + "fa-solid", + if tags_open.get() { + "fa-angle-up" + } else { + "fa-angle-down" + } + ]], + " Tags", + ev(Ev::Click, move |_| { + tags_open.set(!tags_open.get()); + }) + ], ul![ C!["menu-list"], - model.tags.as_ref().map(|tags| view_tag_list(tags.iter())) + IF!(tags_open.get() => model.tags.as_ref().map(|tags| view_tag_list(tags.iter()))), ] ], div![