mirror of
https://github.com/imgurbot12/rmenu.git
synced 2024-11-10 11:33:48 +01:00
feat: upgrade network plugin to dioxus v0.5.1
This commit is contained in:
parent
e6b8018cb5
commit
129ac75287
@ -9,9 +9,9 @@ edition = "2021"
|
||||
anyhow = "1.0.86"
|
||||
async-std = "1.12.0"
|
||||
clap = { version = "4.5.4", features = ["derive"] }
|
||||
dioxus = "0.5.1"
|
||||
dioxus = { version = "0.5.1", features = ["desktop"] }
|
||||
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"
|
||||
env_logger = "0.11.3"
|
||||
futures-channel = "0.3.30"
|
||||
|
@ -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");
|
||||
|
||||
/// Run GUI Application
|
||||
pub fn run_app(ssid: &str, timeout: u32) {
|
||||
let builder = dioxus_desktop::WindowBuilder::new()
|
||||
pub fn run(ssid: String, timeout: u32) {
|
||||
let window = dioxus_desktop::WindowBuilder::new()
|
||||
.with_title("RMenu - Network Login")
|
||||
.with_inner_size(LogicalSize {
|
||||
width: 400,
|
||||
@ -25,14 +25,12 @@ pub fn run_app(ssid: &str, timeout: u32) {
|
||||
.with_focused(true)
|
||||
.with_decorations(false)
|
||||
.with_always_on_top(true);
|
||||
dioxus_desktop::launch_with_props(
|
||||
App,
|
||||
AppProp {
|
||||
ssid: ssid.to_owned(),
|
||||
timeout,
|
||||
},
|
||||
dioxus_desktop::Config::new().with_window(builder),
|
||||
);
|
||||
let config = dioxus_desktop::Config::new().with_window(window);
|
||||
let context = Context { ssid, timeout };
|
||||
LaunchBuilder::desktop()
|
||||
.with_cfg(config)
|
||||
.with_context(context)
|
||||
.launch(gui_main);
|
||||
}
|
||||
|
||||
/// Message to send to GUI
|
||||
@ -45,12 +43,13 @@ pub enum UserMessage {
|
||||
|
||||
impl UserMessage {
|
||||
/// Retrieve CSS-Class to use on UserMessage
|
||||
fn css_class(&self) -> &str {
|
||||
fn css_class(&self) -> String {
|
||||
match self {
|
||||
Self::Error(_) => "error",
|
||||
Self::Success(_) => "success",
|
||||
Self::Nothing => "none",
|
||||
}
|
||||
.to_owned()
|
||||
}
|
||||
/// Retrieve Message Value
|
||||
fn message(&self) -> Option<String> {
|
||||
@ -62,22 +61,14 @@ impl UserMessage {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Props)]
|
||||
struct AppProp {
|
||||
#[derive(Debug, Clone)]
|
||||
struct Context {
|
||||
ssid: String,
|
||||
timeout: u32,
|
||||
}
|
||||
|
||||
//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
|
||||
async fn connect_async(ssid: String, timeout: u32, secret: &str) -> Result<()> {
|
||||
// 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
|
||||
}
|
||||
|
||||
/// Simple Login GUI Application
|
||||
fn App(cx: Scope<AppProp>) -> Element {
|
||||
let secret = use_state(cx, || String::new());
|
||||
let message = use_state(cx, || UserMessage::Nothing);
|
||||
let show_secret = use_state(cx, || false);
|
||||
let loading = use_state(cx, || false);
|
||||
fn gui_main() -> Element {
|
||||
let ctx = use_context::<Context>();
|
||||
let mut message = use_signal(|| UserMessage::Nothing);
|
||||
let mut loading = use_signal(|| false);
|
||||
let mut secret = use_signal(String::new);
|
||||
let mut show_secret = use_signal(|| false);
|
||||
|
||||
// always ensure focus
|
||||
focus(cx);
|
||||
// refocus on input
|
||||
let js = format!("setTimeout(() => {{ document.getElementById('secret').focus() }}, 100)");
|
||||
eval(&js);
|
||||
|
||||
// build keyboard actions event handler
|
||||
let keyboard_controls = move |e: KeyboardEvent| match e.code() {
|
||||
Code::Escape => std::process::exit(0),
|
||||
Code::Enter => {
|
||||
let ssid = cx.props.ssid.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();
|
||||
let timeout = ctx.timeout.to_owned();
|
||||
loading.set(true);
|
||||
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:?}");
|
||||
let result = connect_async(ssid, timeout, &secret).await;
|
||||
let result = connect_async(ssid, timeout, &secret()).await;
|
||||
log::info!("connection result: {result:?}");
|
||||
match result {
|
||||
Ok(_) => {
|
||||
@ -139,27 +129,27 @@ fn App(cx: Scope<AppProp>) -> Element {
|
||||
};
|
||||
|
||||
// retrieve message details / set input-type / get loading css-class
|
||||
let msg_css = message.css_class();
|
||||
let msg_str = message.message();
|
||||
let input_type = match show_secret.get() {
|
||||
let msg_css = message.with(|msg| msg.css_class());
|
||||
let msg_str = message.with(|msg| msg.message());
|
||||
let input_type = match show_secret() {
|
||||
true => "text",
|
||||
false => "password",
|
||||
};
|
||||
let blackout_css = match loading.get() {
|
||||
let blackout_css = match loading() {
|
||||
true => "active",
|
||||
false => "",
|
||||
};
|
||||
|
||||
// complete final rendering
|
||||
cx.render(rsx! {
|
||||
style { DEFAULT_CSS_CONTENT }
|
||||
style { SPINNER_CSS }
|
||||
rsx! {
|
||||
style { "{DEFAULT_CSS_CONTENT}" }
|
||||
style { "{SPINNER_CSS}" }
|
||||
div {
|
||||
onkeydown: keyboard_controls,
|
||||
label {
|
||||
id: "header",
|
||||
"for": "secret",
|
||||
"Wi-Fi Network {cx.props.ssid:?} Requires a Password"
|
||||
"Wi-Fi Network {ctx.ssid:?} Requires a Password"
|
||||
}
|
||||
div {
|
||||
id: "controls",
|
||||
@ -167,36 +157,36 @@ fn App(cx: Scope<AppProp>) -> Element {
|
||||
id: "secret",
|
||||
value: "{secret}",
|
||||
placeholder: "Password",
|
||||
oninput: move |e| secret.set(e.value.clone()),
|
||||
oninput: move |e| secret.set(e.value()),
|
||||
"type": "{input_type}"
|
||||
}
|
||||
button {
|
||||
id: "icon",
|
||||
onclick: |_| show_secret.modify(|v| !v),
|
||||
match show_secret.get() {
|
||||
true => cx.render(rsx! {
|
||||
onclick: move |_| show_secret.toggle(),
|
||||
{match show_secret() {
|
||||
true => rsx! {
|
||||
Icon {
|
||||
fill: "black",
|
||||
icon: FaEye,
|
||||
}
|
||||
}),
|
||||
false => cx.render(rsx! {
|
||||
},
|
||||
false => rsx! {
|
||||
Icon {
|
||||
fill: "black",
|
||||
icon: FaEyeSlash,
|
||||
}
|
||||
})
|
||||
}
|
||||
}}
|
||||
}
|
||||
}
|
||||
if let Some(msg) = msg_str {
|
||||
cx.render(rsx! {
|
||||
{rsx! {
|
||||
div {
|
||||
id: "message",
|
||||
class: "{msg_css}",
|
||||
"{msg}"
|
||||
}
|
||||
})
|
||||
}}
|
||||
}
|
||||
div {
|
||||
id: "blackout",
|
||||
@ -207,5 +197,5 @@ fn App(cx: Scope<AppProp>) -> Element {
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ fn main() -> Result<()> {
|
||||
let connected = context.block_on(try_connect_ap(ssid.clone(), timeout))?;
|
||||
if !connected {
|
||||
log::info!("Spawning GUI to complete AP Login");
|
||||
gui::run_app(&ssid, timeout.unwrap_or(30));
|
||||
gui::run(ssid, timeout.unwrap_or(30));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,6 @@ pub struct Manager {
|
||||
/// AccessPoint Information
|
||||
#[derive(Debug)]
|
||||
pub struct AccessPoint {
|
||||
pub in_use: bool,
|
||||
pub ssid: String,
|
||||
pub rate: u32,
|
||||
pub signal: u8,
|
||||
@ -267,7 +266,6 @@ impl Manager {
|
||||
access.insert(
|
||||
ssid.to_owned(),
|
||||
AccessPoint {
|
||||
in_use: is_active,
|
||||
ssid,
|
||||
rate,
|
||||
signal,
|
||||
|
Loading…
Reference in New Issue
Block a user