Commit 0b0c5fee1ac7c68d63041d7b1bf4f2d9e7d4ad64
1 parent
02651455
Fixes #3 - basic client for file upload
Showing
5 changed files
with
42 additions
and
18 deletions
@@ -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 | } |
@@ -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