Skip to content

Commit

Permalink
initial version; minimal functionality works
Browse files Browse the repository at this point in the history
  • Loading branch information
LumaKernel committed Aug 4, 2024
1 parent 091fac7 commit ace7c70
Show file tree
Hide file tree
Showing 40 changed files with 3,928 additions and 103 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/node-check.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Node.js Check
on:
push:
branches:
- main
pull_request:
jobs:
Deploy-Production:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v4
with:
node-version: '22'
- name: Install
run: corepack npm install
working-directory: ./web
- name: Build
run: corepack npm run build
working-directory: ./web
- name: Type-check
run: corepack npm run type-check
working-directory: ./web
- name: Lint
run: corepack npm run lint
working-directory: ./web
28 changes: 28 additions & 0 deletions .github/workflows/preview.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Vercel Preview Deployment
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
on:
push:
branches-ignore:
- main
jobs:
Deploy-Preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.81.0-nightly
- name: Install Trunk
run: |
cargo install [email protected]
- name: Install Vercel CLI
run: npm install --global vercel@latest
- name: Pull Vercel Environment Information
run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
- name: Build Project Artifacts
run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
- name: Deploy Project Artifacts to Vercel
run: vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }}
28 changes: 28 additions & 0 deletions .github/workflows/prod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Vercel Production Deployment
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
on:
push:
branches:
- main
jobs:
Deploy-Production:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.81.0-nightly
- name: Install Trunk
run: |
cargo install [email protected]
- name: Install Vercel CLI
run: npm install --global vercel@latest
- name: Pull Vercel Environment Information
run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
- name: Build Project Artifacts
run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
- name: Deploy Project Artifacts to Vercel
run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}
21 changes: 21 additions & 0 deletions .github/workflows/rust-check.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Rust Check
on:
push:
branches:
- main
pull_request:
jobs:
Deploy-Production:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: 1.81.0-nightly
- name: Install Leptosfmt
run: cargo install [email protected]
- name: Leptosfmt
run: leptosfmt --check '**/*.rs'
- name: Clippy
run: cargo clippy --all-targets --all-features -- -D warnings
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/target/
/dist/
/index.html
8 changes: 0 additions & 8 deletions .vim/coc-settings.json

This file was deleted.

7 changes: 6 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@ image = "0.25.2"
leptos = { version = "0.6.12", features = ["csr", "nightly"] }
[dependencies.web-sys]
version = "0.3.69"
features = ["File", "FileList"]
features = [
"File",
"FileList",
"BlobPropertyBag",
"Window",
]
23 changes: 23 additions & 0 deletions Trunk.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
trunk-version = "^0.20.2"

[build]
# target = "web/dist/index.html"

[watch]
watch = [
"src",
"Cargo.toml",
"web/dist",
]
ignore = [
]

[[hooks]]
stage = "pre_build"
command = "bash"
command_arguments = ["-c", "cp web/dist/index.html index.html"]

[[hooks]]
stage = "build"
command = "bash"
command_arguments = ["-c", "cp -r web/dist/* $TRUNK_STAGING_DIR/"]
5 changes: 0 additions & 5 deletions index.html

This file was deleted.

10 changes: 10 additions & 0 deletions src/component.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
mod image_diff_summary;
mod image_loader;
mod image_summary;
pub mod ported;
mod setup_ionic;

pub use image_diff_summary::{ImageDiffSumaryInfo, ImageDiffSummary};
pub use image_loader::ImageLoader;
pub use image_summary::{ImageSumaryInfo, ImageSummary};
pub use setup_ionic::SetupIonic;
85 changes: 85 additions & 0 deletions src/component/image_diff_summary.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// NOTE: Leptos limitation. view! { <> .. </> } emits unused_braces warning.
#![allow(unused_braces)]

use crate::image::{ImageDiffError, ImageDiffInfo};
use crate::web::expose_to_window;
use leptos::web_sys::js_sys;
use leptos::web_sys::wasm_bindgen::JsValue;
use leptos::*;
use std::rc::Rc;

pub type ImageDiffSumaryInfo = Option<Result<Rc<ImageDiffInfo>, ImageDiffError>>;

#[component]
pub fn ImageDiffSummary(info: impl Fn() -> ImageDiffSumaryInfo + 'static) -> impl IntoView {
let f = move || {
let info = info()?;
Some(match info {
Ok(info) => {
let ImageDiffInfo {
diff_pixel_count,
diff_highlight,
..
} = info.as_ref();
let mut writer = std::io::Cursor::new(Vec::new());
diff_highlight
.write_to(&mut writer, image::ImageFormat::Png)
.unwrap();
let v = writer.into_inner();
let u8_array = js_sys::Uint8Array::new(&JsValue::from(v.len()));
for (i, &item) in v.iter().enumerate() {
u8_array.set_index(i as u32, item);
}
expose_to_window(&u8_array, "u8_array").unwrap();
let mut options = web_sys::BlobPropertyBag::new();
options.type_("image/png");
let blob = web_sys::Blob::new_with_u8_array_sequence_and_options(
&js_sys::Array::of1(&u8_array),
&options,
)
.unwrap();
expose_to_window(&blob, "blob").unwrap();
let data_url = web_sys::Url::create_object_url_with_blob(&blob).unwrap();
view! {
<>
<ion-card>
<ion-card-header>
<ion-card-title>{"Image Diff"}</ion-card-title>
</ion-card-header>
<ion-card-content>
<p>{format!("{} different pixels", diff_pixel_count)}</p>

{if *diff_pixel_count > 0 {
Some(view! { <img src=data_url style:width="100%"/> })
} else {
None
}}

</ion-card-content>
</ion-card>
</>
}
}
Err(err) => {
view! {
<>
<ImageDiffSummaryError err=move || err.clone()/>
</>
}
}
})
};
view! { <div style:width="320px">{f}</div> }
}

#[component]
fn ImageDiffSummaryError(err: impl Fn() -> ImageDiffError) -> impl IntoView {
let message = match err() {
ImageDiffError::DimensionMismatch => "Image dimensions do not match",
};
view! {
<ion-card>
<ion-card-content>{message}</ion-card-content>
</ion-card>
}
}
45 changes: 45 additions & 0 deletions src/component/image_loader.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use crate::component::ported::ImageDropzone;
use crate::image::{image_format_to_string, image_string_to_format};
use ev::Event;
use image;
use leptos::web_sys::HtmlSelectElement;
use leptos::*;

#[component]
pub fn ImageLoader(
on_image_selected: impl Fn(web_sys::File) + 'static,
on_format_selected: impl Fn(Option<image::ImageFormat>) + 'static,
) -> impl IntoView {
let (image_format, set_image_format) = create_signal("auto:".to_string());
let options = image::ImageFormat::all()
.filter(|format| format.reading_enabled())
.map(|format| {
let s = image_format_to_string(&format);
view! { <ion-select-option value=format!("format:{s}")>{s}</ion-select-option> }
})
.collect::<Vec<_>>();
let on_change = {
move |ev: Event| {
let target = event_target::<HtmlSelectElement>(&ev);
let value = target.value();
set_image_format(value.clone());
on_format_selected(if value == "auto:" {
None
} else {
let format = value
.strip_prefix("format:")
.and_then(image_string_to_format);
format
});
}
};
view! {
<div style:width="320px">
<ImageDropzone on_image_selected=on_image_selected/>
<ion-select label="Image Format" value=image_format on:ionChange=on_change>
<ion-select-option value="auto:">(Auto)</ion-select-option>
{options}
</ion-select>
</div>
}
}
68 changes: 68 additions & 0 deletions src/component/image_summary.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use crate::image::image_format_to_string;
use crate::image::{ImageLoadError, ImageLoadInfo};
use leptos::*;
use std::rc::Rc;

pub type ImageSumaryInfo = Option<Result<Rc<ImageLoadInfo>, ImageLoadError>>;

#[component]
pub fn ImageSummary(
info: impl Fn() -> ImageSumaryInfo + 'static,
image_name: String,
) -> impl IntoView {
let f = move || {
let info = info()?;
Some(match info {
Ok(info) => {
let ImageLoadInfo {
file,
image,
detected_format,
..
} = info.as_ref();
let dimensions = format!("{} x {}", image.width(), image.height());
let pixels = image.width() * image.height();
let format = image_format_to_string(detected_format);
let size = file.size();
view! {
<>
<ion-card>
<ion-card-header>
<ion-card-title>{image_name.clone()}</ion-card-title>
</ion-card-header>
<ion-card-content>
<p>
<span>Dimensions: {dimensions}</span>
<span>{format!(" ({pixels} pixels)")}</span>
</p>
<p>Format: {format}</p>
<p>Size: {size} bytes</p>
</ion-card-content>
</ion-card>
</>
}
}
Err(err) => {
view! {
<>
<ImageSummaryError err=move || err.clone()/>
</>
}
}
})
};
view! { <div style:width="320px">{f}</div> }
}

#[component]
fn ImageSummaryError(err: impl Fn() -> ImageLoadError) -> impl IntoView {
let message = match err() {
ImageLoadError::FormatError => "Failed to determine image format",
ImageLoadError::LoadError => "Failed to load image. HINT: Try a different format",
};
view! {
<ion-card>
<ion-card-content>{message}</ion-card-content>
</ion-card>
}
}
3 changes: 3 additions & 0 deletions src/component/ported.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod image_dropzone;

pub use image_dropzone::ImageDropzone;
Loading

0 comments on commit ace7c70

Please sign in to comment.