logic.rs
4.8 KB
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
use mogwai::prelude::*;
use web_sys::{HtmlInputElement, HtmlCanvasElement, CanvasRenderingContext2d};
use crate::api::upload::UploadApi;
use super::upload::Upload;
#[derive(Clone, Debug)]
pub(super) enum UploadLogic {
Add(DomEvent),
Remove(usize),
Upload,
}
pub(super) async fn upload_preview_logic( mut rx_canvas :broadcast::Receiver<Dom>
, mut rx_click :broadcast::Receiver<DomEvent>
, upload :Upload ) {
if let Some(dom) = rx_canvas.next().await {
if let Either::Left(c) = dom.inner_read() {
let canvas = c.to_owned().dyn_into::<HtmlCanvasElement>().unwrap();
let context = canvas
. get_context("2d").unwrap().unwrap()
. dyn_into::<CanvasRenderingContext2d>().unwrap();
let image_width = upload.bitmap().width() as f64;
let image_height = upload.bitmap().height() as f64;
let canvas_width = canvas.width() as f64;
let canvas_height = canvas.height() as f64;
/* scale with aspect ratio */
let (ox, oy, width, height) = if image_width > image_height {
let f = canvas_width / image_width;
let dest_height = image_height * f;
let o_y = (canvas_height - dest_height) / 2.0;
(0.0, o_y, canvas_width, dest_height)
} else {
let f = canvas_height / image_height;
let dest_width = image_width * f;
let o_x = (canvas_width - dest_width) / 2.0;
(o_x, 0.0, dest_width, canvas_height)
};
context
. draw_image_with_image_bitmap_and_dw_and_dh(
&upload.bitmap()
, ox, oy, width, height )
. unwrap();
}
}
while let Some(_) = rx_click.next().await {
upload.tx_logic . try_broadcast(UploadLogic::Remove(upload.id))
. unwrap();
}
}
pub(super) async fn upload_logic( mut rx_logic :broadcast::Receiver<UploadLogic>
, tx_logic :broadcast::Sender<UploadLogic>
, tx_previews: mpmc::Sender<ListPatch<ViewBuilder<Dom>>>
) {
let mut uploads: ListPatchModel<Upload> = ListPatchModel::new();
let api = UploadApi::new().await.unwrap();
mogwai::spawn(uploads.stream().for_each(move |patch| {
let patch = patch.map(|u| u.into());
let tx_previews = tx_previews.clone();
async move {
tx_previews.send(patch).await.unwrap();
}
}));
let mut next_id = 0;
while let Some(msg) = rx_logic.next().await {
match msg {
UploadLogic::Add(event) =>
if let Either::Left(inner) = event.clone_inner() {
let filelist = inner.dyn_into::<Event>().unwrap()
. target().unwrap()
. dyn_into::<HtmlInputElement>().unwrap()
. files().unwrap();
for index in 0..filelist.length() {
let file = filelist.item(index).unwrap();
let tx_logic = tx_logic.clone();
uploads.list_patch_push( Upload::new(next_id, file, tx_logic)
. await);
next_id += 1;
}
},
UploadLogic::Remove(id) => {
let mut found = None;
for (upload, index) in uploads.read().await.iter().zip(0..) {
if upload.id == id {
found = Some(index);
break;
}
}
if let Some(index) = found {
uploads.list_patch_remove(index).unwrap();
}
},
UploadLogic::Upload => {
let mut remove_ids = vec![];
for upload in uploads.read().await.iter() {
match api.store(upload).await {
Ok(_) => remove_ids.push(upload.id),
Err(e) => log::error!("{:?}", e),
}
}
for id in remove_ids.iter() {
let mut found = None;
for (upload, index) in uploads.read().await.iter().zip(0..) {
if upload.id == *id {
found = Some(index);
break;
}
}
if let Some(index) = found {
uploads.list_patch_remove(index).unwrap();
}
}
}
}
}
}