Favorite Apps & Tricks

Ahright, this has been long due I guess. Having had a HTC HD7 Windows Phone for a couple of months now, here are my top 10 must-have 3rd party apps for WP7. This is a dynamic list though as my needs evolve. So, here goes:

1. Weather Channel — Rich WX data presented in panoramic layout; also provides radar maps, forecast details & videos. Live WX Tile isn’t shabby at all.

2. HTC Hub — This I think is good to have for any HTC phone. And here is the unabashed reason — the manufacturer Live tile is double in size and the weather graphics are stunning ! Also, one has to muse at the over-the-top graphics in the HTC apps contained in the Hub; some useful ones are T-Mobile My Account, Notes & Stocks.

3. Twitter — This is the official Twitter app for WP7. Really like the look & feel in dark theme. No frills, just works with good caching.

4. Netflix — May I say more? This I think is the best Netflix app across all Mobile platforms.

5. Tech News Now — wonderful RSS aggregator from my favorite tech gadget sites.

6. Last.FM — This MSFT-built app has single-handedly made me switch from Pandora to Last.FM. Some of the scrobbling features, continuous play & rich UI is very pleasing. Plus, it works under locked screen; too bad does not prevent screen lock-out in the first place.

7. AP Mobile — Nice news aggregation. Like Live Tile image surprises throughout the day.

8. Open Table — Again, I think this is the best Open Table app across mobile platforms. Metro UI fits this perfectly.

9. Beez – Another cool Twitter client with rather amusing Timeline view. This one is also armed with Push Notifications for DMs & mentions.

10. MyChannel 9 – All Channel 9 videos  & news at your fingertips. Only wish video playback had a few more controls.

Now, there are two that did not make this list, because they are just too good to be ranked .. ha ha. And that’s because yours truly has had his hands in them.

  • Sogeti Hub – Ok, I don’t blame you for not knowing/finding this one .. it has not hit the Marketplace yet. There was some red tape to get Sogeti LLC. set up officially with an account; we should be able to push it out soon. Hopefully, this will be awesome with everything Sogeti in mind, both internal & external facing.
  • ShopTillYouDrop – Now, I am kind-of ashamed to mention this. This was a rather basic Shopping List app I had written way back last year .. it kinda works; but doesn’t look very Metro. In its defense though, it was amongst the very first round of apps to go live in the WP7 Marketplace. I have been working on an update to support multiple lists, richer UI & Push Notifications; but all the other work keeps pushing it off to the back burner. I will make an update soon, I promise !

Ok, now for a few tips that I find handy:

  • Remember, you can hold down the Camera hardware button to bring up the Live cam, even if the phone screen is not lit.
  • Hit the Power button once, and without unlocking, you can change the volume toggle between ring & vibrate.
  • Remember that Games do not always honor the vibrate setting .. be careful in meetings.
  • Markeplace app is kinda sensitive; I know MSFT has promised a fix in the first update. But until then, once in the Marketplace, always let the screen finish loading stuff .. otherwise Marketplace may crash & require a reboot.
  • Use Bing voice search abundantly .. it really works very well.
  • The vibrate mode icon looks like slices of bacon .. rather yummy..ha.

Hope this was entertaining. Please do drop comments with suggestions or other interesting stuff.

Adios!

20 Minute Twitter client for Windows Phone 7!

Flashback to Mix 2010. Microsoft is demonstrating various aspects of the newly announced Windows Phone 7 platform, since Mobile World Congress was merely a curtain raiser. A big focus is the power of Silverlight and how Mobile development would be a breeze with the tools provided. I got to look up who it was; but someone from Microsoft demonstrated making a Windows Phone 7 Twitter client in mere 8 minutes!! Exaggeration, you say. Well, turns out, if you know the Twitter Search API and how to make asynchronous HTTP Get calls in Silverlight, it may not be that far off. I was recently adding Twitter integration to an app, while trying to preserve the familiar look & feel. Let’s give ourselves 20 minutes, shall we? Yes, this is possible.

First, what kind of UI are we looking for? I thought a simple scrolling list of tweets should do, along with Search functionality. Mind you, here we are ONLY doing a tweet reader based on Twitter’s public Search feed; no way for users to sign on or post tweets from one’s account. If you are wanting to the next step in Twitter integration with authentication and ability to post tweets, may I point you to Twitter’s extensive RESTful API and its documentation as below:

http://dev.twitter.com/doc

For our purposes of doing public Searches against Twitter, the simple Search API below works perfectly:

http://dev.twitter.com/doc/get/search

The request to the API is an HTTP GET to an URL passing requisite parameters and the response is JSON/Atom; doesn’t get simpler than that .. but hey, we are building the 20 min app, remember? The Search API allows us to combine most Boolean operators and provides for search capabilities containing word(s), from/replies to user, mentions, hashtags etc. You get to pick what you want for your app.

Ok, so here’s the UI we are shooting to have:

Twitter Client First Pivot Page

Twitter Client Pivot Page 1

Twitter Client Pivot Page 2

Twitter Client Pivot Page 2

Twitter Client Pivot Page 3

Twitter Client Pivot Page 3

Note that we preserve Twitter’s colors for branding and user familiarity.  And yes, since you asked, the Hex for Twitter blue is #4099FF!!

Everything in Silverlight has to relieve the main UI thread from waiting so that user interaction is not hampered. This holds true for HTTP Gets where we have to fire off the call and then wait on a different thread to process the response. Luckily, you need not spin off any threads of your own. Simply use the WebClient class, and assign an ASYNC event handler to process responses when available. This does work out well if trying to show a progress bar; you know exactly when to show & hide. So, here is how we fire off a Search request. This particular request is searching for tweets containing a hashtag; but others would similar as per the API documentation above.

private void FireHashSearch()
 {
 // Build up the Search URI to find tweets containing #sogeti.
 string searchQuery = String.Format(_TwitterSearchBaseUrl, "%23Sogeti", _MaxSearchResultsCount);
 Uri searchQueryUri = new Uri(searchQuery, UriKind.Absolute); 

 // Use the WebClient to go across to Twitter Search API asynchronously.
 WebClient searchTwitter = new WebClient();
 searchTwitter.DownloadStringCompleted += new DownloadStringCompletedEventHandler(TwitterHashSearch_DownloadStringCompleted);
 searchTwitter.DownloadStringAsync(searchQueryUri); 

 // Display Progress bar.
 this.ProgBar.Visibility = System.Windows.Visibility.Visible;
 }

The two constants used above are set as follows:

private const string _TwitterSearchBaseUrl = "http://search.twitter.com/search.atom?q={0}&rpp={1}"; 
private const int _MaxSearchResultsCount = 50;


Now, the response is Atom, which is just a certain form of XML. So, how do you parse? Coming from XML/XSLT background, you might be tempted to think XMLDocument & XPath are the easiest ways to parse. Well, sure they are; but the part of the .NET Framework in Silverlight does not have support for them. Huh? Well, relax. LINQ can be your best friend and is also one of the easiest ways to parse such a response. It also gels really well with Silverlight’s data binding model. More on that in a bit. But, first, let us inspect the response and see what we are interested in. Turns out, 3 small repeating pieces. So, let us write a small class to support them and also aid in our binding.

public class Tweet
 {
 public string MsgURL { get; set; }
 public string Title { get; set; }
 public string Avatar { get; set; }
 }

Now that we know which pieces of data we need, it is also easy to set up the display. Essentially, a listbox with a data template and a progress bar above (yes, the classic WP7 dots that run across your screen). Put this in any generic Silverlight container you want .. Grid, Canvas or Stackpanel.

<ProgressBar Foreground="Red" x:Name="ProgBar" Visibility="Collapsed" 
 IsIndeterminate="True" Height="4" Width="460"
 HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,136,0,0"/>

<ListBox x:Name="lstSogetiHashResults" Background="White" Margin="0, -15, 0,5" 
 ItemsSource="{Binding}" ScrollViewer.HorizontalScrollBarVisibility="Disabled">

 <ListBox.ItemTemplate>
 <DataTemplate>
 <Grid HorizontalAlignment="Stretch" VerticalAlignment="Bottom" >
 <Grid.ColumnDefinitions>
 <ColumnDefinition Width="Auto"/>
 <ColumnDefinition Width="*"/>
 </Grid.ColumnDefinitions> 

 <Image Source="{Binding Mode=OneWay, Path=Avatar}" Grid.Column="0"
 Margin="5" Width="75" Height="75"
 HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
 <TextBlock Text="{Binding Mode=OneWay,Path=Title}" Grid.Column="1" Foreground="Black" Margin="1,3,0,3"
 TextWrapping="Wrap" HorizontalAlignment="Stretch" VerticalAlignment="Center"
 Style="{StaticResource PhoneTextSmallStyle}" FontWeight="SemiBold"/>

 </Grid>
 </DataTemplate>
 </ListBox.ItemTemplate>
</ListBox>

Now, our UI is set up and know what data elements to bind to. Here’s the code to parse the response and data-bind. Notice how we hide the progress bar once we have a response.

private void TwitterHashSearch_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
 {
 if (e.Error != null)
 {
 Tweet error = new Tweet();
 error.Title = "Oops, something went wrong!"; 

 // DataBind.
 List<Tweet> nothingList = new List<Tweet>();
 nothingList.Add(error);
 this.lstSogetiHashResults.DataContext = nothingList;
 }
 else
 {
 // Grab response.
 string results = e.Result; 

 // Remove namespace.
 XDocument xmlTweets = XDocument.Parse(results.Replace("xmlns=\"http://www.w3.org/2005/Atom\"", String.Empty));

 // LINQ to parse.
 var tweets = from entry in xmlTweets.Descendants(XName.Get("entry"))
 select new Tweet
 {
 Title = (string)entry.Descendants(XName.Get("title")).First(),
 MsgURL = (string)entry.Descendants(XName.Get("link")).First().Attribute("href"),
 Avatar = (string)entry.Descendants(XName.Get("link")).ElementAt(1).Attribute("href"),
 }; 

 // DataBind.
 this.lstSogetiHashResults.DataContext = tweets; 
 } 

 // Hide Progress bar.
 this.ProgBar.Visibility = System.Windows.Visibility.Collapsed;
 }

So, there you have it; a quick Twitter reader. You may decide to go a little fancy and add some more requisite pages as a part of a smooth flowing Pivot Control. The application bar at the bottom refreshes the present feed being displayed or allows the user to search. The WP7 application icon pack & a host of other dev resources can be found @ Jeff Blankenburg’s blog here : http://www.jeffblankenburg.com/page/Windows-Phone-7-Resources.aspx.

The refreshes call out to the same Twitter API; but with a “Since_ID” param to update the feeds. The Search pages simply throws in a textbox, a fancy button (ok, bit of Blend work there; you don’t have to in 20 mins) and the same Twitter search API call simply sends along the user entered search criteria as a parameter.

Hope this was of some interest.

Adios!

Can I have fancy Lists please?

Problem Definition:

Ok, at a client where we make a rather sophisticated web application for a big call center. One of the core requirements is to make it super-easy for CSRs to run through scripts on our site, while on the phone with a customer. And one way we achieve that is by having a consistent styling on web page elements with focus and precise tab navigation. Now, there are lots of Dropdown lists and Listboxes in use, which render as <select> HTML elements. Despite endless death wishes, our nemesis IE6 is still in use within the organization; so our site does need to support IE6.

So, here is our problem. IE < 8 does not render <select> lists like other elements in the browser; but rather as Windows OS elements. This leads to weird problems like inability to use custom styles or overlapping over other UI elements (use z-indexing to your advantage to fix up this issue). As for us, we wanted the select lists to have custom styling while idle & when in focus. This included a border which IE simply refuses to render; but it just had to work.

Solution:

There are a few nice JavaScript solutions people have implemented; “Bing” around. But these looked a little complicated. So, my approach was to simply to put a <div> around all the select lists; somewhat hacky, but works with ease. Essentially, the <select> lists may be rendered as needed — MVC helpers, plain HTML, server side etc.; but just wrapped in a <div> tag with a class attribute (I used ‘selectContainer‘). Next, in the site’s JS file or appropriate location, a sprinkle of jQuery magic:


$(document).ready(function ()
{
    $('.selectContainer').addClass("idleField");

    $('.selectContainer').focusin(function ()
    {
        $(this).addClass("focusField");
    });

    $('.selectContainer').focusout(function ()
    {
        $(this).removeClass("focusField").addClass("idleField");
    });
});

Let’s review. What we are doing is once the DOM is ready, we wire up some JavaScript event handlers to the <div> element. The tricky part is that with the addition of a surrounding <div>, we cannot be messing up tab navigation for the <select> elements; but somehow the surrounding <div> has to know when the containing <select> gains/loses focus. This is where jQuery shines with two handy little functions — focusin() & focusout(). As compared to simply focus() & blur(), these events bubble up to the parent controls; which is exactly what we need for our containing <div> tags. The “idleField” & the “focusField” in the code above are simple CSS styles, defined as needed. The final solution looked like this with effortless tabbing & custom styling on lists.

Listbox with custom styling

Listbox with custom styling

Dropdown with custom styling

Dropdown with custom styling

     

 

I’m sure there are lots of other ways to solve the problem at hand, may be more elegant ones too. Please drop ideas/comments.

Adios!