Microsoft: Make the “Metro/Zune” look a standard. Publish it. Push it. Now.

Apple makes user experience inroads every day on Windows when a developer follows Apple’s Human Interface Guidelines for design for a Windows Application.

This post was inspired when imageI installed Miro this morning on my desktop PC. (Don’t get me started that it opts-in a bunch of changes and a toolbar for the browser. Convince me that I want to to do it because it’s the “right” thing – let me opt-in!)

In Miro’s words, it’s an “amazing open-source, non-profit video player.” (See previous annoyance about toolbars and other default-opt-in things the installer attempts).

In any case, it installed. The installer UI had a few cross platform oddities, including not being sized correctly, and worse, showing up too high on one of my monitors.

Here’s the default look:

SNAGHTML1c0109

Hey! It’s iTunes! Great. (iTunes, below as a reference).

image

On the left side (in both applications), is located a Source List (see “Source Lists” in the Apple Human Interface Guidelines). They flipped the play bar to the bottom and tweaked the general look and feel of the buttons, but it’s basically the same UI.

At first, you might think that there’s only so many ways to present that type of UI. I give you the Zune Player (4.7).

SNAGHTML204865

It’s so different I won’t even start listing the differences. I thought about other applications that I have on my Windows PC that follow this style. Admittedly, it’s not very many right now. MetroTwit generally follows the Metro style.

SNAGHTML250657

Windows Live Mail (somewhat) (along with the other Windows Live applications):

SNAGHTML2d268de

Actually, there’s not a formal guide for this style. The closet you might come today is the Windows Phone 7 UI Design and Interaction Guide. That’s a poor substitute though.

There is of course, the Windows User Experience Interaction Guidelines. Oh wow. It’s amazing the amount of bad examples that are sourced from earlier versions of Windows. There are so many (too many). Furthermore, it’s not free from errors itself:

image

image

Microsoft doesn’t bother following it, so it’s not too surprising that many Windows applications do not.

From the Guidelines:

image

From Word 2010:

image

My point isn’t to blast this document. What’s missing from the document is how to build an application that is smooth and modern. It’s an 882 page document currently, that helps you build a nice Windows 95 application. What? Seriously. If you look through the document, it’s really about fixing the problems of Windows 95 through Windows Vista. It doesn’t innovate anything new. It’s about putting up better error messages, being more consistent, etc. All of these things are great. But, can we move beyond that? Can we build something slick and modern that is more than just gas glass?

That’s why I’m pushing for anything more modern now. If the Zune/Metro isn’t it, then create something new for us to follow.

Applications for developers/designers that are released like WebMatrix are a sign that there’s an opportunity to think beyond just glass and better wording. In WebMatrix, I noticed that they’ve done away with standard Modal dialogs. They’re modal – but they float with the main application window (even when they’re showing), much like if they were a web page. Slick. The application is clean and modern. I like it.

SNAGHTML2c968bf

Why can’t we have more of this:

image

instead of this:

SNAGHTML2cbdb11

So, this was just a rant really. But, an important one. Will Windows 8 finally solve this and introduce a awesome and modern User Experience, one that is easily replicated by developers, without the use of dozens of third party components and questionable code from the Internet, and …. Please Microsoft. Do it. Do it for all of us. I don’t care if it’s the Metro/Zune theme or something else. You can do better than Apple.

It’s time for you to innovate again. You’ve got some super app creation platforms (like Silverlight and WPF) and you’ve got awesome development tools (Visual Studio and .NET 4), and you’ve got a lot of great developers ready to rock and roll. Help us build UX that are killer awesome. Build the components – ship them in V1. Do it!

(Oh, and by the way, could you please create a 10 hour battery life Windows 8 tablet? Pretty please?! I’ll buy one!)

Home Desk setup

image

I recently added a 30 inch Dell LCD display to my setup at home. I’d had a 24 inch for 5 years, and had the itch for more pixels!

So, I’ve now got 7,710,720 pixels available!

I couldn’t stand back far enough due to where my desk sits in my den to capture my desk and monitors adequately.

Derserializing ASP.NET MVC JSON formatted Date strings

Have you called an Ajax based action in MVC, only to find that the Date format is being serialized into something that isn’t entirely useful on the client?

{“result”:[{“Author”:”Aaron”,”SentAt”:”\/Date(1296824894700)\/”,”Text”:”Blah Blah”,”Id”:1}],”runAt”:”\/Date(1297031297600)\/”}

You’ll see that the Date is:

\/Date(1296824894700)\/

Alas, that’s not very friendly. For a quick translation, I added the following to jQuery’s dataFilter property so that the date would be formatted in a more human readable format. The dataFilter function is used to sanitize a response from a web server.  Here’s what I added:

$(function () {
    $.ajaxSettings.dataFilter = function (data, type) {
        if (type === 'json') {
            // convert things that look like Dates into a UTC Date string
            // and completely replace them. 
            data = data.replace(/(.*?")(\\\/Date\([0-9\-]+\)\\\/)(")/g,
                function (fullMatch, $1, $2, $3) {
                    try {
                        return $1 + new Date(parseInt($2.substr(7))).toUTCString() + $3;
                    }
                    catch (e) {}
                    // something miserable happened, just return the original string            
                    return $1 + $2 + $3;
                });
        }
        return data;
    };
});

The trick for converting the /\Date(#)\/ syntax easily was from StackOverflow. It even handles time zone info.

I added a regular expression to look for the various elements that represent a Date in Microsoft JSON serialization format. The resulting date is reformatted to a human readable string. There are 3 capturing groups that I’ve named $1, $2, and $3 which need to be preserved otherwise the JSON string is mangled beyond recognition. Those are returned concatenated to preserve the original formatting of the string.

The resulting date is translated to something like:

Fri, 4 Feb 2011 13:08:14 UTC

Of course, you could do whatever formatting you’d like.

 

Bonus

And, as a bonus, you did notice that if you’re using IE9, that the developer tools now have a network trace? Cool. (I’ll still use fiddler for many things, but this will be very handy on machines that don’t have fiddler installed).

SNAGHTML51b4c85a

jQuery 1.5, jquery.validate and Ajax/getJSON

Apparently, the new version of jQuery conflicts with the version of the jquery.validate plugin that is included with Microsoft’s MVC 3 template. After a frustrating hour of debugging and using Fiddler (as I didn’t realize the problem was related to a plugin I wasn’t actively using on the web page), I stumbled into the answer/workaround on github here.

The specific issue that I encountered was what I thought was a simple use of the ajax method of jQuery:

$.ajax({
    url: _fullRoute + "/Fetch",
    data: { since: this._lastRefresh },
    type: "get",            
    dataType: "json"
}).success(function (data) { alert("success"); }).
        error(function (e) { alert("error: " + e.toString()); }).
        complete(function () { alert("complete"); });
}

I’d tried lots of things, experimented with what seemed like countless JsonResult options (along with Json function call changes), and nothing worked. The JavaScript error callback function would always be called. The error: parseerror. Arrgh.

return Json(new { result = “why me!?” }, "application/json", JsonRequestBehavior.AllowGet);

Thankfully, a user on github, jfirebaugh, took the time to resolve the issue and produced a patch (change here).

You can look at the details on github.

After applying the patch, and using the Microsoft Ajax Minifier, I noticed that the file was about 4K smaller than the one that is included with the MVC 3 template. Smile

image

MSBuild Task Reference and Ajax Minification

image

I’m not one for dumping all scripts into a single folder and calling it a day.

The template project for ASP.NET MVC 3 does that unfortunately. So, after a bit of cleanup and adding a few more JavaScript libraries that I needed, I’m left with a reasonably organized folder structure.

I’ve added a folder for JavaScript files associated with Views, in this case, it’s located here: Scripts\Views\ViewName\…

I want to create minified versions of scripts, yet not minify scripts that have already been minified by other processes. The Microsoft Ajax Minifier (download here) includes a msbuild task, making the effort of creating minified scripts painless.

I followed these basic instructions for adding the build task:

http://www.asp.net/ajaxlibrary/AjaxMinQuickStart.ashx

I did not however, as I mentioned, want to compress all JavaScript files.

So, based on this documentation (MSBuild Items), I changed the basic Include settings to reflect my folder structure.

  <Import Project="$(MSBuildExtensionsPath)\Microsoft\MicrosoftAjax\ajaxmin.tasks" />
  <Target Name="AfterBuild">
    <ItemGroup>
      <JS Include="Scripts\Views\\**\*.js" Exclude="Scripts\Views\\**\*.min.js;" />
    </ItemGroup>
    <ItemGroup>
      <CSS Include="**\*.css" Exclude="**\*.min.css" />
    </ItemGroup>
    <AjaxMin JsSourceFiles="@(JS)" JsSourceExtensionPattern="\.js$" JsTargetExtension=".min.js" CssSourceFiles="@(CSS)" CssSourceExtensionPattern="\.css$" CssTargetExtension=".min.css" />
  </Target>

What I wanted specifically, is to only process JavaScript files found in the Scripts\Views subfolders. So, I changed the Include attribute to:

Scripts\Views\**\*.js

Roughly translated to English, the above:

  1. Recursively, find all JavaScript files under the folder Scripts\Views
  2. Skip anything that is already named *.min.js
  3. Minify.