Commit 02651455b83ff4480876d08edeb8e850f5f58526

Authored by Georg Hopp
1 parent a0ed54d6

Upload file selector ready

... ... @@ -19,6 +19,7 @@
19 19 background: #ffffff;
20 20 border-radius: .35em;
21 21 border: 2px solid #bbb;
  22 + cursor: default;
22 23 }
23 24
24 25 .upload > ul > li {
... ...
... ... @@ -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