Aug 29

Frustrating User Experiences: Techmeme Meta Refresh

Tech with tags: , , 4 Comments »

Refreshing Grapes

If you have a site or application where content updates regularly, it can be nice to update the content for the user. Techmeme falls under that category, and they have at the top of their page:

<META HTTP-EQUIV="Refresh" CONTENT="1800">

The problem is that every now and then I come back to the browser and I see:

TechMeme

The refresh seems to be happening when network connectivity isn’t there and thus you get hit and the page dies. This isn’t a huge pain, you can manually refresh, but for some reason it bugs me a little.

What can you do? An ugly, error prone technique would be to test a connection before doing a refresh:

function pingRefresh() {
  var location = window.location;
  var xhr = new XMLHttpRequest();
  xhr.open('HEAD', location);
  xhr.onreadystatechange = function() {
    if (this.readyState == 4 && (this.status == 0 || (this.status >= 200 && this.status < 300))) {
        window.location.reload();       
    }
  }
  xhr.send(null);
}
 
setTimeout(pingRefresh, 60000);

Or, it may make sense to be able to update part of the page (the main div or what have you) instead of asking the entire page to refresh. FriendFeed seems to do this and has:

var gFeedSpecs = {};
var gFeedAutoRefresh = [];
gFeedSpecs['feed1'] = {"start":0,"num":30,"type":2,"hash":"f003fa699d7e64b96f2b901922d13ed8"};
gFeedAutoRefresh.push('feed1');
$(function() { if (gFeedAutoRefresh) { autoRefresher.start(120000); maybeRestoreHtml() } });

Other Frustrating User Experiences

Aug 28

Frustrating User Experiences: Tough Captchas

Tech with tags: No Comments »

Tough Captcha

Captchas are annoying. Half of the implementations that have you type in something from the image are unreadable for my eyes. I am sorry that I have to use them on my own blog. This one though, makes it very tough.

I had this on my own MT blog back in the day, when the code that would generate the images failed leaving the user with no option at all, other than to stop participating. Die captchas, die!

I still find that my own CommentQ plugin that lets me customize questions works fairly well. Because even Ajaxian is “niche” no one has an automatic attack. The odd ones that get through are the farms where captchas are shown to real people who solve them. I still remember the time where I had a spam comment get through, and then a real comment right after from the exact same IP, name, etc…. the spam farmer answered a real post! :)

Other Frustrating User Experiences

Aug 25

Using the W3C Geolocation API Specification today; Extending WhereAreYou

Ajax, Gears, Tech with tags: , , 4 Comments »

Last week I shared the WhereAreYou? application that used the Ajax APIs ClientLocation API to access your location via your IP address.

At the same time, we announced support for the Gears Geolocation API that can calculate your address using a GPS device, WiFi info, cell tower ids, and IP address lookups.

Add to all of that, the W3C Geolocation API that Andrei Popescu of the Gears team is editing. You will notice that it looks similar to the Gears API, with subtle differences. The ClientLocation API is quite different.

To make life easier, I decided to put together a shim called GeoMeta that give you the W3C Geolocation API, and happens to use the other APIs under the hood.

If you have the Geolocation API native in your browser (no one does yet, future proof!) that will be used. If you have Gears, that API will be used, and finally, with nothing the ClientLocation API will be used behind the scenes.

To you the API will look similar:

// navigator.geolocation.getCurrentPosition(successCallback, errorCallback, options)
navigator.geolocation.getCurrentPosition(function(position) {
      var location = [position.address.city, position.address.region, position.address.country].join(', ');
      createMap(position.latitude, position.longitude, location);
}, function() {
      document.getElementById('cantfindyou').innerHTML = "Crap, I don't know. Good hiding!";
});

At least, that is what I would like. Unfortunately, there are a few little differences that leak through.

  • The W3C API only seems to give you a lat / long, so you have to do the geocoding to get address info
  • The Gears API gives you an additional gearsAddress object attached to the resulting position object. This can contain a lot of information on the resulting area (street address to city to …) however for certain providers the API returns that as null, the same as the W3C standard
  • That gearsAddress object has slightly different information from the address data that the ClientLocation API returns.

To give you control when you need it, you can ask the navigator.geolocation object what type it is. navigator.geolocation.type will be null if it is native, but ‘Gears’ or ‘ClientLocation’ if a shim kicks in. You can also check navigator.geolocation.shim to see if it is augmented code.

Implementation

There is some fun implementation code in there if you poke around. For example, for the ClientLocation API, when you make a call, it will be added to a queue if the Google Loader hasn’t fully loaded yet, and it will kick off that call when finished. Dealing with dynamically creating <script src> as a loading mechanism sure is fun!

I like the idea of jumping straight to the W3C standard and updating the shim as the APIs change. That way, when browsers catch up, the code will still work using the native APIs and you don’t have to change a thing.

Where are you?

Aug 24

London Olympics 2012. Poor buggers.

British, Comic, Personal with tags: , , 6 Comments »

London Olympics 2012

As the Olympics comes to a close, I remember seeing the frolics of the opening ceremony, and thinking about how the London contingent must have felt as they are reminded “oh yeah, we are following China.”

To think that London will be mainly hosting in the beauty that is Stratford and the like. I hope the workers are getting paid overtime to make it happen!

China was a coming out. An East meets West. London needs a mission too. If you can look past the infrastructure issues, and how the M25 and Tube will explode, there is a lot going for it. Having the tennis happen at Wimbledon, and some footy at Old Trafford and Wembly, and using other great sites. That could be impressive.

Also, we are lucky that shows such as X-Factor, Pop Idol, and “Brits have some got talent somewhere” will be able to find the two kids to make a different. The cute one to lip sync, and the other one who can actually sing.

London 2012

Can’t wait to be there for London 2012. It has got to be better than the logo!

Athens was returning to the roots, to the country that invented the Olympic Games. China was the most populous country in the world.

London is the capital city of the country that has invented modern sport, that has invented the rules of the sports, and the values of fair play.

It is a cosmopolitan, multi-ethnic and multi-religious city and that’s something they can build on.

Aug 22

TraceMonkey: DOM, Canvas, Opensource and more

Ajax, JavaScript, Tech with tags: 6 Comments »

Brendan Eich promised that trace based JIT’s will give us killer JavaScript speed and now we have seen the fruit of his labour with TraceMonkey (adds trace smarts to Tamarin-tracing).

A lot has been said already, but I am really excited about much more than the “look at how we run Sun Spider”.

The DOM matters

Although it may not sure in todays code drop, Brendan gets that you have to care about the DOM and not running while(1) { cheasyTest(); }:

  • He gets it: “As we trace more of the DOM and our other native code, we increase the memory-safe codebase that must be trusted not to have an exploitable bug.”
  • If DOM code comes out of native code and into JavaScript, it matters: “TraceMonkey advances us toward the Mozilla 2 future where even more Firefox code is written in JS. Firefox gets faster and safer as this process unfolds.”

Canvas

You know Canvas? It’s days are coming… fast, as John Resig mentions:

One area that I’m especially excited about is in relation to Canvas. The primary thing holding back most extensive Canvas development hasn’t been rendering – but the processor limitations of the language (performing the challenging mathematical operations related to vectors, matrices, or collision detection). I expect this area to absolutely explode after the release of Firefox 3.1 as we start to see this work take hold.

Opensource matters

None of this could be accomplished without the great side of opensource. TraceMonkey uses Tamarin-tracing, which enables it to build on amazing code.

TraceMonkey itself is opensource, which enables the SquirrelFish team say, to check it out. And, vice versa. This will keep the competition going along nicely.

This kind of competition is phenomenal for us, the consumers of the Web. Performance is key in 2008, and Web developers get to laugh all the way to the bank.

Thanks guys!

Aug 22

Where are you? Using the new Ajax ClientLocation API

Ajax, Gears, Google, Mobile, Tech with tags: , 22 Comments »

We just announced two new ways to get location info from a browser client.

The Gears GeoLocation API is very detailed. It is able to use GPS, cell towers, WiFi, and ip addresses to work out the location, and you get an “accuracy” parameter to see what was available. As well as getting a position, you can watch a position so you are updated when a change happens. This is perfect for mobile devices that have Gears installed, and since the community is working on the W3C Geolocation spec it should be in many more places soon.

To go with the Gears API, we also have an API that goes along with the AJAX APIs, called ClientLocation.

This is an ip based geocoder that we have made available, and is very simple.

I put together a trivial example called Where Are You? that ties together this API with the Maps API:

You get access to the data from google.loader.ClientLocation, which is null if it can’t be calculated.

Here is a bit of JavaScript that ties it together:

google.load("maps", "2.x");
 
google.setOnLoadCallback(function() {
    if (google.loader.ClientLocation) {
        var cl = google.loader.ClientLocation;
        var location = [cl.address.city, cl.address.region, cl.address.country].join(', ');
 
        createMap(cl.latitude, cl.longitude, location);
    } else {
        document.getElementById('cantfindyou').innerHTML = "Crap, I don't know. Good hiding!";
    }
});
 
function createMap(lat, lng, location) {
    var mapElement = document.getElementById("map");
    mapElement.style.display = 'block';
    var map = new google.maps.Map2(mapElement);
    map.addControl(new GLargeMapControl());
    map.addControl(new GMapTypeControl());
    map.setCenter(new google.maps.LatLng(lat, lng), 13);
    map.openInfoWindow(map.getCenter(), document.createTextNode(location));
}
Aug 20

Frustrating User Experiences: iPhone Mail.app

Tech, iPhone with tags: 14 Comments »

One of the most common tasks that I have as I check email on my phone, is jumping between work and personal email. This breaks down for me on the iPhone due to the menu system.

When you are on one inbox:

iPhone Inbox

you then have to go back, through the list of folders, to the accounts screen:

iPhone Accounts

At this point you then have to go back into the other account. This makes 4 animated clicks to go from Inbox to Inbox, and even more if you are already in a message.

Since this is so common for me, I would like to be able to bypass the menus and have something like a dropdown to go directly from Inbox to Inbox. Here is an incredibly crude visualization:

iPhone Dropdown

Maybe a nice gesture… a swish… which sends you back and forth :)

Other Frustrating User Experiences

Aug 19

Frustrating User Experiences: Wordpress Categories

Tech with tags: , 5 Comments »

I use Wordpress a lot, and love the product. But, when you are working with something every day, you see its quirks too, such as the Wordpress Media Upload.

This time though, I have to mention the categories system. In the latest and greatest 2.6.x branch, the admin console got rev’d quite a bit again, and the categories system now has this:

Wordpress Categories

There is some good thinking in here, such as having the “popular categories” filter, but having a huge list of check boxes in a very small area is painful indeed. Scrolling through the list to find the categories that you want it ugly.

The older version actually suited me quite a bit better:

Wordpress Categories Old

At least here you had the input text box on the top, so you could type in the items, and then you would see them selected and thrown at the top just to let you know. This was much better. The problem was the fact that a Google Suggest-like auto select wasn’t implemented, so you could get the category wrong… ending up with a new one being created. So close. If you were filtered as you typed I would be happy!

Tag, you’re it!

It turns out that the tag support does all of this. It auto completes for you, and works well enough indeed. I know that there are plugins that munge categories and tags, but maybe it is time for Wordpress to nuke one of them and just unify.

Aug 18

Frustrating User Experiences: Boulder Parking Tickets

Tech with tags: 3 Comments »

When I started the Frustrating User Experiences I should have guessed that it would be like shooting fish in a barrel, as it is hard to be anal and get it right. Hell, I could take a look at this blog and find a million things too!

But, this next one is quite funny. I stupidly didn’t put enough money on the meter in Boulder the other day, and came back to a ticket. One cool think about the parking ticket meters in Boulder is that you can pay for them with a credit card which is nice. I wish they could have auto-incremented the fee on there!

A quick aside: A colleague pointed out that while having access to pay with a credit card is great, it means that you can’t use time from the person who left before his ran out! This means that even with the credit card processing fees, the tolls end up being a lot more due to double-dipping!

Anyway, I get a ticket, and I immediately look for a URL to pay (right after I curse). First blunder, it is nowhere to be seen. It just talks about sending in checks and such. Ugh. Luckily, on the back of the envelope rather than the ticket, there is a link to bouldercolorado.gov which does indeed have a way to pay online.

This is what you see when you get there:

Getting started with ticket paying

Notice the lovely contrast on the buttons with text and background.

After putting in my license info I get the following:

Holy checkboxes batman!

Wooah, this is just a subset of the pages of information on tickets to pay! Oh, I should have said, this is a rental car :)

It appears that people don’t pay for any kind of fines on rental cars. There was over $10k on this puppy. I want to do the right thing though, so I hunt for my issue to pay it. You can see all of the checkboxes though right? Oh, there isn’t a “deselect all” option, so I jump on the TAB + SPACE routine… singing a song to keep the rhythm up. After manually deselecting hundreds of these things. I reselect mine, and click on next, only to see:

Pay for them all??

Oh man. I have to pay $6k for the issues that are “over due”. I don’t think so Sherlock!

After all that, I guess it is time to go manual :(

What would I have loved to see?

  • After entering the ticket number and license plate information, “do you just want to pay for this one? or the other 10000?”
  • A de-select all
  • Buttons where the text color and background color aren’t the same

Other Frustrating User Experiences

Aug 15

Optional typing and dynamic languages

JavaScript, Tech with tags: , , 16 Comments »

After listening to Brendan talk about typing on the latest Open Web Podcast episode on ECMAScript Harmony it got me thinking again about optional typing.

It has always bugged me a little to think of type information in my nice clean dynamic languages (Ruby, JavaScript, Python, Perl, etc.).

Looking at even the simplest of code like this (taken from Mike Chamber’s XMPP server in ActionScript 3)

var room:Room = new Room(connection);

It irks me. Just work out that it is a room already won’t you? I know you can do it? You CAN do it. So, leave it out in this case.

Although the type information is optional, it seems that a lot of the code that I have seen in AS3 puts types in all over the place. I somewhat like the idea of using types when you really need them, such as for clear documentation of a core library, or some performance issue that you find is an issue (note: that becomes an issue, not one that is assumed!)

Once you open the door though, can people play that way? Is giving the programmer a bit switch of “shall I put the type in here?” every few seconds a good thing? Especially when the tools try to put the type in all the time?

I also found it very interesting when Brendan talked about how adding type information can actually hurt performance, sharing an example of when var foo:int doesn’t do what you actually need. For me, performance is pretty much out of the window, now, and definitely in the future.

So, I lean towards not needing it. But then I flip over the cards and see stuff like this (note: a mock example):

/**
 * @type Room
 */
var room = new Room(connection);

Ugh. Now we have the worst of all words. We are documenting the code out of band. This is often done for some jsdoc-like tool that will generate docs for you. The problems are:

  • The language itself has no idea about this information. The compiler. Nor, runtime. If there was something that could be done for performance, it couldn’t be
  • How easy would it be to get this out of date. If you change the type no one is going to complain. There is no validation here.
  • Way more verbose!

This alone makes me think that I would rather have optional types just to avoid any hacks like this.

You?