Jan 08

Desktop iPhone Apps with AIR

Adobe, Facebook, Tech with tags: No Comments »

If Ryan and I were in marketing then we would be talking about “making your iPhone applications BREAAAAATHE” or something ;)

Ryan has a wrapper that lets you run iPhone applications inside of the AIR container:

This implementation just uses the mx:HTML tag with the location set to http://iphone.facebook.com with some extra code to handle the custom chrome and the option to make it transparent. Ideally I could take all of the source code for the iPhone application and have all of those files locally installed with the application but going through that code was more time than I had. You’ll also notice that it just refreshes the entire page. My plan is to go through the iPhone facebook code more and call the function that loads the feed information and just refresh that. I’d also like to be able to detect when a new feed item comes in and bubble that up so I can show a notification but detecting changes to the DOM isn’t easily done with AIR so I need to check with the engineering team. I’m going to have some followup posts this week discussing little parts of the application and I’ll also post the source code later this week (I just need to clean it up).

This is a natural fit for certain applications such as Facebook. Doesn’t this application now look a little like Adium sitting over there?

This, once again, gets me back to Face IM. Similar form factor, just add a few more abilities than you get with the iPhone client (which is optimized for having a crappy keyboard etc).

Ryan, we should get together and hack on this bad boy sometime!

Oct 08

Comparing the HEAD from Facebook and Google

Facebook, Tech No Comments »

When I built the Facebook Auto Expand Greasemonkey script I had to find out the function that kicks off the expansion, and I wanted it to be the right one.

Firebug can help out there, but as I looked through I was surprised by something:

Facebook doesn’t seem to minify/compress their JavaScript!

Since they push ~60 billion pages a month, I was a touch surprised. With this nugget I decided to grab the <head> of Facebook and iGoogle to compare.

The obvious differences as you look at them side by side (below):

  • iGoogle inlines a lot more: CSS and some JavaScript
  • Facebook has ~26 separate external CSS link tags for my profile
  • Facebook has a lot of external JavaScript files

Maybe it is time to run some YSlow?

My Facebook HEAD


<head>
<title>Facebook | Home</title>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<meta name="robots" content="noodp" />
<meta name="description" content="Facebook is a social utility that connects people with friends and others who work, study and live around them. People use Facebook to keep up with friends, upload an unlimited number of photos, share links and videos, and learn more about the people they meet." />
<script type="text/javascript">var cc=new Image();cc.onload=function(){cc.hit=(typeof(Env)=="undefined");};cc.src="http://static.ak.facebook.com/images/global_menu_space.gif?12:37897";Env={method:"GET",dev:0,start:(new Date( )).getTime(),cache:(((typeof(cc)!="undefined")&&cc.hit)||0),ps_limit:5,ps_ratio:4,pkgv:1};</script><link rel="stylesheet" href="http://static.ak.facebook.com/css/base.css?12:62201" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/apps_menu.css?12:43718" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/typeahead.css?12:19905" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/wallpro.css?12:57950" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/dialog.css?12:39930" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/attachments.css?12:59060" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/captcha/captcha.css?12:60350" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/dialogpro.css?12:61009" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/editor.css?12:52799" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/components.css?12:53705" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/sharer.css?12:55903" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/share_media.css?12:60984" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/typeaheadpro.css?12:58664" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/inbox/css/inbox.css?12:62108" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/homeslice.css?12:58781" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/info.css?12:56012" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/profile.css?12:60600" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/feed.css?12:61849" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/feed_ad.css?12:43135" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/status.css?12:39712" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/gifts/gift.css?12:36833" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/mobilepro.css?12:60047" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/sms.css?12:59681" type="text/css"/>
<link rel="stylesheet" href="http://static.ak.facebook.com/css/sprite/icons.css?12:56618" type="text/css"/><!--[if lte IE 6]><style type="text/css" media="screen">/* <![CDATA[ */ @import url(http://static.ak.facebook.com/css/ie6.css?12:62634); /* ]]> */</style><![endif]-->
<!--[if gte IE 7]><style type="text/css" media="screen">/* <![CDATA[ */ @import url(http://static.ak.facebook.com/css/ie7.css?12:62093); /* ]]> */</style><![endif]-->
<script type="text/javascript" src="http://static.ak.facebook.com/js/base.js?12:62634"></script>

<script type="text/javascript" src="http://static.ak.facebook.com/js/extended.js?12:59503"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/string.js?12:59850"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/async.js?12:61542"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/deprecated.js?12:58595"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/apps_menu.js?12:55974"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/typeahead_ns.js?12:60552"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/suggest.js?12:52414"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/dynamic_dialog.js?12:51503"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/captcha.js?12:52414"></script>

<script type="text/javascript" src="http://static.ak.facebook.com/js/recaptcha_ajax.js?12:60350"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/typeaheadpro.js?12:61630"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/dialogpro.js?12:62226"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/fbml.js?12:62093"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/swfobject.js?12:55357"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/editor.js?12:58199"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/timezone.js?12:52149"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/share.js?12:61979"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/home.js?12:47671"></script>

<script type="text/javascript" src="http://static.ak.facebook.com/js/polls/polls.js?12:48801"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/pools.js?12:36733"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/editregion.js?12:56446"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/statuspro.js?12:52414"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/profile.js?12:62148"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/rooster.js?12:40867"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/poke.js?12:62143"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/privacy.js?12:57099"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/addfriend.js?12:62209"></script>

<script type="text/javascript" src="http://static.ak.facebook.com/js/mobile.js?12:61909"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/search_typeaheadpro.js?12:59982"></script>
<script type="text/javascript" src="http://static.ak.facebook.com/js/animation.js?12:62119"></script><link rel="search" type="application/opensearchdescription+xml" href="http://static.ak.facebook.com/opensearch_desc.xml?12:27839" title="Facebook" />
<link rel="shortcut icon" href="http://static.ak.facebook.com/favicon.ico" />
</head>

My iGoogle HEAD

<head><meta http-equiv="content-type" content="text/html; charset=UTF-8"><meta name="description" content="iGoogle is your personalized Google page. Add news, photos, weather, and stuff from across the web to your page.">
<link rel="shortcut icon" href=" http://www.google.com/favicon.ico" type="image/x-icon"/>
<link rel="icon" href="http://www.google.com/favicon.ico" type="image/x-icon"/>
<title>iGoogle</title>
<script>var _IG_time_epoch = (new Date()).getTime();var IGoogleTranslation = {};</script>
<script src="/ig/extern_js/f/CgJlbhICdXMrMAE4ACw/93yMfLuYD4A.js"></script>
<script>var domain = document.location.hostname;var google_pos = domain.indexOf('.google.');if (google_pos > -1) {domain = domain.substring(google_pos);document.cookie = "TZ=" + (new Date()).getTimezoneOffset()+ ';path=/;domain=' + domain;}_et="Tr8WCSVW";_source="";_setp_url="/ig/setp";_gmail_json_url="/ig/gmailjson";_magic_tabs_url="/ig/filltab";_prefid="";_uli=true;_pnlo=false;_mpnlo=false;_pl=false;_mod=true;_pid="";_old_html = false;_use_old_feed_styles = false;_cbp=true;_authpath="";_upc();var _pl_data = {};</script>
<script><!--
function save_chkbox_value(hidden_elem_name, checked) {var hidden_elem = document.getElementById(hidden_elem_name);hidden_elem.value = checked ? "1" : "0";}function module_loader_closure(el, rm) {return function() {_IG_RemoveModuleEventHandler(rm.id,'unzip',arguments.callee);el.src=rm.base_iframe_url;};}function RemoteModule(spec_url, id, render_inline, base_iframe_url,caching_disabled, is_zipped) {this.spec_url = spec_url;this.id = id;this.render_inline = render_inline;this.base_iframe_url = base_iframe_url;this.caching_disabled = caching_disabled;this.old_width = 0;this.wants_scaling = false;      this.is_inlined = function() { return this.base_iframe_url == ""; };this.is_zipped = is_zipped;};var remote_modules = [];_IG_RegisterOnloadHandler(function() {for (var i=0;i<remote_modules.length;i++){var rm=remote_modules[i];var el=_gel("remote_iframe_"+rm.id);if(el){if (rm.is_zipped && true) {_IG_AddModuleEventHandler(rm.id, 'unzip',module_loader_closure(el, rm));} else {el.src=rm.base_iframe_url;}}}});function ifpc_resizeIframe(iframe_id, height) {var el = document.getElementById(iframe_id);if (el) {el.style.height = height + "px";}}_IFPC.registerService('resize_iframe', ifpc_resizeIframe);function _ig_gmid_(iframe_id) {return(iframe_id.split("_")[2]);}function _setModTitle(title, module_id) {var title_element = _gel("m_" + module_id + "_title");if (title_element) {title_element.innerHTML = _hesc(title);}}function ifpc_setTitle(iframe_id, title) {if (typeof(iframe_id) == undefined|| !iframe_id || iframe_id == "undefined") {return;}_setModTitle(title, _ig_gmid_(iframe_id));}_IFPC.registerService('set_title', ifpc_setTitle);function _IG_SetTitle(title, specified_module_id) {if (typeof(specified_module_id) == "undefined"|| !specified_module_id || specified_module_id == "undefined") {throw new Error("Inline modules must specify their "+ "__MODULE_ID__ when using _IG_SetTitle");} else {_setModTitle(title, specified_module_id);}}function ifpc_setPref(iframe_id, var_args) {var module_id = _ig_gmid_(iframe_id);var prefs = new _IG_Prefs(module_id);var keyValues = new Array();for (var n = 1; n < arguments.length; n += 2) {keyValues.push(arguments[n], arguments[n + 1]);}prefs.set.apply(prefs, keyValues);}_IFPC.registerService('set_pref', ifpc_setPref);function share_gadget_safe(msg, url, width, mod_id, send_label,cancel_label) {_share_gadget(_hesc(msg), _hesc(url), _hesc(width), _hesc(mod_id),_hesc(send_label), _hesc(cancel_label));}_IFPC.registerService('share_gadget', share_gadget_safe);var isPubSubEventRouterLoaded = false;function setupPubSubEventRouter() {if (!isPubSubEventRouterLoaded) {document.write("\x3cdiv id\x3d\x22remote_pubsub_event_router\x22 name\x3d\x22remote_pubsub_event_router\x22 style\x3d\x22border:0;padding:0;margin:0;width:100%\x22\x3e\x3ciframe id\x3d\x22remote_iframe_pubsub_event_router\x22 name\x3d\x22remote_iframe_pubsub_event_router\x22 style\x3d\x22border:0;padding:0;margin:0;width:0;height:0;overflow:hidden\x22 frameborder\x3d0 scrolling\x3dfalse src\x3d\x22http://pubsub.gmodules.com/ig/modules/pubsub_event_router.html\x22\x3e\x3c/iframe\x3e\x3c/div\x3e");isPubSubEventRouterLoaded = true;}}// -->
</script>
<script src="/ig/f/CSyPjYmOhjg/lib/libminimessage.js"></script>
<style>.modbox .el {display:;}.modbox .csl, .modbox .es {display:none;}.modbox_e .el {display:none;}.modbox_e .csl, .modbox .es {display:;}.dm {position:relative;width:1px;height:1px;}.fres {width:expression(_gel("ffresults").offsetWidth+"px");overflow:hidden;}.panelo {}.panelc {}.mod {}.unmod {}form {display:inline;}.c {clear:both;}.fbox {margin-top:1px;margin-right:6px;display:block;overflow:hidden;width:12px;height:12px;background-image: url('/ig/images/max_dark_blue.gif');background-repeat: no-repeat;cursor:hand;cursor:pointer;}.fmaxbox, .fmaxbox_reverse_directionality {background-image:url('/ig/images/max_dark_blue.gif');}.fminbox, .fminbox_reverse_directionality {background-image:url('/ig/images/min_dark_blue.gif');}a.fmaxbox:hover, a.fmaxbox_reverse_directionality:hover {background-image:url('/ig/images/max_dark_blue_highlight.gif');}a.fminbox:hover, a.fminbox_reverse_directionality:hover {background-image:url('/ig/images/min_dark_blue_highlight.gif');}a.ddbox {background-image:url(/ig/images/arrow_blue.gif);}a.ddbox:hover {background-image:url(/ig/images/arrow_blue_highlight.gif);}a.delbox {background-image:url(/ig/images/x_blue.gif);}a.delbox:hover {background-image:url(/ig/images/x_blue_highlight.gif);}a.minbox {background-image:url(/ig/images/min_blue.gif);}a.minbox:hover {background-image:url(/ig/images/min_blue_highlight.gif);}a.maxbox {background-image:url(/ig/images/max_blue.gif);}a.maxbox:hover {background-image:url(/ig/images/max_blue_highlight.gif);}.f_tbl {font-size:12px;margin-right:2px;margin-left:2px;padding-top:4px;padding-bottom:4px;}.fr_tbl {margin-right:2px;margin-left:2px;padding-top:4px;padding-bottom:4px;}.fb {font-size:12px;padding:2px;padding-top:4px;border: 1px solid #d1d3d4;border-top:none;overflow:auto;}.sftl {border: 1px solid #d1d3d4;border-bottom:none;}.sftl_reverse_directionality {border: 1px solid #d1d3d4;border-bottom:none;clear: right;text-align: right;}.uftl {border:1px solid white;border-bottom:none;}.uftl_reverse_directionality {border:1px solid white;border-bottom:none;clear: right;text-align: right;}.remote_module_textbox {box-sizing:border-box;-moz-box-sizing:border-box;padding:1px;padding-left:4px;margin:2px;margin-left:3px;width: 95%;}* html .remote_module_textbox {width: 91%;}.remote_module_select {box-sizing:border-box;-moz-box-sizing:border-box;padding:0px;width:95%;margin:2px;margin-left:3px;}</style><link rel="stylesheet" type="text/css" href="/ig/f/hDk4Fm4iv7I/ig.css"/><style></style><style>#gbar{float:left;height:22px}
#gbarl{border-top:1px solid #c9d7f1;font-size:0;height:1px;position:absolute;right:0;top:24px;width:110%}
#gbar a{color:#00c}
#gbar .gbard{background:#fff;border:1px solid;border-color:#c9d7f1 #36c #36c #a2bae7;display:none;font-size:13px;position:absolute;top:24px;z-index:1000}
#gbar .gbard a{display:block;padding:.2em .5em;text-decoration:none;white-space:nowrap}
#gbar .gbard a:hover{background:#36c;color:#fff}
#gbar td{font-size:13px;padding-right:1em}
#guser{font-size:13px;padding-bottom:7px !important;padding-top:0}
#gbarc{font-size:0;height:1px}
#guser,#gbarc{background-color:#fff}#guser{color:#000;margin-bottom:0px}#guser a:link,#guser a:visited,#guser a:hover{color:#00c}#gbarl{border-top:0;border-bottom:1px solid #c9d7f1}#guser{padding-right:10px ! important;}</style>
<script>window.gbar={};(function(){function o(a,b,c){var e="on"+b;if(a.addEventListener){a.addEventListener(b,c,false)}else if(a.attachEvent){a.attachEvent(e,c)}else{var d=a[e];a[e]=function(){var f=d.apply(this,arguments),g=c.apply(this,arguments);return f==undefined?g:(g==undefined?f:g&&f)}}};var h=window.gbar,m=["affdom","channel","client","hl","hs","ie","lr","ned","oe","og","rls","rlz"];function i(a){return escape(unescape(a.replace(/\+/g," "))).replace(/\+/g,"%2B")}function j(a){return a=="c"||a=="o"||a=="m"}h.getHtml=function(a){var b;for(var c=0;c<a.length;c++){if(a[c][2]==""){b=a[c][0]}}var e=j(b)?" target=_blank":"",d="<td nowrap>",f="<table border=0 cellpadding=0 cellspacing=0 style=margin-left:"+h.getPad(true)+"px><tr>"+d;for(var c=0;c<a.length;c++){if(a[c][0]==b){f+=a[c][1].bold()+d}else{f+="<a href=";if(a[c][3]==3){f+='# onclick="this.blur();return gbar.toggle(event)" style=text-decoration:none'+e+"><u>"+a[c][1]+"</u> <span style=font-size:11px>▼</span></a><tr><td colspan="+c+"><td><iframe class=gbard id=gbarif style=border:0;z-index:999></iframe><div class=gbard id=gbardd onclick=gbar.stopB(event)>";d=""}else{f+=n(b,a[c][0],a[c][2])+e+" onclick=gbar.close(event)>"+a[c][1]+"</a>"+d}}}f+="</div></table>";return f};h.getPad=function(a){var b=-1,c=a?10:4,e=document.body.currentStyle,d=document.defaultView;if(e){b=a?e.marginLeft:e.marginTop}else if(d){b=a?d.getComputedStyle(document.body,"").marginLeft:d.getComputedStyle(document.body,"").marginTop}b=parseInt(b,10);return b>=0&&b<c?c-b:1};function n(a,b,c){var e=window.location.search.substring(1),d=e.match("q=([^&]*)"),f=e.match("near=([^&]*)"),g=c+(c.match("[?]")?"&":"?");g+="tab="+a+b;if(j(b)&&window.location.protocol=="https:"){g=g.replace("http:","https:")}if(!j(b)&&!j(a)){for(var k=0;k<m.length;k++){var l=e.match("("+m[k]+")=([^&]*)");if(l){g+="&"+l[1]+"="+i(l[2])}}if(d&&f&&a=="l"&&b!="l"){g+="&q="+i(d[1])+"+"+i(f[0])}else if(d){g+="&q="+i(d[1])}}return g}h.toggle=function(a){h.stopB(a);var b=document.getElementById("gbardd"),c=document.getElementById("gbarif");if(b&&c){b.style.display=b.style.display=="block"?"none":"block";c.width=b.offsetWidth;c.height=b.offsetHeight;c.style.display=b.style.display}return false};h.close=function(a){var b=document.getElementById("gbardd");if(b&&b.style.display=="block"){h.toggle(a)}};h.stopB=function(a){if(!a){a=window.event}a.cancelBubble=true};o(document,"click",h.close);})();</script>
</head>
Oct 07

Greasemonkey script to expand Facebook Leftbar

Facebook, Tech 1 Comment »

For some reason it has always bugged me to only have a few applications show in the left bar, with the “more >>” link that you have to hover/click on to get the full list.

So, I wrote the simplest of Greasemonkey scripts to automatically expand the more link whenever I go to a Facebook page.

Now I have all of my gems (Pet Monkeys and co…) in plain sight. I am glad I am doing the important things while I wait for my flight from London back home to the US. Yup, “back home” to the US :)

facebookexpandedmore.png

Oct 05

The relationship between the platform vendor and the third party developers: Google, Facebook, Apple, Microsoft

Facebook, Tech 1 Comment »

At the end of Dave Morin’s Facebook talk at he kindly did the usual, and accepted questions from the audience. For all of the other talks that I participated in, the questions were fired off by fellow developers and were generally technical.

This time around, it was time for the reporters. They popped out of nowhere to ask the usual silly questions that you KNOW the guy can’t answer. I get them all the time for Google. “When is the Google Deathstar coming out”. What are they thinking? Do they think that I will slip and think “hmm, I guess we released the Deathstar so I can start talking about it up on stage here!”

Anyway, one of the rants hidden in a question was about how the platform competes with third party applications. It is as though it is so novel that Facebook has some apps and features like the Wall, Videos, Photos, …. and that they may overlap with applications that others have developed. This is not new guys:

  • Microsoft: They are ruthless right? They keep expanding out with applications on Windows. From MS Paint to an office suite to a TCP/IP stack to a Media Player to a web browser … fast forward … anti-virus and firewall software.
  • Apple: iLife + iWork. How dare they.
  • Google: Various Google Gadgets (e.g. gmail viewer)
  • Facebook: As said, a better Wall. Friend grouping. Videos. Photos.

So, everyone does it. I think the key points from the platform vendors side are:

  1. Make your applications true showcases. Apple sets the standard on its platform, and developers often compare their work to these showcases. If you are going to do apps on your own platform, make they ridiculously good
  2. Share knowledge on how you produce your fantastic applications
  3. Be transparent. I love how the Google Gears team was allowed to follow their vision on getting the code out when it was a baby. You could imagine that some of the Google teams, that could maybe be interested in taking their apps offline, would like to have worked on a private Gears platform…. and only announce it when all of the apps are ready. Instead we did the opposite, and the side effect is that Zoho has an opportunity to be the first online word processor to work offline wth Gears (not Google Docs). This is actually a good thing for Google Gears itself, as it isn’t meant to be about Google. We wanted to make sure there was a level playing field.
  4. Try to be good to the community by letting people know when you stomp on them. Microsoft at least told Norton and co. that they were getting into the security business natively. This allows your developers to choose whether to directly compete, or head off to a niche

The “niche” is key. You KNOW that Facebook is going to make its profile page better, which will include a better wall (sorry SuperWall) or better friend grouping (sorry TopFriends). As a third party developer you know the risk.

If you go into something generic, and it becomes popular, expect the platform vendor to do something in that space.

If you go into something niche, then you are probably safer. If you make a killer application for lawyers, then you will probably be safe.

If you decide that you want to target everyone and build a generic app, you just have to know that either:

  • a) If successful you will get competition from others, potentially including the platform
  • b) At least have a bit of time to make money on top

In general, make a product rather than a feature.

But wait, isn’t Facebook a little different? The virality model is such that the big guys like RockMe have an advantage in that they can watch out for anything popular, and quickly jump in and use their overall platform to promote their quickly-hacked-up solution.

You come up with the next cool mini-app, and then they clone it and advertise the hell out of their clone on their most popular applications.

That is life. It isn’t new. Big players are able to do that on the other platforms too.

Again, you have to assume competition and use your unique assets to counter it… or sell out to the big guy! :)

Oct 04

Identity Matcher: Import social graphes

Facebook, Ruby, Tech No Comments »

My favourite talk at the FOWA was Matt Biddulph talking about his experience with Dopplr which is a fantastic little service (and I was shown today that the colors change EVEN on the favicon.ico when you are in a different location!!!).

Matt’s talk was high level, but he managed to keep it interesting and it wasn’t about pimping Dopplr.

He also released identity matcher, a new open source project that allows you to import social graphs! Now we can all work together on this instead of reinventing the wheel:

This code, extracted from the Rails codebase of dopplr.com, extends your User model with methods to pull in social network information from sites such as GMail, Twitter, Flickr, Facebook and any site supporting appropriate Microformats.

This is an alpha-quality plugin. It was extracted from our codebase at the start of October 2007 and may still contain dopplr-specific code (although we tried to avoid that).

The code is just one file with a few includes and you can now matches_identities in your Rails model. Of course, you can abstract out the Rails stuff and just have a library to do the matching. Very nice indeed.

Now I just want the option to say “if someone shares their stuff with me on Dopplr, and they are friends with me via another service (e.g. Facebook, Twitter) just go ahead and share back automatically!”

.

Sep 30

Facebook: “In the works”

Facebook, Tech No Comments »

Being able to talk about what you are working on is a good thing. Sometimes the whole “we don’t pre-announce” world that big companies can get involved in is a real pain.

It is great to see In the works as a section of “What’s New” at Facebook:

Sort out your friends.

We

Sep 26

FriendVox Facebook IM != Face ‘IM

Facebook, Tech 7 Comments »

I got excited when I saw a snippet in my RSS reader that said Facebook IM client coming soon!.

When I dug into it, I quickly found that they were talking about FriendVox which is literally an IM. Who knows if these screenshots are accurate:

As soon as I saw this I said …. NOOOOOOOOOOOOOO. The point isn’t to do yet another IM client. The point to Face IM is to do much more. I don’t need another application that lists the name of various friends giving me no useful information. The point is to have a client that gives me more about my social graph, and if done well, I wouldn’t even have a browser open to Facebook that I have to reload to see if anything is new.

Sep 25

Facebook really does remember you now?

Facebook, Tech No Comments »

It appears that Facebook really does remember you, and doesn’t kick you out if you log-on from another computer, which was a source of frustration!

It is nice to see some of the items from my list get knocked out.

facebookrememberme.png

Aug 28

Face ‘IM: The social graph outside

Facebook, Tech No Comments »

I keep waiting for Facebook, or someone else, to announce “Face IM”, an IM client that uses the social graph that I have already setup in Facebook to manage my IM life.

Another IM system???? Well, they wouldn’t have to run their own service, but could play the meta-role a la Adium/Trillian and use the IM names that the users have already put in. This would all be hidden from the users though, they would just start chatting to their friends. At some point it may make sense to setup Jabber so users without IM settings can play too.

Just as Gmail changed the way I use my email system (now I am not anal about filters and directories….) Face IM could do something different with IM.

I currently have IM taking up part of my screen, on one of my virtual desktops. All that is shown there is a list of people. Who cares? Instead of showing that list, what if the application looked like Joe’s iPhone application?

A nice clean interface to my event stream as well as my friends. I would probably use that over a tab in my browser. I would give up the view of a bunch of friends names, and instead have rich information as well as the spring board to IM.

Of course, just like Gmail, you could tie in the IM system to the Facebook Mail system too, and they could even get all Meebo-y if they wanted.

I am more interested in taking the social graph outside of Facebook.com. The platform is about more than the walled garden, and showing this via Face IM would be great.