Commit 6534170de7c765b99af9ce22f47aeb88d40b3ba6

Authored by Georg Hopp
1 parent 73d74786

remove example code

1 -[package]  
2 -name = "mogwai-list"  
3 -version = "0.0.0"  
4 -authors = ["Georg Hopp <georg@steffers.org>"]  
5 -workspace = ".."  
6 -edition = "2018"  
7 -  
8 -[lib]  
9 -crate-type = ["cdylib", "rlib"]  
10 -  
11 -[features]  
12 -default = ["console_error_panic_hook"]  
13 -  
14 -[dependencies]  
15 -artshop-common = { path = "../common" }  
16 -katex = { version = "0.4", default-features = false, features = ["wasm-js"] }  
17 -pulldown-cmark = "0.9"  
18 -console_log = "^0.1"  
19 -log = "^0.4"  
20 -serde = { version = "^1.0", features = ["derive"] }  
21 -serde_json = "^1.0"  
22 -wasm-bindgen = "^0.2"  
23 -wasm-bindgen-futures = "^0.4"  
24 -  
25 -# The `console_error_panic_hook` crate provides better debugging of panics by  
26 -# logging them with `console.error`. This is great for development, but requires  
27 -# all the `std::fmt` and `std::panicking` infrastructure, so isn't great for  
28 -# code size when deploying.  
29 -console_error_panic_hook = { version = "0.1.6", optional = true }  
30 -wee_alloc = { version = "0.4.2", optional = true }  
31 -js-sys = "^0.3"  
32 -  
33 -[dependencies.mogwai]  
34 -version = "^0.5"  
35 -  
36 -[dependencies.web-sys]  
37 -version = "^0.3"  
38 -features = [  
39 - "Document",  
40 - "DomParser",  
41 - "Headers",  
42 - "HtmlElement",  
43 - "HtmlInputElement",  
44 - "MouseEvent",  
45 - "Node",  
46 - "Request",  
47 - "RequestInit",  
48 - "RequestMode",  
49 - "Response",  
50 - "SupportedType",  
51 - "Window",  
52 -]  
53 -  
54 -[dev-dependencies]  
55 -wasm-bindgen-test = "0.2"  
1 -#![allow(unused_braces)]  
2 -use log::Level;  
3 -use mogwai::{futures, prelude::*};  
4 -use std::panic;  
5 -use wasm_bindgen::prelude::*;  
6 -  
7 -/// An item widget.  
8 -/// Keeps track of clicks.  
9 -#[derive(Clone, Debug)]  
10 -struct Item {  
11 - id: usize,  
12 - clicks: Model<u32>,  
13 -}  
14 -  
15 -/// An item's update messages.  
16 -#[derive(Clone)]  
17 -enum ItemMsg {  
18 - /// The user clicked  
19 - Click,  
20 - /// The user requested this item be removed  
21 - Remove,  
22 -}  
23 -  
24 -/// One item's logic loop.  
25 -async fn item_logic(  
26 - id: usize,  
27 - clicks: Model<u32>,  
28 - mut from_view: broadcast::Receiver<ItemMsg>,  
29 - to_list: broadcast::Sender<ListMsg>,  
30 -) {  
31 - loop {  
32 - match from_view.recv().await {  
33 - Ok(ItemMsg::Click) => {  
34 - clicks.visit_mut(|c| *c += 1).await;  
35 - }  
36 - Ok(ItemMsg::Remove) => {  
37 - to_list.broadcast(ListMsg::RemoveItem(id)).await.unwrap();  
38 - break;  
39 - }  
40 - Err(_) => break,  
41 - }  
42 - }  
43 - log::info!("item {} logic loop is done", id);  
44 -}  
45 -  
46 -// ANCHOR: item_view  
47 -fn item_view(  
48 - clicks: impl Stream<Item = u32> + Sendable,  
49 - to_logic: broadcast::Sender<ItemMsg>,  
50 -) -> ViewBuilder<Dom> {  
51 - builder! {  
52 - <li>  
53 - <button  
54 - style:cursor="pointer"  
55 - on:click=to_logic.sink().contra_map(|_| ItemMsg::Click)>  
56 - "Increment"  
57 - </button>  
58 - <button  
59 - style:cursor="pointer"  
60 - on:click=to_logic.sink().contra_map(|_| ItemMsg::Remove)>  
61 - "Remove"  
62 - </button>  
63 - " "  
64 - <span>  
65 - {  
66 - ("", clicks.map(|clicks| match clicks {  
67 - 1 => "1 click".to_string(),  
68 - n => format!("{} clicks", n),  
69 - }))  
70 - }  
71 - </span>  
72 - </li>  
73 - }  
74 -}  
75 -// ANCHOR_END: item_view  
76 -  
77 -/// Create a new item component.  
78 -fn item(id: usize, clicks: Model<u32>, to_list: broadcast::Sender<ListMsg>) -> Component<Dom> {  
79 - let (tx, rx) = broadcast::bounded(1);  
80 - Component::from(item_view(clicks.stream(), tx)).with_logic(item_logic(id, clicks, rx, to_list))  
81 -}  
82 -  
83 -#[derive(Clone)]  
84 -enum ListMsg {  
85 - /// Create a new item  
86 - NewItem,  
87 - /// Remove the item with the given id  
88 - RemoveItem(usize),  
89 -}  
90 -  
91 -// ANCHOR: list_logic_coms  
92 -/// Launch the logic loop of our list of items.  
93 -async fn list_logic(  
94 - input: broadcast::Receiver<ListMsg>,  
95 - tx_patch_children: mpmc::Sender<ListPatch<ViewBuilder<Dom>>>,  
96 -) {  
97 - // Set up our communication from items to this logic loop by  
98 - // * creating a list patch model  
99 - // * creating a channel to go from item to list logic (aka here)  
100 - // * creating a side-effect stream (for_each) that runs for each item patch  
101 - // * map patches of Item to patches of builders and send that to our view  
102 - // through tx_patch_children  
103 - let mut items: ListPatchModel<Item> = ListPatchModel::new();  
104 - let (to_list, from_items) = broadcast::bounded::<ListMsg>(1);  
105 - let to_list = to_list.clone();  
106 - let all_item_patches = items.stream().map(move |patch| {  
107 - log::info!("mapping patch for item: {:?}", patch);  
108 - let to_list = to_list.clone();  
109 - patch.map(move |Item { id, clicks }: Item| {  
110 - let to_list = to_list.clone();  
111 - let component = item(id, clicks, to_list);  
112 - let builder: ViewBuilder<Dom> = component.into();  
113 - builder  
114 - })  
115 - }).for_each(move |patch| {  
116 - let tx_patch_children = tx_patch_children.clone();  
117 - async move {  
118 - tx_patch_children.send(patch).await.unwrap();  
119 - }  
120 - });  
121 - mogwai::spawn(all_item_patches);  
122 - // ANCHOR_END: list_logic_coms  
123 - // ANCHOR: list_logic_loop  
124 - // Combine the input from our view with the input from our items  
125 - let mut input = futures::stream::select_all(vec![input, from_items]);  
126 - let mut next_id = 0;  
127 - loop {  
128 - match input.next().await {  
129 - Some(ListMsg::NewItem) => {  
130 - log::info!("creating a new item");  
131 - let item: Item = Item {  
132 - id: next_id,  
133 - clicks: Model::new(0),  
134 - };  
135 - next_id += 1;  
136 - // patch our items easily and _item_patch_stream's for_each runs automatically,  
137 - // keeping the list of item views in sync  
138 - items.list_patch_push(item);  
139 - }  
140 - Some(ListMsg::RemoveItem(id)) => {  
141 - log::info!("removing item: {}", id);  
142 - let mut may_index = None;  
143 - 'find_item_by_id: for (item, index) in items.read().await.iter().zip(0..) {  
144 - if item.id == id {  
145 - may_index = Some(index);  
146 - break 'find_item_by_id;  
147 - }  
148 - }  
149 -  
150 - if let Some(index) = may_index {  
151 - // patch our items to remove the item at the index  
152 - let _ = items.list_patch_remove(index);  
153 - }  
154 - }  
155 - _ => {  
156 - log::error!("Leaving list logic loop - this shouldn't happen");  
157 - break;  
158 - },  
159 - }  
160 - }  
161 - // ANCHOR_END: list_logic_loop  
162 -}  
163 -  
164 -// ANCHOR: list_view  
165 -fn list_view<T>(to_logic: broadcast::Sender<ListMsg>, children: T) -> ViewBuilder<Dom>  
166 -where  
167 - T: Stream<Item = ListPatch<ViewBuilder<Dom>>> + Sendable,  
168 -{  
169 - builder! {  
170 - <fieldset>  
171 - <legend>"A List of Gizmos"</legend>  
172 - <button style:cursor="pointer" on:click=to_logic.sink().contra_map(|_| ListMsg::NewItem)>  
173 - "Create a new item"  
174 - </button>  
175 - <fieldset>  
176 - <legend>"Items"</legend>  
177 - <ol patch:children=children>  
178 - </ol>  
179 - </fieldset>  
180 - </fieldset>  
181 - }  
182 -}  
183 -// ANCHOR_END: list_view  
184 -  
185 -/// Create our list component.  
186 -fn list() -> Component<Dom> {  
187 - let (logic_tx, logic_rx) = broadcast::bounded(1);  
188 - let (item_patch_tx, item_patch_rx) = mpmc::bounded(1);  
189 - Component::from(list_view(logic_tx, item_patch_rx))  
190 - .with_logic(list_logic(logic_rx, item_patch_tx))  
191 -}  
192 -  
193 -#[wasm_bindgen]  
194 -pub fn main(parent_id: Option<String>) -> Result<(), JsValue> {  
195 - panic::set_hook(Box::new(console_error_panic_hook::hook));  
196 - console_log::init_with_level(Level::Trace).unwrap();  
197 - let component = list();  
198 - let view = component.build().unwrap();  
199 -  
200 - if let Some(id) = parent_id {  
201 - let parent = mogwai::utils::document().get_element_by_id(&id).unwrap();  
202 - view.run_in_container(&parent)  
203 - } else {  
204 - view.run()  
205 - }  
206 -}  
Please register or login to post a comment