If you’re a button, you have one job
61 points by noncrab
61 points by noncrab
Mild snark, but, if we're discussing good UI/UX: embedding videos with no controls or other indication they they're videos is terrible. Lots of us have auto play disabled by default. I just sat there looking at two basically identical images thinking "so what?"
Here's me thinking "it has a video?" I missed it too, apparently
And still worse, some of the sources 404, e.g. https://unsung.aresluna.org/_media/if-youre-a-button-you-have-one-job/2-framed.1088w.mp4.
So I have no idea what the Nothing Phone actually did, because neither of its videos worked.
Interesting, I'm using Chrome and got the webm versions of these videos, and they all worked. Not sure why you're getting the mp4 version.
I'm on Librewolf (a Firefox fork/derivative) and the videos did not auto-play for me either. The web console is spitting out a bunch of these errors:
Specified “type” attribute of “video/quicktime;codecs=hvc1” is not supported. Load of media resource _media/if-youre-a-button-you-have-one-job/1-framed-safari.1600w.mov failed. Trying to load from next <source> element.
Why is it 'terrible'? (This is 'mild'?) You kept thinking 'so what' and didn't scroll down a little to read the explanation of the problem?
Since we are in this topic, I must acknowledge that Github shows play controls for animated gifs, something I never see anywhere else.
That might be a browser thing? My browser (Vivaldi on Android) showed a big play button and a progress bar.
Firefox on Linux, it doesn't show anything except the progress bar below it (with JS) and it doesn't autoplay with JS disabled. Had to right click > show controls to manually control the video.
never force the user to wait for the animation to finish.
Amen. As an app, your being pretty should always take a back seat to your user's commands.
Tangentially, I'd extend this principle to games as well. Sometimes games have an ever so slight delay between opening a menu and inputs being registered on it. (Think of a game with flashy menu animations, if you press pause and down in quick succession, will the second option be highlighted once the menu appears?) Input buffering is a nuanced topic in games, but as far as menuing goes I think it rarely feels bad.
There are lots of cases like this. In games is a relatively easy case that should work. But it much harder in a general OS.
For example on GNOME if I tap the super key and start typing I don't think it ever misses the search bar (at least I have never been able to hit it). Last I tried on KRunner it would frequently put a few of the keystrokes into whatever application previously had focus before KRunner assumed focus. I assume this is mostly because KRunner is a separate application and there is a delay while it starts up.
But that would be the next challenge. Imagine if I could hit Enter in the launcher and then start typing and 100% of the time those keystrokes would land in the text editor (or whatever arbitrary application) I just opened. The instant I trigger an all launch future keystrokes go to it.
Of course there are some complications. Like what if it crashes or is very slow? What if the app doesn't open a window? (Maybe it just opens to a tray icon.) Should those keystrokes be buffered forever? Probably not, so when do we stop buffering them? What do we do with the keystrokes that we captured?
there is a delay while it starts up.
this seems like an unforced error. really no excuse for an application to have noticeable startup lag.
You ever run into a rotary encoder that can't keep up? I have a headphone amp with a volume knob that you can't spin very fast or nothing happens. If I was president for a day...
The videos are kinda bad at conveying the information; I had to watch closely to notice the moment they press the button several times in a row.
Now, more on topic. Is the Android phone doing some bad really? I understand the frustration of the author who can click 8 times at high speed and get what they want, but at the same time this reminds me of the "accidental double click detection" in desktop OS. So, for me, it's more a problem of what the manufacturer see as usable and what the user sees as convenient.
And if we are gonna get nit picky, the fact that the iPhone shows a "Done" button while still animating is more distracting for me.
I'm not sure Android is entirely wrong here. I've accidentally double triggered actions because of a slow to respond UI. I think the best option would be to disable the button until the animation is done.
That produces the problem the article illustrated: it is nearly impossible to rotate 90° counterclockwise without looking at the screen. "Click 3 times" won't work, as the extra clicks are ignored while animating. Click, then watch the screen until the animation completes, then click, then watch the screen until the enemy completes, then click is a rather slow process requiring a lot of the users attention.
I think that a better solution would be two provides some kind of immediate feedback on the UI. Perhaps just rendering the button to show that a click was completed. Perhaps some rapid re-rendering of the screen to show what is going on that serves as a placeholder until the (slow) full animation can be rendered.
Yes. It's a tradeoff. But I think I have had double completion of actions because of UI jank more than the problem in the article.
My ideal solution would be to stop rendering animations longer than 50ms, so that the UI responds instantly.
Strongly agree with all the article. I would phrase this as the fault of the animation having violated the Hippocratic oath for animations, which is "first do no harm" aka "first don't interfere with user input".
Any time I see a thing like this, I think about what would happen with my gui toolkit. One thing mine does, which sometimes drives me nuts, is call two clicks in quick succession a double click, a behavior I borrowed from the Windows platform. There's value in this, obviously a double click is a common convention, and having it distinct from click can be useful (ideally, you'd make the click event itself do something idempotent, so even if the event triggers twice, it changes nothing. for example, click event = select item, double click event = trigger default event, and selecting the item twice is harmless, but this isn't what always happens irl), but one annoying thing with this design is if you click on a button very quickly, it triggers the button once.... then calls the double click event, which might not do anything!
So, my toolkit would have this kind of behavior where if you hit it quickly enough, half the clicks would be ignored! This actually shipped but it drove me crazy so my solution to this was...
/++
If true, this button will emit trigger events on double (and other quick events, if added) click events as well as on normal single click events.
History:
Added July 2, 2021
+/
public bool triggersOnMultiClick;
And you set that to true. The problem is I defaulted it to false for backward compatibility since it was released that way....... but you know, I'm due for a new major release... let's change it right now, I think the article's argument is sane.
"Added July 2, 2021, defaulting to false. On July 5, 2026 (v13.0), I decided to change the default to true, so all clicks on the button will trigger it by default. If you want to get the old behavior back, either override the double click event or set triggersOnMultiClick = false after you call the super constructor."
Anyway, my own library's wonky design notwithstanding, another way I can imagine implementing that behavior more accidentally is related to the animation.
If I were implementing an animation - which I very rarely do, I tend to hate those annoying eye-distracting and lag-inducing motions - but if I were to do it, I'd probably do it something along the lines of having an animation position variable in the object, and you set that on click. If you were to click twice and only have one variable, you have two easy options: reset it, skipping the remaining animation and just skipping to the next internal state (how I'd prolly do it), which would look like a visual jerk, or do like if(animationCounter) return;, skipping the event to preserve the visual smoothness. I assume that's what the Android dev did in the article.
The Apple dev probably did a third thing.... have a pending animation queue and the event posts to that. What I wonder: does the internal state update upon posting to the animation queue or upon completion? Or does it actually rotate the image with the animation? In other words, suppose you interrupted the animation and hit save in the middle of it. Would that possibly get you a 45 degree rotated image? The way I'd do it, probably not, I'd just update the exif thing atomically to the 90 degrees then do the transition animation separately.
But I can see reasonable people doing just about of these implementations. Balance of implementation simplicity vs visual fidelity vs ui behavior. And I wouldn't even bother with the animation queue thing at all either, I like the idea of a second press instantly snapping the look to the new state without waiting on an animation to finish, but if the animation is quick enough....
edit: PS one thing that amuses me is whenever i change something in similar times of the year. lol, July 2nd last time I edited this, now July 5, by pure coincidence. golly. but i like writing history like that right in the doc comments, it is nice for lots of reasons, including amusing anecdotes down memory lane when doing changes like this.
edit 2: it occurs to me that Apple prolly provides an animation queue out of the box, but still a question of where you'd change the state. I don't know much about that. On the web tho I'd also update state atomically and have a separate visual-only animation; a css transition between a transform thing. such a css thing would be p easy to implement and reasonably efficient since it'd skip relayouts etc. I wonder if it'd jump or queue if you changed that class name faster than the animation.... g2g rn but maybe ill experiment later.
Maybe I'm getting old but I've had a few instances where this was annoying for accidential double taps
Now as horrible as some people thinking it's sane to have a double tap or a button on the same spot being a sane forn of confirmation. If one thinks something should need a confirmation please don't make an accidental confirmation easy to happen.
But to go back to the example at hand. I think here it is a good idea. In other instances it is not. While not being able to give good examples right now there are physical buttons that intentionally prevent tapping twice until something is "finished happening". And while it's not always an intentional decision it sometimes is.
Jankyness and broken devices that many not so privileged people have to work with us a good reason and there are certainly benefits if you have any health issue that causes a tremor in your hand/fingers.
I think the given example is probably something one can be fine with either way. There are certainly examples where it's more annoying that you have to wait and there are examples where one wished that there would be some throttling whether linked to an animation or something else.
I am eternally frustrated by mobile browser search results updating under my fingers and moving my desired selection to a different spot than the one I end up tapping. I've conditioned myself to wait more, but it can't be that my UI interactions must be sensitive to background asynchronous tasks with jittery completion times due to reception..?