22 Oct 2007
Undo Made Easy with Ajax (Part 2): Time-Sensitive Actions
This is the second part of the Undo Made Easy with Ajax series. If you are jumping in late, make sure to check out part 1.
Last time we covered the event queue method, an entirely client-side way of implementing a light-weight, multi-level undo. I mentioned a couple of caveats, including that it does not work in multi-user collaborations, and that it doesn’t work for time-sensitive actions like sending emails. I missed a significant caveat that one of my readers, Alexander Botero-Lowry, pointed out: That two tabs, pointed to the same page, could get out of sync. I wrote about how to solve that issue with cookies.
This time, let’s take a look at solving Undo for time-sensitive actions. In the event queue method, we could wait until the “onunload” event to sync the user’s actions from client-side to server-side. For time-sensitive actions like sending emails, we don’t have that luxury. Worse, email is a push technology. Once an email has been released into the wild tubes of the Internet, it cannot be unsent.* For the unfortunate who hits “send” only to realize that they’ve CC’ed their boss on a steamy love letter, the only things left to hope for are power outages and spam filters. Given how often spam slips past my filters, the outlook is not so good.
The email needs to get sent soon after the user clicks “send,” and “send” can’t really be undone. What can we do?
We must turn to the interface designer’s old nemesis, the time-based interface, for the solution. Normally, time-based interfaces fail to be truly usable because the timing is never quite right. For some people it is too fast, for others it is too slow. Even your own perception of time changes based on your mental load. When you are thinking hard, you don’t notice the passage of time: What was too slow before will now be too fast. The old saying, “Time flies when you’re having fun,” actually has user-interface implications. A great example of the failure of timing-based interfaces can be seen in text entry on a cellphone, but that’s a topic that will have to wait for another post.
When sending an email, typically it’s during that “‘oh-no’ second“— the split second after hitting send — that you realize that you’ve sent the email to the wrong address. Wanting to unsend an email you sent an hour ago occurs, but with much less frequency. Thus, a time-based solution where the user can unsend an email for only a short period of time makes sense: The back-end can just delay sending the email by 30 seconds to a minute, and if the user wishes to “undo” sending during the grace period, the back-end dequeues the email so that the email never gets sent.
Now, I’m not particularly happy with championing a time-based interface, but I am sandwiched by constraints. On one side, sending an email is a real-world action that is not undoable. On the other side, emails need to be sent in a snappy manner. Undo for time-sensitive actions is a canonical problem, and the only solution I see is a compromise (if anyone can figure out another solution, I’m all ears!). In general, many situations arise in which we as designers are trapped by immutable constraints. The best we can do is to design systems that take care of the most likely use-cases, and allow users to gracefully back out of their most common mistakes. Time-based Undo won’t solve every case of wanting to unsend an email (it won’t help with late-night emails you discover you sent the next morning), but it will catch the majority of mistakenly-sent emails (both the “‘oh-no’ second” variety and the “I-clicked-the-button-accidentally” variety). And it will catch many more emails than a warning ever could. It turns out that Paul Buchheit, the creator of Gmail, has the same thought. Too bad it hasn’t been implemented — it’s a low hanging fruit that could give Gmail an even greater edge over its competition.
There’s really not much to this method. To implement it in the Ajax style, you just need a mutex and a timer. When the time runs out (or the user navigates away from the page), the message is sent. A more robust way involves setting a flag on the server along with a server-side countdown. The tricky part of this whole thing is how to indicate the time remaining in a way that does not scare the user. For instance, a count-down timer evokes an visceral reaction of panic:
Not very good feeling, is it? Instead, a slow fadeout works better:
A count-down that doesn’t begin counting down until the last 10 seconds might work too. It’s an excellent challenge to design mechanisms for nicely displaying a time-limited Undo. Share your thoughts in the comments section. Bonus points for mock-ups of any kind.
Next time, I’ll talk about some of the neater, more robust methods of doing Undo in an Ajaxy way.
by Aza Raskin