Skip to content

Commit

Permalink
Reintroduce the loading spinner (#107)
Browse files Browse the repository at this point in the history
## Context / before
- The loading spinner (and loading text) were removed in
d12c19d
- If `WebRunner::start` fails nothing is shown in HTML, the user has to
open the console to see if something happened (a.k.a. halting problem)

## What changed / now
- before the canvas is loaded a CSS loading spinner with "Loading..."
text is displayed
- if the loading fails, "the app has crashed" text is shown instead
  - still `panic!` in this case (as it did)
- the corresponding div is removed after loading  successfully completes


## How does it look

![image](https://github.com/emilk/eframe_template/assets/58441256/012ef5ec-3e3a-48ca-8971-5fb0afcad738)

![image](https://github.com/emilk/eframe_template/assets/58441256/c2ed1dc9-eec8-4bd5-b134-9a7cf6ab72e5)

## What exactly changed
- introduce dependency to `web-sys`
- add the `loading_text` div that shows the spinner text during loading,
or error if loading fails
- access the DOM (in `main.rs`) after the app has been loaded, and
remove the spinner, or show an error
- if we fail to locate `loading_text` (like when someone removes the div
from `index.html`) - nothing happens

## Discussion
- I wanted to avoid dependency on `web-sys`, but, I don't see any other
simple way to access the spinner
- Another idea I had was to do it straight from the `js` side (like it
was before), however, I don't see a way to receive events from
`WebRunner`
- If this solution is undesired, I think the CSS remnants of the spinner
[should be
removed](master...sedsedus:eframe_template:remove-left-over-css)
(like `lds-dual-ring`)

## Alternative solution
A more thorough solution (in `main.rs`) is
master...sedsedus:eframe_template:fix-css-spinner-install-hook,
where all panics are caught to show HTML error.
I encountered this myself, where I would mistype the canvas id and wait
a few seconds wondering why the app doesn't load, only to discover in
the console that something failed.
This is more thorough (but at the same time a little more complex / less
clean due to hook insertion) because this "invalid canvas id error"
wouldn't get caught by the proposal in this PR

---------

Co-authored-by: Emil Ernerfeldt <[email protected]>
  • Loading branch information
sedsedus and emilk authored Jun 26, 2024
1 parent 3a6b565 commit 6ec4bd5
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 4 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ env_logger = "0.10"
[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen-futures = "0.4"

# to access the DOM (to hide the loading text)
[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys]
version = "0.3.4"

[profile.release]
opt-level = 2 # fast and small wasm
Expand Down
9 changes: 8 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@
transform: rotate(360deg);
}
}

</style>
</head>

Expand All @@ -123,6 +122,14 @@
<!-- the id is hardcoded in main.rs . so, make sure both match. -->
<canvas id="the_canvas_id"></canvas>

<!-- the loading spinner will be removed in main.rs -->
<div class="centered" id="loading_text">
<p style="font-size:16px">
Loading…
</p>
<div class="lds-dual-ring"></div>
</div>

<!--Register Service Worker. this will cache the wasm / js scripts for offline use (for PWA functionality). -->
<!-- Force refresh (Ctrl + F5) to load the latest files instead of cached files -->
<script>
Expand Down
21 changes: 18 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,28 @@ fn main() {
let web_options = eframe::WebOptions::default();

wasm_bindgen_futures::spawn_local(async {
eframe::WebRunner::new()
let start_result = eframe::WebRunner::new()
.start(
"the_canvas_id", // hardcode it
web_options,
Box::new(|cc| Box::new(eframe_template::TemplateApp::new(cc))),
)
.await
.expect("failed to start eframe");
.await;
let loading_text = web_sys::window()
.and_then(|w| w.document())
.and_then(|d| d.get_element_by_id("loading_text"));
match start_result {
Ok(_) => {
loading_text.map(|e| e.remove());
}
Err(e) => {
loading_text.map(|e| {
e.set_inner_html(
"<p> The app has crashed. See the developer console for details. </p>",
)
});
panic!("failed to start eframe: {e:?}");
}
}
});
}

0 comments on commit 6ec4bd5

Please sign in to comment.