From ec7d916edd7076ebbb85ee0160e5c2631109199f Mon Sep 17 00:00:00 2001 From: Orual Date: Sat, 22 Nov 2025 17:56:56 -0500 Subject: [PATCH] client-side works fully again --- Cargo.lock | 779 +++++++++++++++--- Cargo.toml | 3 - crates/weaver-app/Cargo.toml | 3 +- crates/weaver-app/Dioxus.toml | 3 + .../style.css => assets/styling/button.css} | 0 crates/weaver-app/assets/styling/navbar.css | 1 + crates/weaver-app/assets/styling/profile.css | 2 +- crates/weaver-app/{assets => public}/sw.js | 0 crates/weaver-app/src/auth/mod.rs | 13 +- .../accordion/{style.css => accordion.css} | 0 .../src/components/accordion/component.rs | 2 +- .../avatar/{style.css => avatar.css} | 0 .../src/components/avatar/component.rs | 2 +- .../src/components/button/component.rs | 2 +- .../src/components/dialog/component.rs | 2 +- .../dialog/{style.css => dialog.css} | 0 crates/weaver-app/src/components/entry.rs | 149 ++-- crates/weaver-app/src/components/identity.rs | 69 +- .../src/components/input/component.rs | 2 +- .../input/{style.css => input-style.css} | 0 .../src/components/notebook_cover.rs | 5 +- crates/weaver-app/src/components/profile.rs | 9 +- crates/weaver-app/src/data.rs | 302 +++++-- crates/weaver-app/src/env.rs | 6 +- crates/weaver-app/src/main.rs | 66 +- crates/weaver-app/src/service_worker.rs | 23 +- crates/weaver-app/src/views/home.rs | 7 +- crates/weaver-app/src/views/navbar.rs | 97 +-- crates/weaver-app/src/views/notebook.rs | 18 +- crates/weaver-common/src/agent.rs | 253 +++--- crates/weaver-renderer/src/atproto/client.rs | 1 - 31 files changed, 1262 insertions(+), 557 deletions(-) rename crates/weaver-app/{src/components/button/style.css => assets/styling/button.css} (100%) rename crates/weaver-app/{assets => public}/sw.js (100%) rename crates/weaver-app/src/components/accordion/{style.css => accordion.css} (100%) rename crates/weaver-app/src/components/avatar/{style.css => avatar.css} (100%) rename crates/weaver-app/src/components/dialog/{style.css => dialog.css} (100%) rename crates/weaver-app/src/components/input/{style.css => input-style.css} (100%) diff --git a/Cargo.lock b/Cargo.lock index f1150ec..025212c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1042,16 +1042,37 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const-serialize" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08259976d62c715c4826cb4a3d64a3a9e5c5f68f964ff6087319857f569f93a6" +dependencies = [ + "const-serialize-macro 0.6.2", + "serde", +] + [[package]] name = "const-serialize" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd339aa356cc6452308fad2ee56623f900a8e68bc0ab9360a0ddb8270e5640c8" dependencies = [ - "const-serialize-macro", + "const-serialize-macro 0.7.1", "serde", ] +[[package]] +name = "const-serialize-macro" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04382d0d9df7434af6b1b49ea1a026ef39df1b0738b1cc373368cf175354f6eb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.110", +] + [[package]] name = "const-serialize-macro" version = "0.7.1" @@ -1110,6 +1131,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "convert_case" version = "0.8.0" @@ -1401,6 +1431,19 @@ dependencies = [ "syn 2.0.110", ] +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "dashmap" version = "6.1.0" @@ -1625,6 +1668,29 @@ dependencies = [ "subtle", ] +[[package]] +name = "dioxus" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a247114500f1a78e87022defa8173de847accfada8e8809dfae23a118a580c" +dependencies = [ + "dioxus-cli-config 0.6.3", + "dioxus-config-macro 0.6.2", + "dioxus-core 0.6.3", + "dioxus-core-macro 0.6.3", + "dioxus-devtools 0.6.2", + "dioxus-document 0.6.3", + "dioxus-fullstack 0.6.3", + "dioxus-history 0.6.2", + "dioxus-hooks 0.6.2", + "dioxus-html 0.6.3", + "dioxus-logger 0.6.2", + "dioxus-signals 0.6.3", + "dioxus-web 0.6.3", + "manganis 0.6.2", + "warnings", +] + [[package]] name = "dioxus" version = "0.7.1" @@ -1632,28 +1698,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f76e820919058a685a1fdbb2ef4888c73ac77d623c39a7dfde2aa812947246be" dependencies = [ "dioxus-asset-resolver", - "dioxus-cli-config", - "dioxus-config-macro", + "dioxus-cli-config 0.7.1", + "dioxus-config-macro 0.7.1", "dioxus-config-macros", - "dioxus-core", - "dioxus-core-macro", + "dioxus-core 0.7.1", + "dioxus-core-macro 0.7.1", "dioxus-desktop", - "dioxus-devtools", - "dioxus-document", - "dioxus-fullstack", + "dioxus-devtools 0.7.1", + "dioxus-document 0.7.1", + "dioxus-fullstack 0.7.1", "dioxus-fullstack-macro", - "dioxus-history", - "dioxus-hooks", - "dioxus-html", + "dioxus-history 0.7.1", + "dioxus-hooks 0.7.1", + "dioxus-html 0.7.1", "dioxus-liveview", - "dioxus-logger", + "dioxus-logger 0.7.1", "dioxus-router", "dioxus-server", - "dioxus-signals", + "dioxus-signals 0.7.1", "dioxus-ssr", "dioxus-stores", - "dioxus-web", - "manganis", + "dioxus-web 0.7.1", + "manganis 0.7.1", "serde", "subsecond", "warnings", @@ -1666,7 +1732,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f6a124667ce5565c39fe2f33af45c21fe459c5bfcf7a8074ad12c9e9da5817c" dependencies = [ - "dioxus-cli-config", + "dioxus-cli-config 0.7.1", "http", "infer", "jni", @@ -1681,6 +1747,15 @@ dependencies = [ "web-sys", ] +[[package]] +name = "dioxus-cli-config" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdd16948f1ffdb068dd9a64812158073a4250e2af4e98ea31fdac0312e6bce86" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "dioxus-cli-config" version = "0.7.1" @@ -1690,6 +1765,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "dioxus-config-macro" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75cbf582fbb1c32d34a1042ea675469065574109c95154468710a4d73ee98b49" +dependencies = [ + "proc-macro2", + "quote", +] + [[package]] name = "dioxus-config-macro" version = "0.7.1" @@ -1706,6 +1791,27 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0a16b25f8761253ed5ffa4d0789376310fbbc1bbaa8190fc2f374db82c6285a1" +[[package]] +name = "dioxus-core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c03f451a119e47433c16e2d8eb5b15bf7d6e6734eb1a4c47574e6711dadff8d" +dependencies = [ + "const_format", + "dioxus-core-types 0.6.2", + "futures-channel", + "futures-util", + "generational-box 0.6.2", + "longest-increasing-subsequence", + "rustc-hash 1.1.0", + "rustversion", + "serde", + "slab", + "slotmap", + "tracing", + "warnings", +] + [[package]] name = "dioxus-core" version = "0.7.1" @@ -1714,10 +1820,10 @@ checksum = "75468d08468919f783b0f7ee826802f4e8e66c5b5a0451245d861c211ca18216" dependencies = [ "anyhow", "const_format", - "dioxus-core-types", + "dioxus-core-types 0.7.1", "futures-channel", "futures-util", - "generational-box", + "generational-box 0.7.1", "longest-increasing-subsequence", "rustc-hash 2.1.1", "rustversion", @@ -1729,6 +1835,19 @@ dependencies = [ "warnings", ] +[[package]] +name = "dioxus-core-macro" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "105c954caaaedf8cd10f3d1ba576b01e18aa8d33ad435182125eefe488cf0064" +dependencies = [ + "convert_case 0.6.0", + "dioxus-rsx 0.6.2", + "proc-macro2", + "quote", + "syn 2.0.110", +] + [[package]] name = "dioxus-core-macro" version = "0.7.1" @@ -1736,12 +1855,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f145abdb2a3f858456cb4382390863cf0398c228ad0733618f48891da7687be3" dependencies = [ "convert_case 0.8.0", - "dioxus-rsx", + "dioxus-rsx 0.7.1", "proc-macro2", "quote", "syn 2.0.110", ] +[[package]] +name = "dioxus-core-types" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91a82fccfa48574eb7aa183e297769540904694844598433a9eb55896ad9f93b" +dependencies = [ + "once_cell", +] + [[package]] name = "dioxus-core-types" version = "0.7.1" @@ -1760,19 +1888,19 @@ dependencies = [ "cocoa", "core-foundation 0.10.1", "dioxus-asset-resolver", - "dioxus-cli-config", - "dioxus-core", - "dioxus-devtools", - "dioxus-document", - "dioxus-history", - "dioxus-hooks", - "dioxus-html", - "dioxus-interpreter-js", - "dioxus-signals", + "dioxus-cli-config 0.7.1", + "dioxus-core 0.7.1", + "dioxus-devtools 0.7.1", + "dioxus-document 0.7.1", + "dioxus-history 0.7.1", + "dioxus-hooks 0.7.1", + "dioxus-html 0.7.1", + "dioxus-interpreter-js 0.7.1", + "dioxus-signals 0.7.1", "dunce", "futures-channel", "futures-util", - "generational-box", + "generational-box 0.7.1", "global-hotkey", "infer", "jni", @@ -1803,16 +1931,32 @@ dependencies = [ "wry", ] +[[package]] +name = "dioxus-devtools" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712a7300f1e8181218187b03502044157eef04e0a25b518117c5ef9ae1096880" +dependencies = [ + "dioxus-core 0.6.3", + "dioxus-devtools-types 0.6.2", + "dioxus-signals 0.6.3", + "serde", + "serde_json", + "tracing", + "tungstenite 0.23.0", + "warnings", +] + [[package]] name = "dioxus-devtools" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4eb2c5019b7fa72e8e6b21ba99e9263bd390c9a30bbf09793b72f4b57ed7c3d7" dependencies = [ - "dioxus-cli-config", - "dioxus-core", - "dioxus-devtools-types", - "dioxus-signals", + "dioxus-cli-config 0.7.1", + "dioxus-core 0.7.1", + "dioxus-devtools-types 0.7.1", + "dioxus-signals 0.7.1", "futures-channel", "futures-util", "serde", @@ -1824,36 +1968,97 @@ dependencies = [ "warnings", ] +[[package]] +name = "dioxus-devtools-types" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f62434973c0c9c5a3bc42e9cd5e7070401c2062a437fb5528f318c3e42ebf4ff" +dependencies = [ + "dioxus-core 0.6.3", + "serde", +] + [[package]] name = "dioxus-devtools-types" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b007cec5b8548281921c4e4678926a3936e9d6757e951380685cc6121a6f974" dependencies = [ - "dioxus-core", + "dioxus-core 0.7.1", "serde", "subsecond-types", ] +[[package]] +name = "dioxus-document" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "802a2014d1662b6615eec0a275745822ee4fc66aacd9d0f2fb33d6c8da79b8f2" +dependencies = [ + "dioxus-core 0.6.3", + "dioxus-core-macro 0.6.3", + "dioxus-core-types 0.6.2", + "dioxus-html 0.6.3", + "futures-channel", + "futures-util", + "generational-box 0.6.2", + "lazy-js-bundle 0.6.2", + "serde", + "serde_json", + "tracing", +] + [[package]] name = "dioxus-document" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c55bcae9aaf150d4a141c61b3826da5a7ac23dfff09726568525cd46336e9a2" dependencies = [ - "dioxus-core", - "dioxus-core-macro", - "dioxus-core-types", - "dioxus-html", + "dioxus-core 0.7.1", + "dioxus-core-macro 0.7.1", + "dioxus-core-types 0.7.1", + "dioxus-html 0.7.1", "futures-channel", "futures-util", - "generational-box", + "generational-box 0.7.1", "lazy-js-bundle 0.7.1", "serde", "serde_json", "tracing", ] +[[package]] +name = "dioxus-free-icons" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd226c24168bb63d12d69cc0e7a6d73faa970574445c8e79c29965892f1a2ad8" +dependencies = [ + "dioxus 0.6.3", +] + +[[package]] +name = "dioxus-fullstack" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe99b48a1348eec385b5c4bd3e80fd863b0d3b47257d34e2ddc58754dec5d128" +dependencies = [ + "base64 0.22.1", + "bytes", + "ciborium", + "dioxus-devtools 0.6.2", + "dioxus-history 0.6.2", + "dioxus-lib", + "dioxus-web 0.6.3", + "dioxus_server_macro", + "futures-channel", + "futures-util", + "generational-box 0.6.2", + "once_cell", + "serde", + "server_fn", + "tracing", +] + [[package]] name = "dioxus-fullstack" version = "0.7.1" @@ -1874,13 +2079,13 @@ dependencies = [ "content_disposition", "derive_more 2.0.1", "dioxus-asset-resolver", - "dioxus-cli-config", - "dioxus-core", + "dioxus-cli-config 0.7.1", + "dioxus-core 0.7.1", "dioxus-fullstack-core", "dioxus-fullstack-macro", - "dioxus-hooks", - "dioxus-html", - "dioxus-signals", + "dioxus-hooks 0.7.1", + "dioxus-html 0.7.1", + "dioxus-signals 0.7.1", "form_urlencoded", "futures", "futures-channel", @@ -1899,7 +2104,7 @@ dependencies = [ "send_wrapper", "serde", "serde_json", - "serde_qs", + "serde_qs 0.15.0", "serde_urlencoded", "thiserror 2.0.17", "tokio", @@ -1929,14 +2134,14 @@ dependencies = [ "axum-core", "base64 0.22.1", "ciborium", - "dioxus-core", - "dioxus-document", - "dioxus-history", - "dioxus-hooks", - "dioxus-signals", + "dioxus-core 0.7.1", + "dioxus-document 0.7.1", + "dioxus-history 0.7.1", + "dioxus-hooks 0.7.1", + "dioxus-signals 0.7.1", "futures-channel", "futures-util", - "generational-box", + "generational-box 0.7.1", "http", "inventory", "parking_lot", @@ -1961,33 +2166,82 @@ dependencies = [ "xxhash-rust", ] +[[package]] +name = "dioxus-history" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ae4e22616c698f35b60727313134955d885de2d32e83689258e586ebc9b7909" +dependencies = [ + "dioxus-core 0.6.3", + "tracing", +] + [[package]] name = "dioxus-history" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dac73657da5c7a20629482d774b52f4a4f7cb57a520649f1d855d4073e809c98" dependencies = [ - "dioxus-core", + "dioxus-core 0.7.1", "tracing", ] +[[package]] +name = "dioxus-hooks" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "948e2b3f20d9d4b2c300aaa60281b1755f3298684448920b27106da5841896d0" +dependencies = [ + "dioxus-core 0.6.3", + "dioxus-signals 0.6.3", + "futures-channel", + "futures-util", + "generational-box 0.6.2", + "rustversion", + "slab", + "tracing", + "warnings", +] + [[package]] name = "dioxus-hooks" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffd445f16d64939e06cd71a1c63a665f383fda6b7882f4c6f8f1bd6efca2046" dependencies = [ - "dioxus-core", - "dioxus-signals", + "dioxus-core 0.7.1", + "dioxus-signals 0.7.1", "futures-channel", "futures-util", - "generational-box", + "generational-box 0.7.1", "rustversion", "slab", "tracing", "warnings", ] +[[package]] +name = "dioxus-html" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59c9a40e6fee20ce7990095492dedb6a753eebe05e67d28271a249de74dc796d" +dependencies = [ + "async-trait", + "dioxus-core 0.6.3", + "dioxus-core-macro 0.6.3", + "dioxus-core-types 0.6.2", + "dioxus-hooks 0.6.2", + "dioxus-html-internal-macro 0.6.2", + "enumset", + "euclid", + "futures-channel", + "generational-box 0.6.2", + "keyboard-types", + "lazy-js-bundle 0.6.2", + "rustversion", + "tracing", +] + [[package]] name = "dioxus-html" version = "0.7.1" @@ -1996,16 +2250,16 @@ checksum = "9f407fc73a9554a644872fcccc9faf762acad8f45158e3d67e42ab8dd42f4586" dependencies = [ "async-trait", "bytes", - "dioxus-core", - "dioxus-core-macro", - "dioxus-core-types", - "dioxus-hooks", - "dioxus-html-internal-macro", + "dioxus-core 0.7.1", + "dioxus-core-macro 0.7.1", + "dioxus-core-types 0.7.1", + "dioxus-hooks 0.7.1", + "dioxus-html-internal-macro 0.7.1", "enumset", "euclid", "futures-channel", "futures-util", - "generational-box", + "generational-box 0.7.1", "keyboard-types", "lazy-js-bundle 0.7.1", "rustversion", @@ -2015,6 +2269,18 @@ dependencies = [ "tracing", ] +[[package]] +name = "dioxus-html-internal-macro" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43ba87b53688a2c9f619ecdf4b3b955bc1f08bd0570a80a0d626c405f6d14a76" +dependencies = [ + "convert_case 0.6.0", + "proc-macro2", + "quote", + "syn 2.0.110", +] + [[package]] name = "dioxus-html-internal-macro" version = "0.7.1" @@ -2027,15 +2293,31 @@ dependencies = [ "syn 2.0.110", ] +[[package]] +name = "dioxus-interpreter-js" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330707b10ca75cb0eb05f9e5f8d80217cd0d7e62116a8277ae363c1a09b57a22" +dependencies = [ + "js-sys", + "lazy-js-bundle 0.6.2", + "rustc-hash 1.1.0", + "sledgehammer_bindgen", + "sledgehammer_utils", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "dioxus-interpreter-js" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83ab170d89308399205f8ad3d43d8d419affe317016b41ca0695186f7593cba2" dependencies = [ - "dioxus-core", - "dioxus-core-types", - "dioxus-html", + "dioxus-core 0.7.1", + "dioxus-core-types 0.7.1", + "dioxus-html 0.7.1", "js-sys", "lazy-js-bundle 0.7.1", "rustc-hash 2.1.1", @@ -2047,6 +2329,24 @@ dependencies = [ "web-sys", ] +[[package]] +name = "dioxus-lib" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5405b71aa9b8b0c3e0d22728f12f34217ca5277792bd315878cc6ecab7301b72" +dependencies = [ + "dioxus-config-macro 0.6.2", + "dioxus-core 0.6.3", + "dioxus-core-macro 0.6.3", + "dioxus-document 0.6.3", + "dioxus-history 0.6.2", + "dioxus-hooks 0.6.2", + "dioxus-html 0.6.3", + "dioxus-rsx 0.6.2", + "dioxus-signals 0.6.3", + "warnings", +] + [[package]] name = "dioxus-liveview" version = "0.7.1" @@ -2054,16 +2354,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca4f2850ec1a468c6f15b578c43218562d2309aadaf2b8bf17f54ce30e72f594" dependencies = [ "axum", - "dioxus-cli-config", - "dioxus-core", - "dioxus-devtools", - "dioxus-document", - "dioxus-history", - "dioxus-html", - "dioxus-interpreter-js", + "dioxus-cli-config 0.7.1", + "dioxus-core 0.7.1", + "dioxus-devtools 0.7.1", + "dioxus-document 0.7.1", + "dioxus-history 0.7.1", + "dioxus-html 0.7.1", + "dioxus-interpreter-js 0.7.1", "futures-channel", "futures-util", - "generational-box", + "generational-box 0.7.1", "rustc-hash 2.1.1", "serde", "serde_json", @@ -2075,13 +2375,26 @@ dependencies = [ "tracing", ] +[[package]] +name = "dioxus-logger" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "545961e752f6c8bf59c274951b3c8b18a106db6ad2f9e2035b29e1f2a3e899b1" +dependencies = [ + "console_error_panic_hook", + "dioxus-cli-config 0.6.3", + "tracing", + "tracing-subscriber", + "tracing-wasm", +] + [[package]] name = "dioxus-logger" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42237934c6a67f5ed9a8c37e47ca980ee7cfec9e783a9a1f8c2e36c8b96ae74b" dependencies = [ - "dioxus-cli-config", + "dioxus-cli-config 0.7.1", "tracing", "tracing-subscriber", "tracing-wasm", @@ -2092,7 +2405,7 @@ name = "dioxus-primitives" version = "0.0.1" source = "git+https://github.com/DioxusLabs/components#a15f329d1dc2bd76cd4030b27ecd70edb9fd8c6b" dependencies = [ - "dioxus", + "dioxus 0.7.1", "dioxus-time", "lazy-js-bundle 0.6.2", "num-integer", @@ -2106,15 +2419,15 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdf1b95b7cafd07a2b39651ab2b146e4aa72acb0295cd52f422b7db5e2ab6eeb" dependencies = [ - "dioxus-cli-config", - "dioxus-core", - "dioxus-core-macro", + "dioxus-cli-config 0.7.1", + "dioxus-core 0.7.1", + "dioxus-core-macro 0.7.1", "dioxus-fullstack-core", - "dioxus-history", - "dioxus-hooks", - "dioxus-html", + "dioxus-history 0.7.1", + "dioxus-hooks 0.7.1", + "dioxus-html 0.7.1", "dioxus-router-macro", - "dioxus-signals", + "dioxus-signals 0.7.1", "percent-encoding", "rustversion", "tracing", @@ -2136,6 +2449,18 @@ dependencies = [ "syn 2.0.110", ] +[[package]] +name = "dioxus-rsx" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eb588e05800b5a7eb90b2f40fca5bbd7626e823fb5e1ba21e011de649b45aa1" +dependencies = [ + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn 2.0.110", +] + [[package]] name = "dioxus-rsx" version = "0.7.1" @@ -2161,26 +2486,26 @@ dependencies = [ "bytes", "chrono", "ciborium", - "dashmap", - "dioxus-cli-config", - "dioxus-core", - "dioxus-core-macro", - "dioxus-devtools", - "dioxus-document", + "dashmap 6.1.0", + "dioxus-cli-config 0.7.1", + "dioxus-core 0.7.1", + "dioxus-core-macro 0.7.1", + "dioxus-devtools 0.7.1", + "dioxus-document 0.7.1", "dioxus-fullstack-core", - "dioxus-history", - "dioxus-hooks", - "dioxus-html", - "dioxus-interpreter-js", - "dioxus-logger", + "dioxus-history 0.7.1", + "dioxus-hooks 0.7.1", + "dioxus-html 0.7.1", + "dioxus-interpreter-js 0.7.1", + "dioxus-logger 0.7.1", "dioxus-router", - "dioxus-signals", + "dioxus-signals 0.7.1", "dioxus-ssr", "enumset", "futures", "futures-channel", "futures-util", - "generational-box", + "generational-box 0.7.1", "http", "http-body-util", "hyper", @@ -2192,7 +2517,7 @@ dependencies = [ "rustc-hash 2.1.1", "serde", "serde_json", - "serde_qs", + "serde_qs 0.15.0", "subsecond", "thiserror 2.0.17", "tokio", @@ -2206,16 +2531,33 @@ dependencies = [ "walkdir", ] +[[package]] +name = "dioxus-signals" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10e032dbb3a2c0386ec8b8ee59bc20b5aeb67038147c855801237b45b13d72ac" +dependencies = [ + "dioxus-core 0.6.3", + "futures-channel", + "futures-util", + "generational-box 0.6.2", + "once_cell", + "parking_lot", + "rustc-hash 1.1.0", + "tracing", + "warnings", +] + [[package]] name = "dioxus-signals" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3895cc17ff5b43ada07743111be586e7a927ed7ec511457020e4235e13e63fe6" dependencies = [ - "dioxus-core", + "dioxus-core 0.7.1", "futures-channel", "futures-util", - "generational-box", + "generational-box 0.7.1", "parking_lot", "rustc-hash 2.1.1", "tracing", @@ -2229,8 +2571,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "592391fc30a77f94bc5a3385d1569052907e3b3cecb28099671b9d5801dee6c6" dependencies = [ "askama_escape", - "dioxus-core", - "dioxus-core-types", + "dioxus-core 0.7.1", + "dioxus-core-types 0.7.1", "rustc-hash 2.1.1", ] @@ -2240,8 +2582,8 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8521729ac35f362476ac4eb7d1c4ab79e7e92a0facfdea3ee978c0ddf7108d37" dependencies = [ - "dioxus-core", - "dioxus-signals", + "dioxus-core 0.7.1", + "dioxus-signals 0.7.1", "dioxus-stores-macro", ] @@ -2262,7 +2604,7 @@ name = "dioxus-time" version = "0.7.0" source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#8c868ac1d60e3232e3f16f6195d6deb3c016de17" dependencies = [ - "dioxus", + "dioxus 0.7.1", "futures", "gloo-timers", "tokio", @@ -2281,25 +2623,57 @@ dependencies = [ "syn 2.0.110", ] +[[package]] +name = "dioxus-web" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e7c12475c3d360058b8afe1b68eb6dfc9cbb7dcd760aed37c5f85c561c83ed1" +dependencies = [ + "async-trait", + "ciborium", + "dioxus-cli-config 0.6.3", + "dioxus-core 0.6.3", + "dioxus-core-types 0.6.2", + "dioxus-devtools 0.6.2", + "dioxus-document 0.6.3", + "dioxus-history 0.6.2", + "dioxus-html 0.6.3", + "dioxus-interpreter-js 0.6.2", + "dioxus-signals 0.6.3", + "futures-channel", + "futures-util", + "generational-box 0.6.2", + "js-sys", + "lazy-js-bundle 0.6.2", + "rustc-hash 1.1.0", + "serde", + "serde-wasm-bindgen 0.5.0", + "serde_json", + "tracing", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "dioxus-web" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76155ecd44535e7c096ec8c5aac4a945899e47567ead4869babdaa74f3f9bca0" dependencies = [ - "dioxus-cli-config", - "dioxus-core", - "dioxus-core-types", - "dioxus-devtools", - "dioxus-document", + "dioxus-cli-config 0.7.1", + "dioxus-core 0.7.1", + "dioxus-core-types 0.7.1", + "dioxus-devtools 0.7.1", + "dioxus-document 0.7.1", "dioxus-fullstack-core", - "dioxus-history", - "dioxus-html", - "dioxus-interpreter-js", - "dioxus-signals", + "dioxus-history 0.7.1", + "dioxus-html 0.7.1", + "dioxus-interpreter-js 0.7.1", + "dioxus-signals 0.7.1", "futures-channel", "futures-util", - "generational-box", + "generational-box 0.7.1", "gloo-timers", "js-sys", "lazy-js-bundle 0.7.1", @@ -2315,6 +2689,18 @@ dependencies = [ "web-sys", ] +[[package]] +name = "dioxus_server_macro" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "371a5b21989a06b53c5092e977b3f75d0e60a65a4c15a2aa1d07014c3b2dda97" +dependencies = [ + "proc-macro2", + "quote", + "server_fn_macro", + "syn 2.0.110", +] + [[package]] name = "dirs" version = "6.0.0" @@ -3059,6 +3445,16 @@ dependencies = [ "x11", ] +[[package]] +name = "generational-box" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a673cf4fb0ea6a91aa86c08695756dfe875277a912cdbf33db9a9f62d47ed82b" +dependencies = [ + "parking_lot", + "tracing", +] + [[package]] name = "generational-box" version = "0.7.1" @@ -4219,7 +4615,7 @@ name = "jacquard-lexicon" version = "0.9.2" dependencies = [ "cid", - "dashmap", + "dashmap 6.1.0", "heck 0.5.0", "inventory", "jacquard-common", @@ -4246,7 +4642,7 @@ dependencies = [ "base64 0.22.1", "bytes", "chrono", - "dashmap", + "dashmap 6.1.0", "elliptic-curve", "http", "jacquard-common", @@ -4696,15 +5092,38 @@ dependencies = [ "libc", ] +[[package]] +name = "manganis" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317af44b15e7605b85f04525449a3bb631753040156c9b318e6cba8a3ea4ef73" +dependencies = [ + "const-serialize 0.6.2", + "manganis-core 0.6.2", + "manganis-macro 0.6.2", +] + [[package]] name = "manganis" version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "124f8f094eb75783b38209ce4d534b9617da4efac652802d9bafe05043a3ec95" dependencies = [ - "const-serialize", - "manganis-core", - "manganis-macro", + "const-serialize 0.7.1", + "manganis-core 0.7.1", + "manganis-macro 0.7.1", +] + +[[package]] +name = "manganis-core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c38bee65cc725b2bba23b5dbb290f57c8be8fadbe2043fb7e2ce73022ea06519" +dependencies = [ + "const-serialize 0.6.2", + "dioxus-cli-config 0.6.3", + "dioxus-core-types 0.6.2", + "serde", ] [[package]] @@ -4713,12 +5132,25 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fbd1fb8c5aabcc54c6b02dbc968e1c89c28f3e543f2789ef9e3ce45dbdf5df" dependencies = [ - "const-serialize", - "dioxus-cli-config", - "dioxus-core-types", + "const-serialize 0.7.1", + "dioxus-cli-config 0.7.1", + "dioxus-core-types 0.7.1", "serde", ] +[[package]] +name = "manganis-macro" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9f4f71310913c40174d9f0cfcbcb127dad0329ecdb3945678a120db22d3d065" +dependencies = [ + "dunce", + "manganis-core 0.6.2", + "proc-macro2", + "quote", + "syn 2.0.110", +] + [[package]] name = "manganis-macro" version = "0.7.1" @@ -4727,7 +5159,7 @@ checksum = "45d6fec2a8249739bb30b53a08ecbb217f76096c08f1053f38ec3981ba424c11" dependencies = [ "dunce", "macro-string", - "manganis-core", + "manganis-core 0.7.1", "proc-macro2", "quote", "syn 2.0.110", @@ -4983,7 +5415,7 @@ version = "0.10.99" dependencies = [ "crossbeam-channel", "crossbeam-utils", - "dashmap", + "dashmap 6.1.0", "smallvec", "tagptr", "triomphe", @@ -4997,7 +5429,7 @@ source = "git+https://github.com/moka-rs/mini-moka?rev=da864e849f5d034f32e02197f dependencies = [ "crossbeam-channel", "crossbeam-utils", - "dashmap", + "dashmap 6.1.0", "smallvec", "tagptr", "triomphe", @@ -6839,6 +7271,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "serde-wasm-bindgen" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + [[package]] name = "serde-wasm-bindgen" version = "0.6.5" @@ -6930,6 +7373,17 @@ dependencies = [ "serde_core", ] +[[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 1.0.69", +] + [[package]] name = "serde_qs" version = "0.15.0" @@ -7023,6 +7477,58 @@ dependencies = [ "serde", ] +[[package]] +name = "server_fn" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fae7a3038a32e5a34ba32c6c45eb4852f8affaf8b794ebfcd4b1099e2d62ebe" +dependencies = [ + "bytes", + "const_format", + "dashmap 5.5.3", + "futures", + "gloo-net", + "http", + "js-sys", + "once_cell", + "send_wrapper", + "serde", + "serde_json", + "serde_qs 0.12.0", + "server_fn_macro_default", + "thiserror 1.0.69", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "xxhash-rust", +] + +[[package]] +name = "server_fn_macro" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faaaf648c6967aef78177c0610478abb5a3455811f401f3c62d10ae9bd3901a1" +dependencies = [ + "const_format", + "convert_case 0.6.0", + "proc-macro2", + "quote", + "syn 2.0.110", + "xxhash-rust", +] + +[[package]] +name = "server_fn_macro_default" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2aa8119b558a17992e0ac1fd07f080099564f24532858811ce04f742542440" +dependencies = [ + "server_fn_macro", + "syn 2.0.110", +] + [[package]] name = "servo_arc" version = "0.2.0" @@ -8396,6 +8902,24 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "tungstenite" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e2ce1e47ed2994fd43b04c8f618008d4cabdd5ee34027cf14f9d918edd9c8" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand 0.8.5", + "sha1", + "thiserror 1.0.69", + "utf-8", +] + [[package]] name = "tungstenite" version = "0.24.0" @@ -8896,8 +9420,9 @@ dependencies = [ "base64 0.22.1", "chrono", "console_error_panic_hook", - "dashmap", - "dioxus", + "dashmap 6.1.0", + "dioxus 0.7.1", + "dioxus-free-icons", "dioxus-primitives", "dotenvy", "gloo-storage", @@ -8990,7 +9515,7 @@ dependencies = [ "axum", "chrono", "clap", - "dashmap", + "dashmap 6.1.0", "diesel", "diesel-async", "diesel_migrations", @@ -9035,7 +9560,7 @@ name = "weaver-renderer" version = "0.1.0" dependencies = [ "bitflags 2.10.0", - "dashmap", + "dashmap 6.1.0", "http", "ignore", "insta", diff --git a/Cargo.toml b/Cargo.toml index dfc6cf3..84738f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,13 +58,10 @@ jacquard-lexicon = { path = "../jacquard/crates/jacquard-lexicon", default-featu [profile.wasm-dev] inherits = "dev" -opt-level = 1 -lto = true debug = true [profile.server-dev] inherits = "dev" -lto = true debug = true [profile.android-dev] diff --git a/crates/weaver-app/Cargo.toml b/crates/weaver-app/Cargo.toml index 43a13ed..d44613d 100644 --- a/crates/weaver-app/Cargo.toml +++ b/crates/weaver-app/Cargo.toml @@ -5,7 +5,7 @@ authors = ["Orual "] edition = "2024" [features] -default = ["web", "no-app-index"] +default = ["web", "fullstack-server", "no-app-index"] # Fullstack mode with SSR and server functions fullstack-server = ["dioxus/fullstack"] wasm-split = ["dioxus/wasm-split"] @@ -41,6 +41,7 @@ humansize = "2.0.0" base64 = "0.22" http = "1.3" reqwest = { version = "0.12", default-features = false, features = ["json"] } +dioxus-free-icons = { version = "0.9", features = ["font-awesome-brands"] } # diesel = { version = "2.3", features = ["sqlite", "returning_clauses_for_sqlite_3_35", "chrono", "serde_json"] } # diesel_migrations = { version = "2.3", features = ["sqlite"] } diff --git a/crates/weaver-app/Dioxus.toml b/crates/weaver-app/Dioxus.toml index f9475c0..6b8b36f 100644 --- a/crates/weaver-app/Dioxus.toml +++ b/crates/weaver-app/Dioxus.toml @@ -5,6 +5,9 @@ # HTML title tag content title = "Weaver" +out_dir = "dist" +asset_dir = "public" + # include `assets` in web platform [web.resource] diff --git a/crates/weaver-app/src/components/button/style.css b/crates/weaver-app/assets/styling/button.css similarity index 100% rename from crates/weaver-app/src/components/button/style.css rename to crates/weaver-app/assets/styling/button.css diff --git a/crates/weaver-app/assets/styling/navbar.css b/crates/weaver-app/assets/styling/navbar.css index bb47509..9d29a1b 100644 --- a/crates/weaver-app/assets/styling/navbar.css +++ b/crates/weaver-app/assets/styling/navbar.css @@ -36,6 +36,7 @@ .auth-button { align-self: flex-end; + background-color: var(--color-base); } .auth-handle { diff --git a/crates/weaver-app/assets/styling/profile.css b/crates/weaver-app/assets/styling/profile.css index 2a51d84..48f38a0 100644 --- a/crates/weaver-app/assets/styling/profile.css +++ b/crates/weaver-app/assets/styling/profile.css @@ -8,7 +8,7 @@ .profile-banner { max-width: 100%; - height: 200px; + height: 150px; overflow: hidden; } diff --git a/crates/weaver-app/assets/sw.js b/crates/weaver-app/public/sw.js similarity index 100% rename from crates/weaver-app/assets/sw.js rename to crates/weaver-app/public/sw.js diff --git a/crates/weaver-app/src/auth/mod.rs b/crates/weaver-app/src/auth/mod.rs index 6d1538e..fbb8c83 100644 --- a/crates/weaver-app/src/auth/mod.rs +++ b/crates/weaver-app/src/auth/mod.rs @@ -6,7 +6,6 @@ mod state; pub use state::AuthState; use crate::fetch::Fetcher; -#[cfg(all(feature = "fullstack-server", feature = "server"))] use dioxus::prelude::*; #[cfg(all(feature = "fullstack-server", feature = "server"))] use jacquard::oauth::types::OAuthClientMetadata; @@ -26,12 +25,18 @@ pub async fn client_metadata() -> Result> { } #[cfg(not(target_arch = "wasm32"))] -pub async fn restore_session(_fetcher: Fetcher) -> Result<(), String> { +pub async fn restore_session( + _fetcher: Fetcher, + _auth_state: Signal, +) -> Result<(), String> { Ok(()) } #[cfg(target_arch = "wasm32")] -pub async fn restore_session(fetcher: Fetcher) -> Result<(), CapturedError> { +pub async fn restore_session( + fetcher: Fetcher, + mut auth_state: Signal, +) -> Result<(), CapturedError> { use dioxus::prelude::*; use gloo_storage::{LocalStorage, Storage}; use jacquard::types::string::Did; @@ -70,8 +75,6 @@ pub async fn restore_session(fetcher: Fetcher) -> Result<(), CapturedError> { let (restored_did, session_id) = session.session_info().await; // Update auth state - let mut auth_state = try_consume_context::>() - .ok_or(CapturedError::from_display("AuthState not in context"))?; auth_state .write() .set_authenticated(restored_did, session_id); diff --git a/crates/weaver-app/src/components/accordion/style.css b/crates/weaver-app/src/components/accordion/accordion.css similarity index 100% rename from crates/weaver-app/src/components/accordion/style.css rename to crates/weaver-app/src/components/accordion/accordion.css diff --git a/crates/weaver-app/src/components/accordion/component.rs b/crates/weaver-app/src/components/accordion/component.rs index 55fd0a9..b4ffb33 100644 --- a/crates/weaver-app/src/components/accordion/component.rs +++ b/crates/weaver-app/src/components/accordion/component.rs @@ -6,7 +6,7 @@ use dioxus_primitives::accordion::{ #[component] pub fn Accordion(props: AccordionProps) -> Element { rsx! { - document::Link { rel: "stylesheet", href: asset!("./style.css") } + document::Link { rel: "stylesheet", href: asset!("./accordion.css") } accordion::Accordion { class: "accordion", id: props.id, diff --git a/crates/weaver-app/src/components/avatar/style.css b/crates/weaver-app/src/components/avatar/avatar.css similarity index 100% rename from crates/weaver-app/src/components/avatar/style.css rename to crates/weaver-app/src/components/avatar/avatar.css diff --git a/crates/weaver-app/src/components/avatar/component.rs b/crates/weaver-app/src/components/avatar/component.rs index 30374bb..d418e0f 100644 --- a/crates/weaver-app/src/components/avatar/component.rs +++ b/crates/weaver-app/src/components/avatar/component.rs @@ -50,7 +50,7 @@ pub struct AvatarProps { #[component] pub fn Avatar(props: AvatarProps) -> Element { rsx! { - document::Link { rel: "stylesheet", href: asset!("./style.css") } + document::Link { rel: "stylesheet", href: asset!("./avatar.css") } avatar::Avatar { class: "avatar {props.size.to_class()}", diff --git a/crates/weaver-app/src/components/button/component.rs b/crates/weaver-app/src/components/button/component.rs index 6e6a967..56e7eb4 100644 --- a/crates/weaver-app/src/components/button/component.rs +++ b/crates/weaver-app/src/components/button/component.rs @@ -35,7 +35,7 @@ pub fn Button( children: Element, ) -> Element { rsx! { - document::Link { rel: "stylesheet", href: asset!("./style.css") } + document::Link { rel: "stylesheet", href: asset!("/assets/styling/button.css") } button { class: "button", diff --git a/crates/weaver-app/src/components/dialog/component.rs b/crates/weaver-app/src/components/dialog/component.rs index 63fd609..1cb4bff 100644 --- a/crates/weaver-app/src/components/dialog/component.rs +++ b/crates/weaver-app/src/components/dialog/component.rs @@ -6,7 +6,7 @@ use dioxus_primitives::dialog::{ #[component] pub fn DialogRoot(props: DialogRootProps) -> Element { rsx! { - document::Link { rel: "stylesheet", href: asset!("./style.css") } + document::Link { rel: "stylesheet", href: asset!("./dialog.css") } dialog::DialogRoot { class: "dialog-backdrop", id: props.id, diff --git a/crates/weaver-app/src/components/dialog/style.css b/crates/weaver-app/src/components/dialog/dialog.css similarity index 100% rename from crates/weaver-app/src/components/dialog/style.css rename to crates/weaver-app/src/components/dialog/dialog.css diff --git a/crates/weaver-app/src/components/entry.rs b/crates/weaver-app/src/components/entry.rs index 56d7a05..3fd49c7 100644 --- a/crates/weaver-app/src/components/entry.rs +++ b/crates/weaver-app/src/components/entry.rs @@ -4,7 +4,7 @@ use crate::blobcache::BlobCache; use crate::{ components::avatar::{Avatar, AvatarImage}, - data::{NotebookHandle, use_handle}, + data::use_handle, }; use crate::Route; @@ -30,6 +30,12 @@ pub fn EntryPage( book_title: ReadSignal, title: ReadSignal, ) -> Element { + tracing::debug!( + "EntryPage component rendering for ident: {:?}, book: {}, title: {}", + ident(), + book_title(), + title() + ); rsx! { {std::iter::once(rsx! {Entry {ident, book_title, title}})} } @@ -41,62 +47,64 @@ pub fn Entry( book_title: ReadSignal, title: ReadSignal, ) -> Element { + tracing::debug!( + "Entry component rendering for ident: {:?}, book: {}, title: {}", + ident(), + book_title(), + title() + ); // Use feature-gated hook for SSR support let entry = crate::data::use_entry_data(ident, book_title, title); - let handle = use_context::(); let fetcher = use_context::(); + tracing::debug!("Entry component got entry data"); // Handle blob caching when entry data is available - if let Ok(entry) = entry { - match &*entry.read() { - Some((book_entry_view, entry_record)) => { - if let Some(embeds) = &entry_record.embeds { - if let Some(images) = &embeds.images { - // Register blob mappings with service worker (client-side only) - #[cfg(all( - target_family = "wasm", - target_os = "unknown", - not(feature = "fullstack-server") - ))] - { - let fetcher = fetcher.clone(); - let images = images.clone(); - spawn(async move { - let _ = crate::service_worker::register_entry_blobs( - &ident(), - book_title().as_str(), - &images, - &fetcher, - ) - .await; - }); - } + match &*entry.read() { + Some((book_entry_view, entry_record)) => { + if let Some(embeds) = &entry_record.embeds { + if let Some(images) = &embeds.images { + // Register blob mappings with service worker (client-side only) + #[cfg(all( + target_family = "wasm", + target_os = "unknown", + not(feature = "fullstack-server") + ))] + { + let fetcher = fetcher.clone(); + let images = images.clone(); + spawn(async move { + let _ = crate::service_worker::register_entry_blobs( + &ident(), + book_title().as_str(), + &images, + &fetcher, + ) + .await; + }); } } - rsx! { EntryPageView { - book_entry_view: book_entry_view.clone(), - entry_record: entry_record.clone(), - ident: handle.as_ref().unwrap().clone(), - book_title: book_title() - } } } - _ => rsx! { p { "Loading..." } }, + rsx! { EntryPageView { + book_entry_view: book_entry_view.clone(), + entry_record: entry_record.clone(), + ident: ident(), + book_title: book_title() + } } } - } else { - rsx! { p { "Loading..." } } + _ => rsx! { p { "Loading..." } }, } } /// Full entry page with metadata, content, and navigation #[component] fn EntryPageView( - book_entry_view: BookEntryView<'static>, - entry_record: entry::Entry<'static>, - ident: AtIdentifier<'static>, - book_title: SmolStr, + book_entry_view: ReadSignal>, + entry_record: ReadSignal>, + ident: ReadSignal>, + book_title: ReadSignal, ) -> Element { // Extract metadata - let entry_view = &book_entry_view.entry; + let entry_view = &book_entry_view().entry; let title = entry_view .title .as_ref() @@ -110,13 +118,13 @@ fn EntryPageView( div { class: "entry-page-layout", // Left gutter with prev button - if let Some(ref prev) = book_entry_view.prev { + if let Some(ref prev) = book_entry_view().prev { div { class: "nav-gutter nav-prev", NavButton { direction: "prev", entry: prev.entry.clone(), - ident: ident.clone(), - book_title: book_title.clone() + ident: ident(), + book_title: book_title() } } } @@ -126,25 +134,24 @@ fn EntryPageView( // Metadata header EntryMetadata { entry_view: entry_view.clone(), - ident: ident.clone(), - created_at: entry_record.created_at.clone() + created_at: entry_record().created_at.clone() } // Rendered markdown - EntryMarkdownDirect { + EntryMarkdown { content: entry_record, - ident: ident.clone() + ident } } // Right gutter with next button - if let Some(ref next) = book_entry_view.next { + if let Some(ref next) = book_entry_view().next { div { class: "nav-gutter nav-next", NavButton { direction: "next", entry: next.entry.clone(), - ident: ident.clone(), - book_title: book_title.clone() + ident: ident(), + book_title: book_title() } } } @@ -157,6 +164,7 @@ pub fn EntryCard( entry: BookEntryView<'static>, book_title: SmolStr, author_count: usize, + ident: AtIdentifier<'static>, ) -> Element { use crate::Route; use jacquard::from_data; @@ -168,8 +176,6 @@ pub fn EntryCard( .as_ref() .map(|t| t.as_ref()) .unwrap_or("Untitled"); - - let ident = use_context::(); // Format date let formatted_date = entry_view .indexed_at @@ -197,7 +203,7 @@ pub fn EntryCard( div { class: "entry-card", Link { to: Route::EntryPage { - ident: ident.as_ref().unwrap().clone(), + ident: ident, book_title: book_title.clone(), title: title.to_string().into() }, @@ -221,6 +227,7 @@ pub fn EntryCard( match &author.record.inner { ProfileDataViewInner::ProfileView(profile) => { let display_name = profile.display_name.as_ref().map(|n| n.as_ref()).unwrap_or("Unknown"); + let handle = profile.handle.clone(); rsx! { if let Some(ref avatar_url) = profile.avatar { Avatar { @@ -228,11 +235,12 @@ pub fn EntryCard( } } span { class: "author-name", "{display_name}" } - span { class: "meta-label", "@{ident.as_ref().unwrap()}" } + span { class: "meta-label", "@{handle}" } } } ProfileDataViewInner::ProfileViewDetailed(profile) => { let display_name = profile.display_name.as_ref().map(|n| n.as_ref()).unwrap_or("Unknown"); + let handle = profile.handle.clone(); rsx! { if let Some(ref avatar_url) = profile.avatar { Avatar { @@ -240,7 +248,7 @@ pub fn EntryCard( } } span { class: "author-name", "{display_name}" } - span { class: "meta-label", "@{ident.as_ref().unwrap()}" } + span { class: "meta-label", "@{handle}" } } } ProfileDataViewInner::TangledProfileView(profile) => { @@ -282,11 +290,7 @@ pub fn EntryCard( /// Metadata header showing title, authors, date, tags #[component] -fn EntryMetadata( - entry_view: EntryView<'static>, - ident: AtIdentifier<'static>, - created_at: Datetime, -) -> Element { +fn EntryMetadata(entry_view: EntryView<'static>, created_at: Datetime) -> Element { let title = entry_view .title .as_ref() @@ -311,9 +315,11 @@ fn EntryMetadata( match &author.record.inner { ProfileDataViewInner::ProfileView(profile) => { let display_name = profile.display_name.as_ref().map(|n| n.as_ref()).unwrap_or("Unknown"); + let handle = profile.handle.clone(); + rsx! { Link { - to: Route::RepositoryIndex { ident: ident.clone() }, + to: Route::RepositoryIndex { ident: AtIdentifier::Handle(handle.clone()) }, div { class: "entry-authors", if let Some(ref avatar_url) = profile.avatar { Avatar { @@ -323,16 +329,17 @@ fn EntryMetadata( } } span { class: "author-name", "{display_name}" } - span { class: "meta-label", "@{ident}" } + span { class: "meta-label", "@{handle}" } } } } } ProfileDataViewInner::ProfileViewDetailed(profile) => { let display_name = profile.display_name.as_ref().map(|n| n.as_ref()).unwrap_or("Unknown"); + let handle = profile.handle.clone(); rsx! { Link { - to: Route::RepositoryIndex { ident: ident.clone() }, + to: Route::RepositoryIndex { ident: AtIdentifier::Handle(handle.clone()) }, div { class: "entry-authors", if let Some(ref avatar_url) = profile.avatar { Avatar { @@ -342,7 +349,7 @@ fn EntryMetadata( } } span { class: "author-name", "{display_name}" } - span { class: "meta-label", "@{ident}" } + span { class: "meta-label", "@{handle}" } } } } @@ -423,22 +430,18 @@ fn NavButton( pub struct EntryMarkdownProps { #[props(default)] id: Signal, - #[props(default)] + #[props(default = use_signal(||"entry".to_string()))] class: Signal, content: ReadSignal>, ident: ReadSignal>, } /// Render some text as markdown. -#[allow(unused)] pub fn EntryMarkdown(props: EntryMarkdownProps) -> Element { - let processed = crate::data::use_rendered_markdown( - props.content, - props.ident, - )?; + let processed = crate::data::use_rendered_markdown(props.content, props.ident); match &*processed.read() { - Some(Some(html_buf)) => rsx! { + Some(html_buf) => rsx! { div { id: "{&*props.id.read()}", class: "{&*props.class.read()}", @@ -466,10 +469,10 @@ fn EntryMarkdownDirect( // Use feature-gated hook for SSR support let content = use_signal(|| content); let ident = use_signal(|| ident); - let processed = crate::data::use_rendered_markdown(content.into(), ident.into())?; + let processed = crate::data::use_rendered_markdown(content.into(), ident.into()); match &*processed.read() { - Some(Some(html_buf)) => rsx! { + Some(html_buf) => rsx! { div { id: "{id}", class: "{class}", diff --git a/crates/weaver-app/src/components/identity.rs b/crates/weaver-app/src/components/identity.rs index 1b873ab..5829ef2 100644 --- a/crates/weaver-app/src/components/identity.rs +++ b/crates/weaver-app/src/components/identity.rs @@ -8,9 +8,10 @@ const NOTEBOOK_CARD_CSS: Asset = asset!("/assets/styling/notebook-card.css"); #[component] pub fn Repository(ident: ReadSignal>) -> Element { - // Fetch notebooks for this specific DID with SSR support - let notebooks = data::use_notebooks_for_did(ident)?; - use_context_provider(|| notebooks); + tracing::debug!("Repository component rendering for ident: {:?}", ident()); + // Fetch notebooks for this specific DID with SSR support; + tracing::debug!("Repository component context set up"); + rsx! { div { Outlet:: {} @@ -18,52 +19,50 @@ pub fn Repository(ident: ReadSignal>) -> Element { } } -pub fn use_repo_notebook_context() --> Option, Vec>)>>>> { - try_use_context::, Vec>)>>>>() -} - #[component] pub fn RepositoryIndex(ident: ReadSignal>) -> Element { + tracing::debug!( + "RepositoryIndex component rendering for ident: {:?}", + ident() + ); use crate::components::ProfileDisplay; - let notebooks = use_repo_notebook_context(); - let profile = crate::data::use_profile_data(ident)?; + let notebooks = data::use_notebooks_for_did(ident); + let profile = crate::data::use_profile_data(ident); + tracing::debug!("RepositoryIndex got profile and notebooks"); rsx! { document::Stylesheet { href: NOTEBOOK_CARD_CSS } div { class: "repository-layout", // Profile sidebar (desktop) / header (mobile) aside { class: "repository-sidebar", - ProfileDisplay { profile } + ProfileDisplay { profile, notebooks } } // Main content area main { class: "repository-main", div { class: "notebooks-list", - if let Some(notebooks) = notebooks { - match &*notebooks.read() { - Some(notebook_list) => rsx! { - for notebook in notebook_list.iter() { - { - let view = ¬ebook.0; - let entries = ¬ebook.1; - rsx! { - div { - key: "{view.cid}", - NotebookCard { - notebook: view.clone(), - entry_refs: entries.clone() - } - } - } - } - } - }, - None => rsx! { - div { "Loading notebooks..." } - } - } - } + match &*notebooks.read() { + Some(notebook_list) => rsx! { + for notebook in notebook_list.iter() { + { + let view = ¬ebook.0; + let entries = ¬ebook.1; + rsx! { + div { + key: "{view.cid}", + NotebookCard { + notebook: view.clone(), + entry_refs: entries.clone() + } + } + } + } + } + }, + None => rsx! { + div { "Loading notebooks..." } + } + } } } } diff --git a/crates/weaver-app/src/components/input/component.rs b/crates/weaver-app/src/components/input/component.rs index 5a1807e..a27d37d 100644 --- a/crates/weaver-app/src/components/input/component.rs +++ b/crates/weaver-app/src/components/input/component.rs @@ -26,7 +26,7 @@ pub fn Input( children: Element, ) -> Element { rsx! { - document::Link { rel: "stylesheet", href: asset!("./style.css") } + document::Link { rel: "stylesheet", href: asset!("./input-style.css") } input { class: "input", oninput: move |e| _ = oninput.map(|callback| callback(e)), diff --git a/crates/weaver-app/src/components/input/style.css b/crates/weaver-app/src/components/input/input-style.css similarity index 100% rename from crates/weaver-app/src/components/input/style.css rename to crates/weaver-app/src/components/input/input-style.css diff --git a/crates/weaver-app/src/components/notebook_cover.rs b/crates/weaver-app/src/components/notebook_cover.rs index 60991f7..e7495c9 100644 --- a/crates/weaver-app/src/components/notebook_cover.rs +++ b/crates/weaver-app/src/components/notebook_cover.rs @@ -1,9 +1,6 @@ #![allow(non_snake_case)] -use crate::{ - components::avatar::{Avatar, AvatarImage}, - data::NotebookHandle, -}; +use crate::components::avatar::{Avatar, AvatarImage}; use dioxus::prelude::*; use weaver_api::sh_weaver::notebook::NotebookView; diff --git a/crates/weaver-app/src/components/profile.rs b/crates/weaver-app/src/components/profile.rs index df5bf62..3b41a02 100644 --- a/crates/weaver-app/src/components/profile.rs +++ b/crates/weaver-app/src/components/profile.rs @@ -5,7 +5,6 @@ use std::sync::Arc; use crate::components::{ BskyIcon, TangledIcon, avatar::{Avatar, AvatarImage}, - identity::use_repo_notebook_context, }; use dioxus::prelude::*; use weaver_api::com_atproto::repo::strong_ref::StrongRef; @@ -15,8 +14,10 @@ use weaver_common::agent::NotebookView; const PROFILE_CSS: Asset = asset!("/assets/styling/profile.css"); #[component] -pub fn ProfileDisplay(profile: Memo>>) -> Element { - let notebooks = use_repo_notebook_context(); +pub fn ProfileDisplay( + profile: Memo>>, + notebooks: Memo, Vec>)>>>, +) -> Element { match &*profile.read() { Some(profile_view) => { let profile_view = Arc::new(profile_view.clone()); @@ -57,7 +58,7 @@ pub fn ProfileDisplay(profile: Memo>>) -> Elemen div { class: "profile-extras", // Stats - ProfileStats { notebooks: notebooks.unwrap() } + ProfileStats { notebooks: notebooks } // Links ProfileLinks { profile_view } diff --git a/crates/weaver-app/src/data.rs b/crates/weaver-app/src/data.rs index ae8844b..c06cc37 100644 --- a/crates/weaver-app/src/data.rs +++ b/crates/weaver-app/src/data.rs @@ -36,7 +36,7 @@ pub fn use_entry_data( ident: ReadSignal>, book_title: ReadSignal, title: ReadSignal, -) -> Result, Entry<'static>)>>, RenderError> { +) -> Memo, Entry<'static>)>> { let fetcher = use_context::(); let fetcher = fetcher.clone(); let res = use_server_future(move || { @@ -75,8 +75,9 @@ pub fn use_entry_data( None } } - })?; // Handle the Result first to avoid calling use_memo in a closure - Ok(use_memo(move || { + }); + use_memo(use_reactive!(|res| { + let res = res.ok()?; if let Some(Some((ev, e))) = &*res.read() { use jacquard::from_json_value; @@ -95,27 +96,47 @@ pub fn use_entry_data( ident: ReadSignal>, book_title: ReadSignal, title: ReadSignal, -) -> Result, Entry<'static>)>>, RenderError> { +) -> Memo, Entry<'static>)>> { let fetcher = use_context::(); let fetcher = fetcher.clone(); let res = use_resource(move || { let fetcher = fetcher.clone(); async move { - fetcher + if let Some(entry) = fetcher .get_entry(ident(), book_title(), title()) .await .ok() .flatten() - .map(|arc| { - ( - serde_json::to_value(arc.0.clone()).unwrap(), - serde_json::to_value(arc.1.clone()).unwrap(), - ) - }) + { + let (_book_entry_view, entry_record) = (&entry.0, &entry.1); + if let Some(embeds) = &entry_record.embeds { + if let Some(images) = &embeds.images { + #[cfg(all( + target_family = "wasm", + target_os = "unknown", + not(feature = "fullstack-server") + ))] + { + let _ = crate::service_worker::register_entry_blobs( + &ident(), + book_title().as_str(), + images, + &fetcher, + ) + .await; + } + } + } + Some(( + serde_json::to_value(entry.0.clone()).unwrap(), + serde_json::to_value(entry.1.clone()).unwrap(), + )) + } else { + None + } } }); - res.suspend()?; - Ok(use_memo(move || { + use_memo(move || { if let Some(Some((ev, e))) = &*res.read() { use jacquard::from_json_value; @@ -126,27 +147,96 @@ pub fn use_entry_data( } else { None } - })) + }) } pub fn use_get_handle(did: Did<'static>) -> AtIdentifier<'static> { let ident = use_signal(use_reactive!(|did| AtIdentifier::Did(did.clone()))); - use_handle(ident.into()) - .read() - .as_ref() - .unwrap_or(&Ok(ident.read().clone())) - .as_ref() - .unwrap() - .clone() + use_handle(ident.into()).read().clone() } -pub fn use_handle( - ident: ReadSignal>, -) -> Resource, IdentityError>> { +#[cfg(feature = "fullstack-server")] +pub fn use_load_handle( + ident: Option>, +) -> ReadSignal>> { + let ident = use_signal(use_reactive!(|ident| ident.clone())); + let fetcher = use_context::(); + let fetcher = fetcher.clone(); + let res = use_server_future(move || { + let client = fetcher.get_client(); + async move { + if let Some(ident) = &*ident.read() { + use jacquard::smol_str::ToSmolStr; + + client + .resolve_ident_owned(ident) + .await + .map(|doc| doc.handles().first().map(|h| h.to_smolstr())) + .unwrap_or(Some(ident.to_smolstr())) + } else { + None + } + } + }); + + use_memo(use_reactive!(|res| { + if let Ok(res) = res { + if let Some(value) = &*res.read() { + if let Some(handle) = value { + AtIdentifier::new_owned(handle.clone()).ok() + } else { + ident.read().clone() + } + } else { + ident.read().clone() + } + } else { + ident.read().clone() + } + })) + .into() +} + +#[cfg(not(feature = "fullstack-server"))] +pub fn use_load_handle( + ident: Option>, +) -> ReadSignal>> { + let ident = use_signal(use_reactive!(|ident| ident.clone())); + let fetcher = use_context::(); + let fetcher = fetcher.clone(); + let res = use_resource(move || { + let client = fetcher.get_client(); + async move { + if let Some(ident) = &*ident.read() { + client + .resolve_ident_owned(ident) + .await + .map(|doc| { + doc.handles() + .first() + .map(|h| AtIdentifier::Handle(h.clone()).into_static()) + }) + .unwrap_or(Some(ident.clone())) + } else { + None + } + } + }); + + if let Ok(ident) = res.suspend() { + ident.into() + } else { + ident.into() + } +} +#[cfg(not(feature = "fullstack-server"))] +pub fn use_handle(ident: ReadSignal>) -> ReadSignal> { + let old_ident = ident.read().clone(); let fetcher = use_context::(); let fetcher = fetcher.clone(); - use_resource(move || { + let res = use_resource(move || { let client = fetcher.get_client(); + let old_ident = old_ident.clone(); async move { client .resolve_ident_owned(&*ident.read()) @@ -156,32 +246,54 @@ pub fn use_handle( .first() .map(|h| AtIdentifier::Handle(h.clone()).into_static()) }) - .map(|h| h.ok_or(IdentityError::invalid_well_known()))? + .ok() + .flatten() + .unwrap_or(old_ident) } - }) + }); + if let Ok(ident) = res.suspend() { + ident.into() + } else { + ident + } } +#[cfg(feature = "fullstack-server")] +pub fn use_handle(ident: ReadSignal>) -> ReadSignal> { + let old_ident = ident.read().clone(); + let fetcher = use_context::(); + let fetcher = fetcher.clone(); + let res = use_server_future(move || { + let client = fetcher.get_client(); + let old_ident = old_ident.clone(); + async move { + use jacquard::smol_str::ToSmolStr; -#[derive(Clone, PartialEq, Eq)] -pub struct NotebookHandle(pub Arc>>); + client + .resolve_ident_owned(&*ident.read()) + .await + .map(|doc| { + use jacquard::smol_str::ToSmolStr; -impl NotebookHandle { - pub fn as_ref(&self) -> Option<&AtIdentifier<'static>> { - self.0.as_ref().as_ref() - } -} + doc.handles().first().map(|h| h.to_smolstr()) + }) + .ok() + .flatten() + .unwrap_or(old_ident.to_smolstr()) + } + }); -pub fn use_notebook_handle(ident: Signal>>) -> NotebookHandle { - let ident = if let Some(ident) = &*ident.read() { - let _ident = Signal::new(ident.clone()); - if let Some(Ok(handle)) = &*use_handle(_ident.into()).read() { - Some(handle.clone()) + use_memo(use_reactive!(|res| { + if let Ok(res) = res { + if let Some(value) = &*res.read() { + AtIdentifier::new_owned(value).unwrap() + } else { + ident.read().clone() + } } else { - Some(ident.clone()) + ident.read().clone() } - } else { - ident.read().clone() - }; - use_context_provider(|| NotebookHandle(Arc::new(ident))) + })) + .into() } /// Hook to render markdown with SSR support. @@ -189,9 +301,9 @@ pub fn use_notebook_handle(ident: Signal>>) -> Note pub fn use_rendered_markdown( content: ReadSignal>, ident: ReadSignal>, -) -> Result>, RenderError> { +) -> Memo> { let fetcher = use_context::(); - Ok(use_server_future(move || { + let res = use_server_future(move || { let client = fetcher.get_client(); async move { let did = match ident() { @@ -200,7 +312,15 @@ pub fn use_rendered_markdown( }; Some(render_markdown_impl(content(), did).await) } - })?) + }); + use_memo(use_reactive!(|res| { + let res = res.ok()?; + if let Some(Some(value)) = &*res.read() { + Some(value.clone()) + } else { + None + } + })) } /// Hook to render markdown client-side only (no SSR). @@ -208,9 +328,9 @@ pub fn use_rendered_markdown( pub fn use_rendered_markdown( content: ReadSignal>, ident: ReadSignal>, -) -> Result>, RenderError> { +) -> Memo> { let fetcher = use_context::(); - Ok(use_resource(move || { + let res = use_resource(move || { let client = fetcher.get_client(); async move { let did = match ident() { @@ -219,7 +339,14 @@ pub fn use_rendered_markdown( }; Some(render_markdown_impl(content(), did).await) } - })) + }); + use_memo(move || { + if let Some(Some(value)) = &*res.read() { + Some(value.clone()) + } else { + None + } + }) } /// Internal implementation of markdown rendering. @@ -247,20 +374,24 @@ async fn render_markdown_impl(content: Entry<'static>, did: Did<'static>) -> Str #[cfg(feature = "fullstack-server")] pub fn use_profile_data( ident: ReadSignal>, -) -> Result>>, RenderError> { +) -> Memo>> { let fetcher = use_context::(); let res = use_server_future(move || { let fetcher = fetcher.clone(); async move { - fetcher + tracing::debug!("use_profile_data server future STARTED for {:?}", ident()); + let result = fetcher .fetch_profile(&ident()) .await .ok() .map(|arc| serde_json::to_value(&*arc).ok()) - .flatten() + .flatten(); + tracing::debug!("use_profile_data server future COMPLETED for {:?}", ident()); + result } - })?; - Ok(use_memo(move || { + }); + use_memo(use_reactive!(|res| { + let res = res.ok()?; if let Some(Some(value)) = &*res.read() { jacquard::from_json_value::(value.clone()).ok() } else { @@ -273,7 +404,7 @@ pub fn use_profile_data( #[cfg(not(feature = "fullstack-server"))] pub fn use_profile_data( ident: ReadSignal>, -) -> Result>>, RenderError> { +) -> Memo>> { let fetcher = use_context::(); let res = use_resource(move || { let fetcher = fetcher.clone(); @@ -286,21 +417,20 @@ pub fn use_profile_data( .flatten() } }); - res.suspend()?; - Ok(use_memo(move || { + use_memo(move || { if let Some(Some(value)) = &*res.read() { jacquard::from_json_value::(value.clone()).ok() } else { None } - })) + }) } /// Fetches notebooks for a specific DID #[cfg(feature = "fullstack-server")] pub fn use_notebooks_for_did( ident: ReadSignal>, -) -> Result, Vec>)>>>, RenderError> { +) -> Memo, Vec>)>>> { let fetcher = use_context::(); let res = use_server_future(move || { let fetcher = fetcher.clone(); @@ -317,8 +447,9 @@ pub fn use_notebooks_for_did( }) .flatten() } - })?; - Ok(use_memo(move || { + }); + use_memo(use_reactive!(|res| { + let res = res.ok()?; if let Some(Some(values)) = &*res.read() { values .iter() @@ -336,7 +467,7 @@ pub fn use_notebooks_for_did( #[cfg(not(feature = "fullstack-server"))] pub fn use_notebooks_for_did( ident: ReadSignal>, -) -> Result, Vec>)>>>, RenderError> { +) -> Memo, Vec>)>>> { let fetcher = use_context::(); let res = use_resource(move || { let fetcher = fetcher.clone(); @@ -354,8 +485,7 @@ pub fn use_notebooks_for_did( .flatten() } }); - res.suspend()?; - Ok(use_memo(move || { + use_memo(move || { if let Some(Some(values)) = &*res.read() { values .iter() @@ -366,13 +496,13 @@ pub fn use_notebooks_for_did( } else { None } - })) + }) } /// Fetches notebooks from UFOS with SSR support in fullstack mode #[cfg(feature = "fullstack-server")] pub fn use_notebooks_from_ufos() --> Result, Vec>)>>>, RenderError> { +-> Memo, Vec>)>>> { let fetcher = use_context::(); let res = use_server_future(move || { let fetcher = fetcher.clone(); @@ -389,8 +519,9 @@ pub fn use_notebooks_from_ufos() }) .flatten() } - })?; - Ok(use_memo(move || { + }); + use_memo(use_reactive!(|res| { + let res = res.ok()?; if let Some(Some(values)) = &*res.read() { values .iter() @@ -407,7 +538,7 @@ pub fn use_notebooks_from_ufos() /// Fetches notebooks from UFOS client-side only (no SSR) #[cfg(not(feature = "fullstack-server"))] pub fn use_notebooks_from_ufos() --> Result, Vec>)>>>, RenderError> { +-> Memo, Vec>)>>> { let fetcher = use_context::(); let res = use_resource(move || { let fetcher = fetcher.clone(); @@ -425,8 +556,7 @@ pub fn use_notebooks_from_ufos() .flatten() } }); - res.suspend()?; - Ok(use_memo(move || { + use_memo(move || { if let Some(Some(values)) = &*res.read() { values .iter() @@ -437,7 +567,7 @@ pub fn use_notebooks_from_ufos() } else { None } - })) + }) } /// Fetches notebook metadata with SSR support in fullstack mode @@ -445,7 +575,7 @@ pub fn use_notebooks_from_ufos() pub fn use_notebook( ident: ReadSignal>, book_title: ReadSignal, -) -> Result, Vec>)>>, RenderError> { +) -> Memo, Vec>)>> { let fetcher = use_context::(); let res = use_server_future(move || { let fetcher = fetcher.clone(); @@ -458,8 +588,9 @@ pub fn use_notebook( .map(|arc| serde_json::to_value(arc.as_ref()).ok()) .flatten() } - })?; - Ok(use_memo(move || { + }); + use_memo(use_reactive!(|res| { + let res = res.ok()?; if let Some(Some(value)) = &*res.read() { jacquard::from_json_value::<(NotebookView, Vec)>(value.clone()).ok() } else { @@ -473,7 +604,7 @@ pub fn use_notebook( pub fn use_notebook( ident: ReadSignal>, book_title: ReadSignal, -) -> Result, Vec>)>>, RenderError> { +) -> Memo, Vec>)>> { let fetcher = use_context::(); let res = use_resource(move || { let fetcher = fetcher.clone(); @@ -487,8 +618,8 @@ pub fn use_notebook( .flatten() } }); - res.suspend()?; - Ok(use_memo(move || { + use_memo(use_reactive!(|res| { + let res = res.ok()?; if let Some(Some(value)) = &*res.read() { jacquard::from_json_value::<(NotebookView, Vec)>(value.clone()).ok() } else { @@ -502,7 +633,7 @@ pub fn use_notebook( pub fn use_notebook_entries( ident: ReadSignal>, book_title: ReadSignal, -) -> Result>>>, RenderError> { +) -> Memo>>> { let fetcher = use_context::(); let res = use_server_future(move || { let fetcher = fetcher.clone(); @@ -520,9 +651,9 @@ pub fn use_notebook_entries( }) .flatten() } - })?; - res.suspend()?; - Ok(use_memo(move || { + }); + use_memo(use_reactive!(|res| { + let res = res.ok()?; if let Some(Some(values)) = &*res.read() { values .iter() @@ -539,7 +670,7 @@ pub fn use_notebook_entries( pub fn use_notebook_entries( ident: ReadSignal>, book_title: ReadSignal, -) -> Result>>>, RenderError> { +) -> Memo>>> { let fetcher = use_context::(); let r = use_resource(move || { let fetcher = fetcher.clone(); @@ -551,8 +682,7 @@ pub fn use_notebook_entries( .flatten() } }); - r.suspend()?; - Ok(use_memo(move || r.read().as_ref().and_then(|v| v.clone()))) + use_memo(move || r.read().as_ref().and_then(|v| v.clone())) } #[cfg(feature = "fullstack-server")] diff --git a/crates/weaver-app/src/env.rs b/crates/weaver-app/src/env.rs index e130e54..b8c902b 100644 --- a/crates/weaver-app/src/env.rs +++ b/crates/weaver-app/src/env.rs @@ -1,11 +1,11 @@ // This file is automatically generated by build.rs #[allow(unused)] -pub const WEAVER_APP_ENV: &'static str = "prod"; +pub const WEAVER_APP_ENV: &'static str = "dev"; #[allow(unused)] -pub const WEAVER_APP_HOST: &'static str = "https://alpha.weaver.sh"; +pub const WEAVER_APP_HOST: &'static str = "http://localhost"; #[allow(unused)] -pub const WEAVER_APP_DOMAIN: &'static str = "https://alpha.weaver.sh"; +pub const WEAVER_APP_DOMAIN: &'static str = ""; #[allow(unused)] pub const WEAVER_PORT: &'static str = "8080"; #[allow(unused)] diff --git a/crates/weaver-app/src/main.rs b/crates/weaver-app/src/main.rs index 22e1539..ed71929 100644 --- a/crates/weaver-app/src/main.rs +++ b/crates/weaver-app/src/main.rs @@ -112,11 +112,7 @@ fn main() { use std::sync::Arc; #[cfg(not(feature = "fullstack-server"))] - let router = { - axum::Router::new() - .route("/sw.js", get(serve_sw)) - .merge(dioxus::server::router(App)) - }; + let router = { axum::Router::new().merge(dioxus::server::router(App)) }; #[cfg(feature = "fullstack-server")] let router = { @@ -160,33 +156,69 @@ fn main() { #[cfg(not(feature = "server"))] dioxus::launch(App); } +const THEME_DEFAULTS_CSS: Asset = asset!("/assets/styling/theme-defaults.css"); #[component] fn App() -> Element { + tracing::debug!("App component rendering"); + #[allow(unused)] let fetcher = use_context_provider(|| { fetch::Fetcher::new(OAuthClient::new( AuthStore::new(), ClientData::new_public(CONFIG.oauth.clone()), )) }); - use_context_provider(|| Signal::new(AuthState::default())); - use_effect(move || { + let auth_state = use_signal(|| AuthState::default()); + #[allow(unused)] + let auth_state = use_context_provider(|| auth_state); + #[cfg(all( + target_family = "wasm", + target_os = "unknown", + feature = "fullstack-server" + ))] + { let fetcher = fetcher.clone(); - spawn(async move { - if let Err(e) = auth::restore_session(fetcher).await { - tracing::debug!("Session restoration failed: {}", e); + use_future(move || { + let fetcher = fetcher.clone(); + async move { + if let Err(e) = auth::restore_session(fetcher, auth_state).await { + tracing::debug!("Session restoration failed: {}", e); + } } }); - }); + } #[cfg(all( target_family = "wasm", target_os = "unknown", not(feature = "fullstack-server") ))] - spawn(async move { - let _ = service_worker::register_service_worker().await; - }); + { + let fetcher = fetcher.clone(); + use_future(move || { + let fetcher = fetcher.clone(); + async move { + if let Err(e) = auth::restore_session(fetcher, auth_state).await { + tracing::debug!("Session restoration failed: {}", e); + } + } + }); + } + + #[cfg(all( + target_family = "wasm", + target_os = "unknown", + not(feature = "fullstack-server") + ))] + { + use_effect(move || { + let fetcher = fetcher.clone(); + spawn(async move { + tracing::info!("Registering service worker"); + let _ = service_worker::register_service_worker().await; + }); + }); + } rsx! { document::Link { rel: "icon", href: FAVICON } @@ -194,6 +226,8 @@ fn App() -> Element { document::Link { rel: "stylesheet", href: "https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,200;0,300;0,400;0,500;0,600;0,700;1,200;1,300;1,400;1,500;1,600;1,700&family=IBM+Plex+Sans:ital,wght@0,100..700;1,100..700&family=IBM+Plex+Serif:ital,wght@0,200;0,300;0,400;0,500;0,600;0,700;1,200;1,300;1,400;1,500;1,600;1,700&display=swap" } document::Link { rel: "preconnect", href: "https://fonts.googleapis.com" } document::Link { rel: "preconnect", href: "https://fonts.gstatic.com" } + + document::Link { rel: "stylesheet", href: THEME_DEFAULTS_CSS } Router:: {} } } @@ -203,10 +237,10 @@ fn App() -> Element { fn ErrorLayout() -> Element { rsx! { ErrorBoundary { - handle_error: move |err: ErrorContext| { + handle_error: move |_err: ErrorContext| { #[cfg(feature = "fullstack-server")] { - let http_error = FullstackContext::commit_error_status(err.error().unwrap()); + let http_error = FullstackContext::commit_error_status(_err.error().unwrap()); match http_error.status { StatusCode::NOT_FOUND => rsx! { div { "404 - Page not found" } }, _ => rsx! { div { "An unknown error occurred" } }, diff --git a/crates/weaver-app/src/service_worker.rs b/crates/weaver-app/src/service_worker.rs index a96f879..41fe09e 100644 --- a/crates/weaver-app/src/service_worker.rs +++ b/crates/weaver-app/src/service_worker.rs @@ -12,9 +12,10 @@ pub async fn register_service_worker() -> Result<(), JsValue> { let window = web_sys::window().ok_or_else(|| JsValue::from_str("no window"))?; let navigator = window.navigator(); let sw_container = navigator.service_worker(); - + tracing::debug!("Registering service worker"); let promise = sw_container.register("/sw.js"); JsFuture::from(promise).await?; + tracing::debug!("Service worker registered"); Ok(()) } @@ -30,6 +31,7 @@ pub async fn register_entry_blobs( use jacquard::prelude::IdentityResolver; use std::collections::HashMap; + tracing::debug!("registering blobs for {}", book_title); let mut blob_mappings = HashMap::new(); // Resolve DID and PDS URL @@ -61,12 +63,13 @@ pub async fn register_entry_blobs( blob_mappings.insert(name.as_ref().to_string(), blob_url); } } + } - // Send mappings to service worker - if !blob_mappings.is_empty() { - send_blob_mappings(book_title, blob_mappings)?; - } + // Send mappings to service worker + if !blob_mappings.is_empty() { + send_blob_mappings(book_title, blob_mappings)?; } + //} Ok(()) } @@ -80,6 +83,7 @@ fn send_blob_mappings( let navigator = window.navigator(); let sw_container = navigator.service_worker(); + tracing::debug!("sending blob mappings for {}", notebook); let controller = sw_container .controller() .ok_or_else(|| JsValue::from_str("no service worker controller"))?; @@ -97,6 +101,7 @@ fn send_blob_mappings( js_sys::Reflect::set(&msg, &"blobs".into(), &blobs_obj)?; controller.post_message(&msg)?; + tracing::debug!("sent blob mappings for {}", notebook); Ok(()) } @@ -117,4 +122,10 @@ pub fn send_blob_mappings( } // #[used] -// static BINDINGS_JS: Asset = asset!("/assets/sw.js", AssetOptions::js().with_hash_suffix(false)); +// static BINDINGS_JS: Asset = asset!( +// "/sw.js", +// AssetOptions::js() +// .with_hash_suffix(false) +// .with_minify(false) +// .with_preload(true) +// ); diff --git a/crates/weaver-app/src/views/home.rs b/crates/weaver-app/src/views/home.rs index a48f5fd..bc0bc6b 100644 --- a/crates/weaver-app/src/views/home.rs +++ b/crates/weaver-app/src/views/home.rs @@ -8,7 +8,7 @@ const NOTEBOOK_CARD_CSS: Asset = asset!("/assets/styling/notebook-card.css"); #[component] pub fn Home() -> Element { // Fetch notebooks from UFOS with SSR support - let notebooks = data::use_notebooks_from_ufos()?; + let notebooks = data::use_notebooks_from_ufos(); let navigator = use_navigator(); let mut uri_input = use_signal(|| String::new()); @@ -16,9 +16,8 @@ pub fn Home() -> Element { let input_uri = uri_input.read().clone(); if !input_uri.is_empty() { if let Ok(parsed) = AtUri::new(&input_uri) { - navigator.push(Route::RecordPage { - uri: vec![parsed.to_string()], - }); + let link = format!("{}/record/{}", crate::env::WEAVER_APP_DOMAIN, parsed); + navigator.push(link); } } }; diff --git a/crates/weaver-app/src/views/navbar.rs b/crates/weaver-app/src/views/navbar.rs index d4f6a46..ea490e4 100644 --- a/crates/weaver-app/src/views/navbar.rs +++ b/crates/weaver-app/src/views/navbar.rs @@ -1,12 +1,11 @@ use crate::Route; +use crate::auth::AuthState; use crate::components::button::{Button, ButtonVariant}; use crate::components::login::LoginModal; -use crate::data::{use_get_handle, use_notebook_handle}; +use crate::data::{use_get_handle, use_load_handle}; use crate::fetch::Fetcher; use dioxus::prelude::*; -use jacquard::types::did::Did; -const THEME_DEFAULTS_CSS: Asset = asset!("/assets/styling/theme-defaults.css"); const NAVBAR_CSS: Asset = asset!("/assets/styling/navbar.css"); /// The Navbar component that will be rendered on all pages of our app since every page is under the layout. @@ -16,20 +15,25 @@ const NAVBAR_CSS: Asset = asset!("/assets/styling/navbar.css"); /// routes will be rendered under the outlet inside this component #[component] pub fn Navbar() -> Element { + tracing::debug!("Navbar component rendering"); let route = use_route::(); + tracing::debug!("Route: {:?}", route); - let route_handle = use_signal(|| match &route { + let mut auth_state = use_context::>(); + let route_handle = use_load_handle(match &route { Route::EntryPage { ident, .. } => Some(ident.clone()), Route::RepositoryIndex { ident } => Some(ident.clone()), Route::NotebookIndex { ident, .. } => Some(ident.clone()), _ => None, }); - let notebook_handle = use_notebook_handle(route_handle); + let fetcher = use_context::(); + let mut show_login_modal = use_signal(|| false); + + tracing::debug!("Navbar got route_handle: {:?}", route_handle); rsx! { - document::Link { rel: "stylesheet", href: THEME_DEFAULTS_CSS } document::Link { rel: "stylesheet", href: NAVBAR_CSS } - + document::Link { rel: "stylesheet", href: asset!("/assets/styling/button.css") } div { id: "navbar", nav { class: "breadcrumbs", @@ -41,15 +45,17 @@ pub fn Navbar() -> Element { // Show repository breadcrumb if we're on a repository page match route { - Route::RepositoryIndex { .. } => { - let handle = notebook_handle.as_ref().unwrap(); + Route::RepositoryIndex { ident } => { + let route_handle = route_handle.read().clone(); + let handle = route_handle.unwrap_or(ident.clone()); rsx! { span { class: "breadcrumb-separator", " > " } span { class: "breadcrumb breadcrumb-current", "@{handle}" } } }, Route::NotebookIndex { ident, book_title } => { - let handle = notebook_handle.as_ref().unwrap(); + let route_handle = route_handle.read().clone(); + let handle = route_handle.unwrap_or(ident.clone()); rsx! { span { class: "breadcrumb-separator", " > " } Link { @@ -62,7 +68,8 @@ pub fn Navbar() -> Element { } }, Route::EntryPage { ident, book_title, .. } => { - let handle = notebook_handle.as_ref().unwrap(); + let route_handle = route_handle.read().clone(); + let handle = route_handle.unwrap_or(ident.clone()); rsx! { span { class: "breadcrumb-separator", " > " } Link { @@ -81,50 +88,36 @@ pub fn Navbar() -> Element { _ => rsx! {} } } - LoginButton {} - - } - - Outlet:: {} - } -} - -#[component] -fn LoginButton() -> Element { - let fetcher = use_context::(); - let mut show_login_modal = use_signal(|| false); - let mut auth_state = use_context::>(); - let did_signal = use_signal(|| auth_state.read().did.clone()); - if let Some(did) = &*did_signal.read() { - rsx! { - Button { - variant: ButtonVariant::Ghost, - onclick: move |_| { - let fetcher = fetcher.clone(); - auth_state.write().clear(); - async move { - fetcher.downgrade_to_unauthenticated().await; + if auth_state.read().is_authenticated() { + if let Some(did) = &auth_state.read().did { + Button { + variant: ButtonVariant::Ghost, + onclick: move |_| { + let fetcher = fetcher.clone(); + auth_state.write().clear(); + async move { + fetcher.downgrade_to_unauthenticated().await; + } + }, + span { class: "auth-handle", "@{use_get_handle(did.clone())}" } } - }, - span { class: "auth-handle", "@{use_get_handle(did.clone())}" } - } - LoginModal { - open: show_login_modal - } - } - } else { - rsx! { - div { - class: "auth-button", - Button { - variant: ButtonVariant::Ghost, - onclick: move |_| show_login_modal.set(true), - span { class: "auth-handle", "Sign In" } } - } - LoginModal { - open: show_login_modal + } else { + div { + class: "auth-button", + Button { + variant: ButtonVariant::Ghost, + onclick: move |_| show_login_modal.set(true), + span { class: "auth-handle", "Sign In" } + } + + } + LoginModal { + open: show_login_modal + } } } + + Outlet:: {} } } diff --git a/crates/weaver-app/src/views/notebook.rs b/crates/weaver-app/src/views/notebook.rs index 23a45a0..566b77b 100644 --- a/crates/weaver-app/src/views/notebook.rs +++ b/crates/weaver-app/src/views/notebook.rs @@ -17,6 +17,11 @@ const ENTRY_CARD_CSS: Asset = asset!("/assets/styling/entry-card.css"); /// re-run and the rendered HTML will be updated. #[component] pub fn Notebook(ident: ReadSignal>, book_title: SmolStr) -> Element { + tracing::debug!( + "Notebook component rendering for ident: {:?}, book: {}", + ident(), + book_title + ); rsx! { NotebookCss { ident: ident.to_smolstr(), notebook: book_title } Outlet:: {} @@ -28,14 +33,16 @@ pub fn NotebookIndex( ident: ReadSignal>, book_title: ReadSignal, ) -> Element { + tracing::debug!( + "NotebookIndex component rendering for ident: {:?}, book: {}", + ident(), + book_title() + ); // Fetch full notebook metadata with SSR support // IMPORTANT: Call ALL hooks before any ? early returns to maintain hook order let notebook_data = data::use_notebook(ident, book_title); let entries_resource = data::use_notebook_entries(ident, book_title); - - // Now check for errors - let notebook_data = notebook_data?; - let entries_resource = entries_resource?; + tracing::debug!("NotebookIndex got notebook data and entries"); rsx! { document::Link { rel: "stylesheet", href: ENTRY_CARD_CSS } @@ -60,7 +67,8 @@ pub fn NotebookIndex( EntryCard { entry: entry.clone(), book_title: book_title(), - author_count + author_count, + ident: ident(), } } } diff --git a/crates/weaver-common/src/agent.rs b/crates/weaver-common/src/agent.rs index 90612af..90d8d77 100644 --- a/crates/weaver-common/src/agent.rs +++ b/crates/weaver-common/src/agent.rs @@ -614,71 +614,71 @@ pub trait WeaverExt: AgentSessionExt + XrpcExt { AgentError::from(ClientError::invalid_request("Invalid weaver profile URI")) }, )?; - let weaver_future = async { - if let Ok(weaver_record) = self.fetch_record(&weaver_uri).await { - // Convert blobs to CDN URLs - let avatar = weaver_record - .value - .avatar - .as_ref() - .map(|blob| { - let cid = blob.blob().cid(); - jacquard::types::string::Uri::new_owned(format!( - "https://cdn.bsky.app/img/avatar/plain/{}/{}@jpeg", - did, cid - )) - }) - .transpose() - .map_err(|_| { - AgentError::from(ClientError::invalid_request("Invalid avatar URI")) - })?; - let banner = weaver_record - .value - .banner - .as_ref() - .map(|blob| { - let cid = blob.blob().cid(); - jacquard::types::string::Uri::new_owned(format!( - "https://cdn.bsky.app/img/banner/plain/{}/{}@jpeg", - did, cid - )) - }) - .transpose() - .map_err(|_| { - AgentError::from(ClientError::invalid_request("Invalid banner URI")) - })?; - - let profile_view = ProfileView::new() - .did(did.clone()) - .handle(handle.clone()) - .maybe_display_name(weaver_record.value.display_name.clone()) - .maybe_description(weaver_record.value.description.clone()) - .maybe_avatar(avatar) - .maybe_banner(banner) - .maybe_bluesky(weaver_record.value.bluesky) - .maybe_tangled(weaver_record.value.tangled) - .maybe_streamplace(weaver_record.value.streamplace) - .maybe_location(weaver_record.value.location.clone()) - .maybe_links(weaver_record.value.links.clone()) - .maybe_pronouns(weaver_record.value.pronouns.clone()) - .maybe_pinned(weaver_record.value.pinned.clone()) - .indexed_at(jacquard::types::string::Datetime::now()) - .maybe_created_at(weaver_record.value.created_at) - .build(); - - Ok(( - Some(weaver_uri.as_uri().clone().into_static()), - ProfileDataView::new() - .inner(ProfileDataViewInner::ProfileView(Box::new(profile_view))) - .build() - .into_static(), - )) - } else { - Err(WeaverError::Agent( - ClientError::invalid_request("Invalid weaver profile URI").into(), - )) - } - }; + // let weaver_future = async { + // if let Ok(weaver_record) = self.fetch_record(&weaver_uri).await { + // // Convert blobs to CDN URLs + // let avatar = weaver_record + // .value + // .avatar + // .as_ref() + // .map(|blob| { + // let cid = blob.blob().cid(); + // jacquard::types::string::Uri::new_owned(format!( + // "https://cdn.bsky.app/img/avatar/plain/{}/{}@jpeg", + // did, cid + // )) + // }) + // .transpose() + // .map_err(|_| { + // AgentError::from(ClientError::invalid_request("Invalid avatar URI")) + // })?; + // let banner = weaver_record + // .value + // .banner + // .as_ref() + // .map(|blob| { + // let cid = blob.blob().cid(); + // jacquard::types::string::Uri::new_owned(format!( + // "https://cdn.bsky.app/img/banner/plain/{}/{}@jpeg", + // did, cid + // )) + // }) + // .transpose() + // .map_err(|_| { + // AgentError::from(ClientError::invalid_request("Invalid banner URI")) + // })?; + + // let profile_view = ProfileView::new() + // .did(did.clone()) + // .handle(handle.clone()) + // .maybe_display_name(weaver_record.value.display_name.clone()) + // .maybe_description(weaver_record.value.description.clone()) + // .maybe_avatar(avatar) + // .maybe_banner(banner) + // .maybe_bluesky(weaver_record.value.bluesky) + // .maybe_tangled(weaver_record.value.tangled) + // .maybe_streamplace(weaver_record.value.streamplace) + // .maybe_location(weaver_record.value.location.clone()) + // .maybe_links(weaver_record.value.links.clone()) + // .maybe_pronouns(weaver_record.value.pronouns.clone()) + // .maybe_pinned(weaver_record.value.pinned.clone()) + // .indexed_at(jacquard::types::string::Datetime::now()) + // .maybe_created_at(weaver_record.value.created_at) + // .build(); + + // Ok(( + // Some(weaver_uri.as_uri().clone().into_static()), + // ProfileDataView::new() + // .inner(ProfileDataViewInner::ProfileView(Box::new(profile_view))) + // .build() + // .into_static(), + // )) + // } else { + // Err(WeaverError::Agent( + // ClientError::invalid_request("Invalid weaver profile URI").into(), + // )) + // } + // }; let bsky_appview_future = async { if let Ok(bsky_resp) = self .send(GetProfile::new().actor(did.clone()).build()) @@ -718,67 +718,68 @@ pub trait WeaverExt: AgentSessionExt + XrpcExt { AgentError::from(ClientError::invalid_request("Invalid bsky profile URI")) })?; - let bsky_future = async { - let bsky_record = self.fetch_record(&bsky_uri).await?; - - let avatar = bsky_record - .value - .avatar - .as_ref() - .map(|blob| { - let cid = blob.blob().cid(); - jacquard::types::string::Uri::new_owned(format!( - "https://cdn.bsky.app/img/avatar/plain/{}/{}@jpeg", - did, cid - )) - }) - .transpose() - .map_err(|_| { - AgentError::from(ClientError::invalid_request("Invalid avatar URI")) - })?; - let banner = bsky_record - .value - .banner - .as_ref() - .map(|blob| { - let cid = blob.blob().cid(); - jacquard::types::string::Uri::new_owned(format!( - "https://cdn.bsky.app/img/banner/plain/{}/{}@jpeg", - did, cid - )) - }) - .transpose() - .map_err(|_| { - AgentError::from(ClientError::invalid_request("Invalid banner URI")) - })?; - - let profile_detailed = ProfileViewDetailed::new() - .did(did.clone()) - .handle(handle.clone()) - .maybe_display_name(bsky_record.value.display_name.clone()) - .maybe_description(bsky_record.value.description.clone()) - .maybe_avatar(avatar) - .maybe_banner(banner) - .indexed_at(jacquard::types::string::Datetime::now()) - .maybe_created_at(bsky_record.value.created_at) - .build(); - - Ok(( - Some(bsky_uri.as_uri().clone().into_static()), - ProfileDataView::new() - .inner(ProfileDataViewInner::ProfileViewDetailed(Box::new( - profile_detailed, - ))) - .build() - .into_static(), - )) - }; - - n0_future::future::or( - weaver_future, - n0_future::future::or(bsky_appview_future, bsky_future), - ) - .await + // let bsky_future = async { + // let bsky_record = self.fetch_record(&bsky_uri).await?; + + // let avatar = bsky_record + // .value + // .avatar + // .as_ref() + // .map(|blob| { + // let cid = blob.blob().cid(); + // jacquard::types::string::Uri::new_owned(format!( + // "https://cdn.bsky.app/img/avatar/plain/{}/{}@jpeg", + // did, cid + // )) + // }) + // .transpose() + // .map_err(|_| { + // AgentError::from(ClientError::invalid_request("Invalid avatar URI")) + // })?; + // let banner = bsky_record + // .value + // .banner + // .as_ref() + // .map(|blob| { + // let cid = blob.blob().cid(); + // jacquard::types::string::Uri::new_owned(format!( + // "https://cdn.bsky.app/img/banner/plain/{}/{}@jpeg", + // did, cid + // )) + // }) + // .transpose() + // .map_err(|_| { + // AgentError::from(ClientError::invalid_request("Invalid banner URI")) + // })?; + + // let profile_detailed = ProfileViewDetailed::new() + // .did(did.clone()) + // .handle(handle.clone()) + // .maybe_display_name(bsky_record.value.display_name.clone()) + // .maybe_description(bsky_record.value.description.clone()) + // .maybe_avatar(avatar) + // .maybe_banner(banner) + // .indexed_at(jacquard::types::string::Datetime::now()) + // .maybe_created_at(bsky_record.value.created_at) + // .build(); + + // Ok(( + // Some(bsky_uri.as_uri().clone().into_static()), + // ProfileDataView::new() + // .inner(ProfileDataViewInner::ProfileViewDetailed(Box::new( + // profile_detailed, + // ))) + // .build() + // .into_static(), + // )) + // }; + + // n0_future::future::or( + // weaver_future, + // n0_future::future::or(bsky_appview_future, bsky_future), + // ) + // .await + bsky_appview_future.await } } diff --git a/crates/weaver-renderer/src/atproto/client.rs b/crates/weaver-renderer/src/atproto/client.rs index 8dd661d..b1d0952 100644 --- a/crates/weaver-renderer/src/atproto/client.rs +++ b/crates/weaver-renderer/src/atproto/client.rs @@ -203,7 +203,6 @@ impl<'a, R: EmbedResolver> ClientContext<'a, R> { if let Some(embeds) = &entry.embeds { if let Some(images) = &embeds.images { for img in &images.images { - tracing::info!("Image: {:?}", img); if let Some(name) = &img.name { let blob_name = BlobName::from_filename(name.as_ref()); map.insert(blob_name, img.image.blob().cid().clone().into_static()); -- knotmirror 0.0.1