CLI self-updater, warn on version mismatch, direct install.sh option, androidmanifest and info.plist customization, bump to 0.7-alpha.0 (#4095)

* wip.... bun installer

* - warn on incompatible versions
- clean up some logs
- add coloring to log levels

* add toasts to desktop/mobile

* Auto open simulators

* auto boot android

* preserve url

* pull out some of the warnings

* add self-updater

* wip: mcp

* add install.sh and adjust binstall path

* add some cuter styling to logs!

* update "input.css"

* update other input.css

* style a bit more

* change getting started

* add windows installer

* move dioxus-mobile into dioxus-desktop
add sentry wip to cli

* shorten timeout of toast

* fix cli display

* wire up customization of android manifest

* udid is a real word

* add 429 to lychee cache

* accept all 200-204 and 429
This commit is contained in:
Jonathan Kelley authored and GitHub committed 2025-05-14 08:43:11 +02:00
1 parent 53ef78823d
commit 4d3d55a7a3
56 files changed
+1560 -548

No files matched your search

+91 -13
View File
@@ -7,7 +7,8 @@ use crate::{
shortcut::ShortcutRegistry,
webview::WebviewInstance,
};
use dioxus_core::{ElementId, VirtualDom};
use dioxus_core::{ElementId, ScopeId, VirtualDom};
use dioxus_history::History;
use dioxus_html::PlatformEventData;
use std::{
any::Any,
@@ -15,6 +16,7 @@ use std::{
collections::HashMap,
rc::Rc,
sync::Arc,
time::Duration,
};
use tao::{
dpi::PhysicalSize,
@@ -168,12 +170,10 @@ impl App {
#[cfg(all(feature = "devtools", debug_assertions))]
pub fn connect_hotreload(&self) {
if let Some(endpoint) = dioxus_cli_config::devserver_ws_endpoint() {
let proxy = self.shared.proxy.clone();
dioxus_devtools::connect(endpoint, move |msg| {
_ = proxy.send_event(UserWindowEvent::HotReloadEvent(msg));
})
}
let proxy = self.shared.proxy.clone();
dioxus_devtools::connect(move |msg| {
_ = proxy.send_event(UserWindowEvent::HotReloadEvent(msg));
})
}
pub fn handle_new_window(&mut self) {
@@ -322,8 +322,14 @@ impl App {
#[cfg(all(feature = "devtools", debug_assertions))]
pub fn handle_hot_reload_msg(&mut self, msg: dioxus_devtools::DevserverMsg) {
use std::time::Duration;
use dioxus_devtools::DevserverMsg;
// Amount of time that toats should be displayed.
const TOAST_TIMEOUT: Duration = Duration::from_secs(2);
const TOAST_TIMEOUT_LONG: Duration = Duration::from_secs(3600); // Duration::MAX is too long for JS.
match msg {
DevserverMsg::HotReload(hr_msg) => {
for webview in self.webviews.values_mut() {
@@ -343,13 +349,49 @@ impl App {
webview.kick_stylsheets();
}
}
if hr_msg.jump_table.is_some()
&& hr_msg.for_build_id == Some(dioxus_cli_config::build_id())
{
self.send_toast_to_all(
"Hot-patch success!",
&format!("App successfully patched in {} ms", hr_msg.ms_elapsed),
"success",
TOAST_TIMEOUT,
false,
);
}
}
DevserverMsg::FullReloadCommand
| DevserverMsg::FullReloadStart
| DevserverMsg::FullReloadFailed => {
// usually only web gets this message - what are we supposed to do?
// Maybe we could just binary patch ourselves in place without losing window state?
DevserverMsg::FullReloadCommand => {
self.send_toast_to_all(
"Successfully rebuilt.",
"Your app was rebuilt successfully and without error.",
"success",
TOAST_TIMEOUT,
true,
);
}
DevserverMsg::FullReloadStart => self.send_toast_to_all(
"Your app is being rebuilt.",
"A non-hot-reloadable change occurred and we must rebuild.",
"info",
TOAST_TIMEOUT_LONG,
false,
),
DevserverMsg::FullReloadFailed => self.send_toast_to_all(
"Oops! The build failed.",
"We tried to rebuild your app, but something went wrong.",
"error",
TOAST_TIMEOUT_LONG,
false,
),
DevserverMsg::HotPatchStart => self.send_toast_to_all(
"Hot-patching app...",
"Hot-patching modified Rust code.",
"info",
TOAST_TIMEOUT_LONG,
false,
),
DevserverMsg::Shutdown => {
self.control_flow = ControlFlow::Exit;
}
@@ -357,6 +399,20 @@ impl App {
}
}
#[cfg(all(feature = "devtools", debug_assertions))]
fn send_toast_to_all(
&self,
header_text: &str,
message: &str,
level: &str,
duration: Duration,
after_reload: bool,
) {
for webview in self.webviews.values() {
webview.show_toast(header_text, message, level, duration, after_reload);
}
}
pub fn handle_file_dialog_msg(&mut self, msg: IpcMessage, window: WindowId) {
let Ok(file_dialog) = serde_json::from_value::<FileDialogRequest>(msg.params()) else {
return;
@@ -462,6 +518,9 @@ impl App {
#[cfg(debug_assertions)]
fn persist_window_state(&self) {
use dioxus_core::ScopeId;
use dioxus_history::History;
if let Some(webview) = self.webviews.values().next() {
let window = &webview.desktop_context.window;
@@ -491,12 +550,20 @@ impl App {
return;
};
let url = webview.dom.in_runtime(|| {
ScopeId::ROOT
.consume_context::<Rc<dyn History>>()
.unwrap()
.current_route()
});
let state = PreservedWindowState {
x,
y,
width: size.width.max(200),
height: size.height.saturating_sub(adjustment).max(200),
monitor: monitor_name.to_string(),
url: Some(url),
};
// Yes... I know... we're loading a file that might not be ours... but it's a debug feature
@@ -540,6 +607,16 @@ impl App {
if explicit_inner_size.is_none() {
window.set_inner_size(tao::dpi::PhysicalSize::new(size.0, size.1));
}
// Set the url if it exists
webview.dom.in_runtime(|| {
if let Some(url) = state.url {
ScopeId::ROOT
.consume_context::<Rc<dyn History>>()
.unwrap()
.replace(url);
}
})
}
}
}
@@ -563,7 +640,7 @@ impl App {
}
// give it a moment for the event to be processed
std::thread::sleep(std::time::Duration::from_secs(1));
std::thread::sleep(std::time::Duration::from_millis(100));
}
}
});
@@ -578,6 +655,7 @@ struct PreservedWindowState {
width: u32,
height: u32,
monitor: String,
url: Option<String>,
}
/// Hide the last window when using LastWindowHides.