1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
use std::borrow::Cow;
use std::rc::Rc;
use bounce::helmet::{HelmetBridge, StaticWriter};
use bounce::{use_atom_setter, BounceRoot};
use stellation_bridge::state::{BridgeMetadataState, BridgeState};
use stellation_bridge::{Bridge, BridgeMetadata};
use yew::prelude::*;
use yew_router::history::{AnyHistory, History, MemoryHistory};
use yew_router::Router;
use crate::props::ServerAppProps;
#[derive(Properties)]
pub(crate) struct StellationRootProps<CTX, BCTX> {
pub helmet_writer: StaticWriter,
pub server_app_props: ServerAppProps<CTX>,
pub bridge: Bridge,
pub bridge_metadata: Rc<BridgeMetadata<BCTX>>,
}
impl<CTX, BCTX> PartialEq for StellationRootProps<CTX, BCTX> {
fn eq(&self, other: &Self) -> bool {
self.helmet_writer == other.helmet_writer
&& self.server_app_props == other.server_app_props
&& self.bridge == other.bridge
&& Rc::ptr_eq(&self.bridge_metadata, &other.bridge_metadata)
}
}
impl<CTX, BCTX> Clone for StellationRootProps<CTX, BCTX> {
fn clone(&self) -> Self {
Self {
helmet_writer: self.helmet_writer.clone(),
server_app_props: self.server_app_props.clone(),
bridge: self.bridge.clone(),
bridge_metadata: self.bridge_metadata.clone(),
}
}
}
#[function_component]
fn Inner<COMP, CTX, BCTX>(props: &StellationRootProps<CTX, BCTX>) -> Html
where
COMP: BaseComponent<Properties = ServerAppProps<CTX>>,
BCTX: 'static,
{
let StellationRootProps {
helmet_writer,
server_app_props,
bridge,
bridge_metadata,
..
} = props.clone();
let history: AnyHistory = MemoryHistory::new().into();
history
.push_with_query(
server_app_props.path(),
server_app_props
.queries::<Vec<(Cow<'_, str>, Cow<'_, str>)>>()
.expect("failed to parse queries"),
)
.expect("failed to push path.");
let set_bridge = use_atom_setter::<BridgeState>();
let set_bridge_metadata = use_atom_setter::<BridgeMetadataState<BCTX>>();
use_memo(
move |_| {
set_bridge(BridgeState { inner: bridge });
set_bridge_metadata(BridgeMetadataState::from(bridge_metadata));
},
(),
);
let children = html! { <COMP ..server_app_props /> };
html! {
<Router {history}>
<HelmetBridge writer={helmet_writer} />
{children}
</Router>
}
}
#[function_component]
pub(crate) fn StellationRoot<COMP, CTX, BCTX>(props: &StellationRootProps<CTX, BCTX>) -> Html
where
COMP: BaseComponent<Properties = ServerAppProps<CTX>>,
CTX: 'static,
BCTX: 'static,
{
let props = props.clone();
html! {
<BounceRoot>
<Inner<COMP, CTX, BCTX> ..props />
</BounceRoot>
}
}