UX: Ensure loading slider does not 'reset' halfway through a transition (#24446)

For transitions to nested routes (e.g. /u/blah/activity), where each layer has an async model hook, the `loading` event will be fired twice within the same transition. This was causing the loading slider to jump backwards halfway through loading. This commit fixes things to handle nested loading events with a single animation.
This commit is contained in:
David Taylor 2023-11-20 20:14:02 +00:00 committed by GitHub
parent 20e562bd99
commit d641a63236
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 0 deletions

View File

@ -83,6 +83,11 @@ export default class LoadingSlider extends Service.extend(Evented) {
}
transitionStarted() {
if (this.loading) {
// Nested transition
return;
}
this.timer.start();
this.loading = true;
this.trigger("stateChanged", true);
@ -97,6 +102,10 @@ export default class LoadingSlider extends Service.extend(Evented) {
@bind
transitionEnded() {
if (!this.loading) {
return;
}
let duration = this.timer.stop();
if (duration < MIN_LOADING_TIME) {
duration = MIN_LOADING_TIME;

View File

@ -1,3 +1,4 @@
import { getOwner } from "@ember/application";
import {
currentRouteName,
getSettledState,
@ -96,4 +97,19 @@ acceptance("Page Loading Indicator", function (needs) {
assert.strictEqual(currentRouteName(), "about");
assert.dom("#main-outlet section.about").exists();
});
test("it only performs one slide during nested loading events", async function (assert) {
this.siteSettings.page_loading_indicator = "slider";
await visit("/");
const service = getOwner(this).lookup("service:loading-slider");
service.on("stateChanged", (loading) => {
assert.step(`loading: ${loading}`);
});
await visit("/u/eviltrout/activity");
assert.verifySteps(["loading: true", "loading: false"]);
});
});