CLI: Toasts & Tweaks (#2702)

* progress: cli toasts

* forgot the html

* progress: toasts

* revision: don't open splash on desktop

* fix: fmt, spellcheck
This commit is contained in:
Miles Murgaw authored and GitHub committed 2024-07-25 14:38:45 -07:00
1 parent beeee0dda1
commit bd58a92441
10 files changed
+363 -31

No files matched your search

+81 -1
View File
@@ -3,7 +3,12 @@
//! This sets up a websocket connection to the devserver and handles messages from it.
//! We also set up a little recursive timer that will attempt to reconnect if the connection is lost.
use std::fmt::Display;
use std::time::Duration;
use dioxus_core::ScopeId;
use dioxus_hot_reload::{DevserverMsg, HotReloadMsg};
use dioxus_html::prelude::eval;
use futures_channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender};
use js_sys::JsString;
use wasm_bindgen::JsCast;
@@ -14,6 +19,9 @@ const POLL_INTERVAL_MIN: i32 = 250;
const POLL_INTERVAL_MAX: i32 = 4000;
const POLL_INTERVAL_SCALE_FACTOR: i32 = 2;
/// Amount of time that toats should be displayed.
const TOAST_TIMEOUT: Duration = Duration::from_secs(5);
pub(crate) fn init() -> UnboundedReceiver<HotReloadMsg> {
// Create the tx/rx pair that we'll use for the top-level future in the dioxus loop
let (tx, rx) = unbounded();
@@ -62,8 +70,34 @@ fn make_ws(tx: UnboundedSender<HotReloadMsg>, poll_interval: i32, reload: bool)
web_sys::console::error_1(&"Connection to the devserver was closed".into())
}
// The devserver is telling us that it started a full rebuild. This does not mean that it is ready.
Ok(DevserverMsg::FullReloadStart) => show_toast(
"Your app is being rebuilt.",
"A non-hot-reloadable change occurred and we must rebuild.",
ToastLevel::Info,
TOAST_TIMEOUT,
false,
),
// The devserver is telling us that the full rebuild failed.
Ok(DevserverMsg::FullReloadFailed) => show_toast(
"Oops! The build failed.",
"We tried to rebuild your app, but something went wrong.",
ToastLevel::Error,
TOAST_TIMEOUT,
false,
),
// The devserver is telling us to reload the whole page
Ok(DevserverMsg::FullReload) => window().unwrap().location().reload().unwrap(),
Ok(DevserverMsg::FullReloadCommand) => {
show_toast(
"Successfully rebuilt.",
"Your app was rebuilt successfully and without error.",
ToastLevel::Success,
TOAST_TIMEOUT,
true,
);
window().unwrap().location().reload().unwrap()
}
Err(e) => web_sys::console::error_1(
&format!("Error parsing devserver message: {}", e).into(),
@@ -133,6 +167,52 @@ fn make_ws(tx: UnboundedSender<HotReloadMsg>, poll_interval: i32, reload: bool)
}
}
/// Represents what color the toast should have.
enum ToastLevel {
/// Green
Success,
/// Blue
Info,
/// Red
Error,
}
impl Display for ToastLevel {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ToastLevel::Success => write!(f, "success"),
ToastLevel::Info => write!(f, "info"),
ToastLevel::Error => write!(f, "error"),
}
}
}
/// Displays a toast to the developer.
fn show_toast(
header_text: &str,
message: &str,
level: ToastLevel,
duration: Duration,
after_reload: bool,
) {
let as_ms = duration.as_millis();
let js_fn_name = match after_reload {
true => "scheduleDXToast",
false => "showDXToast",
};
ScopeId::ROOT.in_runtime(|| {
eval(&format!(
r#"
if (typeof {js_fn_name} !== "undefined") {{
{js_fn_name}("{header_text}", "{message}", "{level}", {as_ms});
}}
"#,
));
});
}
/// Force a hotreload of the assets on this page by walking them and changing their URLs to include
/// some extra entropy.
///