client-side works fully again

Orual ec7d916e 27f77851

+1256 -551
+652 -127
Cargo.lock
··· 1044 1045 [[package]] 1046 name = "const-serialize" 1047 version = "0.7.1" 1048 source = "registry+https://github.com/rust-lang/crates.io-index" 1049 checksum = "fd339aa356cc6452308fad2ee56623f900a8e68bc0ab9360a0ddb8270e5640c8" 1050 dependencies = [ 1051 - "const-serialize-macro", 1052 "serde", 1053 ] 1054 1055 [[package]] ··· 1112 1113 [[package]] 1114 name = "convert_case" 1115 version = "0.8.0" 1116 source = "registry+https://github.com/rust-lang/crates.io-index" 1117 checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" ··· 1403 1404 [[package]] 1405 name = "dashmap" 1406 version = "6.1.0" 1407 source = "registry+https://github.com/rust-lang/crates.io-index" 1408 checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" ··· 1627 1628 [[package]] 1629 name = "dioxus" 1630 version = "0.7.1" 1631 source = "registry+https://github.com/rust-lang/crates.io-index" 1632 checksum = "f76e820919058a685a1fdbb2ef4888c73ac77d623c39a7dfde2aa812947246be" 1633 dependencies = [ 1634 "dioxus-asset-resolver", 1635 - "dioxus-cli-config", 1636 - "dioxus-config-macro", 1637 "dioxus-config-macros", 1638 - "dioxus-core", 1639 - "dioxus-core-macro", 1640 "dioxus-desktop", 1641 - "dioxus-devtools", 1642 - "dioxus-document", 1643 - "dioxus-fullstack", 1644 "dioxus-fullstack-macro", 1645 - "dioxus-history", 1646 - "dioxus-hooks", 1647 - "dioxus-html", 1648 "dioxus-liveview", 1649 - "dioxus-logger", 1650 "dioxus-router", 1651 "dioxus-server", 1652 - "dioxus-signals", 1653 "dioxus-ssr", 1654 "dioxus-stores", 1655 - "dioxus-web", 1656 - "manganis", 1657 "serde", 1658 "subsecond", 1659 "warnings", ··· 1666 source = "registry+https://github.com/rust-lang/crates.io-index" 1667 checksum = "7f6a124667ce5565c39fe2f33af45c21fe459c5bfcf7a8074ad12c9e9da5817c" 1668 dependencies = [ 1669 - "dioxus-cli-config", 1670 "http", 1671 "infer", 1672 "jni", ··· 1683 1684 [[package]] 1685 name = "dioxus-cli-config" 1686 version = "0.7.1" 1687 source = "registry+https://github.com/rust-lang/crates.io-index" 1688 checksum = "babc8eaf90379352bc4820830749fd231feb9312433d4094b4e7b79d912b3d96" ··· 1692 1693 [[package]] 1694 name = "dioxus-config-macro" 1695 version = "0.7.1" 1696 source = "registry+https://github.com/rust-lang/crates.io-index" 1697 checksum = "30018b5b95567cee42febbb444d5e5e47dbe3e91fa6e44b9e571edad0184cd36" ··· 1708 1709 [[package]] 1710 name = "dioxus-core" 1711 version = "0.7.1" 1712 source = "registry+https://github.com/rust-lang/crates.io-index" 1713 checksum = "75468d08468919f783b0f7ee826802f4e8e66c5b5a0451245d861c211ca18216" 1714 dependencies = [ 1715 "anyhow", 1716 "const_format", 1717 - "dioxus-core-types", 1718 "futures-channel", 1719 "futures-util", 1720 - "generational-box", 1721 "longest-increasing-subsequence", 1722 "rustc-hash 2.1.1", 1723 "rustversion", ··· 1731 1732 [[package]] 1733 name = "dioxus-core-macro" 1734 version = "0.7.1" 1735 source = "registry+https://github.com/rust-lang/crates.io-index" 1736 checksum = "f145abdb2a3f858456cb4382390863cf0398c228ad0733618f48891da7687be3" 1737 dependencies = [ 1738 "convert_case 0.8.0", 1739 - "dioxus-rsx", 1740 "proc-macro2", 1741 "quote", 1742 "syn 2.0.110", ··· 1744 1745 [[package]] 1746 name = "dioxus-core-types" 1747 version = "0.7.1" 1748 source = "registry+https://github.com/rust-lang/crates.io-index" 1749 checksum = "36f5ecf5a51de06d78aded3b5f7516a258f53117cba718bc5706317a3c04c844" ··· 1760 "cocoa", 1761 "core-foundation 0.10.1", 1762 "dioxus-asset-resolver", 1763 - "dioxus-cli-config", 1764 - "dioxus-core", 1765 - "dioxus-devtools", 1766 - "dioxus-document", 1767 - "dioxus-history", 1768 - "dioxus-hooks", 1769 - "dioxus-html", 1770 - "dioxus-interpreter-js", 1771 - "dioxus-signals", 1772 "dunce", 1773 "futures-channel", 1774 "futures-util", 1775 - "generational-box", 1776 "global-hotkey", 1777 "infer", 1778 "jni", ··· 1805 1806 [[package]] 1807 name = "dioxus-devtools" 1808 version = "0.7.1" 1809 source = "registry+https://github.com/rust-lang/crates.io-index" 1810 checksum = "4eb2c5019b7fa72e8e6b21ba99e9263bd390c9a30bbf09793b72f4b57ed7c3d7" 1811 dependencies = [ 1812 - "dioxus-cli-config", 1813 - "dioxus-core", 1814 - "dioxus-devtools-types", 1815 - "dioxus-signals", 1816 "futures-channel", 1817 "futures-util", 1818 "serde", ··· 1822 "tracing", 1823 "tungstenite 0.27.0", 1824 "warnings", 1825 ] 1826 1827 [[package]] ··· 1830 source = "registry+https://github.com/rust-lang/crates.io-index" 1831 checksum = "7b007cec5b8548281921c4e4678926a3936e9d6757e951380685cc6121a6f974" 1832 dependencies = [ 1833 - "dioxus-core", 1834 "serde", 1835 "subsecond-types", 1836 ] 1837 1838 [[package]] 1839 name = "dioxus-document" 1840 version = "0.7.1" 1841 source = "registry+https://github.com/rust-lang/crates.io-index" 1842 checksum = "8c55bcae9aaf150d4a141c61b3826da5a7ac23dfff09726568525cd46336e9a2" 1843 dependencies = [ 1844 - "dioxus-core", 1845 - "dioxus-core-macro", 1846 - "dioxus-core-types", 1847 - "dioxus-html", 1848 "futures-channel", 1849 "futures-util", 1850 - "generational-box", 1851 "lazy-js-bundle 0.7.1", 1852 "serde", 1853 "serde_json", ··· 1855 ] 1856 1857 [[package]] 1858 name = "dioxus-fullstack" 1859 version = "0.7.1" 1860 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1874 "content_disposition", 1875 "derive_more 2.0.1", 1876 "dioxus-asset-resolver", 1877 - "dioxus-cli-config", 1878 - "dioxus-core", 1879 "dioxus-fullstack-core", 1880 "dioxus-fullstack-macro", 1881 - "dioxus-hooks", 1882 - "dioxus-html", 1883 - "dioxus-signals", 1884 "form_urlencoded", 1885 "futures", 1886 "futures-channel", ··· 1899 "send_wrapper", 1900 "serde", 1901 "serde_json", 1902 - "serde_qs", 1903 "serde_urlencoded", 1904 "thiserror 2.0.17", 1905 "tokio", ··· 1929 "axum-core", 1930 "base64 0.22.1", 1931 "ciborium", 1932 - "dioxus-core", 1933 - "dioxus-document", 1934 - "dioxus-history", 1935 - "dioxus-hooks", 1936 - "dioxus-signals", 1937 "futures-channel", 1938 "futures-util", 1939 - "generational-box", 1940 "http", 1941 "inventory", 1942 "parking_lot", ··· 1963 1964 [[package]] 1965 name = "dioxus-history" 1966 version = "0.7.1" 1967 source = "registry+https://github.com/rust-lang/crates.io-index" 1968 checksum = "dac73657da5c7a20629482d774b52f4a4f7cb57a520649f1d855d4073e809c98" 1969 dependencies = [ 1970 - "dioxus-core", 1971 "tracing", 1972 ] 1973 1974 [[package]] 1975 name = "dioxus-hooks" 1976 version = "0.7.1" 1977 source = "registry+https://github.com/rust-lang/crates.io-index" 1978 checksum = "7ffd445f16d64939e06cd71a1c63a665f383fda6b7882f4c6f8f1bd6efca2046" 1979 dependencies = [ 1980 - "dioxus-core", 1981 - "dioxus-signals", 1982 "futures-channel", 1983 "futures-util", 1984 - "generational-box", 1985 "rustversion", 1986 "slab", 1987 "tracing", ··· 1990 1991 [[package]] 1992 name = "dioxus-html" 1993 version = "0.7.1" 1994 source = "registry+https://github.com/rust-lang/crates.io-index" 1995 checksum = "9f407fc73a9554a644872fcccc9faf762acad8f45158e3d67e42ab8dd42f4586" 1996 dependencies = [ 1997 "async-trait", 1998 "bytes", 1999 - "dioxus-core", 2000 - "dioxus-core-macro", 2001 - "dioxus-core-types", 2002 - "dioxus-hooks", 2003 - "dioxus-html-internal-macro", 2004 "enumset", 2005 "euclid", 2006 "futures-channel", 2007 "futures-util", 2008 - "generational-box", 2009 "keyboard-types", 2010 "lazy-js-bundle 0.7.1", 2011 "rustversion", ··· 2017 2018 [[package]] 2019 name = "dioxus-html-internal-macro" 2020 version = "0.7.1" 2021 source = "registry+https://github.com/rust-lang/crates.io-index" 2022 checksum = "a968aae4bc92de87cbac3d0d043803b25a7c62c187841e61adcc9b49917c2b2a" ··· 2029 2030 [[package]] 2031 name = "dioxus-interpreter-js" 2032 version = "0.7.1" 2033 source = "registry+https://github.com/rust-lang/crates.io-index" 2034 checksum = "83ab170d89308399205f8ad3d43d8d419affe317016b41ca0695186f7593cba2" 2035 dependencies = [ 2036 - "dioxus-core", 2037 - "dioxus-core-types", 2038 - "dioxus-html", 2039 "js-sys", 2040 "lazy-js-bundle 0.7.1", 2041 "rustc-hash 2.1.1", ··· 2048 ] 2049 2050 [[package]] 2051 name = "dioxus-liveview" 2052 version = "0.7.1" 2053 source = "registry+https://github.com/rust-lang/crates.io-index" 2054 checksum = "ca4f2850ec1a468c6f15b578c43218562d2309aadaf2b8bf17f54ce30e72f594" 2055 dependencies = [ 2056 "axum", 2057 - "dioxus-cli-config", 2058 - "dioxus-core", 2059 - "dioxus-devtools", 2060 - "dioxus-document", 2061 - "dioxus-history", 2062 - "dioxus-html", 2063 - "dioxus-interpreter-js", 2064 "futures-channel", 2065 "futures-util", 2066 - "generational-box", 2067 "rustc-hash 2.1.1", 2068 "serde", 2069 "serde_json", ··· 2077 2078 [[package]] 2079 name = "dioxus-logger" 2080 version = "0.7.1" 2081 source = "registry+https://github.com/rust-lang/crates.io-index" 2082 checksum = "42237934c6a67f5ed9a8c37e47ca980ee7cfec9e783a9a1f8c2e36c8b96ae74b" 2083 dependencies = [ 2084 - "dioxus-cli-config", 2085 "tracing", 2086 "tracing-subscriber", 2087 "tracing-wasm", ··· 2092 version = "0.0.1" 2093 source = "git+https://github.com/DioxusLabs/components#a15f329d1dc2bd76cd4030b27ecd70edb9fd8c6b" 2094 dependencies = [ 2095 - "dioxus", 2096 "dioxus-time", 2097 "lazy-js-bundle 0.6.2", 2098 "num-integer", ··· 2106 source = "registry+https://github.com/rust-lang/crates.io-index" 2107 checksum = "fdf1b95b7cafd07a2b39651ab2b146e4aa72acb0295cd52f422b7db5e2ab6eeb" 2108 dependencies = [ 2109 - "dioxus-cli-config", 2110 - "dioxus-core", 2111 - "dioxus-core-macro", 2112 "dioxus-fullstack-core", 2113 - "dioxus-history", 2114 - "dioxus-hooks", 2115 - "dioxus-html", 2116 "dioxus-router-macro", 2117 - "dioxus-signals", 2118 "percent-encoding", 2119 "rustversion", 2120 "tracing", ··· 2138 2139 [[package]] 2140 name = "dioxus-rsx" 2141 version = "0.7.1" 2142 source = "registry+https://github.com/rust-lang/crates.io-index" 2143 checksum = "f026380dfda8b93ad995c0a90a62a17b8afeb246baff1b781a52c7b1b3ebd791" ··· 2161 "bytes", 2162 "chrono", 2163 "ciborium", 2164 - "dashmap", 2165 - "dioxus-cli-config", 2166 - "dioxus-core", 2167 - "dioxus-core-macro", 2168 - "dioxus-devtools", 2169 - "dioxus-document", 2170 "dioxus-fullstack-core", 2171 - "dioxus-history", 2172 - "dioxus-hooks", 2173 - "dioxus-html", 2174 - "dioxus-interpreter-js", 2175 - "dioxus-logger", 2176 "dioxus-router", 2177 - "dioxus-signals", 2178 "dioxus-ssr", 2179 "enumset", 2180 "futures", 2181 "futures-channel", 2182 "futures-util", 2183 - "generational-box", 2184 "http", 2185 "http-body-util", 2186 "hyper", ··· 2192 "rustc-hash 2.1.1", 2193 "serde", 2194 "serde_json", 2195 - "serde_qs", 2196 "subsecond", 2197 "thiserror 2.0.17", 2198 "tokio", ··· 2208 2209 [[package]] 2210 name = "dioxus-signals" 2211 version = "0.7.1" 2212 source = "registry+https://github.com/rust-lang/crates.io-index" 2213 checksum = "3895cc17ff5b43ada07743111be586e7a927ed7ec511457020e4235e13e63fe6" 2214 dependencies = [ 2215 - "dioxus-core", 2216 "futures-channel", 2217 "futures-util", 2218 - "generational-box", 2219 "parking_lot", 2220 "rustc-hash 2.1.1", 2221 "tracing", ··· 2229 checksum = "592391fc30a77f94bc5a3385d1569052907e3b3cecb28099671b9d5801dee6c6" 2230 dependencies = [ 2231 "askama_escape", 2232 - "dioxus-core", 2233 - "dioxus-core-types", 2234 "rustc-hash 2.1.1", 2235 ] 2236 ··· 2240 source = "registry+https://github.com/rust-lang/crates.io-index" 2241 checksum = "8521729ac35f362476ac4eb7d1c4ab79e7e92a0facfdea3ee978c0ddf7108d37" 2242 dependencies = [ 2243 - "dioxus-core", 2244 - "dioxus-signals", 2245 "dioxus-stores-macro", 2246 ] 2247 ··· 2262 version = "0.7.0" 2263 source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#8c868ac1d60e3232e3f16f6195d6deb3c016de17" 2264 dependencies = [ 2265 - "dioxus", 2266 "futures", 2267 "gloo-timers", 2268 "tokio", ··· 2283 2284 [[package]] 2285 name = "dioxus-web" 2286 version = "0.7.1" 2287 source = "registry+https://github.com/rust-lang/crates.io-index" 2288 checksum = "76155ecd44535e7c096ec8c5aac4a945899e47567ead4869babdaa74f3f9bca0" 2289 dependencies = [ 2290 - "dioxus-cli-config", 2291 - "dioxus-core", 2292 - "dioxus-core-types", 2293 - "dioxus-devtools", 2294 - "dioxus-document", 2295 "dioxus-fullstack-core", 2296 - "dioxus-history", 2297 - "dioxus-html", 2298 - "dioxus-interpreter-js", 2299 - "dioxus-signals", 2300 "futures-channel", 2301 "futures-util", 2302 - "generational-box", 2303 "gloo-timers", 2304 "js-sys", 2305 "lazy-js-bundle 0.7.1", ··· 2313 "wasm-bindgen-futures", 2314 "wasm-streams", 2315 "web-sys", 2316 ] 2317 2318 [[package]] ··· 3061 3062 [[package]] 3063 name = "generational-box" 3064 version = "0.7.1" 3065 source = "registry+https://github.com/rust-lang/crates.io-index" 3066 checksum = "b3c1ae09dfd2d455484a54b56129b9821241c4b0e412227806b6c3730cd18a29" ··· 4219 version = "0.9.2" 4220 dependencies = [ 4221 "cid", 4222 - "dashmap", 4223 "heck 0.5.0", 4224 "inventory", 4225 "jacquard-common", ··· 4246 "base64 0.22.1", 4247 "bytes", 4248 "chrono", 4249 - "dashmap", 4250 "elliptic-curve", 4251 "http", 4252 "jacquard-common", ··· 4698 4699 [[package]] 4700 name = "manganis" 4701 version = "0.7.1" 4702 source = "registry+https://github.com/rust-lang/crates.io-index" 4703 checksum = "124f8f094eb75783b38209ce4d534b9617da4efac652802d9bafe05043a3ec95" 4704 dependencies = [ 4705 - "const-serialize", 4706 - "manganis-core", 4707 - "manganis-macro", 4708 ] 4709 4710 [[package]] ··· 4713 source = "registry+https://github.com/rust-lang/crates.io-index" 4714 checksum = "41fbd1fb8c5aabcc54c6b02dbc968e1c89c28f3e543f2789ef9e3ce45dbdf5df" 4715 dependencies = [ 4716 - "const-serialize", 4717 - "dioxus-cli-config", 4718 - "dioxus-core-types", 4719 "serde", 4720 ] 4721 4722 [[package]] 4723 name = "manganis-macro" 4724 version = "0.7.1" 4725 source = "registry+https://github.com/rust-lang/crates.io-index" 4726 checksum = "45d6fec2a8249739bb30b53a08ecbb217f76096c08f1053f38ec3981ba424c11" 4727 dependencies = [ 4728 "dunce", 4729 "macro-string", 4730 - "manganis-core", 4731 "proc-macro2", 4732 "quote", 4733 "syn 2.0.110", ··· 4983 dependencies = [ 4984 "crossbeam-channel", 4985 "crossbeam-utils", 4986 - "dashmap", 4987 "smallvec", 4988 "tagptr", 4989 "triomphe", ··· 4997 dependencies = [ 4998 "crossbeam-channel", 4999 "crossbeam-utils", 5000 - "dashmap", 5001 "smallvec", 5002 "tagptr", 5003 "triomphe", ··· 6841 6842 [[package]] 6843 name = "serde-wasm-bindgen" 6844 version = "0.6.5" 6845 source = "registry+https://github.com/rust-lang/crates.io-index" 6846 checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" ··· 6928 "itoa", 6929 "serde", 6930 "serde_core", 6931 ] 6932 6933 [[package]] ··· 7021 dependencies = [ 7022 "base16ct", 7023 "serde", 7024 ] 7025 7026 [[package]] ··· 8398 8399 [[package]] 8400 name = "tungstenite" 8401 version = "0.24.0" 8402 source = "registry+https://github.com/rust-lang/crates.io-index" 8403 checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" ··· 8896 "base64 0.22.1", 8897 "chrono", 8898 "console_error_panic_hook", 8899 - "dashmap", 8900 - "dioxus", 8901 "dioxus-primitives", 8902 "dotenvy", 8903 "gloo-storage", ··· 8990 "axum", 8991 "chrono", 8992 "clap", 8993 - "dashmap", 8994 "diesel", 8995 "diesel-async", 8996 "diesel_migrations", ··· 9035 version = "0.1.0" 9036 dependencies = [ 9037 "bitflags 2.10.0", 9038 - "dashmap", 9039 "http", 9040 "ignore", 9041 "insta",
··· 1044 1045 [[package]] 1046 name = "const-serialize" 1047 + version = "0.6.2" 1048 + source = "registry+https://github.com/rust-lang/crates.io-index" 1049 + checksum = "08259976d62c715c4826cb4a3d64a3a9e5c5f68f964ff6087319857f569f93a6" 1050 + dependencies = [ 1051 + "const-serialize-macro 0.6.2", 1052 + "serde", 1053 + ] 1054 + 1055 + [[package]] 1056 + name = "const-serialize" 1057 version = "0.7.1" 1058 source = "registry+https://github.com/rust-lang/crates.io-index" 1059 checksum = "fd339aa356cc6452308fad2ee56623f900a8e68bc0ab9360a0ddb8270e5640c8" 1060 dependencies = [ 1061 + "const-serialize-macro 0.7.1", 1062 "serde", 1063 + ] 1064 + 1065 + [[package]] 1066 + name = "const-serialize-macro" 1067 + version = "0.6.2" 1068 + source = "registry+https://github.com/rust-lang/crates.io-index" 1069 + checksum = "04382d0d9df7434af6b1b49ea1a026ef39df1b0738b1cc373368cf175354f6eb" 1070 + dependencies = [ 1071 + "proc-macro2", 1072 + "quote", 1073 + "syn 2.0.110", 1074 ] 1075 1076 [[package]] ··· 1133 1134 [[package]] 1135 name = "convert_case" 1136 + version = "0.6.0" 1137 + source = "registry+https://github.com/rust-lang/crates.io-index" 1138 + checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" 1139 + dependencies = [ 1140 + "unicode-segmentation", 1141 + ] 1142 + 1143 + [[package]] 1144 + name = "convert_case" 1145 version = "0.8.0" 1146 source = "registry+https://github.com/rust-lang/crates.io-index" 1147 checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" ··· 1433 1434 [[package]] 1435 name = "dashmap" 1436 + version = "5.5.3" 1437 + source = "registry+https://github.com/rust-lang/crates.io-index" 1438 + checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" 1439 + dependencies = [ 1440 + "cfg-if", 1441 + "hashbrown 0.14.5", 1442 + "lock_api", 1443 + "once_cell", 1444 + "parking_lot_core", 1445 + ] 1446 + 1447 + [[package]] 1448 + name = "dashmap" 1449 version = "6.1.0" 1450 source = "registry+https://github.com/rust-lang/crates.io-index" 1451 checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" ··· 1670 1671 [[package]] 1672 name = "dioxus" 1673 + version = "0.6.3" 1674 + source = "registry+https://github.com/rust-lang/crates.io-index" 1675 + checksum = "60a247114500f1a78e87022defa8173de847accfada8e8809dfae23a118a580c" 1676 + dependencies = [ 1677 + "dioxus-cli-config 0.6.3", 1678 + "dioxus-config-macro 0.6.2", 1679 + "dioxus-core 0.6.3", 1680 + "dioxus-core-macro 0.6.3", 1681 + "dioxus-devtools 0.6.2", 1682 + "dioxus-document 0.6.3", 1683 + "dioxus-fullstack 0.6.3", 1684 + "dioxus-history 0.6.2", 1685 + "dioxus-hooks 0.6.2", 1686 + "dioxus-html 0.6.3", 1687 + "dioxus-logger 0.6.2", 1688 + "dioxus-signals 0.6.3", 1689 + "dioxus-web 0.6.3", 1690 + "manganis 0.6.2", 1691 + "warnings", 1692 + ] 1693 + 1694 + [[package]] 1695 + name = "dioxus" 1696 version = "0.7.1" 1697 source = "registry+https://github.com/rust-lang/crates.io-index" 1698 checksum = "f76e820919058a685a1fdbb2ef4888c73ac77d623c39a7dfde2aa812947246be" 1699 dependencies = [ 1700 "dioxus-asset-resolver", 1701 + "dioxus-cli-config 0.7.1", 1702 + "dioxus-config-macro 0.7.1", 1703 "dioxus-config-macros", 1704 + "dioxus-core 0.7.1", 1705 + "dioxus-core-macro 0.7.1", 1706 "dioxus-desktop", 1707 + "dioxus-devtools 0.7.1", 1708 + "dioxus-document 0.7.1", 1709 + "dioxus-fullstack 0.7.1", 1710 "dioxus-fullstack-macro", 1711 + "dioxus-history 0.7.1", 1712 + "dioxus-hooks 0.7.1", 1713 + "dioxus-html 0.7.1", 1714 "dioxus-liveview", 1715 + "dioxus-logger 0.7.1", 1716 "dioxus-router", 1717 "dioxus-server", 1718 + "dioxus-signals 0.7.1", 1719 "dioxus-ssr", 1720 "dioxus-stores", 1721 + "dioxus-web 0.7.1", 1722 + "manganis 0.7.1", 1723 "serde", 1724 "subsecond", 1725 "warnings", ··· 1732 source = "registry+https://github.com/rust-lang/crates.io-index" 1733 checksum = "7f6a124667ce5565c39fe2f33af45c21fe459c5bfcf7a8074ad12c9e9da5817c" 1734 dependencies = [ 1735 + "dioxus-cli-config 0.7.1", 1736 "http", 1737 "infer", 1738 "jni", ··· 1749 1750 [[package]] 1751 name = "dioxus-cli-config" 1752 + version = "0.6.3" 1753 + source = "registry+https://github.com/rust-lang/crates.io-index" 1754 + checksum = "cdd16948f1ffdb068dd9a64812158073a4250e2af4e98ea31fdac0312e6bce86" 1755 + dependencies = [ 1756 + "wasm-bindgen", 1757 + ] 1758 + 1759 + [[package]] 1760 + name = "dioxus-cli-config" 1761 version = "0.7.1" 1762 source = "registry+https://github.com/rust-lang/crates.io-index" 1763 checksum = "babc8eaf90379352bc4820830749fd231feb9312433d4094b4e7b79d912b3d96" ··· 1767 1768 [[package]] 1769 name = "dioxus-config-macro" 1770 + version = "0.6.2" 1771 + source = "registry+https://github.com/rust-lang/crates.io-index" 1772 + checksum = "75cbf582fbb1c32d34a1042ea675469065574109c95154468710a4d73ee98b49" 1773 + dependencies = [ 1774 + "proc-macro2", 1775 + "quote", 1776 + ] 1777 + 1778 + [[package]] 1779 + name = "dioxus-config-macro" 1780 version = "0.7.1" 1781 source = "registry+https://github.com/rust-lang/crates.io-index" 1782 checksum = "30018b5b95567cee42febbb444d5e5e47dbe3e91fa6e44b9e571edad0184cd36" ··· 1793 1794 [[package]] 1795 name = "dioxus-core" 1796 + version = "0.6.3" 1797 + source = "registry+https://github.com/rust-lang/crates.io-index" 1798 + checksum = "9c03f451a119e47433c16e2d8eb5b15bf7d6e6734eb1a4c47574e6711dadff8d" 1799 + dependencies = [ 1800 + "const_format", 1801 + "dioxus-core-types 0.6.2", 1802 + "futures-channel", 1803 + "futures-util", 1804 + "generational-box 0.6.2", 1805 + "longest-increasing-subsequence", 1806 + "rustc-hash 1.1.0", 1807 + "rustversion", 1808 + "serde", 1809 + "slab", 1810 + "slotmap", 1811 + "tracing", 1812 + "warnings", 1813 + ] 1814 + 1815 + [[package]] 1816 + name = "dioxus-core" 1817 version = "0.7.1" 1818 source = "registry+https://github.com/rust-lang/crates.io-index" 1819 checksum = "75468d08468919f783b0f7ee826802f4e8e66c5b5a0451245d861c211ca18216" 1820 dependencies = [ 1821 "anyhow", 1822 "const_format", 1823 + "dioxus-core-types 0.7.1", 1824 "futures-channel", 1825 "futures-util", 1826 + "generational-box 0.7.1", 1827 "longest-increasing-subsequence", 1828 "rustc-hash 2.1.1", 1829 "rustversion", ··· 1837 1838 [[package]] 1839 name = "dioxus-core-macro" 1840 + version = "0.6.3" 1841 + source = "registry+https://github.com/rust-lang/crates.io-index" 1842 + checksum = "105c954caaaedf8cd10f3d1ba576b01e18aa8d33ad435182125eefe488cf0064" 1843 + dependencies = [ 1844 + "convert_case 0.6.0", 1845 + "dioxus-rsx 0.6.2", 1846 + "proc-macro2", 1847 + "quote", 1848 + "syn 2.0.110", 1849 + ] 1850 + 1851 + [[package]] 1852 + name = "dioxus-core-macro" 1853 version = "0.7.1" 1854 source = "registry+https://github.com/rust-lang/crates.io-index" 1855 checksum = "f145abdb2a3f858456cb4382390863cf0398c228ad0733618f48891da7687be3" 1856 dependencies = [ 1857 "convert_case 0.8.0", 1858 + "dioxus-rsx 0.7.1", 1859 "proc-macro2", 1860 "quote", 1861 "syn 2.0.110", ··· 1863 1864 [[package]] 1865 name = "dioxus-core-types" 1866 + version = "0.6.2" 1867 + source = "registry+https://github.com/rust-lang/crates.io-index" 1868 + checksum = "91a82fccfa48574eb7aa183e297769540904694844598433a9eb55896ad9f93b" 1869 + dependencies = [ 1870 + "once_cell", 1871 + ] 1872 + 1873 + [[package]] 1874 + name = "dioxus-core-types" 1875 version = "0.7.1" 1876 source = "registry+https://github.com/rust-lang/crates.io-index" 1877 checksum = "36f5ecf5a51de06d78aded3b5f7516a258f53117cba718bc5706317a3c04c844" ··· 1888 "cocoa", 1889 "core-foundation 0.10.1", 1890 "dioxus-asset-resolver", 1891 + "dioxus-cli-config 0.7.1", 1892 + "dioxus-core 0.7.1", 1893 + "dioxus-devtools 0.7.1", 1894 + "dioxus-document 0.7.1", 1895 + "dioxus-history 0.7.1", 1896 + "dioxus-hooks 0.7.1", 1897 + "dioxus-html 0.7.1", 1898 + "dioxus-interpreter-js 0.7.1", 1899 + "dioxus-signals 0.7.1", 1900 "dunce", 1901 "futures-channel", 1902 "futures-util", 1903 + "generational-box 0.7.1", 1904 "global-hotkey", 1905 "infer", 1906 "jni", ··· 1933 1934 [[package]] 1935 name = "dioxus-devtools" 1936 + version = "0.6.2" 1937 + source = "registry+https://github.com/rust-lang/crates.io-index" 1938 + checksum = "712a7300f1e8181218187b03502044157eef04e0a25b518117c5ef9ae1096880" 1939 + dependencies = [ 1940 + "dioxus-core 0.6.3", 1941 + "dioxus-devtools-types 0.6.2", 1942 + "dioxus-signals 0.6.3", 1943 + "serde", 1944 + "serde_json", 1945 + "tracing", 1946 + "tungstenite 0.23.0", 1947 + "warnings", 1948 + ] 1949 + 1950 + [[package]] 1951 + name = "dioxus-devtools" 1952 version = "0.7.1" 1953 source = "registry+https://github.com/rust-lang/crates.io-index" 1954 checksum = "4eb2c5019b7fa72e8e6b21ba99e9263bd390c9a30bbf09793b72f4b57ed7c3d7" 1955 dependencies = [ 1956 + "dioxus-cli-config 0.7.1", 1957 + "dioxus-core 0.7.1", 1958 + "dioxus-devtools-types 0.7.1", 1959 + "dioxus-signals 0.7.1", 1960 "futures-channel", 1961 "futures-util", 1962 "serde", ··· 1966 "tracing", 1967 "tungstenite 0.27.0", 1968 "warnings", 1969 + ] 1970 + 1971 + [[package]] 1972 + name = "dioxus-devtools-types" 1973 + version = "0.6.2" 1974 + source = "registry+https://github.com/rust-lang/crates.io-index" 1975 + checksum = "f62434973c0c9c5a3bc42e9cd5e7070401c2062a437fb5528f318c3e42ebf4ff" 1976 + dependencies = [ 1977 + "dioxus-core 0.6.3", 1978 + "serde", 1979 ] 1980 1981 [[package]] ··· 1984 source = "registry+https://github.com/rust-lang/crates.io-index" 1985 checksum = "7b007cec5b8548281921c4e4678926a3936e9d6757e951380685cc6121a6f974" 1986 dependencies = [ 1987 + "dioxus-core 0.7.1", 1988 "serde", 1989 "subsecond-types", 1990 ] 1991 1992 [[package]] 1993 name = "dioxus-document" 1994 + version = "0.6.3" 1995 + source = "registry+https://github.com/rust-lang/crates.io-index" 1996 + checksum = "802a2014d1662b6615eec0a275745822ee4fc66aacd9d0f2fb33d6c8da79b8f2" 1997 + dependencies = [ 1998 + "dioxus-core 0.6.3", 1999 + "dioxus-core-macro 0.6.3", 2000 + "dioxus-core-types 0.6.2", 2001 + "dioxus-html 0.6.3", 2002 + "futures-channel", 2003 + "futures-util", 2004 + "generational-box 0.6.2", 2005 + "lazy-js-bundle 0.6.2", 2006 + "serde", 2007 + "serde_json", 2008 + "tracing", 2009 + ] 2010 + 2011 + [[package]] 2012 + name = "dioxus-document" 2013 version = "0.7.1" 2014 source = "registry+https://github.com/rust-lang/crates.io-index" 2015 checksum = "8c55bcae9aaf150d4a141c61b3826da5a7ac23dfff09726568525cd46336e9a2" 2016 dependencies = [ 2017 + "dioxus-core 0.7.1", 2018 + "dioxus-core-macro 0.7.1", 2019 + "dioxus-core-types 0.7.1", 2020 + "dioxus-html 0.7.1", 2021 "futures-channel", 2022 "futures-util", 2023 + "generational-box 0.7.1", 2024 "lazy-js-bundle 0.7.1", 2025 "serde", 2026 "serde_json", ··· 2028 ] 2029 2030 [[package]] 2031 + name = "dioxus-free-icons" 2032 + version = "0.9.0" 2033 + source = "registry+https://github.com/rust-lang/crates.io-index" 2034 + checksum = "cd226c24168bb63d12d69cc0e7a6d73faa970574445c8e79c29965892f1a2ad8" 2035 + dependencies = [ 2036 + "dioxus 0.6.3", 2037 + ] 2038 + 2039 + [[package]] 2040 + name = "dioxus-fullstack" 2041 + version = "0.6.3" 2042 + source = "registry+https://github.com/rust-lang/crates.io-index" 2043 + checksum = "fe99b48a1348eec385b5c4bd3e80fd863b0d3b47257d34e2ddc58754dec5d128" 2044 + dependencies = [ 2045 + "base64 0.22.1", 2046 + "bytes", 2047 + "ciborium", 2048 + "dioxus-devtools 0.6.2", 2049 + "dioxus-history 0.6.2", 2050 + "dioxus-lib", 2051 + "dioxus-web 0.6.3", 2052 + "dioxus_server_macro", 2053 + "futures-channel", 2054 + "futures-util", 2055 + "generational-box 0.6.2", 2056 + "once_cell", 2057 + "serde", 2058 + "server_fn", 2059 + "tracing", 2060 + ] 2061 + 2062 + [[package]] 2063 name = "dioxus-fullstack" 2064 version = "0.7.1" 2065 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2079 "content_disposition", 2080 "derive_more 2.0.1", 2081 "dioxus-asset-resolver", 2082 + "dioxus-cli-config 0.7.1", 2083 + "dioxus-core 0.7.1", 2084 "dioxus-fullstack-core", 2085 "dioxus-fullstack-macro", 2086 + "dioxus-hooks 0.7.1", 2087 + "dioxus-html 0.7.1", 2088 + "dioxus-signals 0.7.1", 2089 "form_urlencoded", 2090 "futures", 2091 "futures-channel", ··· 2104 "send_wrapper", 2105 "serde", 2106 "serde_json", 2107 + "serde_qs 0.15.0", 2108 "serde_urlencoded", 2109 "thiserror 2.0.17", 2110 "tokio", ··· 2134 "axum-core", 2135 "base64 0.22.1", 2136 "ciborium", 2137 + "dioxus-core 0.7.1", 2138 + "dioxus-document 0.7.1", 2139 + "dioxus-history 0.7.1", 2140 + "dioxus-hooks 0.7.1", 2141 + "dioxus-signals 0.7.1", 2142 "futures-channel", 2143 "futures-util", 2144 + "generational-box 0.7.1", 2145 "http", 2146 "inventory", 2147 "parking_lot", ··· 2168 2169 [[package]] 2170 name = "dioxus-history" 2171 + version = "0.6.2" 2172 + source = "registry+https://github.com/rust-lang/crates.io-index" 2173 + checksum = "5ae4e22616c698f35b60727313134955d885de2d32e83689258e586ebc9b7909" 2174 + dependencies = [ 2175 + "dioxus-core 0.6.3", 2176 + "tracing", 2177 + ] 2178 + 2179 + [[package]] 2180 + name = "dioxus-history" 2181 version = "0.7.1" 2182 source = "registry+https://github.com/rust-lang/crates.io-index" 2183 checksum = "dac73657da5c7a20629482d774b52f4a4f7cb57a520649f1d855d4073e809c98" 2184 dependencies = [ 2185 + "dioxus-core 0.7.1", 2186 "tracing", 2187 ] 2188 2189 [[package]] 2190 name = "dioxus-hooks" 2191 + version = "0.6.2" 2192 + source = "registry+https://github.com/rust-lang/crates.io-index" 2193 + checksum = "948e2b3f20d9d4b2c300aaa60281b1755f3298684448920b27106da5841896d0" 2194 + dependencies = [ 2195 + "dioxus-core 0.6.3", 2196 + "dioxus-signals 0.6.3", 2197 + "futures-channel", 2198 + "futures-util", 2199 + "generational-box 0.6.2", 2200 + "rustversion", 2201 + "slab", 2202 + "tracing", 2203 + "warnings", 2204 + ] 2205 + 2206 + [[package]] 2207 + name = "dioxus-hooks" 2208 version = "0.7.1" 2209 source = "registry+https://github.com/rust-lang/crates.io-index" 2210 checksum = "7ffd445f16d64939e06cd71a1c63a665f383fda6b7882f4c6f8f1bd6efca2046" 2211 dependencies = [ 2212 + "dioxus-core 0.7.1", 2213 + "dioxus-signals 0.7.1", 2214 "futures-channel", 2215 "futures-util", 2216 + "generational-box 0.7.1", 2217 "rustversion", 2218 "slab", 2219 "tracing", ··· 2222 2223 [[package]] 2224 name = "dioxus-html" 2225 + version = "0.6.3" 2226 + source = "registry+https://github.com/rust-lang/crates.io-index" 2227 + checksum = "59c9a40e6fee20ce7990095492dedb6a753eebe05e67d28271a249de74dc796d" 2228 + dependencies = [ 2229 + "async-trait", 2230 + "dioxus-core 0.6.3", 2231 + "dioxus-core-macro 0.6.3", 2232 + "dioxus-core-types 0.6.2", 2233 + "dioxus-hooks 0.6.2", 2234 + "dioxus-html-internal-macro 0.6.2", 2235 + "enumset", 2236 + "euclid", 2237 + "futures-channel", 2238 + "generational-box 0.6.2", 2239 + "keyboard-types", 2240 + "lazy-js-bundle 0.6.2", 2241 + "rustversion", 2242 + "tracing", 2243 + ] 2244 + 2245 + [[package]] 2246 + name = "dioxus-html" 2247 version = "0.7.1" 2248 source = "registry+https://github.com/rust-lang/crates.io-index" 2249 checksum = "9f407fc73a9554a644872fcccc9faf762acad8f45158e3d67e42ab8dd42f4586" 2250 dependencies = [ 2251 "async-trait", 2252 "bytes", 2253 + "dioxus-core 0.7.1", 2254 + "dioxus-core-macro 0.7.1", 2255 + "dioxus-core-types 0.7.1", 2256 + "dioxus-hooks 0.7.1", 2257 + "dioxus-html-internal-macro 0.7.1", 2258 "enumset", 2259 "euclid", 2260 "futures-channel", 2261 "futures-util", 2262 + "generational-box 0.7.1", 2263 "keyboard-types", 2264 "lazy-js-bundle 0.7.1", 2265 "rustversion", ··· 2271 2272 [[package]] 2273 name = "dioxus-html-internal-macro" 2274 + version = "0.6.2" 2275 + source = "registry+https://github.com/rust-lang/crates.io-index" 2276 + checksum = "43ba87b53688a2c9f619ecdf4b3b955bc1f08bd0570a80a0d626c405f6d14a76" 2277 + dependencies = [ 2278 + "convert_case 0.6.0", 2279 + "proc-macro2", 2280 + "quote", 2281 + "syn 2.0.110", 2282 + ] 2283 + 2284 + [[package]] 2285 + name = "dioxus-html-internal-macro" 2286 version = "0.7.1" 2287 source = "registry+https://github.com/rust-lang/crates.io-index" 2288 checksum = "a968aae4bc92de87cbac3d0d043803b25a7c62c187841e61adcc9b49917c2b2a" ··· 2295 2296 [[package]] 2297 name = "dioxus-interpreter-js" 2298 + version = "0.6.2" 2299 + source = "registry+https://github.com/rust-lang/crates.io-index" 2300 + checksum = "330707b10ca75cb0eb05f9e5f8d80217cd0d7e62116a8277ae363c1a09b57a22" 2301 + dependencies = [ 2302 + "js-sys", 2303 + "lazy-js-bundle 0.6.2", 2304 + "rustc-hash 1.1.0", 2305 + "sledgehammer_bindgen", 2306 + "sledgehammer_utils", 2307 + "wasm-bindgen", 2308 + "wasm-bindgen-futures", 2309 + "web-sys", 2310 + ] 2311 + 2312 + [[package]] 2313 + name = "dioxus-interpreter-js" 2314 version = "0.7.1" 2315 source = "registry+https://github.com/rust-lang/crates.io-index" 2316 checksum = "83ab170d89308399205f8ad3d43d8d419affe317016b41ca0695186f7593cba2" 2317 dependencies = [ 2318 + "dioxus-core 0.7.1", 2319 + "dioxus-core-types 0.7.1", 2320 + "dioxus-html 0.7.1", 2321 "js-sys", 2322 "lazy-js-bundle 0.7.1", 2323 "rustc-hash 2.1.1", ··· 2330 ] 2331 2332 [[package]] 2333 + name = "dioxus-lib" 2334 + version = "0.6.2" 2335 + source = "registry+https://github.com/rust-lang/crates.io-index" 2336 + checksum = "5405b71aa9b8b0c3e0d22728f12f34217ca5277792bd315878cc6ecab7301b72" 2337 + dependencies = [ 2338 + "dioxus-config-macro 0.6.2", 2339 + "dioxus-core 0.6.3", 2340 + "dioxus-core-macro 0.6.3", 2341 + "dioxus-document 0.6.3", 2342 + "dioxus-history 0.6.2", 2343 + "dioxus-hooks 0.6.2", 2344 + "dioxus-html 0.6.3", 2345 + "dioxus-rsx 0.6.2", 2346 + "dioxus-signals 0.6.3", 2347 + "warnings", 2348 + ] 2349 + 2350 + [[package]] 2351 name = "dioxus-liveview" 2352 version = "0.7.1" 2353 source = "registry+https://github.com/rust-lang/crates.io-index" 2354 checksum = "ca4f2850ec1a468c6f15b578c43218562d2309aadaf2b8bf17f54ce30e72f594" 2355 dependencies = [ 2356 "axum", 2357 + "dioxus-cli-config 0.7.1", 2358 + "dioxus-core 0.7.1", 2359 + "dioxus-devtools 0.7.1", 2360 + "dioxus-document 0.7.1", 2361 + "dioxus-history 0.7.1", 2362 + "dioxus-html 0.7.1", 2363 + "dioxus-interpreter-js 0.7.1", 2364 "futures-channel", 2365 "futures-util", 2366 + "generational-box 0.7.1", 2367 "rustc-hash 2.1.1", 2368 "serde", 2369 "serde_json", ··· 2377 2378 [[package]] 2379 name = "dioxus-logger" 2380 + version = "0.6.2" 2381 + source = "registry+https://github.com/rust-lang/crates.io-index" 2382 + checksum = "545961e752f6c8bf59c274951b3c8b18a106db6ad2f9e2035b29e1f2a3e899b1" 2383 + dependencies = [ 2384 + "console_error_panic_hook", 2385 + "dioxus-cli-config 0.6.3", 2386 + "tracing", 2387 + "tracing-subscriber", 2388 + "tracing-wasm", 2389 + ] 2390 + 2391 + [[package]] 2392 + name = "dioxus-logger" 2393 version = "0.7.1" 2394 source = "registry+https://github.com/rust-lang/crates.io-index" 2395 checksum = "42237934c6a67f5ed9a8c37e47ca980ee7cfec9e783a9a1f8c2e36c8b96ae74b" 2396 dependencies = [ 2397 + "dioxus-cli-config 0.7.1", 2398 "tracing", 2399 "tracing-subscriber", 2400 "tracing-wasm", ··· 2405 version = "0.0.1" 2406 source = "git+https://github.com/DioxusLabs/components#a15f329d1dc2bd76cd4030b27ecd70edb9fd8c6b" 2407 dependencies = [ 2408 + "dioxus 0.7.1", 2409 "dioxus-time", 2410 "lazy-js-bundle 0.6.2", 2411 "num-integer", ··· 2419 source = "registry+https://github.com/rust-lang/crates.io-index" 2420 checksum = "fdf1b95b7cafd07a2b39651ab2b146e4aa72acb0295cd52f422b7db5e2ab6eeb" 2421 dependencies = [ 2422 + "dioxus-cli-config 0.7.1", 2423 + "dioxus-core 0.7.1", 2424 + "dioxus-core-macro 0.7.1", 2425 "dioxus-fullstack-core", 2426 + "dioxus-history 0.7.1", 2427 + "dioxus-hooks 0.7.1", 2428 + "dioxus-html 0.7.1", 2429 "dioxus-router-macro", 2430 + "dioxus-signals 0.7.1", 2431 "percent-encoding", 2432 "rustversion", 2433 "tracing", ··· 2451 2452 [[package]] 2453 name = "dioxus-rsx" 2454 + version = "0.6.2" 2455 + source = "registry+https://github.com/rust-lang/crates.io-index" 2456 + checksum = "3eb588e05800b5a7eb90b2f40fca5bbd7626e823fb5e1ba21e011de649b45aa1" 2457 + dependencies = [ 2458 + "proc-macro2", 2459 + "proc-macro2-diagnostics", 2460 + "quote", 2461 + "syn 2.0.110", 2462 + ] 2463 + 2464 + [[package]] 2465 + name = "dioxus-rsx" 2466 version = "0.7.1" 2467 source = "registry+https://github.com/rust-lang/crates.io-index" 2468 checksum = "f026380dfda8b93ad995c0a90a62a17b8afeb246baff1b781a52c7b1b3ebd791" ··· 2486 "bytes", 2487 "chrono", 2488 "ciborium", 2489 + "dashmap 6.1.0", 2490 + "dioxus-cli-config 0.7.1", 2491 + "dioxus-core 0.7.1", 2492 + "dioxus-core-macro 0.7.1", 2493 + "dioxus-devtools 0.7.1", 2494 + "dioxus-document 0.7.1", 2495 "dioxus-fullstack-core", 2496 + "dioxus-history 0.7.1", 2497 + "dioxus-hooks 0.7.1", 2498 + "dioxus-html 0.7.1", 2499 + "dioxus-interpreter-js 0.7.1", 2500 + "dioxus-logger 0.7.1", 2501 "dioxus-router", 2502 + "dioxus-signals 0.7.1", 2503 "dioxus-ssr", 2504 "enumset", 2505 "futures", 2506 "futures-channel", 2507 "futures-util", 2508 + "generational-box 0.7.1", 2509 "http", 2510 "http-body-util", 2511 "hyper", ··· 2517 "rustc-hash 2.1.1", 2518 "serde", 2519 "serde_json", 2520 + "serde_qs 0.15.0", 2521 "subsecond", 2522 "thiserror 2.0.17", 2523 "tokio", ··· 2533 2534 [[package]] 2535 name = "dioxus-signals" 2536 + version = "0.6.3" 2537 + source = "registry+https://github.com/rust-lang/crates.io-index" 2538 + checksum = "10e032dbb3a2c0386ec8b8ee59bc20b5aeb67038147c855801237b45b13d72ac" 2539 + dependencies = [ 2540 + "dioxus-core 0.6.3", 2541 + "futures-channel", 2542 + "futures-util", 2543 + "generational-box 0.6.2", 2544 + "once_cell", 2545 + "parking_lot", 2546 + "rustc-hash 1.1.0", 2547 + "tracing", 2548 + "warnings", 2549 + ] 2550 + 2551 + [[package]] 2552 + name = "dioxus-signals" 2553 version = "0.7.1" 2554 source = "registry+https://github.com/rust-lang/crates.io-index" 2555 checksum = "3895cc17ff5b43ada07743111be586e7a927ed7ec511457020e4235e13e63fe6" 2556 dependencies = [ 2557 + "dioxus-core 0.7.1", 2558 "futures-channel", 2559 "futures-util", 2560 + "generational-box 0.7.1", 2561 "parking_lot", 2562 "rustc-hash 2.1.1", 2563 "tracing", ··· 2571 checksum = "592391fc30a77f94bc5a3385d1569052907e3b3cecb28099671b9d5801dee6c6" 2572 dependencies = [ 2573 "askama_escape", 2574 + "dioxus-core 0.7.1", 2575 + "dioxus-core-types 0.7.1", 2576 "rustc-hash 2.1.1", 2577 ] 2578 ··· 2582 source = "registry+https://github.com/rust-lang/crates.io-index" 2583 checksum = "8521729ac35f362476ac4eb7d1c4ab79e7e92a0facfdea3ee978c0ddf7108d37" 2584 dependencies = [ 2585 + "dioxus-core 0.7.1", 2586 + "dioxus-signals 0.7.1", 2587 "dioxus-stores-macro", 2588 ] 2589 ··· 2604 version = "0.7.0" 2605 source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#8c868ac1d60e3232e3f16f6195d6deb3c016de17" 2606 dependencies = [ 2607 + "dioxus 0.7.1", 2608 "futures", 2609 "gloo-timers", 2610 "tokio", ··· 2625 2626 [[package]] 2627 name = "dioxus-web" 2628 + version = "0.6.3" 2629 + source = "registry+https://github.com/rust-lang/crates.io-index" 2630 + checksum = "7e7c12475c3d360058b8afe1b68eb6dfc9cbb7dcd760aed37c5f85c561c83ed1" 2631 + dependencies = [ 2632 + "async-trait", 2633 + "ciborium", 2634 + "dioxus-cli-config 0.6.3", 2635 + "dioxus-core 0.6.3", 2636 + "dioxus-core-types 0.6.2", 2637 + "dioxus-devtools 0.6.2", 2638 + "dioxus-document 0.6.3", 2639 + "dioxus-history 0.6.2", 2640 + "dioxus-html 0.6.3", 2641 + "dioxus-interpreter-js 0.6.2", 2642 + "dioxus-signals 0.6.3", 2643 + "futures-channel", 2644 + "futures-util", 2645 + "generational-box 0.6.2", 2646 + "js-sys", 2647 + "lazy-js-bundle 0.6.2", 2648 + "rustc-hash 1.1.0", 2649 + "serde", 2650 + "serde-wasm-bindgen 0.5.0", 2651 + "serde_json", 2652 + "tracing", 2653 + "wasm-bindgen", 2654 + "wasm-bindgen-futures", 2655 + "web-sys", 2656 + ] 2657 + 2658 + [[package]] 2659 + name = "dioxus-web" 2660 version = "0.7.1" 2661 source = "registry+https://github.com/rust-lang/crates.io-index" 2662 checksum = "76155ecd44535e7c096ec8c5aac4a945899e47567ead4869babdaa74f3f9bca0" 2663 dependencies = [ 2664 + "dioxus-cli-config 0.7.1", 2665 + "dioxus-core 0.7.1", 2666 + "dioxus-core-types 0.7.1", 2667 + "dioxus-devtools 0.7.1", 2668 + "dioxus-document 0.7.1", 2669 "dioxus-fullstack-core", 2670 + "dioxus-history 0.7.1", 2671 + "dioxus-html 0.7.1", 2672 + "dioxus-interpreter-js 0.7.1", 2673 + "dioxus-signals 0.7.1", 2674 "futures-channel", 2675 "futures-util", 2676 + "generational-box 0.7.1", 2677 "gloo-timers", 2678 "js-sys", 2679 "lazy-js-bundle 0.7.1", ··· 2687 "wasm-bindgen-futures", 2688 "wasm-streams", 2689 "web-sys", 2690 + ] 2691 + 2692 + [[package]] 2693 + name = "dioxus_server_macro" 2694 + version = "0.6.2" 2695 + source = "registry+https://github.com/rust-lang/crates.io-index" 2696 + checksum = "371a5b21989a06b53c5092e977b3f75d0e60a65a4c15a2aa1d07014c3b2dda97" 2697 + dependencies = [ 2698 + "proc-macro2", 2699 + "quote", 2700 + "server_fn_macro", 2701 + "syn 2.0.110", 2702 ] 2703 2704 [[package]] ··· 3447 3448 [[package]] 3449 name = "generational-box" 3450 + version = "0.6.2" 3451 + source = "registry+https://github.com/rust-lang/crates.io-index" 3452 + checksum = "a673cf4fb0ea6a91aa86c08695756dfe875277a912cdbf33db9a9f62d47ed82b" 3453 + dependencies = [ 3454 + "parking_lot", 3455 + "tracing", 3456 + ] 3457 + 3458 + [[package]] 3459 + name = "generational-box" 3460 version = "0.7.1" 3461 source = "registry+https://github.com/rust-lang/crates.io-index" 3462 checksum = "b3c1ae09dfd2d455484a54b56129b9821241c4b0e412227806b6c3730cd18a29" ··· 4615 version = "0.9.2" 4616 dependencies = [ 4617 "cid", 4618 + "dashmap 6.1.0", 4619 "heck 0.5.0", 4620 "inventory", 4621 "jacquard-common", ··· 4642 "base64 0.22.1", 4643 "bytes", 4644 "chrono", 4645 + "dashmap 6.1.0", 4646 "elliptic-curve", 4647 "http", 4648 "jacquard-common", ··· 5094 5095 [[package]] 5096 name = "manganis" 5097 + version = "0.6.2" 5098 + source = "registry+https://github.com/rust-lang/crates.io-index" 5099 + checksum = "317af44b15e7605b85f04525449a3bb631753040156c9b318e6cba8a3ea4ef73" 5100 + dependencies = [ 5101 + "const-serialize 0.6.2", 5102 + "manganis-core 0.6.2", 5103 + "manganis-macro 0.6.2", 5104 + ] 5105 + 5106 + [[package]] 5107 + name = "manganis" 5108 version = "0.7.1" 5109 source = "registry+https://github.com/rust-lang/crates.io-index" 5110 checksum = "124f8f094eb75783b38209ce4d534b9617da4efac652802d9bafe05043a3ec95" 5111 dependencies = [ 5112 + "const-serialize 0.7.1", 5113 + "manganis-core 0.7.1", 5114 + "manganis-macro 0.7.1", 5115 + ] 5116 + 5117 + [[package]] 5118 + name = "manganis-core" 5119 + version = "0.6.2" 5120 + source = "registry+https://github.com/rust-lang/crates.io-index" 5121 + checksum = "c38bee65cc725b2bba23b5dbb290f57c8be8fadbe2043fb7e2ce73022ea06519" 5122 + dependencies = [ 5123 + "const-serialize 0.6.2", 5124 + "dioxus-cli-config 0.6.3", 5125 + "dioxus-core-types 0.6.2", 5126 + "serde", 5127 ] 5128 5129 [[package]] ··· 5132 source = "registry+https://github.com/rust-lang/crates.io-index" 5133 checksum = "41fbd1fb8c5aabcc54c6b02dbc968e1c89c28f3e543f2789ef9e3ce45dbdf5df" 5134 dependencies = [ 5135 + "const-serialize 0.7.1", 5136 + "dioxus-cli-config 0.7.1", 5137 + "dioxus-core-types 0.7.1", 5138 "serde", 5139 ] 5140 5141 [[package]] 5142 name = "manganis-macro" 5143 + version = "0.6.2" 5144 + source = "registry+https://github.com/rust-lang/crates.io-index" 5145 + checksum = "d9f4f71310913c40174d9f0cfcbcb127dad0329ecdb3945678a120db22d3d065" 5146 + dependencies = [ 5147 + "dunce", 5148 + "manganis-core 0.6.2", 5149 + "proc-macro2", 5150 + "quote", 5151 + "syn 2.0.110", 5152 + ] 5153 + 5154 + [[package]] 5155 + name = "manganis-macro" 5156 version = "0.7.1" 5157 source = "registry+https://github.com/rust-lang/crates.io-index" 5158 checksum = "45d6fec2a8249739bb30b53a08ecbb217f76096c08f1053f38ec3981ba424c11" 5159 dependencies = [ 5160 "dunce", 5161 "macro-string", 5162 + "manganis-core 0.7.1", 5163 "proc-macro2", 5164 "quote", 5165 "syn 2.0.110", ··· 5415 dependencies = [ 5416 "crossbeam-channel", 5417 "crossbeam-utils", 5418 + "dashmap 6.1.0", 5419 "smallvec", 5420 "tagptr", 5421 "triomphe", ··· 5429 dependencies = [ 5430 "crossbeam-channel", 5431 "crossbeam-utils", 5432 + "dashmap 6.1.0", 5433 "smallvec", 5434 "tagptr", 5435 "triomphe", ··· 7273 7274 [[package]] 7275 name = "serde-wasm-bindgen" 7276 + version = "0.5.0" 7277 + source = "registry+https://github.com/rust-lang/crates.io-index" 7278 + checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" 7279 + dependencies = [ 7280 + "js-sys", 7281 + "serde", 7282 + "wasm-bindgen", 7283 + ] 7284 + 7285 + [[package]] 7286 + name = "serde-wasm-bindgen" 7287 version = "0.6.5" 7288 source = "registry+https://github.com/rust-lang/crates.io-index" 7289 checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" ··· 7371 "itoa", 7372 "serde", 7373 "serde_core", 7374 + ] 7375 + 7376 + [[package]] 7377 + name = "serde_qs" 7378 + version = "0.12.0" 7379 + source = "registry+https://github.com/rust-lang/crates.io-index" 7380 + checksum = "0431a35568651e363364210c91983c1da5eb29404d9f0928b67d4ebcfa7d330c" 7381 + dependencies = [ 7382 + "percent-encoding", 7383 + "serde", 7384 + "thiserror 1.0.69", 7385 ] 7386 7387 [[package]] ··· 7475 dependencies = [ 7476 "base16ct", 7477 "serde", 7478 + ] 7479 + 7480 + [[package]] 7481 + name = "server_fn" 7482 + version = "0.6.15" 7483 + source = "registry+https://github.com/rust-lang/crates.io-index" 7484 + checksum = "4fae7a3038a32e5a34ba32c6c45eb4852f8affaf8b794ebfcd4b1099e2d62ebe" 7485 + dependencies = [ 7486 + "bytes", 7487 + "const_format", 7488 + "dashmap 5.5.3", 7489 + "futures", 7490 + "gloo-net", 7491 + "http", 7492 + "js-sys", 7493 + "once_cell", 7494 + "send_wrapper", 7495 + "serde", 7496 + "serde_json", 7497 + "serde_qs 0.12.0", 7498 + "server_fn_macro_default", 7499 + "thiserror 1.0.69", 7500 + "url", 7501 + "wasm-bindgen", 7502 + "wasm-bindgen-futures", 7503 + "wasm-streams", 7504 + "web-sys", 7505 + "xxhash-rust", 7506 + ] 7507 + 7508 + [[package]] 7509 + name = "server_fn_macro" 7510 + version = "0.6.15" 7511 + source = "registry+https://github.com/rust-lang/crates.io-index" 7512 + checksum = "faaaf648c6967aef78177c0610478abb5a3455811f401f3c62d10ae9bd3901a1" 7513 + dependencies = [ 7514 + "const_format", 7515 + "convert_case 0.6.0", 7516 + "proc-macro2", 7517 + "quote", 7518 + "syn 2.0.110", 7519 + "xxhash-rust", 7520 + ] 7521 + 7522 + [[package]] 7523 + name = "server_fn_macro_default" 7524 + version = "0.6.15" 7525 + source = "registry+https://github.com/rust-lang/crates.io-index" 7526 + checksum = "7f2aa8119b558a17992e0ac1fd07f080099564f24532858811ce04f742542440" 7527 + dependencies = [ 7528 + "server_fn_macro", 7529 + "syn 2.0.110", 7530 ] 7531 7532 [[package]] ··· 8904 8905 [[package]] 8906 name = "tungstenite" 8907 + version = "0.23.0" 8908 + source = "registry+https://github.com/rust-lang/crates.io-index" 8909 + checksum = "6e2e2ce1e47ed2994fd43b04c8f618008d4cabdd5ee34027cf14f9d918edd9c8" 8910 + dependencies = [ 8911 + "byteorder", 8912 + "bytes", 8913 + "data-encoding", 8914 + "http", 8915 + "httparse", 8916 + "log", 8917 + "rand 0.8.5", 8918 + "sha1", 8919 + "thiserror 1.0.69", 8920 + "utf-8", 8921 + ] 8922 + 8923 + [[package]] 8924 + name = "tungstenite" 8925 version = "0.24.0" 8926 source = "registry+https://github.com/rust-lang/crates.io-index" 8927 checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" ··· 9420 "base64 0.22.1", 9421 "chrono", 9422 "console_error_panic_hook", 9423 + "dashmap 6.1.0", 9424 + "dioxus 0.7.1", 9425 + "dioxus-free-icons", 9426 "dioxus-primitives", 9427 "dotenvy", 9428 "gloo-storage", ··· 9515 "axum", 9516 "chrono", 9517 "clap", 9518 + "dashmap 6.1.0", 9519 "diesel", 9520 "diesel-async", 9521 "diesel_migrations", ··· 9560 version = "0.1.0" 9561 dependencies = [ 9562 "bitflags 2.10.0", 9563 + "dashmap 6.1.0", 9564 "http", 9565 "ignore", 9566 "insta",
-3
Cargo.toml
··· 58 59 [profile.wasm-dev] 60 inherits = "dev" 61 - opt-level = 1 62 - lto = true 63 debug = true 64 65 [profile.server-dev] 66 inherits = "dev" 67 - lto = true 68 debug = true 69 70 [profile.android-dev]
··· 58 59 [profile.wasm-dev] 60 inherits = "dev" 61 debug = true 62 63 [profile.server-dev] 64 inherits = "dev" 65 debug = true 66 67 [profile.android-dev]
+2 -1
crates/weaver-app/Cargo.toml
··· 5 edition = "2024" 6 7 [features] 8 - default = ["web", "no-app-index"] 9 # Fullstack mode with SSR and server functions 10 fullstack-server = ["dioxus/fullstack"] 11 wasm-split = ["dioxus/wasm-split"] ··· 41 base64 = "0.22" 42 http = "1.3" 43 reqwest = { version = "0.12", default-features = false, features = ["json"] } 44 45 # diesel = { version = "2.3", features = ["sqlite", "returning_clauses_for_sqlite_3_35", "chrono", "serde_json"] } 46 # diesel_migrations = { version = "2.3", features = ["sqlite"] }
··· 5 edition = "2024" 6 7 [features] 8 + default = ["web", "fullstack-server", "no-app-index"] 9 # Fullstack mode with SSR and server functions 10 fullstack-server = ["dioxus/fullstack"] 11 wasm-split = ["dioxus/wasm-split"] ··· 41 base64 = "0.22" 42 http = "1.3" 43 reqwest = { version = "0.12", default-features = false, features = ["json"] } 44 + dioxus-free-icons = { version = "0.9", features = ["font-awesome-brands"] } 45 46 # diesel = { version = "2.3", features = ["sqlite", "returning_clauses_for_sqlite_3_35", "chrono", "serde_json"] } 47 # diesel_migrations = { version = "2.3", features = ["sqlite"] }
+3
crates/weaver-app/Dioxus.toml
··· 5 # HTML title tag content 6 title = "Weaver" 7 8 # include `assets` in web platform 9 [web.resource] 10
··· 5 # HTML title tag content 6 title = "Weaver" 7 8 + out_dir = "dist" 9 + asset_dir = "public" 10 + 11 # include `assets` in web platform 12 [web.resource] 13
+1
crates/weaver-app/assets/styling/navbar.css
··· 36 37 .auth-button { 38 align-self: flex-end; 39 } 40 41 .auth-handle {
··· 36 37 .auth-button { 38 align-self: flex-end; 39 + background-color: var(--color-base); 40 } 41 42 .auth-handle {
+1 -1
crates/weaver-app/assets/styling/profile.css
··· 8 9 .profile-banner { 10 max-width: 100%; 11 - height: 200px; 12 overflow: hidden; 13 } 14
··· 8 9 .profile-banner { 10 max-width: 100%; 11 + height: 150px; 12 overflow: hidden; 13 } 14
crates/weaver-app/assets/sw.js crates/weaver-app/public/sw.js
+8 -5
crates/weaver-app/src/auth/mod.rs
··· 6 pub use state::AuthState; 7 8 use crate::fetch::Fetcher; 9 - #[cfg(all(feature = "fullstack-server", feature = "server"))] 10 use dioxus::prelude::*; 11 #[cfg(all(feature = "fullstack-server", feature = "server"))] 12 use jacquard::oauth::types::OAuthClientMetadata; ··· 26 } 27 28 #[cfg(not(target_arch = "wasm32"))] 29 - pub async fn restore_session(_fetcher: Fetcher) -> Result<(), String> { 30 Ok(()) 31 } 32 33 #[cfg(target_arch = "wasm32")] 34 - pub async fn restore_session(fetcher: Fetcher) -> Result<(), CapturedError> { 35 use dioxus::prelude::*; 36 use gloo_storage::{LocalStorage, Storage}; 37 use jacquard::types::string::Did; ··· 70 let (restored_did, session_id) = session.session_info().await; 71 72 // Update auth state 73 - let mut auth_state = try_consume_context::<Signal<AuthState>>() 74 - .ok_or(CapturedError::from_display("AuthState not in context"))?; 75 auth_state 76 .write() 77 .set_authenticated(restored_did, session_id);
··· 6 pub use state::AuthState; 7 8 use crate::fetch::Fetcher; 9 use dioxus::prelude::*; 10 #[cfg(all(feature = "fullstack-server", feature = "server"))] 11 use jacquard::oauth::types::OAuthClientMetadata; ··· 25 } 26 27 #[cfg(not(target_arch = "wasm32"))] 28 + pub async fn restore_session( 29 + _fetcher: Fetcher, 30 + _auth_state: Signal<AuthState>, 31 + ) -> Result<(), String> { 32 Ok(()) 33 } 34 35 #[cfg(target_arch = "wasm32")] 36 + pub async fn restore_session( 37 + fetcher: Fetcher, 38 + mut auth_state: Signal<AuthState>, 39 + ) -> Result<(), CapturedError> { 40 use dioxus::prelude::*; 41 use gloo_storage::{LocalStorage, Storage}; 42 use jacquard::types::string::Did; ··· 75 let (restored_did, session_id) = session.session_info().await; 76 77 // Update auth state 78 auth_state 79 .write() 80 .set_authenticated(restored_did, session_id);
+1 -1
crates/weaver-app/src/components/accordion/component.rs
··· 6 #[component] 7 pub fn Accordion(props: AccordionProps) -> Element { 8 rsx! { 9 - document::Link { rel: "stylesheet", href: asset!("./style.css") } 10 accordion::Accordion { 11 class: "accordion", 12 id: props.id,
··· 6 #[component] 7 pub fn Accordion(props: AccordionProps) -> Element { 8 rsx! { 9 + document::Link { rel: "stylesheet", href: asset!("./accordion.css") } 10 accordion::Accordion { 11 class: "accordion", 12 id: props.id,
crates/weaver-app/src/components/accordion/style.css crates/weaver-app/src/components/accordion/accordion.css
+1 -1
crates/weaver-app/src/components/avatar/component.rs
··· 50 #[component] 51 pub fn Avatar(props: AvatarProps) -> Element { 52 rsx! { 53 - document::Link { rel: "stylesheet", href: asset!("./style.css") } 54 55 avatar::Avatar { 56 class: "avatar {props.size.to_class()}",
··· 50 #[component] 51 pub fn Avatar(props: AvatarProps) -> Element { 52 rsx! { 53 + document::Link { rel: "stylesheet", href: asset!("./avatar.css") } 54 55 avatar::Avatar { 56 class: "avatar {props.size.to_class()}",
crates/weaver-app/src/components/avatar/style.css crates/weaver-app/src/components/avatar/avatar.css
+1 -1
crates/weaver-app/src/components/button/component.rs
··· 35 children: Element, 36 ) -> Element { 37 rsx! { 38 - document::Link { rel: "stylesheet", href: asset!("./style.css") } 39 40 button { 41 class: "button",
··· 35 children: Element, 36 ) -> Element { 37 rsx! { 38 + document::Link { rel: "stylesheet", href: asset!("/assets/styling/button.css") } 39 40 button { 41 class: "button",
crates/weaver-app/src/components/button/style.css crates/weaver-app/assets/styling/button.css
+1 -1
crates/weaver-app/src/components/dialog/component.rs
··· 6 #[component] 7 pub fn DialogRoot(props: DialogRootProps) -> Element { 8 rsx! { 9 - document::Link { rel: "stylesheet", href: asset!("./style.css") } 10 dialog::DialogRoot { 11 class: "dialog-backdrop", 12 id: props.id,
··· 6 #[component] 7 pub fn DialogRoot(props: DialogRootProps) -> Element { 8 rsx! { 9 + document::Link { rel: "stylesheet", href: asset!("./dialog.css") } 10 dialog::DialogRoot { 11 class: "dialog-backdrop", 12 id: props.id,
crates/weaver-app/src/components/dialog/style.css crates/weaver-app/src/components/dialog/dialog.css
+76 -73
crates/weaver-app/src/components/entry.rs
··· 4 use crate::blobcache::BlobCache; 5 use crate::{ 6 components::avatar::{Avatar, AvatarImage}, 7 - data::{NotebookHandle, use_handle}, 8 }; 9 10 use crate::Route; ··· 30 book_title: ReadSignal<SmolStr>, 31 title: ReadSignal<SmolStr>, 32 ) -> Element { 33 rsx! { 34 {std::iter::once(rsx! {Entry {ident, book_title, title}})} 35 } ··· 41 book_title: ReadSignal<SmolStr>, 42 title: ReadSignal<SmolStr>, 43 ) -> Element { 44 // Use feature-gated hook for SSR support 45 let entry = crate::data::use_entry_data(ident, book_title, title); 46 - let handle = use_context::<NotebookHandle>(); 47 let fetcher = use_context::<crate::fetch::Fetcher>(); 48 49 // Handle blob caching when entry data is available 50 - if let Ok(entry) = entry { 51 - match &*entry.read() { 52 - Some((book_entry_view, entry_record)) => { 53 - if let Some(embeds) = &entry_record.embeds { 54 - if let Some(images) = &embeds.images { 55 - // Register blob mappings with service worker (client-side only) 56 - #[cfg(all( 57 - target_family = "wasm", 58 - target_os = "unknown", 59 - not(feature = "fullstack-server") 60 - ))] 61 - { 62 - let fetcher = fetcher.clone(); 63 - let images = images.clone(); 64 - spawn(async move { 65 - let _ = crate::service_worker::register_entry_blobs( 66 - &ident(), 67 - book_title().as_str(), 68 - &images, 69 - &fetcher, 70 - ) 71 - .await; 72 - }); 73 - } 74 } 75 } 76 - rsx! { EntryPageView { 77 - book_entry_view: book_entry_view.clone(), 78 - entry_record: entry_record.clone(), 79 - ident: handle.as_ref().unwrap().clone(), 80 - book_title: book_title() 81 - } } 82 } 83 - _ => rsx! { p { "Loading..." } }, 84 } 85 - } else { 86 - rsx! { p { "Loading..." } } 87 } 88 } 89 90 /// Full entry page with metadata, content, and navigation 91 #[component] 92 fn EntryPageView( 93 - book_entry_view: BookEntryView<'static>, 94 - entry_record: entry::Entry<'static>, 95 - ident: AtIdentifier<'static>, 96 - book_title: SmolStr, 97 ) -> Element { 98 // Extract metadata 99 - let entry_view = &book_entry_view.entry; 100 let title = entry_view 101 .title 102 .as_ref() ··· 110 111 div { class: "entry-page-layout", 112 // Left gutter with prev button 113 - if let Some(ref prev) = book_entry_view.prev { 114 div { class: "nav-gutter nav-prev", 115 NavButton { 116 direction: "prev", 117 entry: prev.entry.clone(), 118 - ident: ident.clone(), 119 - book_title: book_title.clone() 120 } 121 } 122 } ··· 126 // Metadata header 127 EntryMetadata { 128 entry_view: entry_view.clone(), 129 - ident: ident.clone(), 130 - created_at: entry_record.created_at.clone() 131 } 132 133 // Rendered markdown 134 - EntryMarkdownDirect { 135 content: entry_record, 136 - ident: ident.clone() 137 } 138 } 139 140 // Right gutter with next button 141 - if let Some(ref next) = book_entry_view.next { 142 div { class: "nav-gutter nav-next", 143 NavButton { 144 direction: "next", 145 entry: next.entry.clone(), 146 - ident: ident.clone(), 147 - book_title: book_title.clone() 148 } 149 } 150 } ··· 157 entry: BookEntryView<'static>, 158 book_title: SmolStr, 159 author_count: usize, 160 ) -> Element { 161 use crate::Route; 162 use jacquard::from_data; ··· 168 .as_ref() 169 .map(|t| t.as_ref()) 170 .unwrap_or("Untitled"); 171 - 172 - let ident = use_context::<NotebookHandle>(); 173 // Format date 174 let formatted_date = entry_view 175 .indexed_at ··· 197 div { class: "entry-card", 198 Link { 199 to: Route::EntryPage { 200 - ident: ident.as_ref().unwrap().clone(), 201 book_title: book_title.clone(), 202 title: title.to_string().into() 203 }, ··· 221 match &author.record.inner { 222 ProfileDataViewInner::ProfileView(profile) => { 223 let display_name = profile.display_name.as_ref().map(|n| n.as_ref()).unwrap_or("Unknown"); 224 rsx! { 225 if let Some(ref avatar_url) = profile.avatar { 226 Avatar { ··· 228 } 229 } 230 span { class: "author-name", "{display_name}" } 231 - span { class: "meta-label", "@{ident.as_ref().unwrap()}" } 232 } 233 } 234 ProfileDataViewInner::ProfileViewDetailed(profile) => { 235 let display_name = profile.display_name.as_ref().map(|n| n.as_ref()).unwrap_or("Unknown"); 236 rsx! { 237 if let Some(ref avatar_url) = profile.avatar { 238 Avatar { ··· 240 } 241 } 242 span { class: "author-name", "{display_name}" } 243 - span { class: "meta-label", "@{ident.as_ref().unwrap()}" } 244 } 245 } 246 ProfileDataViewInner::TangledProfileView(profile) => { ··· 282 283 /// Metadata header showing title, authors, date, tags 284 #[component] 285 - fn EntryMetadata( 286 - entry_view: EntryView<'static>, 287 - ident: AtIdentifier<'static>, 288 - created_at: Datetime, 289 - ) -> Element { 290 let title = entry_view 291 .title 292 .as_ref() ··· 311 match &author.record.inner { 312 ProfileDataViewInner::ProfileView(profile) => { 313 let display_name = profile.display_name.as_ref().map(|n| n.as_ref()).unwrap_or("Unknown"); 314 rsx! { 315 Link { 316 - to: Route::RepositoryIndex { ident: ident.clone() }, 317 div { class: "entry-authors", 318 if let Some(ref avatar_url) = profile.avatar { 319 Avatar { ··· 323 } 324 } 325 span { class: "author-name", "{display_name}" } 326 - span { class: "meta-label", "@{ident}" } 327 } 328 } 329 } 330 } 331 ProfileDataViewInner::ProfileViewDetailed(profile) => { 332 let display_name = profile.display_name.as_ref().map(|n| n.as_ref()).unwrap_or("Unknown"); 333 rsx! { 334 Link { 335 - to: Route::RepositoryIndex { ident: ident.clone() }, 336 div { class: "entry-authors", 337 if let Some(ref avatar_url) = profile.avatar { 338 Avatar { ··· 342 } 343 } 344 span { class: "author-name", "{display_name}" } 345 - span { class: "meta-label", "@{ident}" } 346 } 347 } 348 } ··· 423 pub struct EntryMarkdownProps { 424 #[props(default)] 425 id: Signal<String>, 426 - #[props(default)] 427 class: Signal<String>, 428 content: ReadSignal<entry::Entry<'static>>, 429 ident: ReadSignal<AtIdentifier<'static>>, 430 } 431 432 /// Render some text as markdown. 433 - #[allow(unused)] 434 pub fn EntryMarkdown(props: EntryMarkdownProps) -> Element { 435 - let processed = crate::data::use_rendered_markdown( 436 - props.content, 437 - props.ident, 438 - )?; 439 440 match &*processed.read() { 441 - Some(Some(html_buf)) => rsx! { 442 div { 443 id: "{&*props.id.read()}", 444 class: "{&*props.class.read()}", ··· 466 // Use feature-gated hook for SSR support 467 let content = use_signal(|| content); 468 let ident = use_signal(|| ident); 469 - let processed = crate::data::use_rendered_markdown(content.into(), ident.into())?; 470 471 match &*processed.read() { 472 - Some(Some(html_buf)) => rsx! { 473 div { 474 id: "{id}", 475 class: "{class}",
··· 4 use crate::blobcache::BlobCache; 5 use crate::{ 6 components::avatar::{Avatar, AvatarImage}, 7 + data::use_handle, 8 }; 9 10 use crate::Route; ··· 30 book_title: ReadSignal<SmolStr>, 31 title: ReadSignal<SmolStr>, 32 ) -> Element { 33 + tracing::debug!( 34 + "EntryPage component rendering for ident: {:?}, book: {}, title: {}", 35 + ident(), 36 + book_title(), 37 + title() 38 + ); 39 rsx! { 40 {std::iter::once(rsx! {Entry {ident, book_title, title}})} 41 } ··· 47 book_title: ReadSignal<SmolStr>, 48 title: ReadSignal<SmolStr>, 49 ) -> Element { 50 + tracing::debug!( 51 + "Entry component rendering for ident: {:?}, book: {}, title: {}", 52 + ident(), 53 + book_title(), 54 + title() 55 + ); 56 // Use feature-gated hook for SSR support 57 let entry = crate::data::use_entry_data(ident, book_title, title); 58 let fetcher = use_context::<crate::fetch::Fetcher>(); 59 + tracing::debug!("Entry component got entry data"); 60 61 // Handle blob caching when entry data is available 62 + match &*entry.read() { 63 + Some((book_entry_view, entry_record)) => { 64 + if let Some(embeds) = &entry_record.embeds { 65 + if let Some(images) = &embeds.images { 66 + // Register blob mappings with service worker (client-side only) 67 + #[cfg(all( 68 + target_family = "wasm", 69 + target_os = "unknown", 70 + not(feature = "fullstack-server") 71 + ))] 72 + { 73 + let fetcher = fetcher.clone(); 74 + let images = images.clone(); 75 + spawn(async move { 76 + let _ = crate::service_worker::register_entry_blobs( 77 + &ident(), 78 + book_title().as_str(), 79 + &images, 80 + &fetcher, 81 + ) 82 + .await; 83 + }); 84 } 85 } 86 } 87 + rsx! { EntryPageView { 88 + book_entry_view: book_entry_view.clone(), 89 + entry_record: entry_record.clone(), 90 + ident: ident(), 91 + book_title: book_title() 92 + } } 93 } 94 + _ => rsx! { p { "Loading..." } }, 95 } 96 } 97 98 /// Full entry page with metadata, content, and navigation 99 #[component] 100 fn EntryPageView( 101 + book_entry_view: ReadSignal<BookEntryView<'static>>, 102 + entry_record: ReadSignal<entry::Entry<'static>>, 103 + ident: ReadSignal<AtIdentifier<'static>>, 104 + book_title: ReadSignal<SmolStr>, 105 ) -> Element { 106 // Extract metadata 107 + let entry_view = &book_entry_view().entry; 108 let title = entry_view 109 .title 110 .as_ref() ··· 118 119 div { class: "entry-page-layout", 120 // Left gutter with prev button 121 + if let Some(ref prev) = book_entry_view().prev { 122 div { class: "nav-gutter nav-prev", 123 NavButton { 124 direction: "prev", 125 entry: prev.entry.clone(), 126 + ident: ident(), 127 + book_title: book_title() 128 } 129 } 130 } ··· 134 // Metadata header 135 EntryMetadata { 136 entry_view: entry_view.clone(), 137 + created_at: entry_record().created_at.clone() 138 } 139 140 // Rendered markdown 141 + EntryMarkdown { 142 content: entry_record, 143 + ident 144 } 145 } 146 147 // Right gutter with next button 148 + if let Some(ref next) = book_entry_view().next { 149 div { class: "nav-gutter nav-next", 150 NavButton { 151 direction: "next", 152 entry: next.entry.clone(), 153 + ident: ident(), 154 + book_title: book_title() 155 } 156 } 157 } ··· 164 entry: BookEntryView<'static>, 165 book_title: SmolStr, 166 author_count: usize, 167 + ident: AtIdentifier<'static>, 168 ) -> Element { 169 use crate::Route; 170 use jacquard::from_data; ··· 176 .as_ref() 177 .map(|t| t.as_ref()) 178 .unwrap_or("Untitled"); 179 // Format date 180 let formatted_date = entry_view 181 .indexed_at ··· 203 div { class: "entry-card", 204 Link { 205 to: Route::EntryPage { 206 + ident: ident, 207 book_title: book_title.clone(), 208 title: title.to_string().into() 209 }, ··· 227 match &author.record.inner { 228 ProfileDataViewInner::ProfileView(profile) => { 229 let display_name = profile.display_name.as_ref().map(|n| n.as_ref()).unwrap_or("Unknown"); 230 + let handle = profile.handle.clone(); 231 rsx! { 232 if let Some(ref avatar_url) = profile.avatar { 233 Avatar { ··· 235 } 236 } 237 span { class: "author-name", "{display_name}" } 238 + span { class: "meta-label", "@{handle}" } 239 } 240 } 241 ProfileDataViewInner::ProfileViewDetailed(profile) => { 242 let display_name = profile.display_name.as_ref().map(|n| n.as_ref()).unwrap_or("Unknown"); 243 + let handle = profile.handle.clone(); 244 rsx! { 245 if let Some(ref avatar_url) = profile.avatar { 246 Avatar { ··· 248 } 249 } 250 span { class: "author-name", "{display_name}" } 251 + span { class: "meta-label", "@{handle}" } 252 } 253 } 254 ProfileDataViewInner::TangledProfileView(profile) => { ··· 290 291 /// Metadata header showing title, authors, date, tags 292 #[component] 293 + fn EntryMetadata(entry_view: EntryView<'static>, created_at: Datetime) -> Element { 294 let title = entry_view 295 .title 296 .as_ref() ··· 315 match &author.record.inner { 316 ProfileDataViewInner::ProfileView(profile) => { 317 let display_name = profile.display_name.as_ref().map(|n| n.as_ref()).unwrap_or("Unknown"); 318 + let handle = profile.handle.clone(); 319 + 320 rsx! { 321 Link { 322 + to: Route::RepositoryIndex { ident: AtIdentifier::Handle(handle.clone()) }, 323 div { class: "entry-authors", 324 if let Some(ref avatar_url) = profile.avatar { 325 Avatar { ··· 329 } 330 } 331 span { class: "author-name", "{display_name}" } 332 + span { class: "meta-label", "@{handle}" } 333 } 334 } 335 } 336 } 337 ProfileDataViewInner::ProfileViewDetailed(profile) => { 338 let display_name = profile.display_name.as_ref().map(|n| n.as_ref()).unwrap_or("Unknown"); 339 + let handle = profile.handle.clone(); 340 rsx! { 341 Link { 342 + to: Route::RepositoryIndex { ident: AtIdentifier::Handle(handle.clone()) }, 343 div { class: "entry-authors", 344 if let Some(ref avatar_url) = profile.avatar { 345 Avatar { ··· 349 } 350 } 351 span { class: "author-name", "{display_name}" } 352 + span { class: "meta-label", "@{handle}" } 353 } 354 } 355 } ··· 430 pub struct EntryMarkdownProps { 431 #[props(default)] 432 id: Signal<String>, 433 + #[props(default = use_signal(||"entry".to_string()))] 434 class: Signal<String>, 435 content: ReadSignal<entry::Entry<'static>>, 436 ident: ReadSignal<AtIdentifier<'static>>, 437 } 438 439 /// Render some text as markdown. 440 pub fn EntryMarkdown(props: EntryMarkdownProps) -> Element { 441 + let processed = crate::data::use_rendered_markdown(props.content, props.ident); 442 443 match &*processed.read() { 444 + Some(html_buf) => rsx! { 445 div { 446 id: "{&*props.id.read()}", 447 class: "{&*props.class.read()}", ··· 469 // Use feature-gated hook for SSR support 470 let content = use_signal(|| content); 471 let ident = use_signal(|| ident); 472 + let processed = crate::data::use_rendered_markdown(content.into(), ident.into()); 473 474 match &*processed.read() { 475 + Some(html_buf) => rsx! { 476 div { 477 id: "{id}", 478 class: "{class}",
+34 -35
crates/weaver-app/src/components/identity.rs
··· 8 9 #[component] 10 pub fn Repository(ident: ReadSignal<AtIdentifier<'static>>) -> Element { 11 - // Fetch notebooks for this specific DID with SSR support 12 - let notebooks = data::use_notebooks_for_did(ident)?; 13 - use_context_provider(|| notebooks); 14 rsx! { 15 div { 16 Outlet::<Route> {} ··· 18 } 19 } 20 21 - pub fn use_repo_notebook_context() 22 - -> Option<Memo<Option<Vec<(NotebookView<'static>, Vec<StrongRef<'static>>)>>>> { 23 - try_use_context::<Memo<Option<Vec<(NotebookView<'static>, Vec<StrongRef<'static>>)>>>>() 24 - } 25 - 26 #[component] 27 pub fn RepositoryIndex(ident: ReadSignal<AtIdentifier<'static>>) -> Element { 28 use crate::components::ProfileDisplay; 29 - let notebooks = use_repo_notebook_context(); 30 - let profile = crate::data::use_profile_data(ident)?; 31 rsx! { 32 document::Stylesheet { href: NOTEBOOK_CARD_CSS } 33 34 div { class: "repository-layout", 35 // Profile sidebar (desktop) / header (mobile) 36 aside { class: "repository-sidebar", 37 - ProfileDisplay { profile } 38 } 39 40 // Main content area 41 main { class: "repository-main", 42 div { class: "notebooks-list", 43 - if let Some(notebooks) = notebooks { 44 - match &*notebooks.read() { 45 - Some(notebook_list) => rsx! { 46 - for notebook in notebook_list.iter() { 47 - { 48 - let view = &notebook.0; 49 - let entries = &notebook.1; 50 - rsx! { 51 - div { 52 - key: "{view.cid}", 53 - NotebookCard { 54 - notebook: view.clone(), 55 - entry_refs: entries.clone() 56 - } 57 - } 58 - } 59 - } 60 - } 61 - }, 62 - None => rsx! { 63 - div { "Loading notebooks..." } 64 - } 65 - } 66 - } 67 } 68 } 69 }
··· 8 9 #[component] 10 pub fn Repository(ident: ReadSignal<AtIdentifier<'static>>) -> Element { 11 + tracing::debug!("Repository component rendering for ident: {:?}", ident()); 12 + // Fetch notebooks for this specific DID with SSR support; 13 + tracing::debug!("Repository component context set up"); 14 + 15 rsx! { 16 div { 17 Outlet::<Route> {} ··· 19 } 20 } 21 22 #[component] 23 pub fn RepositoryIndex(ident: ReadSignal<AtIdentifier<'static>>) -> Element { 24 + tracing::debug!( 25 + "RepositoryIndex component rendering for ident: {:?}", 26 + ident() 27 + ); 28 use crate::components::ProfileDisplay; 29 + let notebooks = data::use_notebooks_for_did(ident); 30 + let profile = crate::data::use_profile_data(ident); 31 + tracing::debug!("RepositoryIndex got profile and notebooks"); 32 rsx! { 33 document::Stylesheet { href: NOTEBOOK_CARD_CSS } 34 35 div { class: "repository-layout", 36 // Profile sidebar (desktop) / header (mobile) 37 aside { class: "repository-sidebar", 38 + ProfileDisplay { profile, notebooks } 39 } 40 41 // Main content area 42 main { class: "repository-main", 43 div { class: "notebooks-list", 44 + match &*notebooks.read() { 45 + Some(notebook_list) => rsx! { 46 + for notebook in notebook_list.iter() { 47 + { 48 + let view = &notebook.0; 49 + let entries = &notebook.1; 50 + rsx! { 51 + div { 52 + key: "{view.cid}", 53 + NotebookCard { 54 + notebook: view.clone(), 55 + entry_refs: entries.clone() 56 + } 57 + } 58 + } 59 + } 60 + } 61 + }, 62 + None => rsx! { 63 + div { "Loading notebooks..." } 64 + } 65 + } 66 } 67 } 68 }
+1 -1
crates/weaver-app/src/components/input/component.rs
··· 26 children: Element, 27 ) -> Element { 28 rsx! { 29 - document::Link { rel: "stylesheet", href: asset!("./style.css") } 30 input { 31 class: "input", 32 oninput: move |e| _ = oninput.map(|callback| callback(e)),
··· 26 children: Element, 27 ) -> Element { 28 rsx! { 29 + document::Link { rel: "stylesheet", href: asset!("./input-style.css") } 30 input { 31 class: "input", 32 oninput: move |e| _ = oninput.map(|callback| callback(e)),
crates/weaver-app/src/components/input/style.css crates/weaver-app/src/components/input/input-style.css
+1 -4
crates/weaver-app/src/components/notebook_cover.rs
··· 1 #![allow(non_snake_case)] 2 3 - use crate::{ 4 - components::avatar::{Avatar, AvatarImage}, 5 - data::NotebookHandle, 6 - }; 7 use dioxus::prelude::*; 8 use weaver_api::sh_weaver::notebook::NotebookView; 9
··· 1 #![allow(non_snake_case)] 2 3 + use crate::components::avatar::{Avatar, AvatarImage}; 4 use dioxus::prelude::*; 5 use weaver_api::sh_weaver::notebook::NotebookView; 6
+5 -4
crates/weaver-app/src/components/profile.rs
··· 5 use crate::components::{ 6 BskyIcon, TangledIcon, 7 avatar::{Avatar, AvatarImage}, 8 - identity::use_repo_notebook_context, 9 }; 10 use dioxus::prelude::*; 11 use weaver_api::com_atproto::repo::strong_ref::StrongRef; ··· 15 const PROFILE_CSS: Asset = asset!("/assets/styling/profile.css"); 16 17 #[component] 18 - pub fn ProfileDisplay(profile: Memo<Option<ProfileDataView<'static>>>) -> Element { 19 - let notebooks = use_repo_notebook_context(); 20 match &*profile.read() { 21 Some(profile_view) => { 22 let profile_view = Arc::new(profile_view.clone()); ··· 57 div { 58 class: "profile-extras", 59 // Stats 60 - ProfileStats { notebooks: notebooks.unwrap() } 61 62 // Links 63 ProfileLinks { profile_view }
··· 5 use crate::components::{ 6 BskyIcon, TangledIcon, 7 avatar::{Avatar, AvatarImage}, 8 }; 9 use dioxus::prelude::*; 10 use weaver_api::com_atproto::repo::strong_ref::StrongRef; ··· 14 const PROFILE_CSS: Asset = asset!("/assets/styling/profile.css"); 15 16 #[component] 17 + pub fn ProfileDisplay( 18 + profile: Memo<Option<ProfileDataView<'static>>>, 19 + notebooks: Memo<Option<Vec<(NotebookView<'static>, Vec<StrongRef<'static>>)>>>, 20 + ) -> Element { 21 match &*profile.read() { 22 Some(profile_view) => { 23 let profile_view = Arc::new(profile_view.clone()); ··· 58 div { 59 class: "profile-extras", 60 // Stats 61 + ProfileStats { notebooks: notebooks } 62 63 // Links 64 ProfileLinks { profile_view }
+216 -86
crates/weaver-app/src/data.rs
··· 36 ident: ReadSignal<AtIdentifier<'static>>, 37 book_title: ReadSignal<SmolStr>, 38 title: ReadSignal<SmolStr>, 39 - ) -> Result<Memo<Option<(BookEntryView<'static>, Entry<'static>)>>, RenderError> { 40 let fetcher = use_context::<crate::fetch::Fetcher>(); 41 let fetcher = fetcher.clone(); 42 let res = use_server_future(move || { ··· 75 None 76 } 77 } 78 - })?; // Handle the Result first to avoid calling use_memo in a closure 79 - Ok(use_memo(move || { 80 if let Some(Some((ev, e))) = &*res.read() { 81 use jacquard::from_json_value; 82 ··· 95 ident: ReadSignal<AtIdentifier<'static>>, 96 book_title: ReadSignal<SmolStr>, 97 title: ReadSignal<SmolStr>, 98 - ) -> Result<Memo<Option<(BookEntryView<'static>, Entry<'static>)>>, RenderError> { 99 let fetcher = use_context::<crate::fetch::Fetcher>(); 100 let fetcher = fetcher.clone(); 101 let res = use_resource(move || { 102 let fetcher = fetcher.clone(); 103 async move { 104 - fetcher 105 .get_entry(ident(), book_title(), title()) 106 .await 107 .ok() 108 .flatten() 109 - .map(|arc| { 110 - ( 111 - serde_json::to_value(arc.0.clone()).unwrap(), 112 - serde_json::to_value(arc.1.clone()).unwrap(), 113 - ) 114 - }) 115 } 116 }); 117 - res.suspend()?; 118 - Ok(use_memo(move || { 119 if let Some(Some((ev, e))) = &*res.read() { 120 use jacquard::from_json_value; 121 ··· 126 } else { 127 None 128 } 129 - })) 130 } 131 132 pub fn use_get_handle(did: Did<'static>) -> AtIdentifier<'static> { 133 let ident = use_signal(use_reactive!(|did| AtIdentifier::Did(did.clone()))); 134 - use_handle(ident.into()) 135 - .read() 136 - .as_ref() 137 - .unwrap_or(&Ok(ident.read().clone())) 138 - .as_ref() 139 - .unwrap() 140 - .clone() 141 } 142 143 - pub fn use_handle( 144 - ident: ReadSignal<AtIdentifier<'static>>, 145 - ) -> Resource<Result<AtIdentifier<'static>, IdentityError>> { 146 let fetcher = use_context::<crate::fetch::Fetcher>(); 147 let fetcher = fetcher.clone(); 148 - use_resource(move || { 149 let client = fetcher.get_client(); 150 async move { 151 client 152 .resolve_ident_owned(&*ident.read()) ··· 156 .first() 157 .map(|h| AtIdentifier::Handle(h.clone()).into_static()) 158 }) 159 - .map(|h| h.ok_or(IdentityError::invalid_well_known()))? 160 } 161 - }) 162 } 163 164 - #[derive(Clone, PartialEq, Eq)] 165 - pub struct NotebookHandle(pub Arc<Option<AtIdentifier<'static>>>); 166 167 - impl NotebookHandle { 168 - pub fn as_ref(&self) -> Option<&AtIdentifier<'static>> { 169 - self.0.as_ref().as_ref() 170 - } 171 - } 172 173 - pub fn use_notebook_handle(ident: Signal<Option<AtIdentifier<'static>>>) -> NotebookHandle { 174 - let ident = if let Some(ident) = &*ident.read() { 175 - let _ident = Signal::new(ident.clone()); 176 - if let Some(Ok(handle)) = &*use_handle(_ident.into()).read() { 177 - Some(handle.clone()) 178 } else { 179 - Some(ident.clone()) 180 } 181 - } else { 182 - ident.read().clone() 183 - }; 184 - use_context_provider(|| NotebookHandle(Arc::new(ident))) 185 } 186 187 /// Hook to render markdown with SSR support. ··· 189 pub fn use_rendered_markdown( 190 content: ReadSignal<Entry<'static>>, 191 ident: ReadSignal<AtIdentifier<'static>>, 192 - ) -> Result<Resource<Option<String>>, RenderError> { 193 let fetcher = use_context::<crate::fetch::Fetcher>(); 194 - Ok(use_server_future(move || { 195 let client = fetcher.get_client(); 196 async move { 197 let did = match ident() { ··· 200 }; 201 Some(render_markdown_impl(content(), did).await) 202 } 203 - })?) 204 } 205 206 /// Hook to render markdown client-side only (no SSR). ··· 208 pub fn use_rendered_markdown( 209 content: ReadSignal<Entry<'static>>, 210 ident: ReadSignal<AtIdentifier<'static>>, 211 - ) -> Result<Resource<Option<String>>, RenderError> { 212 let fetcher = use_context::<crate::fetch::Fetcher>(); 213 - Ok(use_resource(move || { 214 let client = fetcher.get_client(); 215 async move { 216 let did = match ident() { ··· 219 }; 220 Some(render_markdown_impl(content(), did).await) 221 } 222 - })) 223 } 224 225 /// Internal implementation of markdown rendering. ··· 247 #[cfg(feature = "fullstack-server")] 248 pub fn use_profile_data( 249 ident: ReadSignal<AtIdentifier<'static>>, 250 - ) -> Result<Memo<Option<ProfileDataView<'static>>>, RenderError> { 251 let fetcher = use_context::<crate::fetch::Fetcher>(); 252 let res = use_server_future(move || { 253 let fetcher = fetcher.clone(); 254 async move { 255 - fetcher 256 .fetch_profile(&ident()) 257 .await 258 .ok() 259 .map(|arc| serde_json::to_value(&*arc).ok()) 260 - .flatten() 261 } 262 - })?; 263 - Ok(use_memo(move || { 264 if let Some(Some(value)) = &*res.read() { 265 jacquard::from_json_value::<ProfileDataView>(value.clone()).ok() 266 } else { ··· 273 #[cfg(not(feature = "fullstack-server"))] 274 pub fn use_profile_data( 275 ident: ReadSignal<AtIdentifier<'static>>, 276 - ) -> Result<Memo<Option<ProfileDataView<'static>>>, RenderError> { 277 let fetcher = use_context::<crate::fetch::Fetcher>(); 278 let res = use_resource(move || { 279 let fetcher = fetcher.clone(); ··· 286 .flatten() 287 } 288 }); 289 - res.suspend()?; 290 - Ok(use_memo(move || { 291 if let Some(Some(value)) = &*res.read() { 292 jacquard::from_json_value::<ProfileDataView>(value.clone()).ok() 293 } else { 294 None 295 } 296 - })) 297 } 298 299 /// Fetches notebooks for a specific DID 300 #[cfg(feature = "fullstack-server")] 301 pub fn use_notebooks_for_did( 302 ident: ReadSignal<AtIdentifier<'static>>, 303 - ) -> Result<Memo<Option<Vec<(NotebookView<'static>, Vec<StrongRef<'static>>)>>>, RenderError> { 304 let fetcher = use_context::<crate::fetch::Fetcher>(); 305 let res = use_server_future(move || { 306 let fetcher = fetcher.clone(); ··· 317 }) 318 .flatten() 319 } 320 - })?; 321 - Ok(use_memo(move || { 322 if let Some(Some(values)) = &*res.read() { 323 values 324 .iter() ··· 336 #[cfg(not(feature = "fullstack-server"))] 337 pub fn use_notebooks_for_did( 338 ident: ReadSignal<AtIdentifier<'static>>, 339 - ) -> Result<Memo<Option<Vec<(NotebookView<'static>, Vec<StrongRef<'static>>)>>>, RenderError> { 340 let fetcher = use_context::<crate::fetch::Fetcher>(); 341 let res = use_resource(move || { 342 let fetcher = fetcher.clone(); ··· 354 .flatten() 355 } 356 }); 357 - res.suspend()?; 358 - Ok(use_memo(move || { 359 if let Some(Some(values)) = &*res.read() { 360 values 361 .iter() ··· 366 } else { 367 None 368 } 369 - })) 370 } 371 372 /// Fetches notebooks from UFOS with SSR support in fullstack mode 373 #[cfg(feature = "fullstack-server")] 374 pub fn use_notebooks_from_ufos() 375 - -> Result<Memo<Option<Vec<(NotebookView<'static>, Vec<StrongRef<'static>>)>>>, RenderError> { 376 let fetcher = use_context::<crate::fetch::Fetcher>(); 377 let res = use_server_future(move || { 378 let fetcher = fetcher.clone(); ··· 389 }) 390 .flatten() 391 } 392 - })?; 393 - Ok(use_memo(move || { 394 if let Some(Some(values)) = &*res.read() { 395 values 396 .iter() ··· 407 /// Fetches notebooks from UFOS client-side only (no SSR) 408 #[cfg(not(feature = "fullstack-server"))] 409 pub fn use_notebooks_from_ufos() 410 - -> Result<Memo<Option<Vec<(NotebookView<'static>, Vec<StrongRef<'static>>)>>>, RenderError> { 411 let fetcher = use_context::<crate::fetch::Fetcher>(); 412 let res = use_resource(move || { 413 let fetcher = fetcher.clone(); ··· 425 .flatten() 426 } 427 }); 428 - res.suspend()?; 429 - Ok(use_memo(move || { 430 if let Some(Some(values)) = &*res.read() { 431 values 432 .iter() ··· 437 } else { 438 None 439 } 440 - })) 441 } 442 443 /// Fetches notebook metadata with SSR support in fullstack mode ··· 445 pub fn use_notebook( 446 ident: ReadSignal<AtIdentifier<'static>>, 447 book_title: ReadSignal<SmolStr>, 448 - ) -> Result<Memo<Option<(NotebookView<'static>, Vec<StrongRef<'static>>)>>, RenderError> { 449 let fetcher = use_context::<crate::fetch::Fetcher>(); 450 let res = use_server_future(move || { 451 let fetcher = fetcher.clone(); ··· 458 .map(|arc| serde_json::to_value(arc.as_ref()).ok()) 459 .flatten() 460 } 461 - })?; 462 - Ok(use_memo(move || { 463 if let Some(Some(value)) = &*res.read() { 464 jacquard::from_json_value::<(NotebookView, Vec<StrongRef>)>(value.clone()).ok() 465 } else { ··· 473 pub fn use_notebook( 474 ident: ReadSignal<AtIdentifier<'static>>, 475 book_title: ReadSignal<SmolStr>, 476 - ) -> Result<Memo<Option<(NotebookView<'static>, Vec<StrongRef<'static>>)>>, RenderError> { 477 let fetcher = use_context::<crate::fetch::Fetcher>(); 478 let res = use_resource(move || { 479 let fetcher = fetcher.clone(); ··· 487 .flatten() 488 } 489 }); 490 - res.suspend()?; 491 - Ok(use_memo(move || { 492 if let Some(Some(value)) = &*res.read() { 493 jacquard::from_json_value::<(NotebookView, Vec<StrongRef>)>(value.clone()).ok() 494 } else { ··· 502 pub fn use_notebook_entries( 503 ident: ReadSignal<AtIdentifier<'static>>, 504 book_title: ReadSignal<SmolStr>, 505 - ) -> Result<Memo<Option<Vec<BookEntryView<'static>>>>, RenderError> { 506 let fetcher = use_context::<crate::fetch::Fetcher>(); 507 let res = use_server_future(move || { 508 let fetcher = fetcher.clone(); ··· 520 }) 521 .flatten() 522 } 523 - })?; 524 - res.suspend()?; 525 - Ok(use_memo(move || { 526 if let Some(Some(values)) = &*res.read() { 527 values 528 .iter() ··· 539 pub fn use_notebook_entries( 540 ident: ReadSignal<AtIdentifier<'static>>, 541 book_title: ReadSignal<SmolStr>, 542 - ) -> Result<Memo<Option<Vec<BookEntryView<'static>>>>, RenderError> { 543 let fetcher = use_context::<crate::fetch::Fetcher>(); 544 let r = use_resource(move || { 545 let fetcher = fetcher.clone(); ··· 551 .flatten() 552 } 553 }); 554 - r.suspend()?; 555 - Ok(use_memo(move || r.read().as_ref().and_then(|v| v.clone()))) 556 } 557 558 #[cfg(feature = "fullstack-server")]
··· 36 ident: ReadSignal<AtIdentifier<'static>>, 37 book_title: ReadSignal<SmolStr>, 38 title: ReadSignal<SmolStr>, 39 + ) -> Memo<Option<(BookEntryView<'static>, Entry<'static>)>> { 40 let fetcher = use_context::<crate::fetch::Fetcher>(); 41 let fetcher = fetcher.clone(); 42 let res = use_server_future(move || { ··· 75 None 76 } 77 } 78 + }); 79 + use_memo(use_reactive!(|res| { 80 + let res = res.ok()?; 81 if let Some(Some((ev, e))) = &*res.read() { 82 use jacquard::from_json_value; 83 ··· 96 ident: ReadSignal<AtIdentifier<'static>>, 97 book_title: ReadSignal<SmolStr>, 98 title: ReadSignal<SmolStr>, 99 + ) -> Memo<Option<(BookEntryView<'static>, Entry<'static>)>> { 100 let fetcher = use_context::<crate::fetch::Fetcher>(); 101 let fetcher = fetcher.clone(); 102 let res = use_resource(move || { 103 let fetcher = fetcher.clone(); 104 async move { 105 + if let Some(entry) = fetcher 106 .get_entry(ident(), book_title(), title()) 107 .await 108 .ok() 109 .flatten() 110 + { 111 + let (_book_entry_view, entry_record) = (&entry.0, &entry.1); 112 + if let Some(embeds) = &entry_record.embeds { 113 + if let Some(images) = &embeds.images { 114 + #[cfg(all( 115 + target_family = "wasm", 116 + target_os = "unknown", 117 + not(feature = "fullstack-server") 118 + ))] 119 + { 120 + let _ = crate::service_worker::register_entry_blobs( 121 + &ident(), 122 + book_title().as_str(), 123 + images, 124 + &fetcher, 125 + ) 126 + .await; 127 + } 128 + } 129 + } 130 + Some(( 131 + serde_json::to_value(entry.0.clone()).unwrap(), 132 + serde_json::to_value(entry.1.clone()).unwrap(), 133 + )) 134 + } else { 135 + None 136 + } 137 } 138 }); 139 + use_memo(move || { 140 if let Some(Some((ev, e))) = &*res.read() { 141 use jacquard::from_json_value; 142 ··· 147 } else { 148 None 149 } 150 + }) 151 } 152 153 pub fn use_get_handle(did: Did<'static>) -> AtIdentifier<'static> { 154 let ident = use_signal(use_reactive!(|did| AtIdentifier::Did(did.clone()))); 155 + use_handle(ident.into()).read().clone() 156 + } 157 + 158 + #[cfg(feature = "fullstack-server")] 159 + pub fn use_load_handle( 160 + ident: Option<AtIdentifier<'static>>, 161 + ) -> ReadSignal<Option<AtIdentifier<'static>>> { 162 + let ident = use_signal(use_reactive!(|ident| ident.clone())); 163 + let fetcher = use_context::<crate::fetch::Fetcher>(); 164 + let fetcher = fetcher.clone(); 165 + let res = use_server_future(move || { 166 + let client = fetcher.get_client(); 167 + async move { 168 + if let Some(ident) = &*ident.read() { 169 + use jacquard::smol_str::ToSmolStr; 170 + 171 + client 172 + .resolve_ident_owned(ident) 173 + .await 174 + .map(|doc| doc.handles().first().map(|h| h.to_smolstr())) 175 + .unwrap_or(Some(ident.to_smolstr())) 176 + } else { 177 + None 178 + } 179 + } 180 + }); 181 + 182 + use_memo(use_reactive!(|res| { 183 + if let Ok(res) = res { 184 + if let Some(value) = &*res.read() { 185 + if let Some(handle) = value { 186 + AtIdentifier::new_owned(handle.clone()).ok() 187 + } else { 188 + ident.read().clone() 189 + } 190 + } else { 191 + ident.read().clone() 192 + } 193 + } else { 194 + ident.read().clone() 195 + } 196 + })) 197 + .into() 198 } 199 200 + #[cfg(not(feature = "fullstack-server"))] 201 + pub fn use_load_handle( 202 + ident: Option<AtIdentifier<'static>>, 203 + ) -> ReadSignal<Option<AtIdentifier<'static>>> { 204 + let ident = use_signal(use_reactive!(|ident| ident.clone())); 205 + let fetcher = use_context::<crate::fetch::Fetcher>(); 206 + let fetcher = fetcher.clone(); 207 + let res = use_resource(move || { 208 + let client = fetcher.get_client(); 209 + async move { 210 + if let Some(ident) = &*ident.read() { 211 + client 212 + .resolve_ident_owned(ident) 213 + .await 214 + .map(|doc| { 215 + doc.handles() 216 + .first() 217 + .map(|h| AtIdentifier::Handle(h.clone()).into_static()) 218 + }) 219 + .unwrap_or(Some(ident.clone())) 220 + } else { 221 + None 222 + } 223 + } 224 + }); 225 + 226 + if let Ok(ident) = res.suspend() { 227 + ident.into() 228 + } else { 229 + ident.into() 230 + } 231 + } 232 + #[cfg(not(feature = "fullstack-server"))] 233 + pub fn use_handle(ident: ReadSignal<AtIdentifier<'static>>) -> ReadSignal<AtIdentifier<'static>> { 234 + let old_ident = ident.read().clone(); 235 let fetcher = use_context::<crate::fetch::Fetcher>(); 236 let fetcher = fetcher.clone(); 237 + let res = use_resource(move || { 238 let client = fetcher.get_client(); 239 + let old_ident = old_ident.clone(); 240 async move { 241 client 242 .resolve_ident_owned(&*ident.read()) ··· 246 .first() 247 .map(|h| AtIdentifier::Handle(h.clone()).into_static()) 248 }) 249 + .ok() 250 + .flatten() 251 + .unwrap_or(old_ident) 252 } 253 + }); 254 + if let Ok(ident) = res.suspend() { 255 + ident.into() 256 + } else { 257 + ident 258 + } 259 } 260 + #[cfg(feature = "fullstack-server")] 261 + pub fn use_handle(ident: ReadSignal<AtIdentifier<'static>>) -> ReadSignal<AtIdentifier<'static>> { 262 + let old_ident = ident.read().clone(); 263 + let fetcher = use_context::<crate::fetch::Fetcher>(); 264 + let fetcher = fetcher.clone(); 265 + let res = use_server_future(move || { 266 + let client = fetcher.get_client(); 267 + let old_ident = old_ident.clone(); 268 + async move { 269 + use jacquard::smol_str::ToSmolStr; 270 271 + client 272 + .resolve_ident_owned(&*ident.read()) 273 + .await 274 + .map(|doc| { 275 + use jacquard::smol_str::ToSmolStr; 276 277 + doc.handles().first().map(|h| h.to_smolstr()) 278 + }) 279 + .ok() 280 + .flatten() 281 + .unwrap_or(old_ident.to_smolstr()) 282 + } 283 + }); 284 285 + use_memo(use_reactive!(|res| { 286 + if let Ok(res) = res { 287 + if let Some(value) = &*res.read() { 288 + AtIdentifier::new_owned(value).unwrap() 289 + } else { 290 + ident.read().clone() 291 + } 292 } else { 293 + ident.read().clone() 294 } 295 + })) 296 + .into() 297 } 298 299 /// Hook to render markdown with SSR support. ··· 301 pub fn use_rendered_markdown( 302 content: ReadSignal<Entry<'static>>, 303 ident: ReadSignal<AtIdentifier<'static>>, 304 + ) -> Memo<Option<String>> { 305 let fetcher = use_context::<crate::fetch::Fetcher>(); 306 + let res = use_server_future(move || { 307 let client = fetcher.get_client(); 308 async move { 309 let did = match ident() { ··· 312 }; 313 Some(render_markdown_impl(content(), did).await) 314 } 315 + }); 316 + use_memo(use_reactive!(|res| { 317 + let res = res.ok()?; 318 + if let Some(Some(value)) = &*res.read() { 319 + Some(value.clone()) 320 + } else { 321 + None 322 + } 323 + })) 324 } 325 326 /// Hook to render markdown client-side only (no SSR). ··· 328 pub fn use_rendered_markdown( 329 content: ReadSignal<Entry<'static>>, 330 ident: ReadSignal<AtIdentifier<'static>>, 331 + ) -> Memo<Option<String>> { 332 let fetcher = use_context::<crate::fetch::Fetcher>(); 333 + let res = use_resource(move || { 334 let client = fetcher.get_client(); 335 async move { 336 let did = match ident() { ··· 339 }; 340 Some(render_markdown_impl(content(), did).await) 341 } 342 + }); 343 + use_memo(move || { 344 + if let Some(Some(value)) = &*res.read() { 345 + Some(value.clone()) 346 + } else { 347 + None 348 + } 349 + }) 350 } 351 352 /// Internal implementation of markdown rendering. ··· 374 #[cfg(feature = "fullstack-server")] 375 pub fn use_profile_data( 376 ident: ReadSignal<AtIdentifier<'static>>, 377 + ) -> Memo<Option<ProfileDataView<'static>>> { 378 let fetcher = use_context::<crate::fetch::Fetcher>(); 379 let res = use_server_future(move || { 380 let fetcher = fetcher.clone(); 381 async move { 382 + tracing::debug!("use_profile_data server future STARTED for {:?}", ident()); 383 + let result = fetcher 384 .fetch_profile(&ident()) 385 .await 386 .ok() 387 .map(|arc| serde_json::to_value(&*arc).ok()) 388 + .flatten(); 389 + tracing::debug!("use_profile_data server future COMPLETED for {:?}", ident()); 390 + result 391 } 392 + }); 393 + use_memo(use_reactive!(|res| { 394 + let res = res.ok()?; 395 if let Some(Some(value)) = &*res.read() { 396 jacquard::from_json_value::<ProfileDataView>(value.clone()).ok() 397 } else { ··· 404 #[cfg(not(feature = "fullstack-server"))] 405 pub fn use_profile_data( 406 ident: ReadSignal<AtIdentifier<'static>>, 407 + ) -> Memo<Option<ProfileDataView<'static>>> { 408 let fetcher = use_context::<crate::fetch::Fetcher>(); 409 let res = use_resource(move || { 410 let fetcher = fetcher.clone(); ··· 417 .flatten() 418 } 419 }); 420 + use_memo(move || { 421 if let Some(Some(value)) = &*res.read() { 422 jacquard::from_json_value::<ProfileDataView>(value.clone()).ok() 423 } else { 424 None 425 } 426 + }) 427 } 428 429 /// Fetches notebooks for a specific DID 430 #[cfg(feature = "fullstack-server")] 431 pub fn use_notebooks_for_did( 432 ident: ReadSignal<AtIdentifier<'static>>, 433 + ) -> Memo<Option<Vec<(NotebookView<'static>, Vec<StrongRef<'static>>)>>> { 434 let fetcher = use_context::<crate::fetch::Fetcher>(); 435 let res = use_server_future(move || { 436 let fetcher = fetcher.clone(); ··· 447 }) 448 .flatten() 449 } 450 + }); 451 + use_memo(use_reactive!(|res| { 452 + let res = res.ok()?; 453 if let Some(Some(values)) = &*res.read() { 454 values 455 .iter() ··· 467 #[cfg(not(feature = "fullstack-server"))] 468 pub fn use_notebooks_for_did( 469 ident: ReadSignal<AtIdentifier<'static>>, 470 + ) -> Memo<Option<Vec<(NotebookView<'static>, Vec<StrongRef<'static>>)>>> { 471 let fetcher = use_context::<crate::fetch::Fetcher>(); 472 let res = use_resource(move || { 473 let fetcher = fetcher.clone(); ··· 485 .flatten() 486 } 487 }); 488 + use_memo(move || { 489 if let Some(Some(values)) = &*res.read() { 490 values 491 .iter() ··· 496 } else { 497 None 498 } 499 + }) 500 } 501 502 /// Fetches notebooks from UFOS with SSR support in fullstack mode 503 #[cfg(feature = "fullstack-server")] 504 pub fn use_notebooks_from_ufos() 505 + -> Memo<Option<Vec<(NotebookView<'static>, Vec<StrongRef<'static>>)>>> { 506 let fetcher = use_context::<crate::fetch::Fetcher>(); 507 let res = use_server_future(move || { 508 let fetcher = fetcher.clone(); ··· 519 }) 520 .flatten() 521 } 522 + }); 523 + use_memo(use_reactive!(|res| { 524 + let res = res.ok()?; 525 if let Some(Some(values)) = &*res.read() { 526 values 527 .iter() ··· 538 /// Fetches notebooks from UFOS client-side only (no SSR) 539 #[cfg(not(feature = "fullstack-server"))] 540 pub fn use_notebooks_from_ufos() 541 + -> Memo<Option<Vec<(NotebookView<'static>, Vec<StrongRef<'static>>)>>> { 542 let fetcher = use_context::<crate::fetch::Fetcher>(); 543 let res = use_resource(move || { 544 let fetcher = fetcher.clone(); ··· 556 .flatten() 557 } 558 }); 559 + use_memo(move || { 560 if let Some(Some(values)) = &*res.read() { 561 values 562 .iter() ··· 567 } else { 568 None 569 } 570 + }) 571 } 572 573 /// Fetches notebook metadata with SSR support in fullstack mode ··· 575 pub fn use_notebook( 576 ident: ReadSignal<AtIdentifier<'static>>, 577 book_title: ReadSignal<SmolStr>, 578 + ) -> Memo<Option<(NotebookView<'static>, Vec<StrongRef<'static>>)>> { 579 let fetcher = use_context::<crate::fetch::Fetcher>(); 580 let res = use_server_future(move || { 581 let fetcher = fetcher.clone(); ··· 588 .map(|arc| serde_json::to_value(arc.as_ref()).ok()) 589 .flatten() 590 } 591 + }); 592 + use_memo(use_reactive!(|res| { 593 + let res = res.ok()?; 594 if let Some(Some(value)) = &*res.read() { 595 jacquard::from_json_value::<(NotebookView, Vec<StrongRef>)>(value.clone()).ok() 596 } else { ··· 604 pub fn use_notebook( 605 ident: ReadSignal<AtIdentifier<'static>>, 606 book_title: ReadSignal<SmolStr>, 607 + ) -> Memo<Option<(NotebookView<'static>, Vec<StrongRef<'static>>)>> { 608 let fetcher = use_context::<crate::fetch::Fetcher>(); 609 let res = use_resource(move || { 610 let fetcher = fetcher.clone(); ··· 618 .flatten() 619 } 620 }); 621 + use_memo(use_reactive!(|res| { 622 + let res = res.ok()?; 623 if let Some(Some(value)) = &*res.read() { 624 jacquard::from_json_value::<(NotebookView, Vec<StrongRef>)>(value.clone()).ok() 625 } else { ··· 633 pub fn use_notebook_entries( 634 ident: ReadSignal<AtIdentifier<'static>>, 635 book_title: ReadSignal<SmolStr>, 636 + ) -> Memo<Option<Vec<BookEntryView<'static>>>> { 637 let fetcher = use_context::<crate::fetch::Fetcher>(); 638 let res = use_server_future(move || { 639 let fetcher = fetcher.clone(); ··· 651 }) 652 .flatten() 653 } 654 + }); 655 + use_memo(use_reactive!(|res| { 656 + let res = res.ok()?; 657 if let Some(Some(values)) = &*res.read() { 658 values 659 .iter() ··· 670 pub fn use_notebook_entries( 671 ident: ReadSignal<AtIdentifier<'static>>, 672 book_title: ReadSignal<SmolStr>, 673 + ) -> Memo<Option<Vec<BookEntryView<'static>>>> { 674 let fetcher = use_context::<crate::fetch::Fetcher>(); 675 let r = use_resource(move || { 676 let fetcher = fetcher.clone(); ··· 682 .flatten() 683 } 684 }); 685 + use_memo(move || r.read().as_ref().and_then(|v| v.clone())) 686 } 687 688 #[cfg(feature = "fullstack-server")]
+3 -3
crates/weaver-app/src/env.rs
··· 1 // This file is automatically generated by build.rs 2 3 #[allow(unused)] 4 - pub const WEAVER_APP_ENV: &'static str = "prod"; 5 #[allow(unused)] 6 - pub const WEAVER_APP_HOST: &'static str = "https://alpha.weaver.sh"; 7 #[allow(unused)] 8 - pub const WEAVER_APP_DOMAIN: &'static str = "https://alpha.weaver.sh"; 9 #[allow(unused)] 10 pub const WEAVER_PORT: &'static str = "8080"; 11 #[allow(unused)]
··· 1 // This file is automatically generated by build.rs 2 3 #[allow(unused)] 4 + pub const WEAVER_APP_ENV: &'static str = "dev"; 5 #[allow(unused)] 6 + pub const WEAVER_APP_HOST: &'static str = "http://localhost"; 7 #[allow(unused)] 8 + pub const WEAVER_APP_DOMAIN: &'static str = ""; 9 #[allow(unused)] 10 pub const WEAVER_PORT: &'static str = "8080"; 11 #[allow(unused)]
+50 -16
crates/weaver-app/src/main.rs
··· 112 use std::sync::Arc; 113 114 #[cfg(not(feature = "fullstack-server"))] 115 - let router = { 116 - axum::Router::new() 117 - .route("/sw.js", get(serve_sw)) 118 - .merge(dioxus::server::router(App)) 119 - }; 120 121 #[cfg(feature = "fullstack-server")] 122 let router = { ··· 160 #[cfg(not(feature = "server"))] 161 dioxus::launch(App); 162 } 163 164 #[component] 165 fn App() -> Element { 166 let fetcher = use_context_provider(|| { 167 fetch::Fetcher::new(OAuthClient::new( 168 AuthStore::new(), 169 ClientData::new_public(CONFIG.oauth.clone()), 170 )) 171 }); 172 - use_context_provider(|| Signal::new(AuthState::default())); 173 - use_effect(move || { 174 let fetcher = fetcher.clone(); 175 - spawn(async move { 176 - if let Err(e) = auth::restore_session(fetcher).await { 177 - tracing::debug!("Session restoration failed: {}", e); 178 } 179 }); 180 - }); 181 182 #[cfg(all( 183 target_family = "wasm", 184 target_os = "unknown", 185 not(feature = "fullstack-server") 186 ))] 187 - spawn(async move { 188 - let _ = service_worker::register_service_worker().await; 189 - }); 190 191 rsx! { 192 document::Link { rel: "icon", href: FAVICON } ··· 194 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" } 195 document::Link { rel: "preconnect", href: "https://fonts.googleapis.com" } 196 document::Link { rel: "preconnect", href: "https://fonts.gstatic.com" } 197 Router::<Route> {} 198 } 199 } ··· 203 fn ErrorLayout() -> Element { 204 rsx! { 205 ErrorBoundary { 206 - handle_error: move |err: ErrorContext| { 207 #[cfg(feature = "fullstack-server")] 208 { 209 - let http_error = FullstackContext::commit_error_status(err.error().unwrap()); 210 match http_error.status { 211 StatusCode::NOT_FOUND => rsx! { div { "404 - Page not found" } }, 212 _ => rsx! { div { "An unknown error occurred" } },
··· 112 use std::sync::Arc; 113 114 #[cfg(not(feature = "fullstack-server"))] 115 + let router = { axum::Router::new().merge(dioxus::server::router(App)) }; 116 117 #[cfg(feature = "fullstack-server")] 118 let router = { ··· 156 #[cfg(not(feature = "server"))] 157 dioxus::launch(App); 158 } 159 + const THEME_DEFAULTS_CSS: Asset = asset!("/assets/styling/theme-defaults.css"); 160 161 #[component] 162 fn App() -> Element { 163 + tracing::debug!("App component rendering"); 164 + #[allow(unused)] 165 let fetcher = use_context_provider(|| { 166 fetch::Fetcher::new(OAuthClient::new( 167 AuthStore::new(), 168 ClientData::new_public(CONFIG.oauth.clone()), 169 )) 170 }); 171 + let auth_state = use_signal(|| AuthState::default()); 172 + #[allow(unused)] 173 + let auth_state = use_context_provider(|| auth_state); 174 + #[cfg(all( 175 + target_family = "wasm", 176 + target_os = "unknown", 177 + feature = "fullstack-server" 178 + ))] 179 + { 180 let fetcher = fetcher.clone(); 181 + use_future(move || { 182 + let fetcher = fetcher.clone(); 183 + async move { 184 + if let Err(e) = auth::restore_session(fetcher, auth_state).await { 185 + tracing::debug!("Session restoration failed: {}", e); 186 + } 187 } 188 }); 189 + } 190 191 #[cfg(all( 192 target_family = "wasm", 193 target_os = "unknown", 194 not(feature = "fullstack-server") 195 ))] 196 + { 197 + let fetcher = fetcher.clone(); 198 + use_future(move || { 199 + let fetcher = fetcher.clone(); 200 + async move { 201 + if let Err(e) = auth::restore_session(fetcher, auth_state).await { 202 + tracing::debug!("Session restoration failed: {}", e); 203 + } 204 + } 205 + }); 206 + } 207 + 208 + #[cfg(all( 209 + target_family = "wasm", 210 + target_os = "unknown", 211 + not(feature = "fullstack-server") 212 + ))] 213 + { 214 + use_effect(move || { 215 + let fetcher = fetcher.clone(); 216 + spawn(async move { 217 + tracing::info!("Registering service worker"); 218 + let _ = service_worker::register_service_worker().await; 219 + }); 220 + }); 221 + } 222 223 rsx! { 224 document::Link { rel: "icon", href: FAVICON } ··· 226 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" } 227 document::Link { rel: "preconnect", href: "https://fonts.googleapis.com" } 228 document::Link { rel: "preconnect", href: "https://fonts.gstatic.com" } 229 + 230 + document::Link { rel: "stylesheet", href: THEME_DEFAULTS_CSS } 231 Router::<Route> {} 232 } 233 } ··· 237 fn ErrorLayout() -> Element { 238 rsx! { 239 ErrorBoundary { 240 + handle_error: move |_err: ErrorContext| { 241 #[cfg(feature = "fullstack-server")] 242 { 243 + let http_error = FullstackContext::commit_error_status(_err.error().unwrap()); 244 match http_error.status { 245 StatusCode::NOT_FOUND => rsx! { div { "404 - Page not found" } }, 246 _ => rsx! { div { "An unknown error occurred" } },
+17 -6
crates/weaver-app/src/service_worker.rs
··· 12 let window = web_sys::window().ok_or_else(|| JsValue::from_str("no window"))?; 13 let navigator = window.navigator(); 14 let sw_container = navigator.service_worker(); 15 - 16 let promise = sw_container.register("/sw.js"); 17 JsFuture::from(promise).await?; 18 19 Ok(()) 20 } ··· 30 use jacquard::prelude::IdentityResolver; 31 use std::collections::HashMap; 32 33 let mut blob_mappings = HashMap::new(); 34 35 // Resolve DID and PDS URL ··· 61 blob_mappings.insert(name.as_ref().to_string(), blob_url); 62 } 63 } 64 65 - // Send mappings to service worker 66 - if !blob_mappings.is_empty() { 67 - send_blob_mappings(book_title, blob_mappings)?; 68 - } 69 } 70 71 Ok(()) 72 } ··· 80 let navigator = window.navigator(); 81 let sw_container = navigator.service_worker(); 82 83 let controller = sw_container 84 .controller() 85 .ok_or_else(|| JsValue::from_str("no service worker controller"))?; ··· 97 js_sys::Reflect::set(&msg, &"blobs".into(), &blobs_obj)?; 98 99 controller.post_message(&msg)?; 100 101 Ok(()) 102 } ··· 117 } 118 119 // #[used] 120 - // static BINDINGS_JS: Asset = asset!("/assets/sw.js", AssetOptions::js().with_hash_suffix(false));
··· 12 let window = web_sys::window().ok_or_else(|| JsValue::from_str("no window"))?; 13 let navigator = window.navigator(); 14 let sw_container = navigator.service_worker(); 15 + tracing::debug!("Registering service worker"); 16 let promise = sw_container.register("/sw.js"); 17 JsFuture::from(promise).await?; 18 + tracing::debug!("Service worker registered"); 19 20 Ok(()) 21 } ··· 31 use jacquard::prelude::IdentityResolver; 32 use std::collections::HashMap; 33 34 + tracing::debug!("registering blobs for {}", book_title); 35 let mut blob_mappings = HashMap::new(); 36 37 // Resolve DID and PDS URL ··· 63 blob_mappings.insert(name.as_ref().to_string(), blob_url); 64 } 65 } 66 + } 67 68 + // Send mappings to service worker 69 + if !blob_mappings.is_empty() { 70 + send_blob_mappings(book_title, blob_mappings)?; 71 } 72 + //} 73 74 Ok(()) 75 } ··· 83 let navigator = window.navigator(); 84 let sw_container = navigator.service_worker(); 85 86 + tracing::debug!("sending blob mappings for {}", notebook); 87 let controller = sw_container 88 .controller() 89 .ok_or_else(|| JsValue::from_str("no service worker controller"))?; ··· 101 js_sys::Reflect::set(&msg, &"blobs".into(), &blobs_obj)?; 102 103 controller.post_message(&msg)?; 104 + tracing::debug!("sent blob mappings for {}", notebook); 105 106 Ok(()) 107 } ··· 122 } 123 124 // #[used] 125 + // static BINDINGS_JS: Asset = asset!( 126 + // "/sw.js", 127 + // AssetOptions::js() 128 + // .with_hash_suffix(false) 129 + // .with_minify(false) 130 + // .with_preload(true) 131 + // );
+3 -4
crates/weaver-app/src/views/home.rs
··· 8 #[component] 9 pub fn Home() -> Element { 10 // Fetch notebooks from UFOS with SSR support 11 - let notebooks = data::use_notebooks_from_ufos()?; 12 let navigator = use_navigator(); 13 let mut uri_input = use_signal(|| String::new()); 14 ··· 16 let input_uri = uri_input.read().clone(); 17 if !input_uri.is_empty() { 18 if let Ok(parsed) = AtUri::new(&input_uri) { 19 - navigator.push(Route::RecordPage { 20 - uri: vec![parsed.to_string()], 21 - }); 22 } 23 } 24 };
··· 8 #[component] 9 pub fn Home() -> Element { 10 // Fetch notebooks from UFOS with SSR support 11 + let notebooks = data::use_notebooks_from_ufos(); 12 let navigator = use_navigator(); 13 let mut uri_input = use_signal(|| String::new()); 14 ··· 16 let input_uri = uri_input.read().clone(); 17 if !input_uri.is_empty() { 18 if let Ok(parsed) = AtUri::new(&input_uri) { 19 + let link = format!("{}/record/{}", crate::env::WEAVER_APP_DOMAIN, parsed); 20 + navigator.push(link); 21 } 22 } 23 };
+45 -52
crates/weaver-app/src/views/navbar.rs
··· 1 use crate::Route; 2 use crate::components::button::{Button, ButtonVariant}; 3 use crate::components::login::LoginModal; 4 - use crate::data::{use_get_handle, use_notebook_handle}; 5 use crate::fetch::Fetcher; 6 use dioxus::prelude::*; 7 - use jacquard::types::did::Did; 8 9 - const THEME_DEFAULTS_CSS: Asset = asset!("/assets/styling/theme-defaults.css"); 10 const NAVBAR_CSS: Asset = asset!("/assets/styling/navbar.css"); 11 12 /// The Navbar component that will be rendered on all pages of our app since every page is under the layout. ··· 16 /// routes will be rendered under the outlet inside this component 17 #[component] 18 pub fn Navbar() -> Element { 19 let route = use_route::<Route>(); 20 21 - let route_handle = use_signal(|| match &route { 22 Route::EntryPage { ident, .. } => Some(ident.clone()), 23 Route::RepositoryIndex { ident } => Some(ident.clone()), 24 Route::NotebookIndex { ident, .. } => Some(ident.clone()), 25 _ => None, 26 }); 27 - let notebook_handle = use_notebook_handle(route_handle); 28 29 rsx! { 30 - document::Link { rel: "stylesheet", href: THEME_DEFAULTS_CSS } 31 document::Link { rel: "stylesheet", href: NAVBAR_CSS } 32 - 33 div { 34 id: "navbar", 35 nav { class: "breadcrumbs", ··· 41 42 // Show repository breadcrumb if we're on a repository page 43 match route { 44 - Route::RepositoryIndex { .. } => { 45 - let handle = notebook_handle.as_ref().unwrap(); 46 rsx! { 47 span { class: "breadcrumb-separator", " > " } 48 span { class: "breadcrumb breadcrumb-current", "@{handle}" } 49 } 50 }, 51 Route::NotebookIndex { ident, book_title } => { 52 - let handle = notebook_handle.as_ref().unwrap(); 53 rsx! { 54 span { class: "breadcrumb-separator", " > " } 55 Link { ··· 62 } 63 }, 64 Route::EntryPage { ident, book_title, .. } => { 65 - let handle = notebook_handle.as_ref().unwrap(); 66 rsx! { 67 span { class: "breadcrumb-separator", " > " } 68 Link { ··· 81 _ => rsx! {} 82 } 83 } 84 - LoginButton {} 85 - 86 - } 87 - 88 - Outlet::<Route> {} 89 - } 90 - } 91 - 92 - #[component] 93 - fn LoginButton() -> Element { 94 - let fetcher = use_context::<Fetcher>(); 95 - let mut show_login_modal = use_signal(|| false); 96 - let mut auth_state = use_context::<Signal<crate::auth::AuthState>>(); 97 - let did_signal = use_signal(|| auth_state.read().did.clone()); 98 - if let Some(did) = &*did_signal.read() { 99 - rsx! { 100 - Button { 101 - variant: ButtonVariant::Ghost, 102 - onclick: move |_| { 103 - let fetcher = fetcher.clone(); 104 - auth_state.write().clear(); 105 - async move { 106 - fetcher.downgrade_to_unauthenticated().await; 107 } 108 - }, 109 - span { class: "auth-handle", "@{use_get_handle(did.clone())}" } 110 - } 111 - LoginModal { 112 - open: show_login_modal 113 - } 114 - } 115 - } else { 116 - rsx! { 117 - div { 118 - class: "auth-button", 119 - Button { 120 - variant: ButtonVariant::Ghost, 121 - onclick: move |_| show_login_modal.set(true), 122 - span { class: "auth-handle", "Sign In" } 123 } 124 - } 125 - LoginModal { 126 - open: show_login_modal 127 } 128 } 129 } 130 }
··· 1 use crate::Route; 2 + use crate::auth::AuthState; 3 use crate::components::button::{Button, ButtonVariant}; 4 use crate::components::login::LoginModal; 5 + use crate::data::{use_get_handle, use_load_handle}; 6 use crate::fetch::Fetcher; 7 use dioxus::prelude::*; 8 9 const NAVBAR_CSS: Asset = asset!("/assets/styling/navbar.css"); 10 11 /// The Navbar component that will be rendered on all pages of our app since every page is under the layout. ··· 15 /// routes will be rendered under the outlet inside this component 16 #[component] 17 pub fn Navbar() -> Element { 18 + tracing::debug!("Navbar component rendering"); 19 let route = use_route::<Route>(); 20 + tracing::debug!("Route: {:?}", route); 21 22 + let mut auth_state = use_context::<Signal<crate::auth::AuthState>>(); 23 + let route_handle = use_load_handle(match &route { 24 Route::EntryPage { ident, .. } => Some(ident.clone()), 25 Route::RepositoryIndex { ident } => Some(ident.clone()), 26 Route::NotebookIndex { ident, .. } => Some(ident.clone()), 27 _ => None, 28 }); 29 + let fetcher = use_context::<Fetcher>(); 30 + let mut show_login_modal = use_signal(|| false); 31 + 32 + tracing::debug!("Navbar got route_handle: {:?}", route_handle); 33 34 rsx! { 35 document::Link { rel: "stylesheet", href: NAVBAR_CSS } 36 + document::Link { rel: "stylesheet", href: asset!("/assets/styling/button.css") } 37 div { 38 id: "navbar", 39 nav { class: "breadcrumbs", ··· 45 46 // Show repository breadcrumb if we're on a repository page 47 match route { 48 + Route::RepositoryIndex { ident } => { 49 + let route_handle = route_handle.read().clone(); 50 + let handle = route_handle.unwrap_or(ident.clone()); 51 rsx! { 52 span { class: "breadcrumb-separator", " > " } 53 span { class: "breadcrumb breadcrumb-current", "@{handle}" } 54 } 55 }, 56 Route::NotebookIndex { ident, book_title } => { 57 + let route_handle = route_handle.read().clone(); 58 + let handle = route_handle.unwrap_or(ident.clone()); 59 rsx! { 60 span { class: "breadcrumb-separator", " > " } 61 Link { ··· 68 } 69 }, 70 Route::EntryPage { ident, book_title, .. } => { 71 + let route_handle = route_handle.read().clone(); 72 + let handle = route_handle.unwrap_or(ident.clone()); 73 rsx! { 74 span { class: "breadcrumb-separator", " > " } 75 Link { ··· 88 _ => rsx! {} 89 } 90 } 91 + if auth_state.read().is_authenticated() { 92 + if let Some(did) = &auth_state.read().did { 93 + Button { 94 + variant: ButtonVariant::Ghost, 95 + onclick: move |_| { 96 + let fetcher = fetcher.clone(); 97 + auth_state.write().clear(); 98 + async move { 99 + fetcher.downgrade_to_unauthenticated().await; 100 + } 101 + }, 102 + span { class: "auth-handle", "@{use_get_handle(did.clone())}" } 103 + } 104 + } 105 + } else { 106 + div { 107 + class: "auth-button", 108 + Button { 109 + variant: ButtonVariant::Ghost, 110 + onclick: move |_| show_login_modal.set(true), 111 + span { class: "auth-handle", "Sign In" } 112 } 113 + 114 } 115 + LoginModal { 116 + open: show_login_modal 117 + } 118 } 119 } 120 + 121 + Outlet::<Route> {} 122 } 123 }
+13 -5
crates/weaver-app/src/views/notebook.rs
··· 17 /// re-run and the rendered HTML will be updated. 18 #[component] 19 pub fn Notebook(ident: ReadSignal<AtIdentifier<'static>>, book_title: SmolStr) -> Element { 20 rsx! { 21 NotebookCss { ident: ident.to_smolstr(), notebook: book_title } 22 Outlet::<Route> {} ··· 28 ident: ReadSignal<AtIdentifier<'static>>, 29 book_title: ReadSignal<SmolStr>, 30 ) -> Element { 31 // Fetch full notebook metadata with SSR support 32 // IMPORTANT: Call ALL hooks before any ? early returns to maintain hook order 33 let notebook_data = data::use_notebook(ident, book_title); 34 let entries_resource = data::use_notebook_entries(ident, book_title); 35 - 36 - // Now check for errors 37 - let notebook_data = notebook_data?; 38 - let entries_resource = entries_resource?; 39 40 rsx! { 41 document::Link { rel: "stylesheet", href: ENTRY_CARD_CSS } ··· 60 EntryCard { 61 entry: entry.clone(), 62 book_title: book_title(), 63 - author_count 64 } 65 } 66 }
··· 17 /// re-run and the rendered HTML will be updated. 18 #[component] 19 pub fn Notebook(ident: ReadSignal<AtIdentifier<'static>>, book_title: SmolStr) -> Element { 20 + tracing::debug!( 21 + "Notebook component rendering for ident: {:?}, book: {}", 22 + ident(), 23 + book_title 24 + ); 25 rsx! { 26 NotebookCss { ident: ident.to_smolstr(), notebook: book_title } 27 Outlet::<Route> {} ··· 33 ident: ReadSignal<AtIdentifier<'static>>, 34 book_title: ReadSignal<SmolStr>, 35 ) -> Element { 36 + tracing::debug!( 37 + "NotebookIndex component rendering for ident: {:?}, book: {}", 38 + ident(), 39 + book_title() 40 + ); 41 // Fetch full notebook metadata with SSR support 42 // IMPORTANT: Call ALL hooks before any ? early returns to maintain hook order 43 let notebook_data = data::use_notebook(ident, book_title); 44 let entries_resource = data::use_notebook_entries(ident, book_title); 45 + tracing::debug!("NotebookIndex got notebook data and entries"); 46 47 rsx! { 48 document::Link { rel: "stylesheet", href: ENTRY_CARD_CSS } ··· 67 EntryCard { 68 entry: entry.clone(), 69 book_title: book_title(), 70 + author_count, 71 + ident: ident(), 72 } 73 } 74 }
+121 -120
crates/weaver-common/src/agent.rs
··· 614 AgentError::from(ClientError::invalid_request("Invalid weaver profile URI")) 615 }, 616 )?; 617 - let weaver_future = async { 618 - if let Ok(weaver_record) = self.fetch_record(&weaver_uri).await { 619 - // Convert blobs to CDN URLs 620 - let avatar = weaver_record 621 - .value 622 - .avatar 623 - .as_ref() 624 - .map(|blob| { 625 - let cid = blob.blob().cid(); 626 - jacquard::types::string::Uri::new_owned(format!( 627 - "https://cdn.bsky.app/img/avatar/plain/{}/{}@jpeg", 628 - did, cid 629 - )) 630 - }) 631 - .transpose() 632 - .map_err(|_| { 633 - AgentError::from(ClientError::invalid_request("Invalid avatar URI")) 634 - })?; 635 - let banner = weaver_record 636 - .value 637 - .banner 638 - .as_ref() 639 - .map(|blob| { 640 - let cid = blob.blob().cid(); 641 - jacquard::types::string::Uri::new_owned(format!( 642 - "https://cdn.bsky.app/img/banner/plain/{}/{}@jpeg", 643 - did, cid 644 - )) 645 - }) 646 - .transpose() 647 - .map_err(|_| { 648 - AgentError::from(ClientError::invalid_request("Invalid banner URI")) 649 - })?; 650 651 - let profile_view = ProfileView::new() 652 - .did(did.clone()) 653 - .handle(handle.clone()) 654 - .maybe_display_name(weaver_record.value.display_name.clone()) 655 - .maybe_description(weaver_record.value.description.clone()) 656 - .maybe_avatar(avatar) 657 - .maybe_banner(banner) 658 - .maybe_bluesky(weaver_record.value.bluesky) 659 - .maybe_tangled(weaver_record.value.tangled) 660 - .maybe_streamplace(weaver_record.value.streamplace) 661 - .maybe_location(weaver_record.value.location.clone()) 662 - .maybe_links(weaver_record.value.links.clone()) 663 - .maybe_pronouns(weaver_record.value.pronouns.clone()) 664 - .maybe_pinned(weaver_record.value.pinned.clone()) 665 - .indexed_at(jacquard::types::string::Datetime::now()) 666 - .maybe_created_at(weaver_record.value.created_at) 667 - .build(); 668 669 - Ok(( 670 - Some(weaver_uri.as_uri().clone().into_static()), 671 - ProfileDataView::new() 672 - .inner(ProfileDataViewInner::ProfileView(Box::new(profile_view))) 673 - .build() 674 - .into_static(), 675 - )) 676 - } else { 677 - Err(WeaverError::Agent( 678 - ClientError::invalid_request("Invalid weaver profile URI").into(), 679 - )) 680 - } 681 - }; 682 let bsky_appview_future = async { 683 if let Ok(bsky_resp) = self 684 .send(GetProfile::new().actor(did.clone()).build()) ··· 718 AgentError::from(ClientError::invalid_request("Invalid bsky profile URI")) 719 })?; 720 721 - let bsky_future = async { 722 - let bsky_record = self.fetch_record(&bsky_uri).await?; 723 724 - let avatar = bsky_record 725 - .value 726 - .avatar 727 - .as_ref() 728 - .map(|blob| { 729 - let cid = blob.blob().cid(); 730 - jacquard::types::string::Uri::new_owned(format!( 731 - "https://cdn.bsky.app/img/avatar/plain/{}/{}@jpeg", 732 - did, cid 733 - )) 734 - }) 735 - .transpose() 736 - .map_err(|_| { 737 - AgentError::from(ClientError::invalid_request("Invalid avatar URI")) 738 - })?; 739 - let banner = bsky_record 740 - .value 741 - .banner 742 - .as_ref() 743 - .map(|blob| { 744 - let cid = blob.blob().cid(); 745 - jacquard::types::string::Uri::new_owned(format!( 746 - "https://cdn.bsky.app/img/banner/plain/{}/{}@jpeg", 747 - did, cid 748 - )) 749 - }) 750 - .transpose() 751 - .map_err(|_| { 752 - AgentError::from(ClientError::invalid_request("Invalid banner URI")) 753 - })?; 754 755 - let profile_detailed = ProfileViewDetailed::new() 756 - .did(did.clone()) 757 - .handle(handle.clone()) 758 - .maybe_display_name(bsky_record.value.display_name.clone()) 759 - .maybe_description(bsky_record.value.description.clone()) 760 - .maybe_avatar(avatar) 761 - .maybe_banner(banner) 762 - .indexed_at(jacquard::types::string::Datetime::now()) 763 - .maybe_created_at(bsky_record.value.created_at) 764 - .build(); 765 766 - Ok(( 767 - Some(bsky_uri.as_uri().clone().into_static()), 768 - ProfileDataView::new() 769 - .inner(ProfileDataViewInner::ProfileViewDetailed(Box::new( 770 - profile_detailed, 771 - ))) 772 - .build() 773 - .into_static(), 774 - )) 775 - }; 776 777 - n0_future::future::or( 778 - weaver_future, 779 - n0_future::future::or(bsky_appview_future, bsky_future), 780 - ) 781 - .await 782 } 783 } 784
··· 614 AgentError::from(ClientError::invalid_request("Invalid weaver profile URI")) 615 }, 616 )?; 617 + // let weaver_future = async { 618 + // if let Ok(weaver_record) = self.fetch_record(&weaver_uri).await { 619 + // // Convert blobs to CDN URLs 620 + // let avatar = weaver_record 621 + // .value 622 + // .avatar 623 + // .as_ref() 624 + // .map(|blob| { 625 + // let cid = blob.blob().cid(); 626 + // jacquard::types::string::Uri::new_owned(format!( 627 + // "https://cdn.bsky.app/img/avatar/plain/{}/{}@jpeg", 628 + // did, cid 629 + // )) 630 + // }) 631 + // .transpose() 632 + // .map_err(|_| { 633 + // AgentError::from(ClientError::invalid_request("Invalid avatar URI")) 634 + // })?; 635 + // let banner = weaver_record 636 + // .value 637 + // .banner 638 + // .as_ref() 639 + // .map(|blob| { 640 + // let cid = blob.blob().cid(); 641 + // jacquard::types::string::Uri::new_owned(format!( 642 + // "https://cdn.bsky.app/img/banner/plain/{}/{}@jpeg", 643 + // did, cid 644 + // )) 645 + // }) 646 + // .transpose() 647 + // .map_err(|_| { 648 + // AgentError::from(ClientError::invalid_request("Invalid banner URI")) 649 + // })?; 650 651 + // let profile_view = ProfileView::new() 652 + // .did(did.clone()) 653 + // .handle(handle.clone()) 654 + // .maybe_display_name(weaver_record.value.display_name.clone()) 655 + // .maybe_description(weaver_record.value.description.clone()) 656 + // .maybe_avatar(avatar) 657 + // .maybe_banner(banner) 658 + // .maybe_bluesky(weaver_record.value.bluesky) 659 + // .maybe_tangled(weaver_record.value.tangled) 660 + // .maybe_streamplace(weaver_record.value.streamplace) 661 + // .maybe_location(weaver_record.value.location.clone()) 662 + // .maybe_links(weaver_record.value.links.clone()) 663 + // .maybe_pronouns(weaver_record.value.pronouns.clone()) 664 + // .maybe_pinned(weaver_record.value.pinned.clone()) 665 + // .indexed_at(jacquard::types::string::Datetime::now()) 666 + // .maybe_created_at(weaver_record.value.created_at) 667 + // .build(); 668 669 + // Ok(( 670 + // Some(weaver_uri.as_uri().clone().into_static()), 671 + // ProfileDataView::new() 672 + // .inner(ProfileDataViewInner::ProfileView(Box::new(profile_view))) 673 + // .build() 674 + // .into_static(), 675 + // )) 676 + // } else { 677 + // Err(WeaverError::Agent( 678 + // ClientError::invalid_request("Invalid weaver profile URI").into(), 679 + // )) 680 + // } 681 + // }; 682 let bsky_appview_future = async { 683 if let Ok(bsky_resp) = self 684 .send(GetProfile::new().actor(did.clone()).build()) ··· 718 AgentError::from(ClientError::invalid_request("Invalid bsky profile URI")) 719 })?; 720 721 + // let bsky_future = async { 722 + // let bsky_record = self.fetch_record(&bsky_uri).await?; 723 724 + // let avatar = bsky_record 725 + // .value 726 + // .avatar 727 + // .as_ref() 728 + // .map(|blob| { 729 + // let cid = blob.blob().cid(); 730 + // jacquard::types::string::Uri::new_owned(format!( 731 + // "https://cdn.bsky.app/img/avatar/plain/{}/{}@jpeg", 732 + // did, cid 733 + // )) 734 + // }) 735 + // .transpose() 736 + // .map_err(|_| { 737 + // AgentError::from(ClientError::invalid_request("Invalid avatar URI")) 738 + // })?; 739 + // let banner = bsky_record 740 + // .value 741 + // .banner 742 + // .as_ref() 743 + // .map(|blob| { 744 + // let cid = blob.blob().cid(); 745 + // jacquard::types::string::Uri::new_owned(format!( 746 + // "https://cdn.bsky.app/img/banner/plain/{}/{}@jpeg", 747 + // did, cid 748 + // )) 749 + // }) 750 + // .transpose() 751 + // .map_err(|_| { 752 + // AgentError::from(ClientError::invalid_request("Invalid banner URI")) 753 + // })?; 754 755 + // let profile_detailed = ProfileViewDetailed::new() 756 + // .did(did.clone()) 757 + // .handle(handle.clone()) 758 + // .maybe_display_name(bsky_record.value.display_name.clone()) 759 + // .maybe_description(bsky_record.value.description.clone()) 760 + // .maybe_avatar(avatar) 761 + // .maybe_banner(banner) 762 + // .indexed_at(jacquard::types::string::Datetime::now()) 763 + // .maybe_created_at(bsky_record.value.created_at) 764 + // .build(); 765 766 + // Ok(( 767 + // Some(bsky_uri.as_uri().clone().into_static()), 768 + // ProfileDataView::new() 769 + // .inner(ProfileDataViewInner::ProfileViewDetailed(Box::new( 770 + // profile_detailed, 771 + // ))) 772 + // .build() 773 + // .into_static(), 774 + // )) 775 + // }; 776 777 + // n0_future::future::or( 778 + // weaver_future, 779 + // n0_future::future::or(bsky_appview_future, bsky_future), 780 + // ) 781 + // .await 782 + bsky_appview_future.await 783 } 784 } 785
-1
crates/weaver-renderer/src/atproto/client.rs
··· 203 if let Some(embeds) = &entry.embeds { 204 if let Some(images) = &embeds.images { 205 for img in &images.images { 206 - tracing::info!("Image: {:?}", img); 207 if let Some(name) = &img.name { 208 let blob_name = BlobName::from_filename(name.as_ref()); 209 map.insert(blob_name, img.image.blob().cid().clone().into_static());
··· 203 if let Some(embeds) = &entry.embeds { 204 if let Some(images) = &embeds.images { 205 for img in &images.images { 206 if let Some(name) = &img.name { 207 let blob_name = BlobName::from_filename(name.as_ref()); 208 map.insert(blob_name, img.image.blob().cid().clone().into_static());