cli json output, dx bundle fix, dx serve --platform android, race condition, drop ssg platform (#3186)
* clean up logging to avoid random extra trace * fix race condition with updates * properly wire up verbose * fix bundling (macos) and logging * Add structured output * clean up clap names * extract out wire format * switch structured key to json * fix random println, fallback to `dioxus/platform` * clean up logging for run/build * clean up logging around project * remove manual exits * fix tokio runtime for mobile * rework dog app * rip out ssg * Switch dioxus/axum to dioxus/server * add android template inline * pre restructure for bundle prep * add the whole res directory * Better theme for the app * remove mobile demo now that most apps work natively * self-referential android * only use deep linking for assets * fix imports for android * clippy, fixup ios and android * I'm not boxing compiler message you can't make me * fix clippy on unix
This commit is contained in:
1 parent
8a998e7d49
commit
ac3e33af46
116 files changed
+2367
-6091
No files matched your search
@@ -68,6 +68,7 @@ impl AppHandle {
|
||||
// These need to be stable within a release version (ie 0.6.0)
|
||||
let mut envs = vec![
|
||||
("DIOXUS_CLI_ENABLED", "true".to_string()),
|
||||
("RUST_BACKTRACE", "1".to_string()),
|
||||
(
|
||||
dioxus_cli_config::DEVSERVER_RAW_ADDR_ENV,
|
||||
devserver_ip.to_string(),
|
||||
@@ -116,7 +117,7 @@ impl AppHandle {
|
||||
|
||||
// https://developer.android.com/studio/run/emulator-commandline
|
||||
Platform::Android => {
|
||||
tracing::error!("Android is not yet supported, sorry!");
|
||||
self.open_android_sim(envs).await?;
|
||||
None
|
||||
}
|
||||
|
||||
@@ -159,7 +160,7 @@ impl AppHandle {
|
||||
// we won't actually be using the build dir.
|
||||
let asset_dir = match self.runtime_asst_dir.as_ref() {
|
||||
Some(dir) => dir.to_path_buf().join("assets/"),
|
||||
None => self.app.asset_dir(),
|
||||
None => self.app.build.asset_dir(),
|
||||
};
|
||||
|
||||
tracing::debug!("Hotreloading asset {changed_file:?} in target {asset_dir:?}");
|
||||
@@ -237,13 +238,16 @@ impl AppHandle {
|
||||
/// TODO(jon): we should probably check if there's a simulator running before trying to install,
|
||||
/// and open the simulator if we have to.
|
||||
async fn open_ios_sim(&mut self, envs: Vec<(&str, String)>) -> Result<Child> {
|
||||
tracing::debug!("Installing app to simulator {:?}", self.app.app_dir());
|
||||
tracing::debug!(
|
||||
"Installing app to simulator {:?}",
|
||||
self.app.build.root_dir()
|
||||
);
|
||||
|
||||
let res = Command::new("xcrun")
|
||||
.arg("simctl")
|
||||
.arg("install")
|
||||
.arg("booted")
|
||||
.arg(self.app.app_dir())
|
||||
.arg(self.app.build.root_dir())
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.output()
|
||||
@@ -262,15 +266,13 @@ impl AppHandle {
|
||||
.arg("launch")
|
||||
.arg("--console")
|
||||
.arg("booted")
|
||||
.arg("com.dioxuslabs")
|
||||
.arg(self.app.bundle_identifier())
|
||||
.envs(ios_envs)
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.kill_on_drop(true)
|
||||
.spawn()?;
|
||||
|
||||
tracing::debug!("Launched app on simulator with exit code: {child:?}");
|
||||
|
||||
Ok(child)
|
||||
}
|
||||
|
||||
@@ -309,7 +311,7 @@ impl AppHandle {
|
||||
// # xcrun devicectl device process resume --device "${DEVICE_UUID}" --pid "${STATUS_PID}" > "${XCRUN_DEVICE_PROCESS_RESUME_LOG_DIR}" 2>&1
|
||||
|
||||
use serde_json::Value;
|
||||
let app_path = self.app.app_dir();
|
||||
let app_path = self.app.build.root_dir();
|
||||
|
||||
install_app(&app_path).await?;
|
||||
|
||||
@@ -448,4 +450,32 @@ impl AppHandle {
|
||||
|
||||
unimplemented!("dioxus-cli doesn't support ios devices yet.")
|
||||
}
|
||||
|
||||
async fn open_android_sim(&self, envs: Vec<(&str, String)>) -> Result<()> {
|
||||
// Install
|
||||
// adb install -r app-debug.apk
|
||||
let _output = Command::new("adb")
|
||||
.arg("install")
|
||||
.arg("-r")
|
||||
.arg(self.app.apk_path())
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.output()
|
||||
.await?;
|
||||
|
||||
// adb shell am start -n com.example.androidfinal/com.example.androidfinal.MainActivity
|
||||
let _output = Command::new("adb")
|
||||
.arg("shell")
|
||||
.arg("am")
|
||||
.arg("start")
|
||||
.arg("-n")
|
||||
.arg("com.example.androidfinal/com.example.androidfinal.MainActivity")
|
||||
.envs(envs)
|
||||
.stderr(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.output()
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,4 @@
|
||||
use crate::{
|
||||
BuildUpdate, Builder, DioxusCrate, Error, Platform, Result, ServeArgs, TraceController,
|
||||
TraceSrc,
|
||||
};
|
||||
use crate::{BuildUpdate, Builder, Error, Platform, Result, ServeArgs, TraceController, TraceSrc};
|
||||
|
||||
mod ansi_buffer;
|
||||
mod detect;
|
||||
@@ -40,9 +37,13 @@ pub(crate) use watcher::*;
|
||||
/// - I'd love to be able to configure the CLI while it's running so we can change settings on the fly.
|
||||
/// - I want us to be able to detect a `server_fn` in the project and then upgrade from a static server
|
||||
/// to a dynamic one on the fly.
|
||||
pub(crate) async fn serve_all(args: ServeArgs, krate: DioxusCrate) -> Result<()> {
|
||||
pub(crate) async fn serve_all(mut args: ServeArgs) -> Result<()> {
|
||||
// Redirect all logging the cli logger
|
||||
let mut tracer = TraceController::redirect();
|
||||
|
||||
// Load the krate and resolve the server args against it - this might log so do it after we turn on the tracer first
|
||||
let krate = args.load_krate()?;
|
||||
|
||||
// Note that starting the builder will queue up a build immediately
|
||||
let mut builder = Builder::start(&krate, args.build_args())?;
|
||||
let mut devserver = WebServer::start(&krate, &args)?;
|
||||
@@ -53,15 +54,15 @@ pub(crate) async fn serve_all(args: ServeArgs, krate: DioxusCrate) -> Result<()>
|
||||
// This is our default splash screen. We might want to make this a fancier splash screen in the future
|
||||
// Also, these commands might not be the most important, but it's all we've got enabled right now
|
||||
tracing::info!(
|
||||
r#"Serving your Dioxus app: {} 🚀
|
||||
|
||||
- Press `ctrl+c` to exit the server
|
||||
- Press `r` to rebuild the app
|
||||
- Press `o` to open the app
|
||||
- Press `t` to toggle cargo output
|
||||
- Press `/` for more commands and shortcuts
|
||||
|
||||
Learn more at https://dioxuslabs.com/learn/0.6/getting_started"#,
|
||||
r#"-----------------------------------------------------------------
|
||||
Serving your Dioxus app: {} 🚀
|
||||
• Press `ctrl+c` to exit the server
|
||||
• Press `r` to rebuild the app
|
||||
• Press `o` to open the app
|
||||
• Press `v` to toggle verbose logging
|
||||
• Press `/` for more commands and shortcuts
|
||||
Learn more at https://dioxuslabs.com/learn/0.6/getting_started
|
||||
----------------------------------------------------------------"#,
|
||||
krate.executable_name()
|
||||
);
|
||||
|
||||
@@ -146,7 +147,7 @@ pub(crate) async fn serve_all(args: ServeArgs, krate: DioxusCrate) -> Result<()>
|
||||
screen.new_build_update(&update);
|
||||
|
||||
// And then update the websocketed clients with the new build status in case they want it
|
||||
devserver.new_build_update(&update).await;
|
||||
devserver.new_build_update(&update, &builder).await;
|
||||
|
||||
// And then open the app if it's ready
|
||||
// todo: there might be more things to do here that require coordination with other pieces of the CLI
|
||||
@@ -213,6 +214,7 @@ pub(crate) async fn serve_all(args: ServeArgs, krate: DioxusCrate) -> Result<()>
|
||||
// `Full rebuild:` to line up with
|
||||
// `Hotreloading:` to keep the alignment during long edit sessions
|
||||
tracing::info!("Full rebuild: triggered manually");
|
||||
|
||||
builder.rebuild(args.build_arguments.clone());
|
||||
runner.file_map.force_rebuild();
|
||||
devserver.start_build().await
|
||||
@@ -248,7 +250,6 @@ pub(crate) async fn serve_all(args: ServeArgs, krate: DioxusCrate) -> Result<()>
|
||||
_ = devserver.shutdown().await;
|
||||
_ = screen.shutdown();
|
||||
builder.abort_all();
|
||||
tracer.shutdown();
|
||||
|
||||
if let Err(err) = err {
|
||||
eprintln!("Exiting with error: {}", err);
|
||||
|
||||
@@ -99,8 +99,8 @@ impl Output {
|
||||
more_modal_open: false,
|
||||
pending_logs: VecDeque::new(),
|
||||
throbber: RefCell::new(throbber_widgets_tui::ThrobberState::default()),
|
||||
trace: cfg.trace,
|
||||
verbose: cfg.verbose,
|
||||
trace: crate::logging::VERBOSITY.get().unwrap().trace,
|
||||
verbose: crate::logging::VERBOSITY.get().unwrap().verbose,
|
||||
tick_animation: false,
|
||||
tick_interval: {
|
||||
let mut interval = tokio::time::interval(Duration::from_millis(TICK_RATE_MS));
|
||||
@@ -152,10 +152,8 @@ impl Output {
|
||||
.execute(DisableBracketedPaste)?;
|
||||
disable_raw_mode()?;
|
||||
|
||||
// print a few lines to not cut off the output
|
||||
for _ in 0..3 {
|
||||
println!();
|
||||
}
|
||||
// print a line to force the cursor down (no tearing)
|
||||
println!();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -331,10 +329,12 @@ impl Output {
|
||||
/// we won't be drawing it.
|
||||
pub(crate) fn new_build_update(&mut self, update: &BuildUpdate) {
|
||||
match update {
|
||||
BuildUpdate::CompilerMessage { .. } => {}
|
||||
BuildUpdate::Progress { .. } => self.tick_animation = true,
|
||||
BuildUpdate::Progress {
|
||||
stage: BuildStage::Starting { .. },
|
||||
} => self.tick_animation = true,
|
||||
BuildUpdate::BuildReady { .. } => self.tick_animation = false,
|
||||
BuildUpdate::BuildFailed { .. } => self.tick_animation = false,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,7 +381,7 @@ impl Output {
|
||||
let mut area = frame.area();
|
||||
area.width = area.width.clamp(0, VIEWPORT_MAX_WIDTH);
|
||||
|
||||
let [_top, body, bottom] = Layout::vertical([
|
||||
let [_top, body, _bottom] = Layout::vertical([
|
||||
Constraint::Length(1),
|
||||
Constraint::Fill(1),
|
||||
Constraint::Length(1),
|
||||
@@ -391,7 +391,6 @@ impl Output {
|
||||
|
||||
self.render_borders(frame, area);
|
||||
self.render_body(frame, body, state);
|
||||
self.render_bottom_row(frame, bottom, state);
|
||||
self.render_body_title(frame, _top, state);
|
||||
}
|
||||
|
||||
@@ -512,6 +511,7 @@ impl Output {
|
||||
BuildStage::Failed => lines.push("Failed".red()),
|
||||
BuildStage::Aborted => lines.push("Aborted".red()),
|
||||
BuildStage::Restarting => lines.push("Restarting".yellow()),
|
||||
_ => {}
|
||||
};
|
||||
|
||||
frame.render_widget(Line::from(lines), status_line);
|
||||
@@ -712,23 +712,6 @@ impl Output {
|
||||
);
|
||||
}
|
||||
|
||||
/// Render the version number on the bottom right
|
||||
fn render_bottom_row(&self, frame: &mut Frame, area: Rect, _state: RenderState) {
|
||||
// Split the area into two chunks
|
||||
let row = Layout::horizontal([Constraint::Fill(1), Constraint::Fill(1)]).split(area);
|
||||
|
||||
frame.render_widget(
|
||||
Paragraph::new(Line::from(vec![
|
||||
// "🧬 dx".dark_gray(),
|
||||
// " ".dark_gray(),
|
||||
// self.dx_version.as_str().dark_gray(),
|
||||
// " ".dark_gray(),
|
||||
]))
|
||||
.right_aligned(),
|
||||
row[1],
|
||||
);
|
||||
}
|
||||
|
||||
/// Render borders around the terminal, forcing an inner clear while we're at it
|
||||
fn render_borders(&self, frame: &mut Frame, area: Rect) {
|
||||
frame.render_widget(ratatui::widgets::Clear, area);
|
||||
@@ -784,7 +767,7 @@ impl Output {
|
||||
|
||||
// Render the log into an ansi string
|
||||
// We're going to add some metadata to it like the timestamp and source and then dump it to the raw ansi sequences we need to send to crossterm
|
||||
let output_sequence = tracemsg_to_ansi_string(log, term_size.width);
|
||||
let output_sequence = Self::tracemsg_to_ansi_string(log, term_size.width);
|
||||
|
||||
// Get the lines of the output sequence and their overflow
|
||||
let lines = output_sequence.lines().collect::<Vec<_>>();
|
||||
@@ -863,94 +846,94 @@ impl Output {
|
||||
false => VIEWPORT_HEIGHT_SMALL,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn tracemsg_to_ansi_string(log: TraceMsg, term_width: u16) -> String {
|
||||
let rendered = match log.content {
|
||||
TraceContent::Cargo(msg) => msg.message.rendered.unwrap_or_default(),
|
||||
TraceContent::Text(text) => text,
|
||||
};
|
||||
fn tracemsg_to_ansi_string(log: TraceMsg, term_width: u16) -> String {
|
||||
let rendered = match log.content {
|
||||
TraceContent::Cargo(msg) => msg.message.rendered.unwrap_or_default(),
|
||||
TraceContent::Text(text) => text,
|
||||
};
|
||||
|
||||
// Create a paragraph widget using the log line itself
|
||||
// From here on out, we want to work with the escaped ansi string and the "real lines" to be printed
|
||||
//
|
||||
// We make a special case for lines that look like frames (ie ==== or ---- or ------) and make them
|
||||
// dark gray, just for readability.
|
||||
//
|
||||
// todo(jon): refactor this out to accept any widget, not just paragraphs
|
||||
let paragraph = Paragraph::new({
|
||||
use ansi_to_tui::IntoText;
|
||||
use chrono::Timelike;
|
||||
// Create a paragraph widget using the log line itself
|
||||
// From here on out, we want to work with the escaped ansi string and the "real lines" to be printed
|
||||
//
|
||||
// We make a special case for lines that look like frames (ie ==== or ---- or ------) and make them
|
||||
// dark gray, just for readability.
|
||||
//
|
||||
// todo(jon): refactor this out to accept any widget, not just paragraphs
|
||||
let paragraph = Paragraph::new({
|
||||
use ansi_to_tui::IntoText;
|
||||
use chrono::Timelike;
|
||||
|
||||
let mut text = Text::default();
|
||||
let mut text = Text::default();
|
||||
|
||||
for (idx, raw_line) in rendered.lines().enumerate() {
|
||||
let line_as_text = raw_line.into_text().unwrap();
|
||||
let is_pretending_to_be_frame = raw_line
|
||||
.chars()
|
||||
.all(|c| c == '=' || c == '-' || c == ' ' || c == '─');
|
||||
for (idx, raw_line) in rendered.lines().enumerate() {
|
||||
let line_as_text = raw_line.into_text().unwrap();
|
||||
let is_pretending_to_be_frame = raw_line
|
||||
.chars()
|
||||
.all(|c| c == '=' || c == '-' || c == ' ' || c == '─');
|
||||
|
||||
for (subline_idx, line) in line_as_text.lines.into_iter().enumerate() {
|
||||
let mut out_line = if idx == 0 && subline_idx == 0 {
|
||||
let mut formatted_line = Line::default();
|
||||
for (subline_idx, line) in line_as_text.lines.into_iter().enumerate() {
|
||||
let mut out_line = if idx == 0 && subline_idx == 0 {
|
||||
let mut formatted_line = Line::default();
|
||||
|
||||
formatted_line.push_span(
|
||||
Span::raw(format!(
|
||||
"{:02}:{:02}:{:02} ",
|
||||
log.timestamp.hour(),
|
||||
log.timestamp.minute(),
|
||||
log.timestamp.second()
|
||||
))
|
||||
.dark_gray(),
|
||||
);
|
||||
formatted_line.push_span(
|
||||
Span::raw(format!(
|
||||
"[{src}] {padding}",
|
||||
src = log.source,
|
||||
padding =
|
||||
" ".repeat(3usize.saturating_sub(log.source.to_string().len()))
|
||||
))
|
||||
.style(match log.source {
|
||||
TraceSrc::App(_platform) => Style::new().blue(),
|
||||
TraceSrc::Dev => Style::new().magenta(),
|
||||
TraceSrc::Build => Style::new().yellow(),
|
||||
TraceSrc::Bundle => Style::new().magenta(),
|
||||
TraceSrc::Cargo => Style::new().yellow(),
|
||||
TraceSrc::Unknown => Style::new().gray(),
|
||||
}),
|
||||
);
|
||||
formatted_line.push_span(
|
||||
Span::raw(format!(
|
||||
"{:02}:{:02}:{:02} ",
|
||||
log.timestamp.hour(),
|
||||
log.timestamp.minute(),
|
||||
log.timestamp.second()
|
||||
))
|
||||
.dark_gray(),
|
||||
);
|
||||
formatted_line.push_span(
|
||||
Span::raw(format!(
|
||||
"[{src}] {padding}",
|
||||
src = log.source,
|
||||
padding =
|
||||
" ".repeat(3usize.saturating_sub(log.source.to_string().len()))
|
||||
))
|
||||
.style(match log.source {
|
||||
TraceSrc::App(_platform) => Style::new().blue(),
|
||||
TraceSrc::Dev => Style::new().magenta(),
|
||||
TraceSrc::Build => Style::new().yellow(),
|
||||
TraceSrc::Bundle => Style::new().magenta(),
|
||||
TraceSrc::Cargo => Style::new().yellow(),
|
||||
TraceSrc::Unknown => Style::new().gray(),
|
||||
}),
|
||||
);
|
||||
|
||||
for span in line.spans {
|
||||
formatted_line.push_span(span);
|
||||
for span in line.spans {
|
||||
formatted_line.push_span(span);
|
||||
}
|
||||
|
||||
formatted_line
|
||||
} else {
|
||||
line
|
||||
};
|
||||
|
||||
if is_pretending_to_be_frame {
|
||||
out_line = out_line.dark_gray();
|
||||
}
|
||||
|
||||
formatted_line
|
||||
} else {
|
||||
line
|
||||
};
|
||||
|
||||
if is_pretending_to_be_frame {
|
||||
out_line = out_line.dark_gray();
|
||||
text.lines.push(out_line);
|
||||
}
|
||||
|
||||
text.lines.push(out_line);
|
||||
}
|
||||
}
|
||||
|
||||
text
|
||||
});
|
||||
text
|
||||
});
|
||||
|
||||
// We want to get the escaped ansii string and then by dumping the paragraph as ascii codes (again)
|
||||
//
|
||||
// This is important because the line_count method on paragraph takes into account the width of these codes
|
||||
// the 3000 clip width is to bound log lines to a reasonable memory usage
|
||||
// We could consider reusing this buffer since it's a lot to allocate, but log printing is not the
|
||||
// slowest thing in the world and allocating is pretty fast...
|
||||
//
|
||||
// After we've dumped the ascii out, we want to call "trim_end" which ensures we don't attempt
|
||||
// to print extra characters as lines, since AnsiStringBuffer will in fact attempt to print empty
|
||||
// cells as characters. That might not actually be important, but we want to shrink the buffer
|
||||
// before printing it
|
||||
let line_count = paragraph.line_count(term_width);
|
||||
AnsiStringBuffer::new(3000, line_count as u16).render(¶graph)
|
||||
// We want to get the escaped ansii string and then by dumping the paragraph as ascii codes (again)
|
||||
//
|
||||
// This is important because the line_count method on paragraph takes into account the width of these codes
|
||||
// the 3000 clip width is to bound log lines to a reasonable memory usage
|
||||
// We could consider reusing this buffer since it's a lot to allocate, but log printing is not the
|
||||
// slowest thing in the world and allocating is pretty fast...
|
||||
//
|
||||
// After we've dumped the ascii out, we want to call "trim_end" which ensures we don't attempt
|
||||
// to print extra characters as lines, since AnsiStringBuffer will in fact attempt to print empty
|
||||
// cells as characters. That might not actually be important, but we want to shrink the buffer
|
||||
// before printing it
|
||||
let line_count = paragraph.line_count(term_width);
|
||||
AnsiStringBuffer::new(3000, line_count as u16).render(¶graph)
|
||||
}
|
||||
}
|
||||
@@ -111,6 +111,16 @@ impl AppRunner {
|
||||
// todo(jon): we should allow rebinding to the same port in fullstack itself
|
||||
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
|
||||
|
||||
// Add some cute logging
|
||||
if self.builds_opened == 0 {
|
||||
tracing::info!(
|
||||
"Build completed successfully in {:?}ms, launching app! 💫",
|
||||
app.app.time_taken.as_millis()
|
||||
);
|
||||
} else {
|
||||
tracing::info!("Build completed in {:?}ms", app.app.time_taken.as_millis());
|
||||
}
|
||||
|
||||
// Start the new app before we kill the old one to give it a little bit of time
|
||||
let mut handle = AppHandle::new(app).await?;
|
||||
handle
|
||||
@@ -120,6 +130,7 @@ impl AppRunner {
|
||||
self.builds_opened == 0 && should_open_web,
|
||||
)
|
||||
.await?;
|
||||
|
||||
self.builds_opened += 1;
|
||||
self.running.insert(platform, handle);
|
||||
|
||||
@@ -264,17 +275,17 @@ impl AppRunner {
|
||||
.arg("simctl")
|
||||
.arg("get_app_container")
|
||||
.arg("booted")
|
||||
.arg("com.dioxuslabs")
|
||||
.arg(runner.app.bundle_identifier())
|
||||
.output()
|
||||
.await;
|
||||
|
||||
if let Ok(res) = res {
|
||||
tracing::debug!("Using runtime asset dir: {:?}", res);
|
||||
tracing::trace!("Using runtime asset dir: {:?}", res);
|
||||
|
||||
if let Ok(out) = String::from_utf8(res.stdout) {
|
||||
let out = out.trim();
|
||||
|
||||
tracing::debug!("Setting Runtime asset dir: {out:?}");
|
||||
tracing::trace!("Setting Runtime asset dir: {out:?}");
|
||||
runner.runtime_asst_dir = Some(PathBuf::from(out));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,7 +204,11 @@ impl WebServer {
|
||||
}
|
||||
|
||||
/// Sends an updated build status to all clients.
|
||||
pub(crate) async fn new_build_update(&mut self, update: &BuildUpdate) {
|
||||
pub(crate) async fn new_build_update(
|
||||
&mut self,
|
||||
update: &BuildUpdate,
|
||||
builder: &super::Builder,
|
||||
) {
|
||||
match update {
|
||||
BuildUpdate::Progress { stage } => {
|
||||
// Todo(miles): wire up more messages into the splash screen UI
|
||||
@@ -220,11 +224,13 @@ impl WebServer {
|
||||
krate,
|
||||
..
|
||||
} => {
|
||||
self.build_status.set(Status::Building {
|
||||
progress: (*current as f64 / *total as f64).clamp(0.0, 1.0),
|
||||
build_message: format!("{krate} compiling"),
|
||||
});
|
||||
self.send_build_status().await;
|
||||
if !builder.is_finished() {
|
||||
self.build_status.set(Status::Building {
|
||||
progress: (*current as f64 / *total as f64).clamp(0.0, 1.0),
|
||||
build_message: format!("{krate} compiling"),
|
||||
});
|
||||
self.send_build_status().await;
|
||||
}
|
||||
}
|
||||
BuildStage::OptimizingWasm {} => {}
|
||||
BuildStage::Aborted => {}
|
||||
@@ -250,7 +256,7 @@ impl WebServer {
|
||||
return;
|
||||
}
|
||||
|
||||
tracing::debug!("Sending hotreload to clients {:?}", reload);
|
||||
tracing::trace!("Sending hotreload to clients {:?}", reload);
|
||||
|
||||
let msg = DevserverMsg::HotReload(reload);
|
||||
let msg = serde_json::to_string(&msg).unwrap();
|
||||
@@ -281,6 +287,8 @@ impl WebServer {
|
||||
|
||||
/// Tells all clients to reload if possible for new changes.
|
||||
pub(crate) async fn send_reload_command(&mut self) {
|
||||
tracing::trace!("Sending reload to toast");
|
||||
|
||||
tokio::time::sleep(std::time::Duration::from_millis(500)).await;
|
||||
|
||||
self.build_status.set(Status::Ready);
|
||||
|
||||
Reference in new issue
Block a user