diff --git a/Cargo.lock b/Cargo.lock index ff223b3..9321164 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1448,9 +1448,9 @@ checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "reqwest" -version = "0.11.19" +version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20b9b67e2ca7dd9e9f9285b759de30ff538aab981abaaf7bc9bd90b84a0126c3" +checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ "base64 0.21.2", "bytes", @@ -2224,12 +2224,11 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "winreg" -version = "0.50.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" dependencies = [ - "cfg-if", - "windows-sys", + "winapi", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 7cb6ede..20dab38 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,2 @@ [workspace] members = ["dyesub-tool"] -resolver = "2" \ No newline at end of file diff --git a/dyesub-tool/Cargo.toml b/dyesub-tool/Cargo.toml index db45730..d8ac557 100644 --- a/dyesub-tool/Cargo.toml +++ b/dyesub-tool/Cargo.toml @@ -16,11 +16,4 @@ strum = "0.25.0" strum_macros = "0.25.2" wasm-bindgen = "0.2.87" wasm-bindgen-futures = "0.4.37" - -[dependencies.web-sys] -version = "0.3.64" -features = [ - "File", - "FileList", - "Request" -] +web-sys = { version = "0.3.64", features = ["FileList", "Blob"] } diff --git a/dyesub-tool/src/components/keyboardfromfile.rs b/dyesub-tool/src/components/keyboardfromfile.rs deleted file mode 100644 index 9a5ff38..0000000 --- a/dyesub-tool/src/components/keyboardfromfile.rs +++ /dev/null @@ -1,66 +0,0 @@ -use leptos::{html::Input, *}; -use web_sys::File; - -use super::ResultMessage; -use crate::{ - components::ResultMessageData, error::ReadKleError, models::Colorway, utils::read_file, -}; - -#[component] -pub fn KeyboardFromFile( - cx: Scope, - set_keyboard: WriteSignal>, -) -> impl IntoView { - let file_input = create_node_ref::(cx); - let (file, set_file) = create_signal(cx, Option::::None); - let (result_message, set_result_message) = create_signal(cx, Option::::None); - let on_submit = move || { - spawn_local(async move { - match read_kle_from_file(file).await { - Ok(keyboard) => { - set_result_message(Some(ResultMessageData { - title: "Success".to_owned(), - message: view! { cx, - "Loaded KLE layout "{&keyboard.metadata.name}" successfully!" - } - .into_view(cx), - colorway: Colorway::Ok, - })); - set_keyboard(Some(keyboard)); - } - Err(err) => { - set_result_message(Some(ResultMessageData { - message: view! { cx, - { - err.to_string() - } - } - .into_view(cx), - title: >::into(err).to_string(), - colorway: Colorway::Bad, - })); - file_input().unwrap().set_value(""); - } - } - }); - }; - view! { cx, -

"Load KLE JSON from file"

- - - } -} - -async fn read_kle_from_file( - file: ReadSignal>, -) -> Result { - Ok(serde_json::from_str(&read_file(file).await?)?) -} diff --git a/dyesub-tool/src/components/keyboardfromweb.rs b/dyesub-tool/src/components/keyboardfromweb.rs deleted file mode 100644 index 0be3101..0000000 --- a/dyesub-tool/src/components/keyboardfromweb.rs +++ /dev/null @@ -1,59 +0,0 @@ -use leptos::{html::Input, *}; -use web_sys::SubmitEvent; - -use super::{ResultMessage, ResultMessageData}; -use crate::{error::FetchKleError, models::Colorway, utils::fetch_file}; - -async fn fetch_layout(url: &str) -> Result { - let layout_string = fetch_file(url).await?; - Ok(serde_json::from_str(&layout_string)?) -} - -#[component] -pub fn KeyboardFromWeb( - cx: Scope, - set_keyboard: WriteSignal>, -) -> impl IntoView { - let (result_message, set_result_message) = create_signal(cx, Option::::None); - let input_element: NodeRef = create_node_ref(cx); - let on_submit = move |e: SubmitEvent| { - e.prevent_default(); - spawn_local(async move { - let url = input_element.get().unwrap().value(); - match fetch_layout(&url).await { - Ok(keyboard) => { - set_result_message(Some(ResultMessageData { - title: "Success".to_owned(), - message: view! { cx, - "Loaded KLE layout "{&keyboard.metadata.name}" successfully!" - } - .into_view(cx), - colorway: Colorway::Ok, - })); - set_keyboard(Some(keyboard)); - } - Err(err) => { - set_result_message(Some(ResultMessageData { - message: view! { cx, - { - err.to_string() - } - } - .into_view(cx), - title: >::into(err).to_string(), - colorway: Colorway::Bad, - })); - input_element().unwrap().set_value(""); - } - } - }) - }; - view! { cx, -

"Load KLE JSON from web"

- -
- - -
- } -} diff --git a/dyesub-tool/src/components/mod.rs b/dyesub-tool/src/components/mod.rs deleted file mode 100644 index d9229fc..0000000 --- a/dyesub-tool/src/components/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -mod resultmessage; -pub use resultmessage::{ResultMessage, ResultMessageData}; - -mod keyboardfromfile; -pub use keyboardfromfile::KeyboardFromFile; - -mod keyboardfromweb; -pub use keyboardfromweb::KeyboardFromWeb; diff --git a/dyesub-tool/src/components/resultmessage.rs b/dyesub-tool/src/components/resultmessage.rs deleted file mode 100644 index 6e13e02..0000000 --- a/dyesub-tool/src/components/resultmessage.rs +++ /dev/null @@ -1,33 +0,0 @@ -use class_list::class_list; -use leptos::*; - -use crate::models::Colorway; - -#[derive(Clone)] -pub struct ResultMessageData { - pub title: String, - pub message: View, - pub colorway: Colorway, -} - -#[component] -pub fn ResultMessage(cx: Scope, message: ReadSignal>) -> impl IntoView { - let (open, set_open) = create_signal(cx, true); - create_effect(cx, move |_| { - message.track(); - set_open(true); - }); - move || { - view! { cx, - - {move || message().map(|ResultMessageData { title, message, colorway }| view! { cx, -
- {title} - -

{message}

-
- })} -
- } - } -} diff --git a/dyesub-tool/src/error/fetchfile.rs b/dyesub-tool/src/error/fetchfile.rs deleted file mode 100644 index ed7bfc7..0000000 --- a/dyesub-tool/src/error/fetchfile.rs +++ /dev/null @@ -1,22 +0,0 @@ -use derive_more::From; -use strum_macros::IntoStaticStr; -use wasm_bindgen::JsValue; - -#[derive(From, IntoStaticStr)] -pub enum FetchFileError { - #[strum(serialize = "Failed to fetch file")] - Request(JsValue), - #[strum(serialize = "Failed to read fetched file to string")] - ReadToString, -} - -impl ToString for FetchFileError { - fn to_string(&self) -> String { - use FetchFileError::*; - match self { - Request(error) => error.as_string(), - _ => None, - } - .unwrap_or_else(|| "".to_string()) - } -} diff --git a/dyesub-tool/src/error/fetchkle.rs b/dyesub-tool/src/error/fetchkle.rs deleted file mode 100644 index 2844f22..0000000 --- a/dyesub-tool/src/error/fetchkle.rs +++ /dev/null @@ -1,38 +0,0 @@ -use derive_more::From; -use strum_macros::IntoStaticStr; - -use super::FetchFileError; - -#[derive(From, IntoStaticStr)] -pub enum FetchKleError { - #[strum( - serialize = "Invalid source. Must be KLE layout, gist URL, gist ID, or direct URL to JSON file" - )] - InvalidSource, - #[strum(serialize = "Failed to fetch file")] - FetchFile(FetchFileError), - #[strum(serialize = "Failed to parse KLE JSON")] - Serde(serde_json::Error), -} - -impl ToString for FetchKleError { - fn to_string(&self) -> String { - use FetchKleError::*; - match self { - FetchFile(error) => Some(match error { - FetchFileError::Request(error_info) => { - let mut full_error = <&FetchFileError as Into<&str>>::into(error).to_string(); - if let Some(error_info) = error_info.as_string() { - full_error.push_str(": "); - full_error.push_str(&error_info); - } - full_error - } - FetchFileError::ReadToString => error.to_string(), - }), - Serde(error) => Some(error.to_string()), - _ => None, - } - .unwrap_or_else(|| "".to_string()) - } -} diff --git a/dyesub-tool/src/error/mod.rs b/dyesub-tool/src/error/mod.rs deleted file mode 100644 index 7e1ac15..0000000 --- a/dyesub-tool/src/error/mod.rs +++ /dev/null @@ -1,11 +0,0 @@ -mod fetchfile; -pub use fetchfile::FetchFileError; - -mod readfile; -pub use readfile::ReadFileError; - -mod fetchkle; -pub use fetchkle::FetchKleError; - -mod readkle; -pub use readkle::ReadKleError; diff --git a/dyesub-tool/src/error/readfile.rs b/dyesub-tool/src/error/readfile.rs deleted file mode 100644 index 50a5955..0000000 --- a/dyesub-tool/src/error/readfile.rs +++ /dev/null @@ -1,24 +0,0 @@ -use derive_more::From; -use strum_macros::IntoStaticStr; -use wasm_bindgen::JsValue; - -#[derive(From, IntoStaticStr)] -pub enum ReadFileError { - #[strum(serialize = "No file chosen")] - NoFile, - #[strum(serialize = "Failed to open file")] - TextAwait(JsValue), - #[strum(serialize = "Failed to parse file to string")] - ParseToString, -} - -impl ToString for ReadFileError { - fn to_string(&self) -> String { - use ReadFileError::*; - match self { - TextAwait(error) => error.as_string(), - _ => None, - } - .unwrap_or_else(|| "".to_string()) - } -} diff --git a/dyesub-tool/src/error/readkle.rs b/dyesub-tool/src/error/readkle.rs deleted file mode 100644 index dc3f5f1..0000000 --- a/dyesub-tool/src/error/readkle.rs +++ /dev/null @@ -1,21 +0,0 @@ -use derive_more::From; -use strum_macros::IntoStaticStr; - -use super::ReadFileError; - -#[derive(From, IntoStaticStr)] -pub enum ReadKleError { - ReadFile(ReadFileError), - #[strum(serialize = "Failed to parse KLE JSON")] - Serde(serde_json::Error), -} - -impl ToString for ReadKleError { - fn to_string(&self) -> String { - use ReadKleError::*; - match self { - ReadFile(error) => error.to_string(), - Serde(error) => error.to_string(), - } - } -} diff --git a/dyesub-tool/src/main.rs b/dyesub-tool/src/main.rs index 4f7358a..249d4ab 100644 --- a/dyesub-tool/src/main.rs +++ b/dyesub-tool/src/main.rs @@ -1,30 +1,166 @@ #![feature(async_closure)] -mod components; -mod error; -mod models; -#[allow(dead_code)] mod render; -#[allow(dead_code)] pub mod svg; -mod utils; -use leptos::*; -use wasm_bindgen::JsCast; +use class_list::class_list; +use derive_more::From; +use leptos::{ev::SubmitEvent, html::Input, *}; +use strum_macros::IntoStaticStr; +use wasm_bindgen::{JsCast, JsValue}; +use web_sys::File; -use components::*; +#[derive(Clone)] +struct ResultMessageData { + title: String, + message: View, + colorway: Colorway, +} + +#[derive(Default, Clone, Copy, IntoStaticStr)] +#[allow(dead_code)] +enum Colorway { + #[default] + #[strum(serialize = "plain")] + Plain, + #[strum(serialize = "info")] + Info, + #[strum(serialize = "ok")] + Ok, + #[strum(serialize = "warn")] + Warn, + #[strum(serialize = "bad")] + Bad, +} #[component] -fn App(cx: Scope) -> impl IntoView { - let (_keyboard, set_keyboard) = create_signal(cx, None); - - view! { cx, - - +fn ResultMessage(cx: Scope, message: ReadSignal>) -> impl IntoView { + let (open, set_open) = create_signal(cx, true); + create_effect(cx, move |_| { + message.track(); + set_open(true); + }); + move || view! { cx, + + {move || message().map(|ResultMessageData { title, message, colorway }| view! { cx, +
>::into(colorway)] style="position: relative"> + {title} + +

{message}

+
+ })} +
} } -fn main() { +#[derive(From, IntoStaticStr)] +enum ReadKleError { + #[strum(serialize = "No file chosen")] + NoFile, + #[strum(serialize = "Failed to open file")] + TextAwait(JsValue), + #[strum(serialize = "Failed to parse file to string")] + ParseToString, + #[strum(serialize = "Failed to parse KLE JSON")] + Serde(serde_json::Error), +} + +impl ToString for ReadKleError { + fn to_string(&self) -> String { + if let Self::TextAwait(error) = self { + if let Some(error) = error.as_string() { + return error; + } + } else if let Self::Serde(error) = self { + return error.to_string(); + } + "".to_string() + } +} + +async fn read_kle_from_file( + file: &ReadSignal>, +) -> Result { + let file = match file() { + Some(file) => file, + None => return Err(ReadKleError::NoFile), + }; + let file_contents = match wasm_bindgen_futures::JsFuture::from(file.text()) + .await? + .as_string() + { + Some(contents) => contents, + None => return Err(ReadKleError::ParseToString), + }; + let keyboard = serde_json::from_str(&file_contents)?; + Ok(keyboard) +} + +#[component] +fn KeyboardFromFile( + cx: Scope, + set_keyboard: WriteSignal>, +) -> impl IntoView { + let file_input = create_node_ref::(cx); + let (file, set_file) = create_signal(cx, Option::::None); + let (result_message, set_result_message) = create_signal(cx, Option::::None); + let on_submit = move || { + spawn_local(async move { + match read_kle_from_file(&file).await { + Ok(keyboard) => { + set_result_message(Some(ResultMessageData { + title: "Success".to_owned(), + message: view! { cx, + "Loaded KLE layout "{&keyboard.metadata.name}" successfully!" + } + .into_view(cx), + colorway: Colorway::Ok, + })); + set_keyboard(Some(keyboard)); + } + Err(err) => { + set_result_message(Some(ResultMessageData { + message: view! { cx, + { + err.to_string() + } + } + .into_view(cx), + title: >::into(err).to_string(), + colorway: Colorway::Bad, + })); + file_input().unwrap().set_value(""); + } + } + }); + }; + view! { cx, +

"Load KLE JSON from file"

+ +
+ +
+ } +} + +#[component] +fn App(cx: Scope) -> impl IntoView { + let (keyboard, set_keyboard) = create_signal(cx, None); + + view! { cx, + + } +} + +pub fn main() { let root = document().query_selector("main").unwrap().unwrap(); mount_to(root.unchecked_into(), |cx| view! { cx, }); } diff --git a/dyesub-tool/src/models/colorway.rs b/dyesub-tool/src/models/colorway.rs deleted file mode 100644 index c2128ee..0000000 --- a/dyesub-tool/src/models/colorway.rs +++ /dev/null @@ -1,25 +0,0 @@ -use class_list::traits::ClassList; -use strum_macros::IntoStaticStr; - -#[derive(Default, Clone, Copy, IntoStaticStr)] -#[allow(dead_code)] -pub enum Colorway { - #[default] - #[strum(serialize = "plain")] - Plain, - #[strum(serialize = "info")] - Info, - #[strum(serialize = "ok")] - Ok, - #[strum(serialize = "warn")] - Warn, - #[strum(serialize = "bad")] - Bad, -} - -impl ClassList for Colorway { - fn to_class_list(&self, _normalize: bool) -> String { - let class: &str = self.into(); - class.to_string() - } -} diff --git a/dyesub-tool/src/models/mod.rs b/dyesub-tool/src/models/mod.rs deleted file mode 100644 index e260b2a..0000000 --- a/dyesub-tool/src/models/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -mod colorway; -pub use colorway::Colorway; diff --git a/dyesub-tool/src/utils.rs b/dyesub-tool/src/utils.rs deleted file mode 100644 index 012b92f..0000000 --- a/dyesub-tool/src/utils.rs +++ /dev/null @@ -1,29 +0,0 @@ -use leptos::*; -use wasm_bindgen_futures::JsFuture; -use web_sys::{File, Request, Window}; - -use crate::error::{FetchFileError, ReadFileError}; - -pub fn window() -> Window { - web_sys::window().unwrap() -} - -pub async fn read_file(file: ReadSignal>) -> Result { - let file = match file() { - Some(file) => file, - None => return Err(ReadFileError::NoFile), - }; - match JsFuture::from(file.text()).await?.as_string() { - Some(contents) => Ok(contents), - None => Err(ReadFileError::ParseToString), - } -} - -pub async fn fetch_file(url: &str) -> Result { - let request = Request::new_with_str(url)?; - let response = JsFuture::from(window().fetch_with_request(&request)).await?; - match response.as_string() { - Some(string) => Ok(string), - None => Err(FetchFileError::ReadToString), - } -}