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,20 +2,31 @@ use std::fmt::Display;
2 2
3 use super::super::error::*; 3 use super::super::error::*;
4 use super::super::client::Client; 4 use super::super::client::Client;
  5 +use crate::upload::upload::Upload;
5 6
6 #[derive(Debug, Clone)] 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 match response.status() { 22 match response.status() {
16 200 => Ok(self), 23 200 => Ok(self),
17 status => Err(Self::status_error(status)), 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 use mogwai::prelude::*; 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 use super::upload::Upload; 6 use super::upload::Upload;
5 7
@@ -7,6 +9,7 @@ use super::upload::Upload; @@ -7,6 +9,7 @@ use super::upload::Upload;
7 pub(super) enum UploadLogic { 9 pub(super) enum UploadLogic {
8 Add(DomEvent), 10 Add(DomEvent),
9 Remove(usize), 11 Remove(usize),
  12 + Upload,
10 } 13 }
11 14
12 pub(super) async fn upload_preview_logic( mut rx_canvas :broadcast::Receiver<Dom> 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,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 upload.tx_logic . try_broadcast(UploadLogic::Remove(upload.id)) 34 upload.tx_logic . try_broadcast(UploadLogic::Remove(upload.id))
32 . unwrap(); 35 . unwrap();
33 } 36 }
@@ -38,6 +41,7 @@ pub(super) async fn upload_logic( mut rx_logic :broadcast::Receiver<UploadLogic> @@ -38,6 +41,7 @@ pub(super) async fn upload_logic( mut rx_logic :broadcast::Receiver<UploadLogic>
38 , tx_previews: mpmc::Sender<ListPatch<ViewBuilder<Dom>>> 41 , tx_previews: mpmc::Sender<ListPatch<ViewBuilder<Dom>>>
39 ) { 42 ) {
40 let mut uploads: ListPatchModel<Upload> = ListPatchModel::new(); 43 let mut uploads: ListPatchModel<Upload> = ListPatchModel::new();
  44 + let api = UploadApi::new().await.unwrap();
41 45
42 mogwai::spawn(uploads.stream().for_each(move |patch| { 46 mogwai::spawn(uploads.stream().for_each(move |patch| {
43 let patch = patch.map(|u| u.into()); 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,6 +84,14 @@ pub(super) async fn upload_logic( mut rx_logic :broadcast::Receiver<UploadLogic>
80 uploads.list_patch_remove(index).unwrap(); 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 mod logic; 1 mod logic;
2 -mod upload; 2 +pub(crate) mod upload;
3 mod view; 3 mod view;
4 4
5 use mogwai::prelude::*; 5 use mogwai::prelude::*;
@@ -4,7 +4,7 @@ use web_sys::{File, ImageBitmap, ReadableStream}; @@ -4,7 +4,7 @@ use web_sys::{File, ImageBitmap, ReadableStream};
4 use super::{view::upload_preview_view, logic::{upload_preview_logic, UploadLogic}}; 4 use super::{view::upload_preview_view, logic::{upload_preview_logic, UploadLogic}};
5 5
6 #[derive(Clone, Debug)] 6 #[derive(Clone, Debug)]
7 -pub(super) struct Upload { 7 +pub(crate) struct Upload {
8 pub(super) id :usize, 8 pub(super) id :usize,
9 file :File, 9 file :File,
10 bitmap :ImageBitmap, 10 bitmap :ImageBitmap,
@@ -26,11 +26,11 @@ impl Upload { @@ -26,11 +26,11 @@ impl Upload {
26 Self { id, file, bitmap, tx_logic } 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 self.file.type_() 30 self.file.type_()
31 } 31 }
32 32
33 - pub(super) fn data(&self) -> ReadableStream { 33 + pub(crate) fn data(&self) -> ReadableStream {
34 self.file.stream() 34 self.file.stream()
35 } 35 }
36 36
@@ -32,9 +32,10 @@ pub(super) fn upload_preview_view( tx_canvas :broadcast::Sender<Dom> @@ -32,9 +32,10 @@ pub(super) fn upload_preview_view( tx_canvas :broadcast::Sender<Dom>
32 pub(super) fn upload_view( tx_logic: broadcast::Sender<UploadLogic> 32 pub(super) fn upload_view( tx_logic: broadcast::Sender<UploadLogic>
33 , rx_previews: mpmc::Receiver<ListPatch<ViewBuilder<Dom>>> 33 , rx_previews: mpmc::Receiver<ListPatch<ViewBuilder<Dom>>>
34 ) -> ViewBuilder<Dom> { 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 // <div class="spin"></div> 40 // <div class="spin"></div>
40 builder! { 41 builder! {
@@ -43,8 +44,8 @@ pub(super) fn upload_view( tx_logic: broadcast::Sender<UploadLogic> @@ -43,8 +44,8 @@ pub(super) fn upload_view( tx_logic: broadcast::Sender<UploadLogic>
43 <input type="file" 44 <input type="file"
44 multiple="multiple" 45 multiple="multiple"
45 accept="image/*" 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 </div> 49 </div>
49 <ul patch:children=rx_previews> 50 <ul patch:children=rx_previews>
50 </ul> 51 </ul>
Please register or login to post a comment