refactor(web): use AnyView return type for all components

This commit is contained in:
2025-12-31 16:09:20 +02:00
parent 6acf98bbae
commit 4c3d620250
5 changed files with 62 additions and 46 deletions

View File

@@ -10,7 +10,7 @@ use leptos::prelude::*;
use std::time::Duration;
#[component]
pub fn CipherForm(algorithm: Algorithm) -> impl IntoView {
pub fn CipherForm(algorithm: Algorithm) -> AnyView {
let (mode, set_mode) = signal(OperationMode::Encrypt);
let (output_fmt, set_output_fmt) = signal(OutputFormat::Hex);
@@ -101,4 +101,5 @@ pub fn CipherForm(algorithm: Algorithm) -> impl IntoView {
</div>
}
.into_any()
}

View File

@@ -13,7 +13,7 @@ use wasm_bindgen::JsCast;
use web_sys::{Blob, Url};
#[component]
pub fn CipherFormCbc() -> impl IntoView {
pub fn CipherFormCbc() -> AnyView {
let (mode, set_mode) = signal(OperationMode::Encrypt);
let (output_fmt, set_output_fmt) = signal(OutputFormat::Hex);
@@ -56,7 +56,7 @@ pub fn CipherFormCbc() -> impl IntoView {
let formatted_iv = format!("0x{iv}");
// Get input data
let input_data: Vec<u8> = match input_mode.get() {
let input_data = match input_mode.get() {
InputMode::Text => {
let text = text_content.get();
if text.is_empty() {
@@ -192,7 +192,10 @@ pub fn CipherFormCbc() -> impl IntoView {
<div class="result-toolbar">
<strong>"Output ("{output_fmt.get().to_string()}")"</strong>
<div class="result-actions">
<button class="btn-copy" on:click=move |_| copy_to_clipboard(output.get())>
<button
class="btn-copy"
on:click=move |_| copy_to_clipboard(output.get())
>
{move || if copy_feedback.get() { "Copied" } else { "Copy" }}
</button>
{move || {
@@ -201,7 +204,8 @@ pub fn CipherFormCbc() -> impl IntoView {
<button class="btn-download" on:click=download_output>
"Download"
</button>
}.into_any()
}
.into_any()
} else {
view! { <span></span> }.into_any()
}
@@ -209,21 +213,25 @@ pub fn CipherFormCbc() -> impl IntoView {
</div>
</div>
<div class="result-content">
<code>{move || {
let out = output.get();
if out.len() > 1000 {
format!("{}... ({} chars total)", &out[..1000], out.len())
} else {
out
}
}}</code>
<code>
{move || {
let out = output.get();
if out.len() > 1000 {
format!("{}... ({} chars total)", &out[..1000], out.len())
} else {
out
}
}}
</code>
</div>
</div>
}.into_any()
}
.into_any()
}}
<ErrorBox error_msg=error_msg />
</div>
}
.into_any()
}
fn parse_hex_string(s: &str) -> Result<Vec<u8>, String> {
@@ -234,7 +242,7 @@ fn parse_hex_string(s: &str) -> Result<Vec<u8>, String> {
.unwrap_or(trimmed);
// Remove whitespace and newlines
let s: String = s.chars().filter(|c| !c.is_whitespace()).collect();
let s = s.chars().filter(|c| !c.is_whitespace()).collect::<String>();
if !s.len().is_multiple_of(2) {
return Err("Hex string must have even length".to_string());
@@ -282,10 +290,7 @@ fn download_bytes(bytes: &[u8], filename: &str) {
return;
};
let Some(window) = web_sys::window() else {
return;
};
let Some(document) = window.document() else {
let Some(document) = window().document() else {
return;
};
let Some(a) = document.create_element("a").ok() else {
@@ -295,7 +300,7 @@ fn download_bytes(bytes: &[u8], filename: &str) {
let _ = a.set_attribute("href", &url);
let _ = a.set_attribute("download", filename);
let a: web_sys::HtmlElement = a.unchecked_into();
let a = a.unchecked_into::<web_sys::HtmlElement>();
a.click();
let _ = Url::revoke_object_url(&url);

View File

@@ -10,7 +10,7 @@ pub fn ConfigurationSection(
set_mode: WriteSignal<OperationMode>,
output_fmt: ReadSignal<OutputFormat>,
update_output: impl Fn(OutputFormat) + Copy + Send + 'static,
) -> impl IntoView {
) -> AnyView {
let handle_format_change = move |ev| {
let val = event_target_value(&ev);
let fmt = OutputFormat::from_str(&val).unwrap_or_default();
@@ -83,4 +83,5 @@ pub fn ConfigurationSection(
</div>
</div>
}
.into_any()
}

View File

@@ -41,7 +41,7 @@ fn read_file(
fn InputModeToggle(
input_mode: ReadSignal<InputMode>,
set_input_mode: WriteSignal<InputMode>,
) -> impl IntoView {
) -> AnyView {
view! {
<div class="input-mode-toggle">
<button
@@ -64,6 +64,7 @@ fn InputModeToggle(
</button>
</div>
}
.into_any()
}
#[component]
@@ -71,7 +72,7 @@ fn TextAreaInput(
text_content: ReadSignal<String>,
set_text_content: WriteSignal<String>,
is_decrypt_mode: Memo<bool>,
) -> impl IntoView {
) -> AnyView {
let handle_text_change = move |ev: Event| {
if let Some(target) = ev.target() {
let textarea: web_sys::HtmlTextAreaElement = target.unchecked_into();
@@ -99,6 +100,7 @@ fn TextAreaInput(
</div>
</div>
}
.into_any()
}
#[component]
@@ -107,7 +109,7 @@ fn FileDropZone(
set_file_data: WriteSignal<Option<Vec<u8>>>,
file_name: ReadSignal<Option<String>>,
set_file_name: WriteSignal<Option<String>>,
) -> impl IntoView {
) -> AnyView {
let (is_dragging, set_is_dragging) = signal(false);
let handle_file_change = move |ev: Event| {
@@ -193,6 +195,7 @@ fn FileDropZone(
</label>
</div>
}
.into_any()
}
#[component]
@@ -201,7 +204,7 @@ fn FileSelected(
file_data: ReadSignal<Option<Vec<u8>>>,
set_file_name: WriteSignal<Option<String>>,
set_file_data: WriteSignal<Option<Vec<u8>>>,
) -> impl IntoView {
) -> AnyView {
let clear_file = move |ev: web_sys::MouseEvent| {
ev.prevent_default();
ev.stop_propagation();
@@ -221,16 +224,18 @@ fn FileSelected(
</button>
</div>
}
.into_any()
}
#[component]
fn FilePlaceholder() -> impl IntoView {
fn FilePlaceholder() -> AnyView {
view! {
<div class="file-placeholder">
<span class="upload-icon">"[+]"</span>
<span>"Click to select a file or drag and drop"</span>
</div>
}
.into_any()
}
#[component]
@@ -244,7 +249,7 @@ pub fn FileTextInput(
file_name: ReadSignal<Option<String>>,
set_file_name: WriteSignal<Option<String>>,
is_decrypt_mode: Memo<bool>,
) -> impl IntoView {
) -> AnyView {
view! {
<div class="form-group">
<div class="label-header">
@@ -281,4 +286,5 @@ pub fn FileTextInput(
}}
</div>
}
.into_any()
}