rsiot/components/cmp_leptos/component/
fn_process.rs1use gloo::storage::{LocalStorage, Storage};
2use leptos::prelude::*;
3use reactive_stores::Store;
4use tokio::{sync::mpsc, task::JoinSet};
5use tracing::debug;
6
7use crate::{
8 executor::{join_set_spawn, CmpInOut},
9 message::{system_messages::*, *},
10};
11
12use super::{
13 super::{Error, Result},
14 Config, StoreBound,
15};
16
17pub async fn fn_process<TMsg, TInputStore, TOutputStore>(
18 config: Config<TMsg, TInputStore, TOutputStore>,
19 in_out: CmpInOut<TMsg>,
20) -> Result
21where
22 TMsg: MsgDataBound + 'static,
23 TInputStore: StoreBound + 'static,
24 TOutputStore: StoreBound + 'static,
25{
26 let input_store = Store::new(config.input_store);
28 let input_store_clone = input_store;
29 let output_store = Store::new(config.output_store);
30 let output_store_clone = output_store;
31 mount_to_body(move || {
32 view! {
33 <RootComponent
34 body_component = config.body_component
35 input_store=input_store_clone
36 output_store=output_store_clone
37 />
38 }
39 });
40 debug!("Leptos app mounted");
41
42 let mut task_set: JoinSet<Result> = JoinSet::new();
43
44 let task = task_input(in_out.clone(), config.fn_input, input_store);
45 join_set_spawn(&mut task_set, task);
46
47 let task = task_output(in_out.clone(), config.fn_output, output_store);
48 join_set_spawn(&mut task_set, task);
49
50 while let Some(task_result) = task_set.join_next().await {
51 task_result??
52 }
53 Ok(())
54}
55
56async fn task_input<TMsg, TInputStore>(
57 mut msg_bus: CmpInOut<TMsg>,
58 fn_input: fn(&Message<TMsg>, &Store<TInputStore>),
59 input_store: Store<TInputStore>,
60) -> Result
61where
62 TMsg: MsgDataBound + 'static,
63 TInputStore: StoreBound + 'static,
64{
65 while let Ok(msg) = msg_bus.recv_input().await {
66 (fn_input)(&msg, &input_store);
67 }
68 Ok(())
69}
70
71async fn task_output<TMsg, TOutputStore>(
72 msg_bus: CmpInOut<TMsg>,
73 fn_output: fn(Store<TOutputStore>, mpsc::Sender<TMsg>),
74 output_store: Store<TOutputStore>,
75) -> Result
76where
77 TMsg: MsgDataBound + 'static,
78 TOutputStore: StoreBound + 'static,
79{
80 let (tx, mut rx) = mpsc::channel(100);
81
82 (fn_output)(output_store, tx);
83
84 while let Some(msg) = rx.recv().await {
85 let msg = Message::new_custom(msg);
86 msg_bus.send_output(msg).await.map_err(Error::CmpOutput)?;
87 }
88
89 Ok(())
90}
91
92fn _try_to_find_token<TMsg>() -> Option<Message<TMsg>>
96where
97 TMsg: MsgDataBound,
98{
99 let msg: Message<TMsg> = LocalStorage::get("System-AuthResponseOk").ok()?;
100 match msg.data {
101 MsgData::System(System::AuthResponseOk(value)) => {
102 let value = AuthRequestByToken { token: value.token };
103 let msg = Message::new(MsgData::System(System::AuthRequestByToken(value)));
104 Some(msg)
105 }
106 _ => None,
107 }
108}
109
110#[component]
112fn RootComponent<TView, TIntoView, TInputStore, TOutputStore>(
113 body_component: TView,
114 input_store: Store<TInputStore>,
115 output_store: Store<TOutputStore>,
116) -> impl IntoView
117where
118 TView: Fn() -> TIntoView,
119 TIntoView: IntoView,
120 TInputStore: StoreBound + 'static,
121 TOutputStore: StoreBound + 'static,
122{
123 provide_context(input_store);
124 provide_context(output_store);
125
126 view! {
127 { body_component() }
128 }
129}