Home  >  

Enhanced status component

Author photo
AddThis Social Bookmark Button
In the last article we worked extensively with the ProfilePic component and showed how the component can be used in real time scenarios. We had an interesting example of a real word application with the "Would you..." application clone. I really had a lot of fun working on it and hope you did too. For us, it's important that we were able to work with components that were previously built based on the previous articles. The goal is to not go against the "DRY“ principle. Every component that was created needs to be reused again, so no development time will be spent on them anymore, except when extending it. This tutorial will deal mostly with text. The idea of the application is the following: We need to create some sort of "Mood Checker", an application that will allow us to browse through the statuses of users.
series badge
Find the rest of this series on the series page.
Here is the final image of the application:

article9_img17.png
So, all statuses will be loaded and stored and the user will be able to browse through the statuses. For example I have basketball on my mind and I need one of my friends to go play basketball. I will type in keywords like "basketball, sports" and the application will filter statuses and display friends with similar activities on their mind. It's a great way collect friends for any sort of event. Also, it can be used to find out how somebody is feeling, like for example you can type in "happy" and the application will display friends that are feeling this way.
In order for this application to work, we need the status component from part 6 of the series where we created a very simple status bar with no formatting at all. This time we need enhance the component a bit to format the text inside of it. While creating this application, we will discover that there are endless possibilities and ways to extend it and this article will be able to cover only one part of those ideas.
Let's define the logic flow of the application.
  • the application loads in the Facebook canvas
  • the application loads the statuses of every friend we have in our list
  • user types in a key word into the search text field
  • the application searches for the keyword in the list of statuses
  • the application displays a list of friends with keywords in the status
Let's start with the actual application.
Open the fla we worked on previously.
article9_ima1.png
Remove all code that was on the first frame and leave the two layer structure of frames.
All we need to remember here is the api key and the secret provided by Facebook for our application.
Next thing we need to do is to create a valid Facebook session with the following code:

import com.facebook.data.users.GetInfoData;
import com.facebook.utils.FacebookSessionUtil;
import com.facebook.data.users.FacebookUser;
import com.facebook.data.users.GetInfoFieldValues;
import com.facebook.commands.users.GetInfo;
import com.facebook.commands.friends.*;
import com.facebook.data.friends.*;
import com.facebook.net.FacebookCall;
import com.facebook.events.FacebookEvent;
import com.facebook.Facebook;

var fbook:Facebook;
var session:FacebookSessionUtil;
var user:FacebookUser;
And then we can start the Facebook session:

session = new FacebookSessionUtil("YOUR_API_KEY", "YOUR_SECRET", loaderInfo);
fbook = session.facebook;
The next thing we need to do is to get the code from article six and reload the UserStatus component. If you followed the previous tutorials, the UserStatus component should be in your library.
article9_img2.png
Let's see if our component is still working (it should work :-) ). In the first step we created a valid Facebook session code:

import com.facebook.data.users.GetInfoData;
import com.facebook.utils.FacebookSessionUtil;
import com.facebook.data.users.FacebookUser;
import com.facebook.data.users.GetInfoFieldValues;
import com.facebook.commands.users.GetInfo;
import com.facebook.commands.friends.*;
import com.facebook.data.friends.*;
import com.facebook.net.FacebookCall;
import com.facebook.events.FacebookEvent;
import com.facebook.Facebook;

var fbook:Facebook;
var session:FacebookSessionUtil;
var user:FacebookUser;

session = new FacebookSessionUtil("YOUR_API_KEY", "YOUR_SECRET", loaderInfo);
fbook = session.facebook;
Now, let's place the UserStatus component on the stage. Drag one instance from the library to the stage:

article9_img3.png
Give it an instance name status1_mc. Finally in the code, place the line of code:

status1_mc.loadStatus(fbook);
The line of code is self explanatory. OK, here is what we got when the swf is compiled, uploaded and loaded in the fb canvas:

article9_img4.png
Yes, that's the modest UserStatus component. But here we can see a little bug. Well this comes from the 6th article where we worked on the basic architecture of FB components. We cared how to create a first functioning FB component, we did not care about details. One detail here is that we forgot to add code that will re-size the text field automatically to fit the length of the Facebook status. We will fix it now and add some other small features.
Let's add now the feature to load statuses from the specific friends. Remember the code from the ProfilePicDisplay component?

public function load(fbook:Facebook, uid:Number):void {
 			
 			var call:GetInfo = new GetInfo([uid], [GetInfoFieldValues.PIC_BIG]);
 			call.addEventListener(FacebookEvent.COMPLETE, onInfo);
 			fbook.post(call);
 
 		}
Let's do the same for the status of the user! Not that difficult:

public function load(fbook:Facebook, uid:Number):void {
 			
 			var call:GetInfo = new GetInfo([uid], [GetInfoFieldValues.STATUS]);
 			call.addEventListener(FacebookEvent.COMPLETE, onInfo);
 			fbook.post(call);
 
 		}
Paste this method and replace the loadStatus method. Now in the first frame of the swf, instead of:

status1_mc.loadStatus(fbook);
paste this:

status1_mc.load(fbook, userID);
Where userID is the uid of one of your friends. I took for example:

status1_mc.load(fbook, 1199659818);
And the result is:

article9_img5.png
Cool, we just loaded the status of one of our friends. Now we are able to place multiple UserStatus components and play around with it. The final thing we need to add is the resizing of the text field. We will do that by adding some code the the existing onInfo method. Here is the code:

private function onInfo(e:FacebookEvent):void{
 			
 			var user = (e.data as GetInfoData).userCollection.getItemAt(0) as FacebookUser;
 			_status_txt.text = user.status.message;
 			_status_txt.width = _status_txt.textWidth;
 		
}
Now take one friend with a longer user id, in my case I took my own status that was cut off previously:
article9_img6.png
We see now that in this case the text field is stretched and the whole string is displayed.
Wow, finally the component is ready to go and we are able to do neat things with it. Now, we need to load the statuses.
The code that loads the friends was already discussed but this time it's a bit different. What do we need actually? We need an array that has the element with the following properties: user id, friend's name, profile picture, status. So let's go to work. On the first frame we have the code that creates the session. Now we need to remove the code that loads the data into status1_mc, so here is what is left on frame 1:

import com.facebook.data.users.GetInfoData;
import com.facebook.utils.FacebookSessionUtil;
import com.facebook.data.users.FacebookUser;
import com.facebook.data.users.GetInfoFieldValues;
import com.facebook.commands.users.GetInfo;
import com.facebook.commands.friends.*;
import com.facebook.data.friends.*;
import com.facebook.net.FacebookCall;
import com.facebook.events.FacebookEvent;
import com.facebook.Facebook;

var fbook:Facebook;
var session:FacebookSessionUtil;
var user:FacebookUser;
var users:Array = new Array();
var uids:Array = new Array();

session = new FacebookSessionUtil("YOUR_API_KEY", "YOUR_SECRET", loaderInfo);
fbook = session.facebook;
Right below that, we should add code that loads the list of friends:

var call:GetFriends = new GetFriends();
call.addEventListener(FacebookEvent.COMPLETE, onFriends);
fbook.post(call);
Right after the call, we need to create the onFriends callback that will receive all friends:

function onFriends(e:FacebookEvent):void{
 	
 	var friends = (e.data as GetFriendsData).friends;
 	var i;
 	var len = friends.length;
 	
 	for(i = 0; i < len; i++){
  		var user = friends.getItemAt(i) as FacebookUser;
  		uids.push(user.uid);
  	}
 		
 	trace(uids);
 
}
In order to get all the data we need, first we need to create a small array containing the list of all uids of our friends. This is created in the onFriends method using the loop. Now when this code is uploaded is should display a list of user ids:

2022256,38503512,61802896...
OK, now that we have the user ids we will pass them to the next Facebook call to get the desired information of friends:

var call:FacebookCall = fbook.post(new GetInfo(uids, [&#8220;stauts&#8221;]));
call.addEventListener(FacebookEvent.COMPLETE, onDataRecieve);
    fbook.post(call);
This call needs to be added inside the onFriends method, so here is the complete method:

function onFriends(e:FacebookEvent):void{
 	
 	var friends = (e.data as GetFriendsData).friends;
 	var i;
 	var len = friends.length;
 	var uids:Array = new Array();
 	for(i = 0; i < len; i++){
  		var user = friends.getItemAt(i) as FacebookUser;
  		uids.push(user.uid);
  	}
 		
 	var call:FacebookCall = fbook.post(new GetInfo(uids, &#8220;status&#8221;]));
 call.addEventListener(FacebookEvent.COMPLETE, onDataRecieve);
     fbook.post(call);
 	
}
Ok, before we test the code, we really need to make sure that some method receives the data about friends, we already nemed it onDataReceive and look like this:

function onDataRecieve(e:FacebookEvent){
 	var userData = ((e.data as GetInfoData).userCollection);
 	var i;
 	var len = userData.length;
 	for(i = 0; i < len; i++){
  		var user = userData.getItemAt(i);
  		var dataObj = new Object();
  		trace(user.status.message, uids[i]);
  		
  	}
 	
}
Now we need to compile the swf and upload it. We should see the list in the output that has the following format:

Status, user id
In my case it looks like this:

Some status, 1110516263
Some other status, 1114566654
Other status, 1118563211
.
.
.
Now we have the data, but the data also need to be stored. Here is how it can be done: In every loop iteration we create an object with the data above and push it as an array element.

import com.facebook.data.users.GetInfoData;
import com.facebook.utils.FacebookSessionUtil;
import com.facebook.data.users.FacebookUser;
import com.facebook.data.users.GetInfoFieldValues;
import com.facebook.commands.users.GetInfo;
import com.facebook.commands.friends.*;
import com.facebook.data.friends.*;
import com.facebook.net.FacebookCall;
import com.facebook.events.FacebookEvent;
import com.facebook.Facebook;

var fbook:Facebook;
var session:FacebookSessionUtil;
var user:FacebookUser;
var users:Array = new Array();
var uids:Array = new Array();

session = new FacebookSessionUtil("YOUR_API_KEY", "YOUR_SECRET", loaderInfo);
fbook = session.facebook;

var call:GetFriends = new GetFriends();
call.addEventListener(FacebookEvent.COMPLETE, onFriends);
fbook.post(call);

function onFriends(e:FacebookEvent):void{
 	
 	var friends = (e.data as GetFriendsData).friends;
 	var i;
 	var len = friends.length;
 	
 	for(i = 0; i < len; i++){
  		var user = friends.getItemAt(i) as FacebookUser;
  		uids.push(user.uid);
  	}
 		
 	var call:FacebookCall = fbook.post(new GetInfo(uids, ["status"]));
 	call.addEventListener(FacebookEvent.COMPLETE, onDataRecieve);
     fbook.post(call);
 
}

function onDataRecieve(e:FacebookEvent){
 	var userData = ((e.data as GetInfoData).userCollection);
 	var i;
 	var len = userData.length;
 	for(i = 0; i < len; i++){
  		var user = userData.getItemAt(i);
  		var dataObj = new Object();
  		dataObj.status = user.status.message;
  		dataObj.uid = uids[i];
  		users[i] = dataObj;
  	}
 	
}
Well now I think we are ready for the next step. The next step is to implement the logic that is necessary for the application flow. There will be 7 (if you want more) status components of the screen.
We can enhance the Status component to display the profile pic and the status in one movieclip. For that, we will extend the UserStatus component.
Duplicate the UserStatus component and name it UserStatusPlus.

article9_img12.png
In our library, we should have now the UserStatusPlus component right below the original one.
Open he UserStatusPlus in edit mode:

article9_img13.png
Change the height of the dummy rectangle to 50 px.

article9_img14.png
Go back to the main timeline, select the UserStatusPlus component and give it the following linkage options:

article9_img15.png
This means we need to create inheritance. Here is the code for the extended component:

package facebookUI{
 
 	import com.facebook.Facebook;
 	import facebookUI.ProfilePicDisplay;
 
 	public class UserStatusPlus extends UserStatus{
  
  		protected var _profilePic_mc = null;
  
  		function UserStatusPlus() {
   		}
  
  		override protected function configUI():void {
   
   			super.configUI();
   
   			_profilePic_mc = new ProfilePicDisplay();
   			addChild(_profilePic_mc);
   			_profilePic_mc.setSize(50, 50);
   
   			_status_txt.x = _profilePic_mc.width;
   
   		}
  
  		override public  function load(fbook:Facebook, uid:Number):void {
   			
   			super.load(fbook, uid);
   			_profilePic_mc.load(fbook, uid);
   
   		}
  
  	}
 
}
Save it as UserStatusPlus.as in the same facebookUI folder where all our Facebook classes reside.

article9_img16.png
Now the great thing about this class is that we only need to pass the user id and the status and the profile pic will be displayed. How lovely! Every time the application user types in a keyword, the application will display max. 7 friends with those keywords in their statuses. This might sound a bit confusing right now, but will be much clearer soon. So, let's place 7 status components below each other like on the image:

article9_img7.png
From top to bottom, in the property inspector, name them status1_mc, status2_mc, etc. respectively. This is the where the statuses of friends will appear as soon as the app user types in a key word. Below we need an input text field, so paste it directly below:

article9_img8.png
I added a background color so that the search text field can be easily distinguished. Name it search_txt in the property inspector. Cool, now we have to add the listener that listens when the app user types in some text:

search_txt.addEventListener(Event.CHANGE, changed);

function changed(e:Event):void{
 	
 	var text:String = e.currentTarget.text;
 
 	trace("Written text: " + text);
 	
}
We need to upload the compiled swf to make sure the listeners works.

article9_img9.png
When we are sure that this works, we can begin searching for statuses.
We will use now the written text to search for keywords. Every time the app user types in a keyword, we simply iterate through the list of friends and check for the occurrence of this keyword. This algorithm may be a little slow, but can be optimized. Here is how the the first version of the function might look like:

search_txt.addEventListener(Event.CHANGE, changed);

function changed(e:Event):void{
 	
 	var t:String = e.currentTarget.text;
 	sT(t);
 	
}

function sT(t:String):Array{
 	var i:Number = 0;
 	var len:Number = users.length;
 	for(i = 0; i < len; i++){
  		var user:Object = users[i];
  		if(user.status.indexOf(t) != -1){
   			trace(user.status);
   		}
  	}
 	return [];
}
The method name sT was shortened because of performance reasons. When we compile and upload, we will quickly see that the method is too slow. For the Flash player, it's too overwhelming to iterate 200 or more times (depends on how many friends we have) every time we type in a character. A better way might be to place a search button on the stage and make the search when the word is typed in a the button is pressed. In order for that to happen, we don’t need the change event anymore:

search_txt.addEventListener(Event.CHANGE, changed);

function changed(e:Event):void{
 	
 	var t:String = e.currentTarget.text;
 	sT(t);
 	
}
We need to place one button beside the text field, give it a label "Search" and the instance name search_btn.

article9_img10.png
Now, we need to call the search method as so as the app user hits the search button. Here is the code:

search_btn.addEventListener(MouseEvent.CLICK, changed);

function changed(e:Event):void{
 	var t:String = search_txt.text;
 	sT(t);
}

//same search function
function sT(t:String):Array{
 	var i:Number = 0;
 	var len:Number = users.length;
 	for(i = 0; i < len; i++){
  		var user:Object = users[i];
  		if(user.status.indexOf(t) != -1){
   			trace(user.status);
   		}
  	}
 	return [];
}
Now when the swf is uploaded we can type in a word, like in my sample "dogs" I get one of my friends who has dogs and similar stuff on his mind.

article9_img11.png
Now there is still a lot to do here. The search method is not yet finished. Until now it only shows the status of the user that has the keyword inside. In reality we want to see the image of the friends with his status displayed as soon as keywords are found.
For that, the whole search algorithm looks like this:

search_btn.addEventListener(MouseEvent.CLICK, changed);

function changed(e:Event):void{
 	var t:String = search_txt.text;
 	var found:Array = sT(t);
 	trace("Found: " + found[0].status);
}

function sT(t:String):Array{
 	var found:Array = new Array();
 	var i:Number = 0;
 	var len:Number = users.length;
 	for(i = 0; i < len; i++){
  		var user:Object = users[i];
  		if(user.status.indexOf(t) != -1){
   			found.push(user);
   		}
  	}
 	return found;
}
Ok, let's test it! When uploaded and when we type a keyword, instead of the status, a whole object with information about the user appears.
Found: Greg Lynch is really really really really really really really happy the dogs came back from the Vet tinted bright yellow and smelling once again of sulfur. Only four more visits until they are better.
Ok, now we to change the changed method in order to display the results:

function changed(e:Event):void{
 	var t:String = search_txt.text;
 	var found:Array = sT(t);
 	var i = 0;
 	var len = found.length;
 	for(i = 0; i < len; i++){
  		this["status" + (i + 1) + "_mc"].load(fbook, found[i].uid);
  	}
}
When uploaded it should look similar like in the image below.

article9_img18.png
Finally, not to confuse you, here is the complete code from frame 1:

import com.facebook.data.users.GetInfoData;
import com.facebook.utils.FacebookSessionUtil;
import com.facebook.data.users.FacebookUser;
import com.facebook.data.users.GetInfoFieldValues;
import com.facebook.commands.users.GetInfo;
import com.facebook.commands.friends.*;
import com.facebook.data.friends.*;
import com.facebook.net.FacebookCall;
import com.facebook.events.FacebookEvent;
import com.facebook.Facebook;

var fbook:Facebook;
var session:FacebookSessionUtil;
var user:FacebookUser;
var users:Array = new Array();
var uids:Array = new Array();

session = new FacebookSessionUtil("YOUR_API_KEY", "YOUR_SECRET", loaderInfo);
fbook = session.facebook;

var call:GetFriends = new GetFriends();
call.addEventListener(FacebookEvent.COMPLETE, onFriends);
fbook.post(call);

function onFriends(e:FacebookEvent):void{
 	
 	var friends = (e.data as GetFriendsData).friends;
 	var i;
 	var len = friends.length;
 	
 	for(i = 0; i < len; i++){
  		var user = friends.getItemAt(i) as FacebookUser;
  		uids.push(user.uid);
  	}
 		
 	var call:FacebookCall = fbook.post(new GetInfo(uids, ["status"]));
 	call.addEventListener(FacebookEvent.COMPLETE, onDataRecieve);
     fbook.post(call);
 
}

function onDataRecieve(e:FacebookEvent){
 	var userData = ((e.data as GetInfoData).userCollection);
 	var i;
 	var len = userData.length;
 	for(i = 0; i < len; i++){
  		var user = userData.getItemAt(i);
  		var dataObj = new Object();
  		dataObj.status = user.status.message;
  		dataObj.uid = uids[i];
  		users[i] = dataObj;
  	}
 	
}

search_btn.addEventListener(MouseEvent.CLICK, changed);

function changed(e:Event):void{
 	var t:String = search_txt.text;
 	var found:Array = sT(t);
 	var i = 0;
 	var len = found.length;
 	for(i = 0; i < len; i++){
  		this["status" + (i + 1) + "_mc"].load(fbook, found[i].uid);
  	}
}

function sT(t:String):Array{
 	var found:Array = new Array();
 	var i:Number = 0;
 	var len:Number = users.length;
 	for(i = 0; i < len; i++){
  		var user:Object = users[i];
  		if(user.status.indexOf(t) != -1){
   			found.push(user);
   		}
  	}
 	return found;
}


To view the entire series please visit http://www.insideria.com/series-facebook-dev.html

Read more from Mirza Hatipovic. Mirza Hatipovic's Atom feed mirzahat on Twitter

Comments

18 Comments

iphone said:

Enhanced status bar with many new options and capabilities:support for mini HTML formatted text in panels, including capability to add hyperlinks, images and blinking text in the statusbar panel.panel with time, date, NUMLock, CAPSLock

Ryan said:

Looks like a pretty good facebook app. With facebook and twitter being the traffic hubs, its important for free web dating sites to develop applications to catch downstream from fb, twitter.

Jason said:

I also agree that it looks like a great app. I currently am working for a New Orleans Wedding photography company and we use twitter and facebook to bring some traffic to our sites. Thanks for the great post!

Christan said:

I just love this App, actually I am hooked on facebook. I work at a golfshop and I dont get to spend time on the internet that much.

Jason said:

I really loved this aplication like the others. I am not the much of a facebook fanatic as most but it does intrest me sometimes. I actually used to work at a Golfshop also. I know boring it can be haha!

Joe Clark said:

I have been involved with computers for a very long time, see I have worked for Solihull laptop screen repairs and I have seen just about everything. I am a avid user of facebook and this app has been really handy for me. Also thanks for the in depth post, its about time. Many blogs these days have very short posts. Thanks

CandyMiller33 said:

I run a great live TV premiership and I am int he process of using Facebook to get more people interested in our premiership. I really think that this app is awesome. Thanks so much for the great application.

JamesAllisson said:

I use Facebook since one year to have more people booking me as magician and with my band. Thanks for this app its realy magical. Hope its helping me for my Coverband & Partyband and Zauberer Koeln

Orlando said:

I really loved this aplication like the others. I mostly spent time on face book and have many friends there but i never think about that application now im going to share it with my friends as we have a big community and i work for chicago real estate and i think it gonna help me lots. thanks for sharing nice information with us.

C++ Help said:

I find this manual really interesting, thanks a lot!

Plinduma said:

Thank You guys for sharing this very good facebook app! I hope I can do this as good as described...

Susan said:

I do absolutely agree with "Orlando" - I love this application like no other! I'm working at a Plinduma restaurant and we have installed this application in all of our Plinduma specialities and cards.
I know it sounds weird, but you can't imagine how useful this application is - i guess it saves me hours of work every day!
Thank You!!

Apex Professionals LLC said:

I really loved this aplication like the others. I mostly spent time on face book and have many friends there but i never think about that application now im going to share it with my friends as we have a big community

Max said:

Hi, I am using Facebook to find other Musicians to chat about cool Music Stuff and things like that, I myself play a lot of Instruments, especially Klavier I also play the Drums and I am from Germany, but not too many Germans use Facebook which is kind of not so cool I thnik, but back to the App... I think this App is a nice one and I am definatly going to try it for my self.

Michael said:

Hi, I really lov this application like the other ones. I am not that much of a facebook fanatic but it does intrest me generally. I'm working as a professional Zauberer (magician) in Germany and I'm thinking about it regulary. Thanks a lot! Michael

Michael said:

Hi, I really lov this application like the other ones. I am not that much of a facebook fanatic but it does intrest me generally. I'm working as a professional Zauberer (magician) in Germany and I'm thinking about it regulary. Thanks a lot! Michael

Markus said:

I use this App all the time to stay in touch with many of my friedns and customers - I`m working as a Zauberer and her it is important to stay in touch with many people

Not another Zauberer please! said:

Wow, you Guys seem to like Zaubering! Well feel free to check out my Artist and Newcomerband Directory - Bandverzeichnis.

Cheers and Rock on!

Leave a comment


Tag Cloud

iPad

What's your take on the iPad? (Putting aside the Flash/iPad flame war)

Answer

Latest Features

Recommended for You

@InsideRIA on Twitter

Archives

  • Or, visit our complete archive.  

About This Site

Welcome to the premiere community site for all things RIA sponsored by O'Reilly Media and Adobe Systems Incorporated.