feat: upgrade network plugin to dioxus v0.5.1

This commit is contained in:
imgurbot12 2024-07-10 01:26:09 -07:00
parent e6b8018cb5
commit 129ac75287
4 changed files with 48 additions and 60 deletions

View File

@ -9,9 +9,9 @@ edition = "2021"
anyhow = "1.0.86" anyhow = "1.0.86"
async-std = "1.12.0" async-std = "1.12.0"
clap = { version = "4.5.4", features = ["derive"] } clap = { version = "4.5.4", features = ["derive"] }
dioxus = "0.5.1" dioxus = { version = "0.5.1", features = ["desktop"] }
dioxus-desktop = "0.5.1" dioxus-desktop = "0.5.1"
dioxus-free-icons = { version = "0.8.5", features = ["font-awesome-regular"] } dioxus-free-icons = { version = "0.8.6", features = ["font-awesome-regular"] }
dioxus-html = "0.5.1" dioxus-html = "0.5.1"
env_logger = "0.11.3" env_logger = "0.11.3"
futures-channel = "0.3.30" futures-channel = "0.3.30"

View File

@ -15,8 +15,8 @@ static SPINNER_HTML: &'static str = include_str!("../public/spinner.html");
static DEFAULT_CSS_CONTENT: &'static str = include_str!("../public/default.css"); static DEFAULT_CSS_CONTENT: &'static str = include_str!("../public/default.css");
/// Run GUI Application /// Run GUI Application
pub fn run_app(ssid: &str, timeout: u32) { pub fn run(ssid: String, timeout: u32) {
let builder = dioxus_desktop::WindowBuilder::new() let window = dioxus_desktop::WindowBuilder::new()
.with_title("RMenu - Network Login") .with_title("RMenu - Network Login")
.with_inner_size(LogicalSize { .with_inner_size(LogicalSize {
width: 400, width: 400,
@ -25,14 +25,12 @@ pub fn run_app(ssid: &str, timeout: u32) {
.with_focused(true) .with_focused(true)
.with_decorations(false) .with_decorations(false)
.with_always_on_top(true); .with_always_on_top(true);
dioxus_desktop::launch_with_props( let config = dioxus_desktop::Config::new().with_window(window);
App, let context = Context { ssid, timeout };
AppProp { LaunchBuilder::desktop()
ssid: ssid.to_owned(), .with_cfg(config)
timeout, .with_context(context)
}, .launch(gui_main);
dioxus_desktop::Config::new().with_window(builder),
);
} }
/// Message to send to GUI /// Message to send to GUI
@ -45,12 +43,13 @@ pub enum UserMessage {
impl UserMessage { impl UserMessage {
/// Retrieve CSS-Class to use on UserMessage /// Retrieve CSS-Class to use on UserMessage
fn css_class(&self) -> &str { fn css_class(&self) -> String {
match self { match self {
Self::Error(_) => "error", Self::Error(_) => "error",
Self::Success(_) => "success", Self::Success(_) => "success",
Self::Nothing => "none", Self::Nothing => "none",
} }
.to_owned()
} }
/// Retrieve Message Value /// Retrieve Message Value
fn message(&self) -> Option<String> { fn message(&self) -> Option<String> {
@ -62,22 +61,14 @@ impl UserMessage {
} }
} }
#[derive(Debug, PartialEq, Props)] #[derive(Debug, Clone)]
struct AppProp { struct Context {
ssid: String, ssid: String,
timeout: u32, timeout: u32,
} }
//TODO: add auth timeout //TODO: add auth timeout
/// Set Cursor/Keyboard Focus onto Input
#[inline]
fn focus<T>(cx: Scope<T>) {
let eval = use_eval(cx);
let js = "document.getElementById(`secret`).focus()";
let _ = eval(&js);
}
/// Complete Network Connection/Authentication Attempt /// Complete Network Connection/Authentication Attempt
async fn connect_async(ssid: String, timeout: u32, secret: &str) -> Result<()> { async fn connect_async(ssid: String, timeout: u32, secret: &str) -> Result<()> {
// retrieve access-point from manager // retrieve access-point from manager
@ -92,31 +83,30 @@ async fn connect_async(ssid: String, timeout: u32, secret: &str) -> Result<()> {
manager.connect(&access_point, Some(secret)).await manager.connect(&access_point, Some(secret)).await
} }
/// Simple Login GUI Application fn gui_main() -> Element {
fn App(cx: Scope<AppProp>) -> Element { let ctx = use_context::<Context>();
let secret = use_state(cx, || String::new()); let mut message = use_signal(|| UserMessage::Nothing);
let message = use_state(cx, || UserMessage::Nothing); let mut loading = use_signal(|| false);
let show_secret = use_state(cx, || false); let mut secret = use_signal(String::new);
let loading = use_state(cx, || false); let mut show_secret = use_signal(|| false);
// always ensure focus // refocus on input
focus(cx); let js = format!("setTimeout(() => {{ document.getElementById('secret').focus() }}, 100)");
eval(&js);
// build keyboard actions event handler // build keyboard actions event handler
let keyboard_controls = move |e: KeyboardEvent| match e.code() { let keyboard_controls = move |e: KeyboardEvent| match e.code() {
Code::Escape => std::process::exit(0), Code::Escape => std::process::exit(0),
Code::Enter => { Code::Enter => {
let ssid = cx.props.ssid.to_owned(); let timeout = ctx.timeout.to_owned();
let timeout = cx.props.timeout.to_owned();
let secret = secret.get().to_owned();
let message = message.to_owned();
let loading = loading.to_owned();
loading.set(true); loading.set(true);
message.set(UserMessage::Nothing); message.set(UserMessage::Nothing);
cx.spawn(async move { spawn(async move {
let ctx = use_context::<Context>();
let ssid = ctx.ssid.to_owned();
log::info!("connecting to ssid: {ssid:?}"); log::info!("connecting to ssid: {ssid:?}");
let result = connect_async(ssid, timeout, &secret).await; let result = connect_async(ssid, timeout, &secret()).await;
log::info!("connection result: {result:?}"); log::info!("connection result: {result:?}");
match result { match result {
Ok(_) => { Ok(_) => {
@ -139,27 +129,27 @@ fn App(cx: Scope<AppProp>) -> Element {
}; };
// retrieve message details / set input-type / get loading css-class // retrieve message details / set input-type / get loading css-class
let msg_css = message.css_class(); let msg_css = message.with(|msg| msg.css_class());
let msg_str = message.message(); let msg_str = message.with(|msg| msg.message());
let input_type = match show_secret.get() { let input_type = match show_secret() {
true => "text", true => "text",
false => "password", false => "password",
}; };
let blackout_css = match loading.get() { let blackout_css = match loading() {
true => "active", true => "active",
false => "", false => "",
}; };
// complete final rendering // complete final rendering
cx.render(rsx! { rsx! {
style { DEFAULT_CSS_CONTENT } style { "{DEFAULT_CSS_CONTENT}" }
style { SPINNER_CSS } style { "{SPINNER_CSS}" }
div { div {
onkeydown: keyboard_controls, onkeydown: keyboard_controls,
label { label {
id: "header", id: "header",
"for": "secret", "for": "secret",
"Wi-Fi Network {cx.props.ssid:?} Requires a Password" "Wi-Fi Network {ctx.ssid:?} Requires a Password"
} }
div { div {
id: "controls", id: "controls",
@ -167,36 +157,36 @@ fn App(cx: Scope<AppProp>) -> Element {
id: "secret", id: "secret",
value: "{secret}", value: "{secret}",
placeholder: "Password", placeholder: "Password",
oninput: move |e| secret.set(e.value.clone()), oninput: move |e| secret.set(e.value()),
"type": "{input_type}" "type": "{input_type}"
} }
button { button {
id: "icon", id: "icon",
onclick: |_| show_secret.modify(|v| !v), onclick: move |_| show_secret.toggle(),
match show_secret.get() { {match show_secret() {
true => cx.render(rsx! { true => rsx! {
Icon { Icon {
fill: "black", fill: "black",
icon: FaEye, icon: FaEye,
} }
}), },
false => cx.render(rsx! { false => rsx! {
Icon { Icon {
fill: "black", fill: "black",
icon: FaEyeSlash, icon: FaEyeSlash,
} }
})
} }
}}
} }
} }
if let Some(msg) = msg_str { if let Some(msg) = msg_str {
cx.render(rsx! { {rsx! {
div { div {
id: "message", id: "message",
class: "{msg_css}", class: "{msg_css}",
"{msg}" "{msg}"
} }
}) }}
} }
div { div {
id: "blackout", id: "blackout",
@ -207,5 +197,5 @@ fn App(cx: Scope<AppProp>) -> Element {
} }
} }
} }
}) }
} }

View File

@ -97,7 +97,7 @@ fn main() -> Result<()> {
let connected = context.block_on(try_connect_ap(ssid.clone(), timeout))?; let connected = context.block_on(try_connect_ap(ssid.clone(), timeout))?;
if !connected { if !connected {
log::info!("Spawning GUI to complete AP Login"); log::info!("Spawning GUI to complete AP Login");
gui::run_app(&ssid, timeout.unwrap_or(30)); gui::run(ssid, timeout.unwrap_or(30));
} }
} }
} }

View File

@ -26,7 +26,6 @@ pub struct Manager {
/// AccessPoint Information /// AccessPoint Information
#[derive(Debug)] #[derive(Debug)]
pub struct AccessPoint { pub struct AccessPoint {
pub in_use: bool,
pub ssid: String, pub ssid: String,
pub rate: u32, pub rate: u32,
pub signal: u8, pub signal: u8,
@ -267,7 +266,6 @@ impl Manager {
access.insert( access.insert(
ssid.to_owned(), ssid.to_owned(),
AccessPoint { AccessPoint {
in_use: is_active,
ssid, ssid,
rate, rate,
signal, signal,