Monday, September 8, 2014

Profile editor using facebook data

Let`s create a simple mobile web-app, which let you to login into facebook and choose few images which you like best.

UX:


At facebook you you can query albums list and then the images of each album.
We will have 3 screens, using jquerymobile for the UI

  1. Login screen, where standard facebook login will happen. There will also be one big button "Find image"
  2. List of album names and number of images in each. each row is clickable. We use simple  jquerymobile list , see w3schools demo
  3. A grid of images of the current album. see here



Code:

Facebook login and API calls

First login using facebook, and then make API calls:
graph api explorer can be used to simulate requests.
[TODO] see the full documentation to handle batching/errors

Fetch albums

We will calls FB.api('/me/albums',fucntion) , get the result JSON and extract the albums from it. We will later replace the html of the content div and call JQueryMobile enhanceWithin() to reformat it, otherwise the list will use the browser default list.
Please note that by doing so, we ignore the url hashing scheme, so "back" will not work automatically for us. We should change this later...

function fetchAlbums()
  {
    console.log('fetchAlbums...');
    FB.api('/me/albums', function(result) {
      var html=  '<ul data-role="listview" data-inset="true">';
      html+='<h2>Albums</h2>'
      for (var i=0; i<result.data.length; i++)
      {
        var album = result.data[i];
        if (typeof album.count == "undefined")
          album.count=0;
        html+='<li><a href="#" onclick="fetchImages('+album.id+')">'+album.name+'<span class="ui-li-count">'+album.count +'</span></a></li>';
      }
      html+='</ul>';
      $( "#main" ).html(html).enhanceWithin();

    });
  }

[syntax-highlighting taken from here using brush: javascript like so: <pre class="brush: javascript">]

TODO: an album has a cover_photo property which can be added as a small icon.

Fetch album images

FB.API(albumId+"/photos") will show a list of photos.
Each photo contains array of images and a small 100px picture. doc here
Some, rather ugly, js code is needed to transform gridSize=3 to ui-grid-b(33% each) and ui-block-a/b/c. 

function fetchImages(albumId)
  {
     var request = albumId+'/photos';
     console.log('calling'+ request);
     FB.api(albumId+'/photos',function(result) {
       
       var gridSize=3; //2 or more
       var maxGridChar= String.fromCharCode("a".charCodeAt(0)+gridSize-2);
       //solo/a/b/c -b means 33%*3
       var html='<div class="ui-grid-' + maxGridChar   +'">';
       
       for (var i=0; i<result.data.length;i++)     {
         var uiBlockIndex= String.fromCharCode("a".charCodeAt(0) +i%gridSize);
         html+='<div class="ui-block-'+uiBlockIndex+'">';
         html+=  '<img src="'+result.data[i].picture+'"/>';
         html+="</div>";
       }
       html+='</div>';
       $("#main").html(html).enhanceWithin();
     });
  }

This table is clearly non responsive and looks rather bad. You can add some css to make it looks a bit better here:

.ui-grid-c img {

  width:100%;

  height:auto;

  margin:10px;

}

.ui-grid-c div {

  padding:10px;

}

JQueryMobile proper dynamic pages

This was a quick-and-dirty sample, where we just replaced the html of the ui-content and called enhancedWithin, by doing so we ignored the built-in pages system and also ignored the links routing (we used onclick to replace the content instead of using the href.
TODO: use pagecontainer widget for a proper way to do it. make sure panels still work well in this case.

No comments: