Nearby Tweet (Makeover)

After spending my weekend reading Sencha Touch, I decided to do a bit of makeover for my “Nearby Tweet”. Sencha Touch kind of save me the time from learning the native mobile SDK like iOS or Andoid. It is using standards such as JavaScript, HTML 5 and CSS3, all I need to learn is the framework.

The previous version has a very important limitation which no geolocation, it is hardcoded to Singapore. Using the Geolocation feature in HTML 5, the application is now able to locate the user and mark the nearby tweets into the map. Another improvement is the use of “Tab Panel” to show both map and the tweets. Here is the screenshots:

So , how is it done?

Step 1: Include Sencha Touch CSS & JavaScript, Google Map API and own CSS & JavaScript.

<!DOCTYPE html>
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 <title>Nearby Tweets Mobile</title>
 <link rel="stylesheet" href="css/ext-touch.css" type="text/css">
 <link rel="stylesheet" href="css/NearByTweetsMobile.css" type="text/css">
 <script type="text/javascript" src="<a href="http://maps.google.com/maps/api/js?sensor=true">http://maps.google.com/maps/api/js?sensor=true</a>"> </script>
 <script type="text/javascript" src="js/ext-touch.js"> </script>
 <script type="text/javascript" src="js/NearByTweetsMobile.js"> </script>
</head>
<body> </body>
</html>

Step 2: Implement the JavaScript for loading the UI, getting the Tweets and marking it on the map. There no change to the code that add marker and get location from previous implmentation.

Ext.setup({
    icon: 'icon.png',
    glossOnIcon: false,
    onReady: function() {
      // nbTweets - tweet list. Using Template to generate the html.
        var nbTweets= new Ext.Component({
            title: 'Nearby Tweets',
            scroll: 'vertical',
            tpl: [
                '<tpl for=".">',
                    '<div>',
                            '<div><img src="{profile_image_url}" /></div>',
                            '<div>',
                                '<h2>{from_user}</h2>',
                                '<p>{text}</p>',
                                '<p>{location}</p>',
                            '</div>',
                    '</div>',
                '</tpl>'
            ]
        });

        var map = new Ext.Map({
            title: 'Map',
            getLocation: true,
            mapOptions: {
                zoom: 12,
                mapTypeId: google.maps.MapTypeId.ROADMAP
            }
        });
       
    var geocoder = new google.maps.Geocoder();

    // Create tab panel for the map and tweet list timeline
        var panel = new Ext.TabPanel({
            fullscreen: true,
            animation: 'slide',
        ui: 'light',
            items: [map, nbTweets]
        });

    // handler for refresh button    
        var refresh = function() {
            var coords = map.geo.coords; // get user geolocation

            Ext.util.JSONP.request({
                url: 'http://search.twitter.com/search.json',
                callbackKey: 'callback',
                params: {
                    geocode: coords.latitude + ',' + coords.longitude + ',' + '10km',
                    rpp: 30
                },
                callback: function(data) {
                    data = data.results;

                    // Update the tweets in nbTweets
                    nbTweets.update(data);
                    // Add points to the map
                    for (var i = 0, ln = data.length; i < ln; i++) {
                        var tweet = data[i];
                        getTweetLocation(map, geocoder, tweet);
                    }
                }
            });
        };

        map.geo.on('update', refresh);

        var tabBar = panel.getTabBar();
        tabBar.addDocked({
            xtype: 'button',
            ui: 'mask',
            iconCls: 'refresh',
            dock: 'right',
            stretch: false,
            align: 'center',
            handler: refresh
        });

    }
});

// These are all Google Maps APIs
function getTweetLocation(map, geocoder, tweet) {
 // insert the code to get tweet location either from the geotag or tweet.location
    if (tweet.geo && tweet.geo.coordinates) {
        var position = new google.maps.LatLng(tweet.geo.coordinates[0], tweet.geo.coordinates[1]);
    addMarker(map, position, tweet);
    } else {
    var geocode = tweet.location.split(": ",2);
    var addr = geocode[1];
    if (addr == undefined) addr = tweet.location;
      if (geocoder) {
        geocoder.geocode( { 'address': addr }, function(results, status) {
          if (status == google.maps.GeocoderStatus.OK) {
           addMarker(map, results[0].geometry.location, tweet);
          } else {
            //alert("Geocode was not successful for the following reason: " + status);
          }
        });
      }
    } // end if tweet.geo
} // end addMarker
       
function addMarker(map, position, tweet) {
 // insert the code to add marker to map.
} // end addMarker

So far, I have tested in iPhone Safari (on iOS4) and it works fine. Not sure how it performs in Android yet. One thing to note is the mobile browser must support HTML 5. 🙂 If you try the links below on Android, drop me a comment whether or not it works and what Android version you are using.

Nearby Tweets Mobile: http://www.wswijaya.com/prototype/NearByTweetsMobile.php

Sencha Touch Version: 0.91 (public beta)

Advertisements