Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance progress state in dialogs #714

Open
jotaen opened this issue May 31, 2021 · 4 comments
Open

Enhance progress state in dialogs #714

jotaen opened this issue May 31, 2021 · 4 comments
Labels
enhancement New feature or request

Comments

@jotaen
Copy link
Contributor

jotaen commented May 31, 2021

As pointed out in #708, we could avoid some repetition in our dialog components by pulling out a generic progress state into the <overlay-panel>. The dialogs would emit events DialogProgressStarted/DialogProgressFinished that the overlay picks up and adjusts the visual state.

That would not just make the code leaner, but it also ensures that the visual pattern is always consistent. In analogy to the error dialog, the progress state could have a blue top border and a slightly blue-ish background, so that the user recognises it easily.

Screenshot 2021-05-31 at 22 43 33

@jotaen jotaen added the enhancement New feature or request label May 31, 2021
@jotaen
Copy link
Contributor Author

jotaen commented Jun 2, 2021

There is also quite a common problem that the progress state appears to be flickering/flashing: the UI switches into loading state for just a split second, because the underlying operation executes very rapidly. This is inconvenient, because the user doesn’t get a chance to grasp what’s going on.

If the progress state was centrally controlled by the overlay panel, we could make it more sophisticated to account for that phenomenon. For example, the progress state could be debounced like so:

  • When the DialogProgressStarted event fires, we wait for ~50–100ms. If DialogProgressFinished was fired in the meantime, we just skip and don’t do anything. If it wasn’t fired, we switch to progress state. That way, we avoid visual flickering for fast operations altogether.
    • During this brief grace period, we need to make the dialog non-interactive (e.g. along the lines of pointer-events: none or so), so that the user cannot accidentally issue multiple clicks to the same button.
  • Once we have switched to progress state, we do it the same the other way around, so that the progress state will show up for at least ~200ms, even if DialogProgressFinished had been fired earlier. That way the user always has enough time to follow the UI.

(exact time values tbd; the event constructor could also take a boolean, such as DialogProgressEvent(true))

@jotaen
Copy link
Contributor Author

jotaen commented Jun 2, 2021

On a general note I think it’s not optimal that we currently tend to skip the loading states in order to avoid the flickering problem. The operations will for sure be very fast most of the time, but in case the network is delayed for example, the user doesn’t get any visual feedback that their command was received and is being processed.

@jdeanwallace
Copy link
Contributor

On a general note I think it’s not optimal that we currently tend to skip the loading states in order to avoid the flickering problem.

I agree with this.

Idea: Computers are too fast. Let's slow everything down for humans. We could enforce a minimum amount of time a state can be active (i.e. loading screen must show for at least 1 sec) to give people time to "grasp what’s going on" 😆

@jotaen4tinypilot
Copy link
Contributor

jotaen4tinypilot commented Aug 15, 2024

I’d like to gently bump this ticket again. We recently worked on introducing a unified success state for dialogs, which already paved the road for extending the overlay with an additional, unified progress state.

As noted above, a unified and more robust progress state isn’t just a UI nicety, but it would also allow us to solve the dialog initialization issue, which currently is a tricky tradeoff between flickering and UI inconsistency.

For historical reference: the flickering issue stems from the fact that most operations within dialogs are usually pretty fast – e.g., network requests to the device backend. So if we display an intermediate “progress” state while these operations are in flight, then it might occur that this progress state appears and then disappears very rapidly again. This happens fast enough that the user is completely unable to read or visually process the progress state, but it’s still slow enough for the user to notice that something was briefly shown for a split second – see a demo of the “Hostname” dialog:

Screen.Recording.2024-08-15.at.12.16.05.mov

This might be quite confusing. In some instances, we therefore refrained from adding a progress state for certain operations, to “work around” this flickering problem. However, this can have an averse effect, e.g. if the user is on a slow network connection, which results in longer network latency. In this case, the UI might appear as stale/broken or non-responsive – such as in the “About” dialog or the “Hostname dialog”:

Screen.Recording.2024-08-15.at.12.21.06.mov
Screen.Recording.2024-08-15.at.12.18.53.mov

The “About” dialog displays blank fields while it’s fetching the info from the device backend, but it actually shouldn’t display anything at all yet. The “Hostname” dialog doesn’t appear to respond at all to the button click (though it actually had already started the operation under the hood), so it might come across as broken; in the worst case, the user clicks the button multiple times, which may result in erratic failures.

With a unified “progress” event (as outlined above), we could solve both the flickering issue and the UI styling.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants