···1414jacquard-axum = { workspace = true, optional = true }
1515weaver-api = { path = "../weaver-api", features = ["streaming"] }
1616markdown-weaver = { workspace = true }
1717+weaver-renderer = { path = "../weaver-renderer" }
1718moka = { version = "0.12", features = ["future"], optional = true }
1819mini-moka = { version = "0.10" }
1920dioxus-primitives = { git = "https://github.com/DioxusLabs/components", version = "0.0.1", default-features = false }
2121+axum = {version = "0.8.6", optional = true}
20222123[features]
2224default = ["web"]
···2729# The feature that are only required for the mobile = ["dioxus/mobile"] build target should be optional and only enabled in the mobile = ["dioxus/mobile"] feature
2830mobile = ["dioxus/mobile"]
2931# The feature that are only required for the server = ["dioxus/server"] build target should be optional and only enabled in the server = ["dioxus/server"] feature
3030-server = ["dioxus/server", "dep:jacquard-axum", "dep:moka"]
3232+server = ["dioxus/server", "dep:jacquard-axum", "dep:moka", "dep:axum"]
···22//! They can be used to defined common UI elements like buttons, forms, and modals. In this template, we define a Hero
33//! component and an Echo component for fullstack apps to be used in our app.
4455-mod cssblob;
55+mod css;
66+pub use css::NotebookCss;
6778mod entry;
89pub use entry::{Entry, EntryCard};
···88use std::sync::Arc;
99use views::{Home, Navbar, Notebook, NotebookIndex, NotebookPage};
10101111+mod blobcache;
1112/// Define a components module that contains all shared components for our app.
1213mod components;
1314mod fetch;
···5354 // Run `serve()` on the server only
5455 #[cfg(feature = "server")]
5556 dioxus::serve(|| async move {
5757+ use axum::{extract::Request, middleware, middleware::Next};
5658 // Create a new router for our app using the `router` function
5757- let mut router = dioxus::server::router(App);
5959+ let mut router = dioxus::server::router(App).layer(middleware::from_fn(
6060+ |mut req: Request, next: Next| async move {
6161+ // Attach some extra state to the request
6262+6363+ use crate::fetch::CachedFetcher;
6464+ use std::convert::Infallible;
6565+ use std::sync::Arc;
6666+ req.extensions_mut()
6767+ .insert(Arc::new(CachedFetcher::new(Arc::new(
6868+ BasicClient::unauthenticated(),
6969+ ))));
7070+7171+ // And then return the response with `next.run()
7272+ Ok::<_, Infallible>(next.run(req).await)
7373+ },
7474+ ));
58755976 // .. customize the router, adding layers and new routes
6077
+4-10
crates/weaver-server/src/views/notebook.rs
···11-use crate::{fetch, Route};
11+use crate::{components::NotebookCss, fetch, Route};
22use dioxus::prelude::*;
33use jacquard::{
44- client::BasicClient,
55- smol_str::SmolStr,
66- types::{ident::AtIdentifier, tid::Tid},
77- CowStr,
44+ smol_str::{SmolStr, ToSmolStr},
55+ types::ident::AtIdentifier,
86};
99-use std::sync::Arc;
1010-1111-const BLOG_CSS: Asset = asset!("/assets/styling/blog.css");
127138/// The Blog page component that will be rendered when the current route is `[Route::Blog]`
149///
···1611/// re-run and the rendered HTML will be updated.
1712#[component]
1813pub fn Notebook(ident: AtIdentifier<'static>, book_title: SmolStr) -> Element {
1919- let fetcher = use_context::<fetch::CachedFetcher>();
2014 rsx! {
2121- document::Link { rel: "stylesheet", href: BLOG_CSS }
1515+ NotebookCss { ident: ident.to_smolstr(), notebook: book_title }
2216 Outlet::<Route> {}
2317 }
2418}
-4
crates/weaver-server/src/views/notebookpage.rs
···22use dioxus::prelude::*;
33use jacquard::types::tid::Tid;
4455-const BLOG_CSS: Asset = asset!("/assets/styling/blog.css");
66-75/// The Blog page component that will be rendered when the current route is `[Route::Blog]`
86///
97/// The component takes a `id` prop of type `i32` from the route enum. Whenever the id changes, the component function will be
···119#[component]
1210pub fn NotebookPage(id: Tid, children: Element) -> Element {
1311 rsx! {
1414- document::Link { rel: "stylesheet", href: BLOG_CSS }
1515-1612 div {
1713 id: "blog",
1814