From 09d93fac79c71b295784679f2f150783fcfcee8e Mon Sep 17 00:00:00 2001 From: ElnuDev Date: Sun, 20 Aug 2023 18:33:36 -0700 Subject: [PATCH] Basic KLE layout loader --- Cargo.lock | 2 + dyesub-tool/Cargo.toml | 2 + dyesub-tool/src/main.rs | 141 ++++++++++++++++++++++++++++++++++++++-- flake.nix | 2 +- 4 files changed, 139 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ab10e89..594941c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -393,6 +393,8 @@ dependencies = [ "strum", "strum_macros", "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", ] [[package]] diff --git a/dyesub-tool/Cargo.toml b/dyesub-tool/Cargo.toml index eea0e69..d3f1121 100644 --- a/dyesub-tool/Cargo.toml +++ b/dyesub-tool/Cargo.toml @@ -14,3 +14,5 @@ serde_json = "1.0.105" strum = "0.25.0" strum_macros = "0.25.2" wasm-bindgen = "0.2.87" +wasm-bindgen-futures = "0.4.37" +web-sys = { version = "0.3.64", features = ["FileList", "Blob"] } diff --git a/dyesub-tool/src/main.rs b/dyesub-tool/src/main.rs index 779ad7b..890fc29 100644 --- a/dyesub-tool/src/main.rs +++ b/dyesub-tool/src/main.rs @@ -1,18 +1,145 @@ +#![feature(async_closure)] + mod render; pub mod svg; -use leptos::*; -use wasm_bindgen::JsCast; +use leptos::{*, ev::SubmitEvent, html::Input}; +use wasm_bindgen::{JsCast, JsValue}; +use web_sys::File; +use strum_macros::IntoStaticStr; +use derive_more::From; + +#[derive(Clone)] +struct ResultMessageData { + title: String, + message: View, + colorway: Colorway, +} + +#[derive(Default, Clone, Copy, IntoStaticStr)] +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 ResultMessage(cx: Scope, message: ReadSignal>) -> impl IntoView { + view! { cx, + +
+

{move || message().unwrap().title}

+

{move || message().unwrap().message}

+
+
+ } +} + +#[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 |e: SubmitEvent| { + e.prevent_default(); + 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, + })) + } + }); + }; + view! { cx, +

"Load KLE JSON from file"

+ +
+ + + + +
+ } +} #[component] fn App(cx: Scope) -> impl IntoView { - let (count, set_count) = create_signal(cx, 0); + let (keyboard, set_keyboard) = create_signal(cx, None); view! { cx, - + } } diff --git a/flake.nix b/flake.nix index 92bac71..eddfd97 100644 --- a/flake.nix +++ b/flake.nix @@ -55,7 +55,7 @@ Updating `cargoHash`: version = "0.1.0"; buildAndTestSubdir = "dyesub-tool"; buildInputs = with pkgs; [ trunk ]; - cargoHash = "sha256-Bxc2koMKq8cGFiJtA0qL1geWQls1k2PgtByg7LZwdlc="; + cargoHash = "sha256-UcFVv4lqmZW4Nwjps2u2cNU323hk8ezifeGU9dEZ7Ao="; meta = meta // { description = "A tool for generating dye sublimation transfer sheet SVGs for Japanese thumb shift 拇指シフト keycaps."; };