From 511b7ae6a66dea302d0760ac067e82a6ac5d5cea Mon Sep 17 00:00:00 2001 From: Kenzi Connor Date: Sat, 10 Aug 2024 18:19:26 -0700 Subject: [PATCH] replace old wasm with the new cleaner stuff --- Cargo.toml | 14 +-- Trunk.toml | 2 +- src/lib.rs | 3 - src/{webc => wasm}/file-byte-reader.js | 0 src/wasm/file_input.rs | 112 ------------------------ src/wasm/image.rs | 116 ------------------------- src/wasm/index.html | 65 +++++++++++--- src/wasm/main.rs | 86 +++++++++--------- src/wasm/mod.rs | 5 -- src/wasm/styles.css | 47 ++++++---- src/webc/index.html | 54 ------------ src/webc/main.rs | 50 ----------- src/webc/styles.css | 94 -------------------- 13 files changed, 126 insertions(+), 522 deletions(-) rename src/{webc => wasm}/file-byte-reader.js (100%) delete mode 100644 src/wasm/file_input.rs delete mode 100644 src/wasm/image.rs delete mode 100644 src/wasm/mod.rs delete mode 100644 src/webc/index.html delete mode 100644 src/webc/main.rs delete mode 100644 src/webc/styles.css diff --git a/Cargo.toml b/Cargo.toml index b2cf432..776d4cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,23 +21,15 @@ name = 'cega-wasm' path = "src/wasm/main.rs" required-features = ["wasm"] -[[bin]] -name = 'cega-webc' -path = "src/webc/main.rs" -required-features = ["webc"] - [features] -default = ["terminal", "png", "webc"] +default = ["terminal", "png", "wasm"] png = ["dep:image"] #terminal related features terminal = ["dep:clap"] #Preview window popup for the terminal gui = ["dep:sdl2"] -#Web usage, may want to build with no-default-features to skip irrelevant terminal stuff -wasm = ["png", "dep:base64", "dep:gloo", "dep:js-sys", "dep:web-sys", "dep:yew"] -#Web component, may want to build with no-default-features to skip irrelevant terminal stuff -webc = ["png", "dep:base64", "dep:gloo", "gloo-utils", "dep:js-sys", "dep:wasm-bindgen", "dep:web-sys"] - +#Web assembly components, may want to build with no-default-features to skip irrelevant terminal stuff +wasm = ["png", "dep:base64", "dep:gloo", "gloo-utils", "dep:js-sys", "dep:wasm-bindgen", "dep:web-sys"] [dev-dependencies] rusty-hook = "^0.11.2" diff --git a/Trunk.toml b/Trunk.toml index 6b12686..4b97348 100644 --- a/Trunk.toml +++ b/Trunk.toml @@ -1,3 +1,3 @@ [build] -target = "src/webc/index.html" +target = "src/wasm/index.html" dist = "target/dist" \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 67a1be4..f4a6d31 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,9 +18,6 @@ pub mod terminal; #[cfg(feature = "png")] pub mod png; -#[cfg(feature = "wasm")] -pub mod wasm; - pub type RawGrid = Vec>; pub type Grid = Vec>; diff --git a/src/webc/file-byte-reader.js b/src/wasm/file-byte-reader.js similarity index 100% rename from src/webc/file-byte-reader.js rename to src/wasm/file-byte-reader.js diff --git a/src/wasm/file_input.rs b/src/wasm/file_input.rs deleted file mode 100644 index 6b1794a..0000000 --- a/src/wasm/file_input.rs +++ /dev/null @@ -1,112 +0,0 @@ -use std::collections::HashMap; - -use gloo::file::callbacks::FileReader; -use web_sys::HtmlInputElement; -use yew::prelude::*; - -#[derive(Clone, PartialEq)] -pub struct FileUpload { - pub name: String, - pub mime_type: String, - pub data: Vec, -} - -pub struct FileInput { - readers: HashMap, -} - -pub enum Msg { - Loaded(FileUpload), - Submit(Option), -} - -#[derive(Properties, PartialEq)] -pub struct Props { - pub onload: Callback, - #[prop_or(AttrValue::Static(""))] - pub accept: AttrValue, - #[prop_or(false)] - pub multiple: bool, - #[prop_or(false)] - pub drag_and_drop: bool, - #[prop_or(AttrValue::Static("Drop Files Here"))] - pub label: AttrValue, - pub children: Option, -} - -impl Component for FileInput { - type Message = Msg; - type Properties = Props; - - fn create(_ctx: &Context) -> Self { - Self { - readers: HashMap::default(), - } - } - - fn update(&mut self, ctx: &Context, msg: Self::Message) -> bool { - match msg { - Msg::Loaded(file) => { - self.readers.remove(&file.name); - ctx.props().onload.emit(file); - } - Msg::Submit(files) => { - if let Some(files) = files { - for file in gloo::file::FileList::from(files).iter() { - let link = ctx.link().clone(); - let name = file.name().clone(); - let mime_type = file.raw_mime_type(); - let task = { - gloo::file::callbacks::read_as_bytes(&file, move |res| { - link.send_message(Msg::Loaded(FileUpload { - data: res.expect("failed to read file"), - mime_type, - name, - })) - }) - }; - self.readers.insert(file.name(), task); - } - } - } - } - true - } - - fn view(&self, ctx: &Context) -> Html { - let label_text = &ctx.props().label; - let children = ctx.props().children.clone(); - let accept = &ctx.props().accept; - let multiple = ctx.props().multiple; - - let noop_drag = Callback::from(|e: DragEvent| { - e.prevent_default(); - }); - let onchange = ctx.link().callback(|e: Event| { - e.prevent_default(); - let input: HtmlInputElement = e.target_unchecked_into(); - Msg::Submit(input.files()) - }); - let ondrop = ctx.link().callback(|event: DragEvent| { - event.prevent_default(); - Msg::Submit(event.data_transfer().unwrap().files()) - }); - - html! { - - } - } -} diff --git a/src/wasm/image.rs b/src/wasm/image.rs deleted file mode 100644 index 69f362e..0000000 --- a/src/wasm/image.rs +++ /dev/null @@ -1,116 +0,0 @@ -use base64::{engine::general_purpose::STANDARD, Engine}; - -use web_sys::HtmlInputElement; -use yew::{html, Callback, Component, Context, Event, Html, Properties, SubmitEvent, TargetCast}; - -use crate::color::palette::palette_from_abbr; -use crate::parser::ParserType; -use crate::{file_data, png}; - -use crate::wasm::FileUpload; - -#[derive(Clone, PartialEq, Properties)] -pub struct Props { - pub file: FileUpload, -} - -pub struct ImageComponent { - width: usize, -} - -pub enum Msg { - Width(usize), -} - -impl ImageComponent { - pub fn src(&self, file: &FileUpload) -> String { - let data = if file.mime_type.contains("image") { - file.data.clone() - } else { - let file_data = file_data::Raw::new(&file.data); - let parser = ParserType::CGA; - let image = file_data.parse(parser, self.width); - let palette = palette_from_abbr("cga0"); - let mut bytes: Vec = Vec::new(); - - let _ = png::write_to(&mut bytes, image.data(), palette.clone()); - bytes - }; - format!("data:application/png;base64,{}", STANDARD.encode(data)) - } - - pub fn previews(&self, ctx: &Context, file: &FileUpload) -> Html { - if file.mime_type.contains("image") { - "".into() - } else { - let file_data = file_data::Raw::new(&file.data); - file_data - .previews() - .iter() - .map(|p| { - let palette = palette_from_abbr("cga0"); - let mut bytes: Vec = Vec::new(); - - let _ = png::write_to(&mut bytes, p.data(), palette.clone()); - let src = format!("data:application/png;base64,{}", STANDARD.encode(bytes)); - let width = p.width().clone(); - html! { -
-

{&width.to_string()}

- -
- } - }) - .collect() - } - } -} - -impl Component for ImageComponent { - type Message = Msg; - type Properties = Props; - - fn create(_ctx: &Context) -> Self { - Self { width: 320 } - } - - fn update(&mut self, _ctx: &Context, msg: Self::Message) -> bool { - match msg { - Msg::Width(w) => { - self.width = w; - } - } - true - } - - fn view(&self, ctx: &Context) -> Html { - let noop = Callback::from(|e: SubmitEvent| { - e.prevent_default(); - }); - let onchange = ctx.link().callback(|e: Event| { - let input: HtmlInputElement = e.target_unchecked_into(); - Msg::Width(input.value().parse().expect("fail to parse width")) - }); - let file = &ctx.props().file; - - html! { - <> -
-
-

{ file.name.to_string() }

- -
-
- - -
-
-
- {self.previews(ctx, file)} -
- - } - } -} diff --git a/src/wasm/index.html b/src/wasm/index.html index b16cafc..f4e4d8e 100644 --- a/src/wasm/index.html +++ b/src/wasm/index.html @@ -1,17 +1,54 @@ - - - - - - + + + + + + + +

Process your CGA/EGAs

+ + + \ No newline at end of file diff --git a/src/wasm/main.rs b/src/wasm/main.rs index 3b42fdb..83dba93 100644 --- a/src/wasm/main.rs +++ b/src/wasm/main.rs @@ -1,52 +1,50 @@ #![cfg(feature = "wasm")] -use std::collections::VecDeque; -use yew::prelude::*; -use yew::virtual_dom::VNode; - -use cega::wasm::image::*; -use cega::wasm::{FileInput, FileUpload}; - -pub enum Msg { - Loaded(FileUpload), +use std::collections::HashMap; + +use base64::engine::general_purpose::STANDARD; +use base64::Engine; +use gloo_utils::format::JsValueSerdeExt; +use wasm_bindgen::prelude::*; + +use cega::color::palette::palette_from_abbr; +use cega::file_data::Raw; +use cega::parser::ParserType; +use cega::png; + +#[wasm_bindgen] +pub fn png(data: &[u8]) -> String { + let file_data = Raw::new(data); + let parser = ParserType::CGA; + let image = file_data.parse(parser, 320); + let palette = palette_from_abbr("cga0"); + let result = png::write2(image.data(), palette.clone()); + format!("data:application/png;base64,{}", STANDARD.encode(result)) } -pub struct App { - images: VecDeque, +#[wasm_bindgen] +pub fn previews(data: &[u8]) -> JsValue { + let file_data = Raw::new(data); + let mut hm = HashMap::new(); + hm.insert("CGA".to_string(), preview(&file_data, ParserType::CGA)); + hm.insert( + "EGARowPlanar".to_string(), + preview(&file_data, ParserType::EGARowPlanar), + ); + JsValue::from_serde(&hm).unwrap() } -impl Component for App { - type Message = Msg; - type Properties = (); - - fn create(_ctx: &Context) -> Self { - Self { - images: VecDeque::default(), - } - } - - fn update(&mut self, _ctx: &Context, msg: Self::Message) -> bool { - match msg { - Msg::Loaded(file) => { - self.images - .push_front(html! { }); - } - } - true - } - - fn view(&self, ctx: &Context) -> Html { - let images: Vec = self.images.clone().into(); - html! { -
-

{ "Process your CGA/EGAs" }

- -
{{ images }}
-
- } - } +pub fn preview(data: &Raw, parser: ParserType) -> Vec { + let palette = parser.image_type().default_color_palette(); + data.previews(parser) + .iter() + .map(|p| { + format!( + "data:application/png;base64,{}", + STANDARD.encode(png::write2(p.data(), palette.clone())) + ) + }) + .collect() } -fn main() { - yew::Renderer::::new().render(); -} +fn main() {} diff --git a/src/wasm/mod.rs b/src/wasm/mod.rs deleted file mode 100644 index 4d74efe..0000000 --- a/src/wasm/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub mod file_input; -pub mod image; - -pub use file_input::FileInput; -pub use file_input::FileUpload; diff --git a/src/wasm/styles.css b/src/wasm/styles.css index 511a652..ffd9e9b 100644 --- a/src/wasm/styles.css +++ b/src/wasm/styles.css @@ -5,10 +5,14 @@ html, body { - margin: 0; + margins 0; padding: 0; background: #2d3131; color: #fcfcfc; + display: flex; + align-items: center; + justify-content: center; + flex-flow: column; } p { @@ -19,18 +23,12 @@ label { cursor: pointer; } - -#wrapper { - width: 70%; - margin: auto; -} - #h1 { font-size: 2rem; text-align: center; } -.drop-container { +/*.drop-container { padding: 4rem; display: flex; flex-direction: column; @@ -44,23 +42,36 @@ label { .drop-container i { font-size: 4rem; } - -.preview-area { +*/ +preview-area { display: flex; - flex-wrap: wrap; - justify-content: center; - align-items: stretch; + flex-flow: row nowrap; + align-items: flex-start; + height: 300px; + overflow-y: scroll; } - -.preview-tile { +preview-item { + margin: 1rem; + padding: .5rem .5rem .8rem .5rem; + display: flex; + flex-direction: column; + align-items: center; + background: #111717; + border-radius: 1rem; + cursor: pointer; +} +preview-item > * { + margin: 0px; +} +/*.preview-tile { display: flex; flex-direction: column; padding: 2rem; margin: 1rem; background: #313737; border-radius: 1rem; -} -.preview-row { +}*/ +/*.preview-row { display: flex; flex-direction: row; padding: 2rem; @@ -80,4 +91,4 @@ label { display: flex; flex-direction: column; justify-content: center; -} \ No newline at end of file +}*/ \ No newline at end of file diff --git a/src/webc/index.html b/src/webc/index.html deleted file mode 100644 index 42a6d52..0000000 --- a/src/webc/index.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - -

Process your CGA/EGAs

- - - - \ No newline at end of file diff --git a/src/webc/main.rs b/src/webc/main.rs deleted file mode 100644 index 8c900a4..0000000 --- a/src/webc/main.rs +++ /dev/null @@ -1,50 +0,0 @@ -#![cfg(feature = "webc")] - -use std::collections::HashMap; - -use base64::engine::general_purpose::STANDARD; -use base64::Engine; -use gloo_utils::format::JsValueSerdeExt; -use wasm_bindgen::prelude::*; - -use cega::color::palette::palette_from_abbr; -use cega::file_data::Raw; -use cega::parser::ParserType; -use cega::png; - -#[wasm_bindgen] -pub fn png(data: &[u8]) -> String { - let file_data = Raw::new(data); - let parser = ParserType::CGA; - let image = file_data.parse(parser, 320); - let palette = palette_from_abbr("cga0"); - let result = png::write2(image.data(), palette.clone()); - format!("data:application/png;base64,{}", STANDARD.encode(result)) -} - -#[wasm_bindgen] -pub fn previews(data: &[u8]) -> JsValue { - let file_data = Raw::new(data); - let mut hm = HashMap::new(); - hm.insert("CGA".to_string(), preview(&file_data, ParserType::CGA)); - hm.insert( - "EGARowPlanar".to_string(), - preview(&file_data, ParserType::EGARowPlanar), - ); - JsValue::from_serde(&hm).unwrap() -} - -pub fn preview(data: &Raw, parser: ParserType) -> Vec { - let palette = parser.image_type().default_color_palette(); - data.previews(parser) - .iter() - .map(|p| { - format!( - "data:application/png;base64,{}", - STANDARD.encode(png::write2(p.data(), palette.clone())) - ) - }) - .collect() -} - -fn main() {} diff --git a/src/webc/styles.css b/src/webc/styles.css deleted file mode 100644 index ffd9e9b..0000000 --- a/src/webc/styles.css +++ /dev/null @@ -1,94 +0,0 @@ -* { - box-sizing: border-box; - font-family: Helvetica Neue, Helvetica, Arial, sans-serif; -} - -html, -body { - margins 0; - padding: 0; - background: #2d3131; - color: #fcfcfc; - display: flex; - align-items: center; - justify-content: center; - flex-flow: column; -} - -p { - text-align: center; -} - -label { - cursor: pointer; -} - -#h1 { - font-size: 2rem; - text-align: center; -} - -/*.drop-container { - padding: 4rem; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - background: #3d4141; - border: 1px dashed #fcfcfc; - border-radius: 1rem; -} - -.drop-container i { - font-size: 4rem; -} -*/ -preview-area { - display: flex; - flex-flow: row nowrap; - align-items: flex-start; - height: 300px; - overflow-y: scroll; -} -preview-item { - margin: 1rem; - padding: .5rem .5rem .8rem .5rem; - display: flex; - flex-direction: column; - align-items: center; - background: #111717; - border-radius: 1rem; - cursor: pointer; -} -preview-item > * { - margin: 0px; -} -/*.preview-tile { - display: flex; - flex-direction: column; - padding: 2rem; - margin: 1rem; - background: #313737; - border-radius: 1rem; -}*/ -/*.preview-row { - display: flex; - flex-direction: row; - padding: 2rem; - margin: 1rem; - background: #313737; - border-radius: 1rem; -} -.preview-row .preview-tile { - background: #111717; - border-radius: 1rem; - cursor: pointer; -} - - -.preview-media { - flex: 1; - display: flex; - flex-direction: column; - justify-content: center; -}*/ \ No newline at end of file