Skip to content

Commit

Permalink
📝 Transfer preload data to render via context.
Browse files Browse the repository at this point in the history
  • Loading branch information
langyo committed Nov 6, 2024
1 parent 15d0734 commit f3b6bc2
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 6 deletions.
5 changes: 4 additions & 1 deletion website/examples/dev/pages/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ pub async fn html(id: String) -> Result<String> {
format!("/component/{}", id),
AppStates {
theme: Default::default(),
data: PageData::Component(ComponentType::from_str(&id)?),
data: PageData::Component {
id: ComponentType::from_str(&id)?,
raw: "いいよ!こいよ".to_string(),
},
},
)
.await
Expand Down
2 changes: 1 addition & 1 deletion website/examples/dev/pages/guide.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub async fn html(id: String) -> Result<String> {
AppStates {
theme: Default::default(),
data: PageData::Guide {
id,
path: id,
raw: "いいよ!こいよ".to_string(),
},
},
Expand Down
8 changes: 5 additions & 3 deletions website/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ derive_struct!(
theme: Theme,
data: enum PageData {
Portal
Guide { id: String, raw: String }
Component(ComponentType)
Guide { path: String, raw: String }
Component { id: ComponentType, raw: String }
} = Portal
}
);
Expand All @@ -51,7 +51,9 @@ impl DeclType for App {
fn decl_render_outside(props: &RoutesOutsideProps<Self::AppStates>) -> yew::HtmlResult {
Ok(yew::html! {
<ThemeContextShell context={props.states.theme.clone()}>
{props.children.clone()}
<crate::preload_data::Provider preload_data={props.states.data.clone()}>
{props.children.clone()}
</crate::preload_data::Provider>
</ThemeContextShell>
})
}
Expand Down
1 change: 1 addition & 0 deletions website/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod app;
pub mod pages;
pub mod preload_data;

#[cfg(target_arch = "wasm32")]
mod web_entry;
Expand Down
15 changes: 15 additions & 0 deletions website/src/pages/component.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use stylist::yew::styled_component;
use wasm_bindgen::{throw_str, UnwrapThrowExt};
use yew::prelude::*;

use hikari_components::form::Button;
use hikari_theme::types::{ColorType, ComponentType};

use crate::{app::PageData, preload_data::PreloadDataContext};

#[derive(Properties, Debug, PartialEq)]
pub struct Props {
#[prop_or_default]
Expand All @@ -12,11 +15,23 @@ pub struct Props {

#[styled_component]
pub fn Component(props: &Props) -> Html {
let status =
use_context::<PreloadDataContext>().expect_throw("Cannot find preload data context");
let (id, raw) = match &status.preload {
PageData::Component { id, raw } => (id, raw),
_ => throw_str("Invalid preload data"),
};

html! {
<>
<h1>{"Component"}</h1>
<p>{format!("Component {:?}", props.id)}</p>

<pre>
<p>{id.to_string()}</p>
<code>{raw}</code>
</pre>

<Button
color={ColorType::Primary}
on_click={move |_| {
Expand Down
15 changes: 15 additions & 0 deletions website/src/pages/guide.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use stylist::yew::styled_component;
use wasm_bindgen::{throw_str, UnwrapThrowExt};
use yew::prelude::*;

use crate::{app::PageData, preload_data::PreloadDataContext};

#[derive(Properties, Debug, PartialEq)]
pub struct Props {
#[prop_or_default]
Expand All @@ -9,10 +12,22 @@ pub struct Props {

#[styled_component]
pub fn Guide(props: &Props) -> Html {
let status =
use_context::<PreloadDataContext>().expect_throw("Cannot find preload data context");
let (path, raw) = match &status.preload {
PageData::Guide { path, raw } => (path, raw),
_ => throw_str("Invalid preload data"),
};

html! {
<>
<h1>{"Guide"}</h1>
<p>{format!("Guide {}", props.id)}</p>

<pre>
<p>{path}</p>
<code>{raw}</code>
</pre>
</>
}
}
42 changes: 42 additions & 0 deletions website/src/preload_data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use yew::prelude::*;

use crate::app::PageData;

#[derive(Debug, PartialEq, Clone)]
pub struct PreloadData {
pub preload: PageData,
}

#[derive(Debug, PartialEq, Clone)]
pub enum PreloadDataAction {}

impl Reducible for PreloadData {
type Action = PreloadDataAction;

fn reduce(self: std::rc::Rc<Self>, _action: Self::Action) -> std::rc::Rc<Self> {
self
}
}

pub type PreloadDataContext = UseReducerHandle<PreloadData>;

#[derive(Properties, Debug, PartialEq)]
pub struct ProviderProps {
pub preload_data: PageData,

#[prop_or_default]
pub children: Html,
}

#[function_component]
pub fn Provider(props: &ProviderProps) -> Html {
let state = use_reducer(|| PreloadData {
preload: props.preload_data.clone(),
});

html! {
<ContextProvider<PreloadDataContext> context={state}>
{props.children.clone()}
</ContextProvider<PreloadDataContext>>
}
}
12 changes: 11 additions & 1 deletion website/src/web_entry.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use anyhow::anyhow;

use wasm_bindgen::prelude::*;
use web_sys::window;

Expand All @@ -18,14 +20,22 @@ impl WebHandle {

#[wasm_bindgen]
pub async fn start(&self) -> Result<(), wasm_bindgen::JsValue> {
let el = gloo::utils::document().query_selector("#ssr_data")?;
let states = el
.ok_or(wasm_bindgen::JsError::new("Cannot find ssr_data element"))?
.inner_html();
let states: AppStates = serde_json::from_str(&states).map_err(|err| {
wasm_bindgen::JsError::new(&format!("Cannot parse ssr_data element: {}", err))
})?;

<App as hikari_boot::Application>::render_with_root(
window()
.expect("Cannot get window object")
.document()
.expect("Cannot get document object")
.get_element_by_id("app")
.expect("Cannot get root element"),
AppStates::default(), // TODO: Read from raw HTML.
states,
);
Ok(())
}
Expand Down

0 comments on commit f3b6bc2

Please sign in to comment.