Showing
5 changed files
with
86 additions
and
40 deletions
... | ... | @@ -3,28 +3,38 @@ use web_sys::{HtmlInputElement, ImageBitmap, HtmlCanvasElement, CanvasRenderingC |
3 | 3 | |
4 | 4 | use super::upload::Upload; |
5 | 5 | |
6 | +#[derive(Clone, Debug)] | |
7 | +pub(super) enum UploadLogic { | |
8 | + Add(DomEvent), | |
9 | + Remove(usize), | |
10 | +} | |
11 | + | |
6 | 12 | pub(super) async fn upload_preview_logic( mut rx_canvas :broadcast::Receiver<Dom> |
7 | - , upload :Upload ) { | |
8 | - while let Some(dom) = rx_canvas.next().await { | |
9 | - match dom.inner_read() { | |
10 | - Either::Left(c) => { | |
11 | - let canvas = c.to_owned().dyn_into::<HtmlCanvasElement>().unwrap(); | |
12 | - let context = canvas | |
13 | - . get_context("2d").unwrap().unwrap() | |
14 | - . dyn_into::<CanvasRenderingContext2d>().unwrap(); | |
15 | - context | |
16 | - . draw_image_with_image_bitmap_and_dw_and_dh( | |
17 | - &upload.bitmap() | |
18 | - , 0.0, 0.0 | |
19 | - , canvas.width() as f64, canvas.height() as f64 ) | |
20 | - . unwrap(); | |
21 | - }, | |
22 | - _ => (), | |
13 | + , mut rx_click :broadcast::Receiver<DomEvent> | |
14 | + , upload :Upload ) { | |
15 | + if let Some(dom) = rx_canvas.next().await { | |
16 | + if let Either::Left(c) = dom.inner_read() { | |
17 | + let canvas = c.to_owned().dyn_into::<HtmlCanvasElement>().unwrap(); | |
18 | + let context = canvas | |
19 | + . get_context("2d").unwrap().unwrap() | |
20 | + . dyn_into::<CanvasRenderingContext2d>().unwrap(); | |
21 | + context | |
22 | + . draw_image_with_image_bitmap_and_dw_and_dh( | |
23 | + &upload.bitmap() | |
24 | + , 0.0, 0.0 | |
25 | + , canvas.width() as f64, canvas.height() as f64 ) | |
26 | + . unwrap(); | |
23 | 27 | } |
24 | 28 | } |
29 | + | |
30 | + while let Some(event) = rx_click.next().await { | |
31 | + upload.tx_logic . try_broadcast(UploadLogic::Remove(upload.id)) | |
32 | + . unwrap(); | |
33 | + } | |
25 | 34 | } |
26 | 35 | |
27 | -pub(super) async fn upload_logic( mut rx_logic: broadcast::Receiver<DomEvent> | |
36 | +pub(super) async fn upload_logic( mut rx_logic :broadcast::Receiver<UploadLogic> | |
37 | + , tx_logic :broadcast::Sender<UploadLogic> | |
28 | 38 | , tx_previews: mpmc::Sender<ListPatch<ViewBuilder<Dom>>> |
29 | 39 | ) { |
30 | 40 | let mut uploads: ListPatchModel<Upload> = ListPatchModel::new(); |
... | ... | @@ -37,20 +47,39 @@ pub(super) async fn upload_logic( mut rx_logic: broadcast::Receiver<DomEvent> |
37 | 47 | } |
38 | 48 | })); |
39 | 49 | |
50 | + let mut next_id = 0; | |
51 | + | |
40 | 52 | while let Some(msg) = rx_logic.next().await { |
41 | - match msg.clone_inner() { | |
42 | - Either::Left(val) => { | |
43 | - let filelist = val.dyn_into::<Event>().unwrap() | |
44 | - . target().unwrap() | |
45 | - . dyn_into::<HtmlInputElement>().unwrap() | |
46 | - . files().unwrap(); | |
47 | - | |
48 | - for index in 0..filelist.length() { | |
49 | - let file = filelist.item(index).unwrap(); | |
50 | - uploads.list_patch_push(Upload::new(file).await); | |
53 | + match msg { | |
54 | + UploadLogic::Add(event) => | |
55 | + if let Either::Left(inner) = event.clone_inner() { | |
56 | + let filelist = inner.dyn_into::<Event>().unwrap() | |
57 | + . target().unwrap() | |
58 | + . dyn_into::<HtmlInputElement>().unwrap() | |
59 | + . files().unwrap(); | |
60 | + | |
61 | + for index in 0..filelist.length() { | |
62 | + let file = filelist.item(index).unwrap(); | |
63 | + let tx_logic = tx_logic.clone(); | |
64 | + uploads.list_patch_push( Upload::new(next_id, file, tx_logic) | |
65 | + . await); | |
66 | + next_id += 1; | |
67 | + } | |
68 | + }, | |
69 | + UploadLogic::Remove(id) => { | |
70 | + let mut found = None; | |
71 | + | |
72 | + for (upload, index) in uploads.read().await.iter().zip(0..) { | |
73 | + if upload.id == id { | |
74 | + found = Some(index); | |
75 | + break; | |
76 | + } | |
77 | + } | |
78 | + | |
79 | + if let Some(index) = found { | |
80 | + uploads.list_patch_remove(index).unwrap(); | |
51 | 81 | } |
52 | 82 | }, |
53 | - _ => (), | |
54 | 83 | } |
55 | 84 | } |
56 | 85 | } | ... | ... |
... | ... | @@ -10,8 +10,8 @@ pub(crate) async fn new() -> Component<Dom> { |
10 | 10 | let (tx_logic, rx_logic) = broadcast::bounded(1); |
11 | 11 | let (tx_previews, rx_previews) = mpmc::bounded(1); |
12 | 12 | |
13 | - let view = upload_view(tx_logic, rx_previews); | |
14 | - let logic = upload_logic(rx_logic, tx_previews); | |
13 | + let view = upload_view(tx_logic.clone(), rx_previews); | |
14 | + let logic = upload_logic(rx_logic, tx_logic, tx_previews); | |
15 | 15 | |
16 | 16 | Component::from(view).with_logic(logic) |
17 | 17 | } | ... | ... |
1 | 1 | use mogwai::{prelude::*, utils::window}; |
2 | 2 | use web_sys::{File, ImageBitmap, ReadableStream}; |
3 | 3 | |
4 | -use super::{view::upload_preview_view, logic::upload_preview_logic}; | |
4 | +use super::{view::upload_preview_view, logic::{upload_preview_logic, UploadLogic}}; | |
5 | 5 | |
6 | 6 | #[derive(Clone, Debug)] |
7 | 7 | pub(super) struct Upload { |
8 | - file :File, | |
9 | - bitmap :ImageBitmap, | |
8 | + pub(super) id :usize, | |
9 | + file :File, | |
10 | + bitmap :ImageBitmap, | |
11 | + pub(super) tx_logic :broadcast::Sender<UploadLogic>, | |
10 | 12 | } |
11 | 13 | |
12 | 14 | impl Upload { |
13 | - pub(super) async fn new(file :File) -> Upload { | |
15 | + pub(super) async fn new( id :usize | |
16 | + , file :File | |
17 | + , tx_logic :broadcast::Sender<UploadLogic> | |
18 | + ) -> Upload { | |
14 | 19 | let bitmap = window() |
15 | 20 | . create_image_bitmap_with_blob(&file.clone().into()) |
16 | 21 | . unwrap(); |
... | ... | @@ -18,7 +23,7 @@ impl Upload { |
18 | 23 | . await.unwrap() |
19 | 24 | . dyn_into::<ImageBitmap>().unwrap(); |
20 | 25 | |
21 | - Self { file, bitmap } | |
26 | + Self { id, file, bitmap, tx_logic } | |
22 | 27 | } |
23 | 28 | |
24 | 29 | pub(super) fn mime_type(&self) -> String { |
... | ... | @@ -37,13 +42,15 @@ impl Upload { |
37 | 42 | impl From<Upload> for Component<Dom> { |
38 | 43 | fn from(upload: Upload) -> Self { |
39 | 44 | let (tx_canvas, rx_canvas) = broadcast::bounded(1); |
45 | + let (tx_click, rx_click) = broadcast::bounded(1); | |
40 | 46 | |
41 | 47 | let view = upload_preview_view( tx_canvas |
48 | + , tx_click | |
42 | 49 | , upload.file.name() |
43 | 50 | , upload.file.size() |
44 | 51 | , upload.file.type_() |
45 | 52 | , upload.file.last_modified() ); |
46 | - let logic = upload_preview_logic(rx_canvas, upload); | |
53 | + let logic = upload_preview_logic(rx_canvas, rx_click, upload); | |
47 | 54 | |
48 | 55 | Component::from(view).with_logic(logic) |
49 | 56 | } | ... | ... |
1 | 1 | use mogwai::prelude::*; |
2 | 2 | |
3 | +use crate::component::upload::logic::UploadLogic; | |
4 | + | |
3 | 5 | pub(super) fn upload_preview_view( tx_canvas :broadcast::Sender<Dom> |
6 | + , tx_click :broadcast::Sender<DomEvent> | |
4 | 7 | , filename :String |
5 | 8 | , size :f64 |
6 | 9 | , mime_type :String |
7 | - , mtime :f64 ) -> ViewBuilder<Dom> { | |
10 | + , mtime :f64 | |
11 | + ) -> ViewBuilder<Dom> { | |
8 | 12 | let post_build = move |dom: &mut Dom| { |
9 | 13 | tx_canvas.try_broadcast(dom.clone()).unwrap(); |
10 | 14 | }; |
11 | 15 | |
12 | 16 | builder! { |
13 | - <li style:display="flex"> | |
17 | + <li style:display="flex" | |
18 | + on:click=tx_click.sink()> | |
14 | 19 | <canvas width="75px" |
15 | 20 | height="75px" |
16 | 21 | post:build=post_build /> |
... | ... | @@ -24,9 +29,13 @@ pub(super) fn upload_preview_view( tx_canvas :broadcast::Sender<Dom> |
24 | 29 | } |
25 | 30 | } |
26 | 31 | |
27 | -pub(super) fn upload_view( tx_logic: broadcast::Sender<DomEvent> | |
32 | +pub(super) fn upload_view( tx_logic: broadcast::Sender<UploadLogic> | |
28 | 33 | , rx_previews: mpmc::Receiver<ListPatch<ViewBuilder<Dom>>> |
29 | 34 | ) -> ViewBuilder<Dom> { |
35 | + let on_change_filter = tx_logic | |
36 | + . sink() | |
37 | + . contra_map(|e| UploadLogic::Add(e)); | |
38 | + | |
30 | 39 | // <div class="spin"></div> |
31 | 40 | builder! { |
32 | 41 | <div class="upload"> |
... | ... | @@ -34,7 +43,7 @@ pub(super) fn upload_view( tx_logic: broadcast::Sender<DomEvent> |
34 | 43 | <input type="file" |
35 | 44 | multiple="multiple" |
36 | 45 | accept="image/*" |
37 | - on:change=tx_logic.sink() /> | |
46 | + on:change=on_change_filter /> | |
38 | 47 | <button>"Upload"</button> |
39 | 48 | </div> |
40 | 49 | <ul patch:children=rx_previews> | ... | ... |
Please
register
or
login
to post a comment