Tuesday, October 6, 2015

talk about hidden features

I've relied on a "Todo"-app for almost two decades, starting with the one built into the PalmPilot PDA, amazingly good for its time. (But not perfect: here I am in 2005 geeking out about what my "ideal" app would look like.) After Apple opened up the appstore, Appigo's "Todo" actually met most of my 2005 requirements, and has proven reliable for all these years. Over that time, I've realized what really sets apart a decent Todo app is flexibility in recurring events: every couple weeks I want to be nudged to pay off my credit card bill, every couple months I want to be nudged to get a haircut, every day I want the double check that I've video recorded a "second of the day", etc. (Heck, Todo Apps are even the "Hello, World" for JS frameworks, but they skip over the recurrence issue, because it's not trivial from a UI or implementation standpoint. Many Todo apps out there make the same shortcut.)

On Shaun McGill's blog, he wrote about starting to dig Apple's builtin apps and services, leading off with Reminders, thanks to the convenience of its Siri integration. I wrote back to complain that iOS "Reminders" will always feel like a baby app because it doesn't do recurring reminders. He said he preferred the simplicity in not having the UI ever-cluttered with future tasks, and that there were hundreds of other 3rd party task apps for my needs. I was about to continue our civil disagreement by pointing out none of those apps will be usable via Siri (which is a whole argument) but then I realized the joke was kind of on both of us:  you can create repeating Reminders via Siri.

And, I thought, only by Siri. But I was mistaken: the functionality is hidden, so that this screen

becomes the following once you click on "Remind me on a day":

(Palm had the same kind of hiding, where the recurrence details were hidden until you set a date.)

It was interesting that Shaun and I both made the same misassumption. Out of sight, out of mind!

Anyway, I'm not sure if Siri integration is enough to make switch over to Reminders. For one thing Reminders can't add a date to a task without a time as well... a very datebook way of thinking that goes in hand with "when should I send a notification" thinking, but doesn't match how I cope with my load of tasks. Similarly, the badge icon task count is underbaked, or at least not updated in a timely fashion.

One thing I like about Reminders is that you're free to edit the order of the list, while Appigo assumes Due Date and priority sorting. Appigo also makes engineery-smart and UX-y dumb assumption about ordering... its due date sorting is strictly chronological (to the day level, and then alphabetical) - time sorting makes some sense because older items are "more overdue" and, presumably, a higher urgency. In reality, an item that has drifted a day or two overdue is probably ok there and demonstrably not a 100% priority, but the stuff that came up today has a chance of being absolutely critical. My ideal, then, would be a reverse time sort option. This might feel strange since it means everything due or overdue is sorted in reverse chronological order and everything upcoming is sorted in more normally, but from a workflow sense it's a viable option.

Friday, October 2, 2015

quickie: viewing JSON in chrome

JSON formatter is a nice module for chrome that makes raw JSON a bit less raw.

(And http://json.parser.online.fr is still my favorite way of editing errant JSON)

Thursday, October 1, 2015

bad ux is a misdemeanor against humanity - google inbox "speed dial" is a joke

There on the right is a snippet from Google Inbox. Those top 5 circles fly up when you hover over the red circle (which is a plus sign at rest)

Three of them are Inbox's best guess about whom I want to mail next. (I think Google calls this "speed dial") The algorithm powering this is terrible. For a while the guesses were ludicrously out of date and arbitrary - people I was writing with regularly but not for months.  Lately they seem more chronologically correct but the relevance just isn't there. For instance, I wrote back to "R" today, in reply to a joke she sent me, and that was the only mail we've exchanged in probably a year. Sending her a new email is clearly not a priority in my online life.

In May I griped about this in the Gmail Forum where I was told they're "based on who I interact with most". The problem is easy to spot: the people I'm interacting with, I'm interacting with, replying-to, in pre-existing, long-lived email threads. A different criteria, say, "accounts I initiate email to", would be so much simpler and actually useful. (For example, I keep having to carefully retype my band's mailing list address, since the threading model wiggio uses hacks the "Reply-To" with a little postfix tag on the username... but I'm sure the no-tag version is the single most common email address I've sent to over the past few weeks, and having that one click away would save me having to wrestle with the recipient autocomplete.)

Then there are two other circles. The gold ticket is the "Invite to Inbox"- oddly overeager self-promotion. The blue finger "Reminder" is equally useless to me. I'm sure some people might try and use their email client for their general Todo management, but I'm certainly not one of them- it's a weird confusion of purpose, a reflection of that eternal goal of being "the program to end all programs" these things have. Zawinski's Law states
Every program attempts to expand until it can read mail. Those programs which cannot so expand are replaced by ones which can.
Same thing here, I guess, but going the other direction.

All this stupidity would be easy to ignore, except for one thing... see how the "I" icon is next to the "close this email"? That icon is blocking the checkbox underneath. (This happens at certain browser widths.) No problem, right? Move the mouse away, the column of circles will collapse to the single red circle, and I can click? Afraid not... somehow, the entire column where the icons would be triggers the icons "helpfully" sliding back into place... the area over the checkbox is blocked, even though it looks clear. Here is a video showing it in action:

So, the 3 poorly chosen icon plus the "let us be your todo!" useless icon plus the self-promotional icon plus poorly chosen size defaults equals a terrible user experience.

I like the Inbox concept... its grouping by category like "Finance" "Purchases" and "Low Priority" is generally good, and it's cool to be able to sweep away a whole chunk of fluff mail with a single click. Still, sometimes I think its "expand in place" paradigm (vs Gmail's "new subscreen", modal approach) can be problematic as seen here. (Also, Gmail's classic approach is pleasant in a "now you're focused on this one thing" kind of way.)

UPDATE: the next day I wasn't reliably able to get the "hidden hover column" to recur; whether that's a fix or just an intermittent bug, I'm not sure. Without that bug, the gratuitous icons are much less of a practical problem

Sunday, September 27, 2015

ezslots - slots for the masses!

For years, the most popular link on my site has been a simple jquery slot machine effect. At the encouragement of a fellow developer (Ron Sparks), I have parlayed that into a proper github project. Maintaining the simplicity was key; there's another similar project that has stolen my google juice thunder, but it's more complex than what I have, so I have worked to Keep It Simple, Silly, so a novice coder can more readily customize it to the effect they want.

Improvements include:

  • under 100 (well-commented) lines!
  • wrapped as an instance
  • being available on github
  • allowing images to be used
  • each reel can have its own options
  • you can call the "win()" function rather than "spin()" and it will show a pre-selected result

So, go to the github project see it in action at the sample page.

Sunday, September 20, 2015

filters in jquery

A year or two ago I made a "cheat sheet" for the chords my band plays. I wanted something that would be easy to manipulate via my iPhone, when I need a quick peek. To put it mildly, I screwed up the UI- and especially what it took to add a new song. I liked the idea of having all the data in the body of the DOM, rather than storing it in, say, JSON and building the page, but I made a dog's breakfast of it...

The core function (which is still there) was alright... tapping the title of a song (an h3 tag) opened up the notes associated with it (in a pre tag). The thing was, I linked the h3 and the pre tag via an id naming convention... so for each song header I had to come up with a shortname id, and then pre section it was with had to have the same id followed by "_". Bleh!

My new approach is to wrap each h3/pre pair in a div. Duhhr- that's just being neat and clean. So the code for responding to a click on a header is:
function clickTitle(){
  var header = $(this);
and I can ignore IDs entirely.

I also realized that, despite ordering the headers alphabetically, it wasn't super-easy to locate a song - like I woudn't know if "When the Saints Go Marching in" be under "When" or "Saints", or would "Just a Closer Walk with Thee" be under "Just" or "Closer" etc... and the mobile safari find function isn't particularly smooth to move in this case.

When it looked like my next big project was going to be in Angular I thought about rebuilding the app using Angular, and in particular the nice loop with filter... some kind of ngRepeat with 
item in items | filter:searchText
would do it, except again it implies an external data rather than DOM-data driven design. (I assume there's some way of doing a more DOM-centric version in Angular, but I'm not adept to know what it looks like... maybe I'll ask my Angular-loving buddy/guru.)

Anyway, jQuery has a decent ".contains()" filter for its selector chains... except it's not case insensitive.  But, the font of all wisdom StackOverflow had the solution for that:
jQuery.expr[':'].Contains = function(a,i,m){
     return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())>=0;

Adds a "Contains" (vs "contains") that is case-insensitive. So combining that with a  .on('input') on the input box and it worked pretty well. (And I really like the "verb" centric approach, of setting up an easy to understand event handler in jQuery, vs the "noun" centric approach of setting a loop and filter that automagically updates in Angular.)

Thursday, September 17, 2015

the ios 9 lowercase keyboard

I have never been as much of a typography and kerning wonk as maybe I should be, but the new iOS 9 lowercase keyboard feels wrong to me. (A lot of people don't like the way the keycaps swap, but it may be a matter of people getting used to it.)

Here is a sample:

made a quick Processing.js program to try to explore the idea, and came up with this:

Red lines are geared at the uppercase boundaries, blue line for lowecase. In my Processing you can press the button to swap upper and lower.

The lines I tried to draw might not be perfect, but it still seemed to reinforce my intuition... in short, it feels like Apple used the centering relative to the uppercase, and sometimes that feels off. Maybe to reduce the jarring-ness of the transition when you toggle from one to the other? Characters such as "f" "t" and "y" feel especially off to me.

Wednesday, September 16, 2015

ember vs angular, and doing the thing right vs doing the right thing

I'm looking for the best way for me to quickly become proficient in ember.js - with the additional caveat that I'd like to up-to-date. One of the reasons we picked ember over angular is that Angular seems to be in a weird 2-on-the-horizon state, but ember has some of that same issue (but the changes in syntax and best practices seem less radical.)

Currently a good bet (though I'm just starting with it) is https://www.ludu.co/course/ember/ - its approach of starting with a single, meat-y "real world" style example seems really promising for my learning style.

I liked this quote, about its use of HTMLBars (a descendent of Handlebars) for templating:
One of the advantages of using a real template engine instead of just adding "magic attributes" to your HTML elements (like in Angular) is that there's a clear distinction between the markup and the logic in your templates.
Man! That is kind of central for me, something that subconsciously really bugged me about angular.

A lot of it comes from my strength/weakness of my long history in web development...  I subconsciously map modern in-browser coding (with a library like jQuery or in some framework) to what used to happen on the server, while HTML rendering has always been HTML rendering. Angular's slamming them together as one thing never felt right to me -- similarly, JSP's "everything is a tag" had a similar semantic confusion!

But some engineers love the consistency of "we can do everything in xhtml-compliant tags". I suspect that these are the people who think in nouns and capabilities, vs other folks like me who think in terms of verbs and interactions.

Speaking of my strength/weakness routed in history: one thing about the "Libraries vs Frameworks" debate. I've done many, many projects over the years, but the bulk of them haven small scale, quick hit things. In most ways these are more forgiving than larger scale projects that have to be worked on by many people over a long term. I've learned from experience that coding libraries (such as jQuery) can "scale up" to handle more complex projects, and if you're thoughtful about it it doesn't even have to get too messy. I'm not yet convinced of the reverse however. When Ember pulls down 25,000 files - literally -  to get to a proper "Hello,World" environment, it seems like it will never be great for things simpler than its sweet spot of power CRUD-ish apps.

A final confession / point to work on: all these years and I haven't ever grown to love unit tests. I like integration tests and End to End and the like, but unit tests, meh... especially when written by the developer who wrote the code itself. (Like I wrote a year ago It's really hard to get someone to find something they don't want to find!) Here's a new variation on the the thought: it's generally not so difficult to write code to a spec. The hard part is getting that spec right for all those hidden and implied edge cases, and not realizing what assumptions you're making - in my experience, that's where bugs actually happen. But all units test do is test an implementation against the spec! They can demonstrate you're doing the thing right, but don't have much to say about whether you're doing the right thing...

Still, unit tests are an excellent way of talking to the future, telling them what the spec is, and permitting more freedom for fearless refactoring....