This year, everything should go “Touch-first”

Happy 2017!

I’ve been considering buying an iPad Pro. I’ve always felt that the iPad is an "in-between" device that can’t fit my life well. But there is proof that the desktop is getting... deprecated. Here’s a good article from The Verge that talks about it.

Is it time to transition over?

By the end of 2016, many major websites saw traffic shift from desktop to mobile. Mobile has become the dominant form of computing for the every day consumer.

From a platform perspective, native apps started to transition over to web experiences. Hopefully, "Progressive Web Apps" will replace the generation of native content apps we have today.

What we didn’t seem to have gotten around in 2016 was to really question our approach to mobile and touch. Our approach remains primitive. We pick up interactions like "text editing" and try to retrofit mobile into it. We don't question the fundamentals to ensure the new experience fits well. I can’t help but feel that “keyboard covers” are a grave mistake.

Consider how someone uses a mobile device. He/she would be leaning back on a comfy couch, holding on to a tablet with both hands. Or, they may be standing in a crowded train, arm wrapped around a pole, trying their best to type with the two thumbs. The users' posture and environments above doesn't allow for a traditional editing experience.

We have to be more creative with the solutions we engineer. If we do transition well, these touch-first solutions should make us more efficient!

Also consider the change from a mouse to multi-touch. Direct manipulation of objects could be amazing. We see some of these interactions when we use apps for drawing, photo editing or maps. But more mundane tasks, like text editing, never seem to get much of a boost from touch. We seem to staying on safe ground with rows of buttons to carry out functions. We spend significant time manipulating and navigating between elements. Yet, these tasks tend to be not touch friendly; at least not enough to be more efficient.

It feels like we transferred the interaction to mobile, instead of converting the intent. We should be evaluating the purpose of every task and attempting to accomplish that in a "touch-first" way.

It seems that we have some ways to go before we get really good at mobile and touch. I’m hoping for a 2017 filled with ideas and techniques that shifts our thinking. I’m hoping we build products that are thought from a touch-first (or even touch-only) perspective.

Ember.JS: How to handle invalid URLs

There’s a lot of documentation for the new Ember Router. However, I found that no one was talking about how to handle the “*” route in Ember, i.e. the routes that don’t match anything.

I first tried to look at the ApplicationRoute but that didn’t seem to throw anything. Ember just sits there with a lovely blank page!

 

ApplicationRoute { 
events: {
errors: function(reason, transition) {
console.log("never happened");
}
}
}

So here’s the easiest solution for handling bad urls. My router looks like this now:

App.Router.map( function() {

this.route('login');
this.resource('companies', {path: 'companies'});
this.resource('company', {path: 'companies/:company_nice_url'}, function() {
this.route('members');

});



this.route('bad_url', { path: '/*badurl' }); // Catch everything else!

});

The last route named “bad_url” will catch all the other unrecognized URLs and direct the user to the App.BadUrlRoute where you can handle them. You will get the URL segment as params.bad_url for you to inspect and offer friendly advice like “hey did you mistype companies?”.

If you simply want to show a page that says “There’s no one here you fool!”, just create a handlebars template:

<script type="text/x-handlebars" data-template-name="bad-url">
<h1>There’s no one here you fool!!!!</h1>
</script>

And you’re done! Any path that doesn’t match your routes will get routed through ‘bad-url’, where you can act on it accordingly.

 

EDIT ON 6TH AUGUST

Marcus in the comments pointed out to me that using path: '/*badurl'  is better due to this handling "/this/is/wrong/path" situations. My initial solution to using a dynamic segment (:bad_url) did not catch this. Thanks to all the commenters!

 

EDIT ON 7TH AUGUST

I have realised that having "*badurl" instead of ":bad_url" has one caveat. I am implementing a funky search route that deals with all URLs past a base route like this: /search/x/y/z/a/b/c . Having the astriks to catch all the bad url's makes it impossible to have a search router which deals with "/search/*search_terms". So there you go... ups and downs to both methods. More on that awesome search route another day... :)

 

How is Facebook Chat Heads possible on Android?

This has been the question since the day I saw Facebook unveil the new Facebook Home suite of apps. Workmate of mine (_) might have found the answer on good-ol' StackOverflow!

http://stackoverflow.com/questions/13346111/draw-overlay-in-android-system-wide

Basically, you are able to spawn a service which draws directly on to the Android System's WindowManager by adding a new subview on top of everything. It requires some special Android permissions that the user can agree to during the install. Code example on the link.

Can't help but deeply appreciate the flexibility of Android.

Passing session keys in headers for Embjer.JS Data REST calls

First thing you have to do is to override the RESTAdapter if you aren't already. The ajax function is the key. It is given the jQuery hash that will get passed down so all you have to do is to populate the beforeSend key with a function like below. The 'xhr' passed in can be set with a request header value.

DS.MyAppRESTAdapter = DS.RESTAdapter.extend({

ajax: function(url, type, hash) {

hash.beforeSend = function (xhr) {
if (MyApp.isLoggedIn()) {
xhr.setRequestHeader('x-token', MyApp.session.token);
}
};

// handle errors if ember-data doesn't already
if (hash.error == undefined) {
hash.error = function(xhr) {
this.didError(null, type, null, xhr);
}
}
// do some other work and call super()
...
this._super(url, type, hash);
},

didError: function(store, type, record, xhr) {
if (xhr.status == 401) { ... }
}
});

That's it! Your app should now be firing off request headers like a pro! I've also left my basic error handling code to catch instances when ember-data simply does nothing. This will probably change in the future leading up to a stable 1.0.

Still learning this stuff, happy to hear about a better way to do it if you know :).

Trouble with Time Zones and Day Light Savings in iOS

As you all know, Suneth and I are working on 60Hz 2.0 and we had the weirdest date related problem yesterday. We have a weekly calendar which tells you when your library shows air and what are the premiering (returning or new series) airing on any particular day.

Yesterday, our calendar looked like this!!

 We have 2 Sundays!!!

Huh??

After a lot of digging around the problem was this: yesterday, Sydney timezone rolled back an hour due to day light savings.

We calculate each day by dropping its time component from [NSDate date]. We use a special category which gives us today [NSDate today] and work our way back to calculate the week and all the other relative days. For the first cell, which is correct, we have April 7th, Midnight. When it comes to Monday, Sydney rolled an hour backwards. Instead of getting April 8 Midnight, we're getting April 7th, 11PM. This accounts for the second 7th of April! After looking for bugs in all over the code, we finally figured it out.

The fix was to simply take midday for today calculations. Adding 12 hours to today fixes and stays away from all kinds of DST issues (I hope).