Commit 0b0c5fee1ac7c68d63041d7b1bf4f2d9e7d4ad64

Authored by Georg Hopp
1 parent 02651455

Fixes #3 - basic client for file upload

... ... @@ -2,20 +2,31 @@ use std::fmt::Display;
2 2
3 3 use super::super::error::*;
4 4 use super::super::client::Client;
  5 +use crate::upload::upload::Upload;
5 6
6 7 #[derive(Debug, Clone)]
7   -pub struct Upload {
8   - client: Client,
  8 +pub struct UploadApi {
  9 + client :Client,
9 10 }
10 11
11   -impl Upload {
12   - pub(crate) async fn new(name :&str) -> Result<()> {
13   - Ok(())
14   - /*
  12 +impl UploadApi {
  13 + pub(crate) async fn new() -> Result<UploadApi> {
  14 + let client = Client::new()?;
  15 + Ok(UploadApi { client })
  16 + }
  17 +
  18 + pub(crate) async fn store(&self, upload :&Upload) -> Result<&UploadApi> {
  19 + let response = self.client.post_stream( "/api/v0/upload"
  20 + , &upload.mime_type()
  21 + , upload.data() ).await?;
15 22 match response.status() {
16 23 200 => Ok(self),
17 24 status => Err(Self::status_error(status)),
18 25 }
19   - */
  26 + }
  27 +
  28 + fn status_error<I: Display>(status :I) -> Error {
  29 + let err_str = format!("Invalid response status: {}", status);
  30 + Error::from(err_str.as_str())
20 31 }
21 32 }
... ...
1 1 use mogwai::prelude::*;
2   -use web_sys::{HtmlInputElement, ImageBitmap, HtmlCanvasElement, CanvasRenderingContext2d};
  2 +use web_sys::{HtmlInputElement, HtmlCanvasElement, CanvasRenderingContext2d};
  3 +
  4 +use crate::api::upload::UploadApi;
3 5
4 6 use super::upload::Upload;
5 7
... ... @@ -7,6 +9,7 @@ use super::upload::Upload;
7 9 pub(super) enum UploadLogic {
8 10 Add(DomEvent),
9 11 Remove(usize),
  12 + Upload,
10 13 }
11 14
12 15 pub(super) async fn upload_preview_logic( mut rx_canvas :broadcast::Receiver<Dom>
... ... @@ -27,7 +30,7 @@ pub(super) async fn upload_preview_logic( mut rx_canvas :broadcast::Receiver<Dom
27 30 }
28 31 }
29 32
30   - while let Some(event) = rx_click.next().await {
  33 + while let Some(_) = rx_click.next().await {
31 34 upload.tx_logic . try_broadcast(UploadLogic::Remove(upload.id))
32 35 . unwrap();
33 36 }
... ... @@ -38,6 +41,7 @@ pub(super) async fn upload_logic( mut rx_logic :broadcast::Receiver<UploadLogic>
38 41 , tx_previews: mpmc::Sender<ListPatch<ViewBuilder<Dom>>>
39 42 ) {
40 43 let mut uploads: ListPatchModel<Upload> = ListPatchModel::new();
  44 + let api = UploadApi::new().await.unwrap();
41 45
42 46 mogwai::spawn(uploads.stream().for_each(move |patch| {
43 47 let patch = patch.map(|u| u.into());
... ... @@ -80,6 +84,14 @@ pub(super) async fn upload_logic( mut rx_logic :broadcast::Receiver<UploadLogic>
80 84 uploads.list_patch_remove(index).unwrap();
81 85 }
82 86 },
  87 + UploadLogic::Upload => {
  88 + for upload in uploads.read().await.iter() {
  89 + match api.store(upload).await {
  90 + Ok(_) => (),
  91 + Err(e) => log::error!("{:?}", e),
  92 + }
  93 + }
  94 + }
83 95 }
84 96 }
85 97 }
... ...
1 1 mod logic;
2   -mod upload;
  2 +pub(crate) mod upload;
3 3 mod view;
4 4
5 5 use mogwai::prelude::*;
... ...
... ... @@ -4,7 +4,7 @@ use web_sys::{File, ImageBitmap, ReadableStream};
4 4 use super::{view::upload_preview_view, logic::{upload_preview_logic, UploadLogic}};
5 5
6 6 #[derive(Clone, Debug)]
7   -pub(super) struct Upload {
  7 +pub(crate) struct Upload {
8 8 pub(super) id :usize,
9 9 file :File,
10 10 bitmap :ImageBitmap,
... ... @@ -26,11 +26,11 @@ impl Upload {
26 26 Self { id, file, bitmap, tx_logic }
27 27 }
28 28
29   - pub(super) fn mime_type(&self) -> String {
  29 + pub(crate) fn mime_type(&self) -> String {
30 30 self.file.type_()
31 31 }
32 32
33   - pub(super) fn data(&self) -> ReadableStream {
  33 + pub(crate) fn data(&self) -> ReadableStream {
34 34 self.file.stream()
35 35 }
36 36
... ...
... ... @@ -32,9 +32,10 @@ pub(super) fn upload_preview_view( tx_canvas :broadcast::Sender<Dom>
32 32 pub(super) fn upload_view( tx_logic: broadcast::Sender<UploadLogic>
33 33 , rx_previews: mpmc::Receiver<ListPatch<ViewBuilder<Dom>>>
34 34 ) -> ViewBuilder<Dom> {
35   - let on_change_filter = tx_logic
36   - . sink()
37   - . contra_map(|e| UploadLogic::Add(e));
  35 + let select_filter = tx_logic.sink()
  36 + . contra_map(|e| UploadLogic::Add(e));
  37 + let upload_filter = tx_logic.sink()
  38 + . contra_map(|_| UploadLogic::Upload);
38 39
39 40 // <div class="spin"></div>
40 41 builder! {
... ... @@ -43,8 +44,8 @@ pub(super) fn upload_view( tx_logic: broadcast::Sender<UploadLogic>
43 44 <input type="file"
44 45 multiple="multiple"
45 46 accept="image/*"
46   - on:change=on_change_filter />
47   - <button>"Upload"</button>
  47 + on:change=select_filter />
  48 + <button on:click=upload_filter>"Upload"</button>
48 49 </div>
49 50 <ul patch:children=rx_previews>
50 51 </ul>
... ...
Please register or login to post a comment