Inwerpsel / use-theme-editor

A React theme editor
GNU General Public License v3.0
4 stars 0 forks source link

Improve "stash" UX #69

Open Inwerpsel opened 2 months ago

Inwerpsel commented 2 months ago

The "stash" is a concept introduced to the application history implementation to make it less fleeting. When visiting an older point in history and making changes, instead of immediately discarding future entries, they're first parked in the stash and can be reused by replaying on top of another point of the timeline.

stashbutton

While the concept is simple, it allows for many useful interactions and can have a profound effect on how confidently history features can be used.

Interactions

Splicing in more changes

Since UI state is also restored while browsing history, it can be convenient to apply additional changes while browsing through history.

Most of the following video is to create the context leading to the button usage, which is at 0:40.

https://github.com/Inwerpsel/use-theme-editor/assets/7604138/98223647-f9d3-4ff4-88cf-7ea99029b1ba

Recovering from accidental history disruption

An accidental click (or other interaction) can potentially "destroy" a lot of work (in this app, could be tens or even hundreds of changes). Previously, this was avoided by prompting the user if this happened with more than 5 future changes. The stash avoids this prompt (see challenges).

For the usage, imagine the change in the previous video was done by accident. The usage would be the same, with one difference: you'd move the timeline back to undo the changes, rather than preserving them.

This is why the button shows the amount of new steps since the stash was created. It allows to restore the exact timeline, by making the number 0.

Reordering the timeline

It can sometimes be useful to move a section of the timeline to another place. For example you might want to see how the latest changes affect all prior changes. Or the latest changes are more certain than everything before.

Especially when using the timeline as a development tool to replay a session this has turned out handy many times.

Challenges

Interaction with locks

What should happen if an entry that goes into the stash was locked? We can't just remove the lock, as that would cause the UI state to change in an unexpected way, and basically replace the locked state with a (from the user POV) random state. It's also probably not what the user intends when locking something.

Currently, locked states are added as an additional entry, right before the new state, and then locked there. For "simple" state (no reducer) all other entries for the same state that go into the stash are permanently removed. If the locked state is reducer-based, it creates an additional entry for each action that would go into the stash. Those actions are removed from the stash, so that they don't get duplicated when applying the stash. Actions for that state after the locked state still get permanently removed.

Currently, the only reducer-based state is the theme editor state (manipulation of CSS values).

While the current behavior allows you to get the right end state, it does move all reducer state out of its context (entries for inspector state that allow you to see the UI of each change).

This breaks a potentially very useful use case: lock the theme editor state to its latest value, while using the timeline to browse back to older UI and then reapply the stash to splice in edits. You get the expected editor state, but every time you apply such stash, you lose the coherence of a part of the timeline. It would be nice if the stash was smart enough to rewrite the timeline to put these things in their original place.

Confusing prompt when replacing stash with a new stash

There is a still a prompt when a new stash overrides the old one, and the old one had over 5 entries. This doesn't happen a lot, but can be very confusing in the current implementation, as it's not obvious what is in each stash. You also have to cancel the prompt and re-perform the interaction if you want to look at the old stash first.

Single vs multiple stashes

The simplicity of having just a single stash benefits both implementation and UX. It avoids most memory concerns, and can always be used with a single click. Though it also causes interruption when 2 stashes compete for this place. And sometimes you do actually want to keep multiple.

Terminology

"Stash" was chosen as a working name, and so far I found no better alternative. It might not resound as much with non-developer users, but it also doesn't conflict with any known concept/UI element names and is short but not too short.

For the numbers shown on the button, "steps" was chosen over "changes", because the latter would imply it contains only changes made to the styles, while there's also things like which UI element is open and which screen size is used. Perhaps if the stash gets reduced to only actual changes (by either not storing UI navigation separately, or by filtering/squashing when creating the stash), the term "changes" can be used instead.

Other

Additional UI/features