Splash Screens (#2657)
* progress: loading splash screen * feat: loading screen plash * feat: splash screens --------- Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com>
This commit is contained in:
1 parent
8b5ad5d925
commit
856fadc9d6
6 files changed
+458
-119
No files matched your search
Vendored
+1
-1
@@ -9,5 +9,5 @@
|
||||
"rust-analyzer.cargo.features": "all",
|
||||
"rust-analyzer.check.allTargets": true,
|
||||
// we don't want the formatter to kick in while we're working on dioxus itself
|
||||
"dioxus.formatOnSave": "disabled"
|
||||
"dioxus.formatOnSave": "disabled",
|
||||
}
|
||||
@@ -156,7 +156,7 @@ pub struct ApplicationConfig {
|
||||
}
|
||||
|
||||
fn default_name() -> String {
|
||||
"name".into()
|
||||
"my-cool-project".into()
|
||||
}
|
||||
|
||||
fn default_platform() -> Platform {
|
||||
|
||||
+417
-107
@@ -1,118 +1,428 @@
|
||||
<!DOCTYPE html>
|
||||
<html style="margin: 0; padding: 0; width: 100%; height: 100%">
|
||||
<head>
|
||||
<title>Dioxus Build In Progress</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta charset="UTF-8" />
|
||||
<style>
|
||||
#main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Dioxus Build</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/png" href="https://avatars.githubusercontent.com/u/79236386?s=200&v=4">
|
||||
<style>
|
||||
/* Fira Mono Font */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Fira+Mono:wght@400;500;700&display=swap');
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow-x: hidden;
|
||||
font-family: "Fira Mono", monospace;
|
||||
color: #313131;
|
||||
background-repeat: repeat;
|
||||
background-image: url('data:image/png;base64,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 truncated
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none !important;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
/* Header */
|
||||
#header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 80vw;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#header>#dioxus {
|
||||
margin-left: 10px;
|
||||
font-weight: 500;
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
#header>#project-info {
|
||||
margin-left: auto;
|
||||
font-weight: 500;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.content-container {
|
||||
width: max-content;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 10vh;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.content-header-text {
|
||||
font-weight: 700;
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
/* Building proggres screen */
|
||||
#building>h1 {
|
||||
margin-bottom: 60px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#building>#progress-bar {
|
||||
width: 100%;
|
||||
height: 8px;
|
||||
background-color: #BEC4D0;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#building>#progress-bar>div {
|
||||
height: 100%;
|
||||
background-color: #55A4FF;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#building>#text {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#building>#text>h4 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#building>#text>#build-message {
|
||||
margin-right: auto;
|
||||
font-weight: 500;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
#building>#text>#build-progress-percent {
|
||||
margin-left: auto;
|
||||
font-weight: 700;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
/* Error */
|
||||
#error {
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
#error>h1 {
|
||||
margin-bottom: 20px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#error>#error-sub-text {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
#error>#error-block {
|
||||
background-color: #BEC4D0;
|
||||
border-radius: 5px;
|
||||
padding: 20px;
|
||||
font-weight: 500;
|
||||
overflow-x: auto;
|
||||
white-space: pre-wrap;
|
||||
min-width: 640px;
|
||||
}
|
||||
|
||||
/* Text coloring */
|
||||
.err {
|
||||
color: #d94545;
|
||||
}
|
||||
|
||||
.info {
|
||||
color: #3980d1;
|
||||
}
|
||||
|
||||
.warn {
|
||||
color: #CC7E00;
|
||||
}
|
||||
|
||||
.text-theme {
|
||||
color: #313131;
|
||||
}
|
||||
|
||||
|
||||
/* Footer */
|
||||
#footer {
|
||||
width: 100vw;
|
||||
margin-top: 100px;
|
||||
}
|
||||
|
||||
#footer>h4 {
|
||||
text-align: center;
|
||||
box-sizing: content-box;
|
||||
font-size: 1.1rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
#footer>h4>a {
|
||||
text-decoration: none;
|
||||
color: #313131;
|
||||
}
|
||||
|
||||
#footer>h4>a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@media (max-width: 725px) {
|
||||
#header {
|
||||
width: 95vw;
|
||||
}
|
||||
|
||||
#building {
|
||||
width: 95vw;
|
||||
}
|
||||
|
||||
#building>h1 {
|
||||
width: 100%;
|
||||
background: #f6f7f8;
|
||||
}
|
||||
#main :nth-child(n) {
|
||||
animation: fade-in 0.5s;
|
||||
}
|
||||
|
||||
@media (max-width: 780px) {
|
||||
#header {
|
||||
width: 95vw;
|
||||
}
|
||||
#error-message {
|
||||
color: rgb(182, 0, 0);
|
||||
font-size: 0.75em;
|
||||
white-space: pre-wrap;
|
||||
|
||||
#error {
|
||||
width: 95vw;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
#main {
|
||||
background: #000;
|
||||
color: #f6f7f8;
|
||||
}
|
||||
#error-message {
|
||||
color: rgb(255, 89, 89);
|
||||
}
|
||||
|
||||
#error>h1 {
|
||||
width: 100%;
|
||||
}
|
||||
@keyframes fade-in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#error>#error-block {
|
||||
min-width: auto;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body style="margin: 0; padding: 0; width: 100%; height: 100%">
|
||||
<div id="main">
|
||||
<h1 id="loading-indicator">Building project 0%</h1>
|
||||
}
|
||||
|
||||
/* Dark Theme */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
color: #E2E5E9;
|
||||
background-repeat: repeat;
|
||||
background-image: url('data:image/png;base64,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 truncated
|
||||
|
||||
}
|
||||
|
||||
/* Text coloring */
|
||||
.err {
|
||||
color: #F04C4C;
|
||||
}
|
||||
|
||||
.info {
|
||||
color: #55A4FF;
|
||||
}
|
||||
|
||||
.warn {
|
||||
color: #FFCB51;
|
||||
}
|
||||
|
||||
.text-theme {
|
||||
color: #E2E5E9;
|
||||
}
|
||||
|
||||
#building>#progress-bar,
|
||||
#error>#error-block {
|
||||
background-color: #111318;
|
||||
}
|
||||
|
||||
#footer>h4>a {
|
||||
color: #E2E5E9;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Header -->
|
||||
<div id="header">
|
||||
<!-- Dioxus Logo -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" xmlns:v="https://vecta.io/nano">
|
||||
<path
|
||||
d="M22.158 1.783c0 3.077-.851 5.482-2.215 7.377s-3.32 3.557-5.447 5.33-4.425 3.657-6.252 6.195-3.102 5.515-3.102 9.532h4.699c0-3.077.853-5.377 2.217-7.272s3.32-3.557 5.447-5.33 4.425-3.657 6.252-6.195 3.102-5.62 3.102-9.637z"
|
||||
fill="#e96020" />
|
||||
<path
|
||||
d="M9.531 25.927c-.635 0-1.021.515-1.02 1.15s.385 1.151 1.02 1.15H22.47a1.151 1.151 0 1 0 0-2.301zm1.361-4.076c-.608 0-.954.558-.953 1.166s.346 1.035.953 1.035h10.217a1.101 1.101 0 1 0 0-2.201zm0-13.594a1.101 1.101 0 1 0 0 2.201h10.217c.607 0 .953-.598.953-1.205s-.345-.996-.953-.996zM9.531 4.021A1.15 1.15 0 0 0 8.38 5.17a1.15 1.15 0 0 0 1.15 1.15h12.94c.635 0 1.021-.498 1.02-1.133s-.386-1.166-1.02-1.166z"
|
||||
fill="#2d323b" />
|
||||
<path
|
||||
d="M5.142 1.783c0 4.016 1.275 7.099 3.102 9.637s4.125 4.422 6.252 6.195 4.083 3.656 5.447 5.551 2.215 3.974 2.215 7.051h4.701c0-4.016-1.275-7.038-3.102-9.576s-4.125-4.422-6.252-6.195-4.083-3.435-5.447-5.33S9.841 4.86 9.841 1.783z"
|
||||
fill="#00a8d6" />
|
||||
</svg>
|
||||
|
||||
<h2 id="dioxus">Dioxus</h2>
|
||||
|
||||
<!-- Project platform and name -->
|
||||
<h2 id="project-info">N/A | N/A</h2>
|
||||
</div>
|
||||
|
||||
<!-- Building progress screen -->
|
||||
<div class="content-container" id="building">
|
||||
<h1 class="content-header-text">One sec! <br />We're building your app now.</h1>
|
||||
|
||||
<div id="progress-bar">
|
||||
<div id="progress-bar-inner" style="width: 1%;"></div>
|
||||
</div>
|
||||
<script>
|
||||
// Wait for a "Ready" message from the server on the websocket served at /_dioxus/build_status
|
||||
let protocol;
|
||||
if (window.location.protocol === "https:") {
|
||||
protocol = "wss:";
|
||||
} else {
|
||||
protocol = "ws:";
|
||||
<div id="text">
|
||||
<!-- Funny loading messages or something -->
|
||||
<h4 id="build-message">Starting the build...</h4>
|
||||
|
||||
<!-- Progress % -->
|
||||
<h4 id="build-progress-percent">0%</h4>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Building Error -->
|
||||
<div class="content-container hidden" id="error">
|
||||
<h1 class="content-header-text">Oops! The build failed.</h1>
|
||||
<p id="error-sub-text"><span id="error-inner-sub-text" class="warn">compiling my-cool-project</span> encountered an
|
||||
error:</p>
|
||||
<div id="error-block">
|
||||
<span class="err">error</span><span>: expected `;`, found `rsx`</span> <br />
|
||||
<span class="info"> --></span><span> src/main.rs:21:6</span><br />
|
||||
<span class="info"> |</span><br />
|
||||
<span class="info">21 |</span><span> a</span><br />
|
||||
<span class="info"> |</span><span class="err"> ^ help: add `;` here</span><br />
|
||||
<span class="info">22 |</span><span> rsx! {</span><br />
|
||||
<span class="info"> |</span><span class="info"> --- unexpected token</span><br />
|
||||
|
||||
<span class="err">error</span><span>: could not compile `my-cool-app` (bin "my-cool-app") due to 1 previous
|
||||
error</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Footer Of Links -->
|
||||
<div id="footer">
|
||||
<h4>
|
||||
<a href="https://docs.rs/dioxus/latest/dioxus/">docs</a>
|
||||
|
|
||||
<a href="https://dioxuslabs.com/learn">guides</a>
|
||||
|
|
||||
<a href="https://discord.gg/KrGKhBbU6s">help</a>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<!-- Logic -->
|
||||
<script>
|
||||
let APPLICATION_NAME = "N/A";
|
||||
|
||||
// Wait for a "Ready" message from the server on the websocket served at /_dioxus/build_status
|
||||
let protocol;
|
||||
if (window.location.protocol === "https:") {
|
||||
protocol = "wss:";
|
||||
} else {
|
||||
protocol = "ws:";
|
||||
}
|
||||
let url =
|
||||
protocol + "//" + window.location.host + "/_dioxus/build_status";
|
||||
let ws = new WebSocket(url);
|
||||
|
||||
// WS Message Handling
|
||||
ws.onmessage = (event) => {
|
||||
// Parse the message as json
|
||||
let data = JSON.parse(event.data);
|
||||
console.log(data);
|
||||
|
||||
// If the message is "Ready", reload the page
|
||||
if (data.type === "Ready") {
|
||||
setTimeout(() => {
|
||||
// Once we get a "Ready" message, reload the page
|
||||
window.location.reload();
|
||||
}, 500);
|
||||
} else if (data.type === "ClientInit") {
|
||||
// Get project info
|
||||
APPLICATION_NAME = data.data.application_name;
|
||||
const platform = data.data.platform;
|
||||
|
||||
// Set project info
|
||||
let projectInfo = document.getElementById("project-info");
|
||||
projectInfo.innerText = `${platform} | ${APPLICATION_NAME}`;
|
||||
|
||||
} else if (data.type === "BuildError") {
|
||||
// If the message is "BuildError", display an error message
|
||||
// Show correct view for message.
|
||||
let errorContainer = document.getElementById("error");
|
||||
errorContainer.className = "content-container";
|
||||
|
||||
let buildingContainer = document.getElementById("building");
|
||||
buildingContainer.className = "content-container hidden";
|
||||
|
||||
let errorInnerSubText = document.getElementById("error-inner-sub-text");
|
||||
errorInnerSubText.innerText = `compiling ${APPLICATION_NAME}`;
|
||||
|
||||
// Replace with our styling.
|
||||
let color1 = data.data.error.replaceAll("style='color:#f55'", "class='err'");
|
||||
let color2 = color1.replaceAll("style='color:#5ff'", "class='info'");
|
||||
let color3 = color2.replaceAll("style='color:#fff'", "class='text-theme'");
|
||||
let formatting1 = color3.replaceAll("<b>", "");
|
||||
let formatting2 = formatting1.replaceAll("</b>", "");
|
||||
|
||||
let errorBlock = document.getElementById("error-block");
|
||||
errorBlock.innerHTML = formatting2;
|
||||
|
||||
console.log(data.data.error);
|
||||
} else if (data.type === "Building") {
|
||||
// Show correct view for message.
|
||||
let errorContainer = document.getElementById("error");
|
||||
errorContainer.className = "content-container hidden";
|
||||
|
||||
let buildingContainer = document.getElementById("building");
|
||||
buildingContainer.className = "content-container";
|
||||
|
||||
// Get the current progress
|
||||
const progress = data.data.progress;
|
||||
const roundedProgress = Math.round(progress * 100);
|
||||
// Update the loading indicator
|
||||
let loadingPercent = document.getElementById("build-progress-percent");
|
||||
let loadingBar = document.getElementById("progress-bar-inner");
|
||||
|
||||
const formattedProgress = `${roundedProgress}%`;
|
||||
loadingPercent.innerHTML = formattedProgress;
|
||||
loadingBar.style.width = formattedProgress;
|
||||
|
||||
// Show progress message
|
||||
const message = data.data.build_message;
|
||||
let buildMessage = document.getElementById("build-message");
|
||||
buildMessage.innerText = message;
|
||||
}
|
||||
let url =
|
||||
protocol + "//" + window.location.host + "/_dioxus/build_status";
|
||||
let ws = new WebSocket(url);
|
||||
ws.onmessage = (event) => {
|
||||
// Parse the message as json
|
||||
let data = JSON.parse(event.data);
|
||||
// If the message is "Ready", reload the page
|
||||
if (data.type === "Ready") {
|
||||
setTimeout(() => {
|
||||
// Once we get a "Ready" message, reload the page
|
||||
window.location.reload();
|
||||
}, 500);
|
||||
} else if (data.type === "BuildError") {
|
||||
// If the message is "BuildError", display an error message
|
||||
document.getElementById("main").innerHTML = `<div>
|
||||
<h1>Failed to build project</h1>
|
||||
<pre id="error-message">${data.data.error}</pre>
|
||||
</div>`;
|
||||
} else if (data.type === "Building") {
|
||||
// Get the current progress
|
||||
const progress = data.data.progress;
|
||||
const roundedProgress = Math.round(progress * 100);
|
||||
// Update the loading indicator
|
||||
let loadingIndicator = document.getElementById("loading-indicator");
|
||||
if (loadingIndicator) {
|
||||
loadingIndicator.innerHTML = `Building project ${roundedProgress}%`;
|
||||
} else {
|
||||
document.getElementById(
|
||||
"main"
|
||||
).innerHTML = `<h1 id="loading-indicator">Building project ${progress}%</h1>`;
|
||||
}
|
||||
}
|
||||
};
|
||||
const POLL_INTERVAL_MIN = 250;
|
||||
const POLL_INTERVAL_MAX = 4000;
|
||||
const POLL_INTERVAL_SCALE_FACTOR = 2;
|
||||
};
|
||||
|
||||
const reload_upon_connect = (event, poll_interval) => {
|
||||
// Firefox will send a 1001 code when the connection is closed because the page is reloaded
|
||||
// Only firefox will trigger the onclose event when the page is reloaded manually: https://stackoverflow.com/questions/10965720/should-websocket-onclose-be-triggered-by-user-navigation-or-refresh
|
||||
// We should not reload the page in this case
|
||||
if (event.code === 1001) {
|
||||
return;
|
||||
}
|
||||
window.setTimeout(() => {
|
||||
var ws = new WebSocket(url);
|
||||
ws.onopen = () => window.location.reload();
|
||||
ws.onclose = (event) => {
|
||||
reload_upon_connect(
|
||||
event,
|
||||
Math.min(
|
||||
POLL_INTERVAL_MAX,
|
||||
poll_interval * POLL_INTERVAL_SCALE_FACTOR
|
||||
)
|
||||
);
|
||||
};
|
||||
}, poll_interval);
|
||||
};
|
||||
|
||||
ws.onclose = (event) => reload_upon_connect(event, POLL_INTERVAL_MIN);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
// WS Reconnect Logic
|
||||
const POLL_INTERVAL_MIN = 250;
|
||||
const POLL_INTERVAL_MAX = 4000;
|
||||
const POLL_INTERVAL_SCALE_FACTOR = 2;
|
||||
|
||||
const reload_upon_connect = (event, poll_interval) => {
|
||||
// Firefox will send a 1001 code when the connection is closed because the page is reloaded
|
||||
// Only firefox will trigger the onclose event when the page is reloaded manually: https://stackoverflow.com/questions/10965720/should-websocket-onclose-be-triggered-by-user-navigation-or-refresh
|
||||
// We should not reload the page in this case
|
||||
if (event.code === 1001) {
|
||||
return;
|
||||
}
|
||||
window.setTimeout(() => {
|
||||
var ws = new WebSocket(url);
|
||||
ws.onopen = () => window.location.reload();
|
||||
ws.onclose = (event) => {
|
||||
reload_upon_connect(
|
||||
event,
|
||||
Math.min(
|
||||
POLL_INTERVAL_MAX,
|
||||
poll_interval * POLL_INTERVAL_SCALE_FACTOR
|
||||
)
|
||||
);
|
||||
};
|
||||
}, poll_interval);
|
||||
};
|
||||
|
||||
ws.onclose = (event) => reload_upon_connect(event, POLL_INTERVAL_MIN);
|
||||
</script>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -11,7 +11,7 @@ use tracing::Level;
|
||||
|
||||
use super::BuildRequest;
|
||||
|
||||
#[derive(Default, Debug, PartialOrd, Ord, PartialEq, Eq)]
|
||||
#[derive(Default, Debug, PartialOrd, Ord, PartialEq, Eq, Clone, Copy)]
|
||||
pub enum Stage {
|
||||
#[default]
|
||||
Initializing = 0,
|
||||
|
||||
@@ -106,8 +106,9 @@ pub async fn serve_all(serve: Serve, dioxus_crate: DioxusCrate) -> Result<()> {
|
||||
// We also can check the status of the builds here in case we have multiple ongoing builds
|
||||
match application {
|
||||
Ok(BuilderUpdate::Progress { platform, update }) => {
|
||||
let update_stage = update.stage;
|
||||
screen.new_build_logs(platform, update);
|
||||
server.update_build_status(screen.build_progress.progress()).await;
|
||||
server.update_build_status(screen.build_progress.progress(), update_stage.to_string()).await;
|
||||
}
|
||||
Ok(BuilderUpdate::Ready { results }) => {
|
||||
if !results.is_empty() {
|
||||
|
||||
@@ -46,8 +46,17 @@ use tower_http::{
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(tag = "type", content = "data")]
|
||||
enum Status {
|
||||
Building { progress: f64 },
|
||||
BuildError { error: String },
|
||||
ClientInit {
|
||||
application_name: String,
|
||||
platform: String,
|
||||
},
|
||||
Building {
|
||||
progress: f64,
|
||||
build_message: String,
|
||||
},
|
||||
BuildError {
|
||||
error: String,
|
||||
},
|
||||
Ready,
|
||||
}
|
||||
|
||||
@@ -77,14 +86,21 @@ pub(crate) struct Server {
|
||||
_server_task: JoinHandle<Result<()>>,
|
||||
/// We proxy (not hot reloading) fullstack requests to this port
|
||||
pub fullstack_port: Option<u16>,
|
||||
|
||||
build_status: SharedStatus,
|
||||
application_name: String,
|
||||
platform: String,
|
||||
}
|
||||
|
||||
impl Server {
|
||||
pub fn start(serve: &Serve, cfg: &DioxusCrate) -> Self {
|
||||
let (hot_reload_sockets_tx, hot_reload_sockets_rx) = futures_channel::mpsc::unbounded();
|
||||
let (build_status_sockets_tx, build_status_sockets_rx) = futures_channel::mpsc::unbounded();
|
||||
let build_status = SharedStatus::new(Status::Building { progress: 0.0 });
|
||||
|
||||
let build_status = SharedStatus::new(Status::Building {
|
||||
progress: 0.0,
|
||||
build_message: "Starting the build...".to_string(),
|
||||
});
|
||||
|
||||
let addr = serve.server_arguments.address.address();
|
||||
let start_browser = serve.server_arguments.open.unwrap_or_default();
|
||||
@@ -151,7 +167,10 @@ impl Server {
|
||||
_server_task,
|
||||
ip: addr,
|
||||
fullstack_port,
|
||||
|
||||
build_status,
|
||||
application_name: cfg.dioxus_config.application.name.clone(),
|
||||
platform: serve.build_arguments.platform().to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,15 +190,21 @@ impl Server {
|
||||
}
|
||||
|
||||
pub async fn start_build(&mut self) {
|
||||
self.build_status.set(Status::Building { progress: 0.0 });
|
||||
self.build_status.set(Status::Building {
|
||||
progress: 0.0,
|
||||
build_message: "Starting the build...".to_string(),
|
||||
});
|
||||
self.send_build_status().await;
|
||||
}
|
||||
|
||||
pub async fn update_build_status(&mut self, progress: f64) {
|
||||
pub async fn update_build_status(&mut self, progress: f64, build_message: String) {
|
||||
if !matches!(self.build_status.get(), Status::Building { .. }) {
|
||||
return;
|
||||
}
|
||||
self.build_status.set(Status::Building { progress });
|
||||
self.build_status.set(Status::Building {
|
||||
progress,
|
||||
build_message,
|
||||
});
|
||||
self.send_build_status().await;
|
||||
}
|
||||
|
||||
@@ -223,8 +248,11 @@ impl Server {
|
||||
new_build_status_socket = &mut new_build_status_socket => {
|
||||
if let Some(mut new_socket) = new_build_status_socket {
|
||||
drop(new_message);
|
||||
// Update the socket with the current status
|
||||
if send_build_status_to(&self.build_status, &mut new_socket).await.is_ok() {
|
||||
|
||||
// Update the socket with project info and current build status
|
||||
let project_info = SharedStatus::new(Status::ClientInit { application_name: self.application_name.clone(), platform: self.platform.clone() });
|
||||
if send_build_status_to(&project_info, &mut new_socket).await.is_ok() {
|
||||
_ = send_build_status_to(&self.build_status, &mut new_socket).await;
|
||||
self.build_status_sockets.push(new_socket);
|
||||
}
|
||||
return None;
|
||||
|
||||
Reference in new issue
Block a user