tiny-pilot / tinypilot

Use your Raspberry Pi as a browser-based KVM.
https://tinypilotkvm.com
MIT License
2.99k stars 249 forks source link

Enhance progress state in dialogs #714

Open jotaen opened 3 years ago

jotaen commented 3 years ago

As pointed out in https://github.com/mtlynch/tinypilot/pull/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 commented 3 years ago

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:

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

jotaen commented 3 years ago

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 commented 3 years ago

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 commented 1 week ago

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:

https://github.com/user-attachments/assets/ed4efa40-6b15-4290-9a40-059cc2560d4b

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”:

https://github.com/user-attachments/assets/4b2fc92f-8cd1-47d1-a149-2899b9fdea1c

https://github.com/user-attachments/assets/0351202d-8297-45c0-bd80-c78752176259

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.