07 November 2011

Is Spotify evil?

I was using Spotify for a while, the premium version, to get the mobile goodies and I rather liked it...

A while back I saw that they did some joined (joint?..) thing with Facebook and it didn't look really interesting to me as an end user but it did look as a major move in the industry and as a professional, it did catch my attention, at least for a little while.

The other day I got some upgrade and suddenly I couldn't log in. Being used to playing around with Facebook integration of things, I accepted my faith and assumed I just (as always) forgot to read what i agreed to when accepting some licence agreement or whatever. Being a good sport, I clicked what they asked me to do and got into my account, seemingly unharmed by the speed bump some programmer put in my way.

Another few days passed, including some speed bumps and requirement to log in after being idle for a day or two.  Then, suddenly, I got into my account, but my playlists were gone along with favorites etc.
Again, being a good sport and fellow programmer, I just assumed they used the same QA team Skype used last year and tried to find if I did something wrong, or just different for that matter.

After some playing around, sometimes being successful, I finally isolated it..

When I use the same username but with different passwords, I get into my Facebook connected account, or my initial (paid) account. The Facebook one being the empty one and the paid one being the one holding my playlists etc that I actually spent some time setting up.

Obviously, my inconvenience is not the major point here. The fact that Spotify store and use my data in a manner that allows my password to control whether I get into one account or the other, just because they have the same user name is *major understatement ahead* outrageous.

I'm left with one thought: are they evil? or just vastly incompetent?

29 September 2011

How to make sure FB.init is properly finished

When working with the Facebook api, there likely comes a time when you will need to know that FB.init has finished successfully and you can run your scripts to create a wonderful user experience.

Looking into this, it turns out that parts of FB.init runs asynchronously even when using the sync version suggested in the API. This obviously means that you simply cannot trust that your script will work just because you called it after the init call.

To work around this until the Facebook people fix the issue or provide a reliable event or callback, many have suggested various solutions based on timers. A more solid approach can be built around the FB api itself:



Loading FB API asynchronously:


 <script type="text/javascript">
     window.fbAsyncInit = function() {
         /**
          * Workaround for FB.init not being synchronous nor providing a callback method.
          */

         FB.init({
             appId : 'YOUR_APP_ID_HERE',
             cookie : true,
             status : true,
             xfbml : true,
             oauth : true
         });
         FB.getLoginStatus(function(oResponse) {
             if (oResponse.status === 'connected') {
                 // the session is complete, and fully initiated,
                 // go ahead and call your scripts here

             } else {
                 // There was a problem, probably because the user was not logged in,
                 // so put a login sequence or your error handling of choice here

             }
         });
     };
     (function() {
         var e = document.createElement('script');
         e.async = true;
         e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
         document.getElementsByTagName('head')[0].appendChild(e);
     }());
 </script>

Loading FB API synchronously:


 <script src="http://connect.facebook.net/en_US/all.js" type="text/javascript"></script>
 <script type="text/javascript">
     /**
      * Workaround for FB.init not being synchronous nor providing a callback method.
      */

     FB.init({
         appId : 'YOUR_APP_ID_HERE',
         cookie : true,
         status : true,
         xfbml : true,
         oauth : true
     });
     FB.getLoginStatus(function(oResponse) {
         if (oResponse.status === 'connected') {
             // the session is complete, and fully initiated,
             // go ahead and call your scripts here

         } else {
             // There was a problem, probably because the user was not logged in,
             // so put a login sequence or your error handling of choice here

         }
     });
 </script>  



14 March 2011

Kinetic scrolling for WebKit on touch devices

When creating a web app for a touch device, one thing that can cause some headache is trying to get the right "App-feeling" with a nice header that stays in place, and maybe even a footer. Since position:fixed is not supported (at least on iPhone Safari) and scrolling inline content is done using the little known 2-finger scroll (which is also without any nice feel to it whatsoever) there is basically 2 options; to implement a header and footer that moves into place when scrolling (like those annoying ads), or to implement scrolling of the "mid-part".

I spent some time on trying to find a good, free sample on how to do the later without success(but I'm sure they are out there). This weekend I got some time to play around so I thought I'd try to implement that sweet scrolling that you get inside an app on the iPhone(or the Android for that matter). A bunch of hours and quite a few curses later I came up with something that works pretty well :)

You can try it out here:
http://webkitjs.org/ScrollElement/

And here's the source code:


Although this is only tested on a Galaxy S running Froyo, it should work well on Safari on iOS (iPad, iPod, iPhone) and most Android touch phones running a fairly recent version. Oh, I tested it on Chrome and Safari on PC and Mac with decent results as well.

Feel free to use and abuse it as you please. Speaking of which, I'm not sure whether to bother putting some really open licensing in there just to clarify. Input on this would be much appreciated ;)