zomgistania

Main page | About | Articles | Previous Posts | Archives

Friday, August 04, 2006

Implementing automatic version checking in an Opera Widget

Updated August 18th, fixed an issue with the source code which causes a lockup if you're not connected to the internet when the update check runs


As I've been working on my Opera widget World Clocks, I've done a bunch of version updates with new features and such. Of course people might not come back to the download page to check if there's anything new, so it would be useful to be able to tell them automatically when you have a new version available.


So I went and added an automatic new version check, and now I'll tell you how to create one as well.


Preparing the widget

Okay, for the Widget to know when there's a new version you need something to compare. What's better than having a variable store the version of the widget?

var widgetVersion = "1.0";


And what do we compare that with? Let's save a file somewhere on the internet, with the current version of the Widget. For example, I put the current version of my clock widget to here. As you can see, it's just a number.

To allow our widget to access a page in the internet, we must add this to the config.xml file:


<security>
<access>
<protocol>http</protocol>
<host>admins.fi</host>
</access>
</security>

For example, my file is at http://admins.fi/~eagleeye/clockversion.txt, so I set the protocol as http and host to admins.fi.


Creating the update checker

To access that page, we will use the XMLHttpRequest object. For the sake of reusability, let's make our object a bit better than just some code accessing a static page... let's make it reusable in other projects as well!


//parameters:
//vurl: the url where the file to compare is
//cver: current version of the widget
//callback: the function to call when a new version is out
function UpdateChecker(vurl,cver,callback)
{
var checkUrl = vurl;
var currentVersion = cver;
call = callback;

//this function checks for the update
this.Check = function()
{
var req = new XMLHttpRequest();
req.onreadystatechange = function()
{
if(req.readyState == 4)
{
//simply compare the page to the version number
if(req.responseText != currentVersion)
call();
}
}
req.overrideMimeType('text/plain');

//the random part is used to bypass Operas caching.
//sometimes the page stays in cache and wont be updater properly
req.open('GET',checkUrl+'?random='+Math.random(), true);

try
{
req.send(null);
}
catch (e)
{
//problem connecting
}
}
}


it's a very simple XMLHttpRequest function there. To use it, we could do...



function Init()
{
var updater = new UpdateChecker('http://site.com/ver.txt','2.0',newVersion);
updater.Check();
}

function newVersion()
{
//put some code here
//which tells the user
//that a new version is out
}



Simple as that. I'm not going to go into details about using XMLHttpRequest here, there's a very good article at http://developer.mozilla.org/en/docs/AJAX:Getting_Started

5 Comments:

  • I always wanted to do something like this! Thank you for the explanation.

    By Anonymous Icheb, at 9:28 PM  

  • hehehe,

    Interesting but it's not good enough! (lol)

    //put some code here
    //which tells the user
    //that a new version is out

    You could make it so that it downloads the update. (would have to code it differntly)

    If you just want version notification.

    <a href="widget home"><img src"http://yourserver.com/images/widgetstatus-v1.jpg"></a>

    The widgetstatus-v1.jpg is a transparant gif 1x1 px, change the gif for a larget one with "a new version is available".

    The only problem is that it could take a lot of images if you make 200 version opdates. :D

    httpqeuests can do much more as that. But I'm not sure what the advantage would be.

    good luck :)

    By Blogger Gaby de Wilde, at 3:53 PM  

  • Your image notification method is pretty intresting.

    How would you make the widget download itself? I think you'd have to do something like window.open(urltowidget), which is a bit sneaky imo and the user would still have to close the old widget.

    By Blogger Jani, at 4:57 PM  

  • I think it could ajax some of the new features into the widget html and save it into a cookie. Would have to write it a bit different.

    By Blogger Gaby de Wilde, at 6:09 PM  

  • Now that I think of it, it could be possible in the following way:


    Save the main widget code from the widget to a preference using widget.setPreferenceForKey.

    The widget code would be loaded from here.

    Now, the updater code would obviously be separate from the preference, so when it would find a new version, it could download the new code and save it to the preference.


    I think this method might be workable. Other than that, the iframe-method where all the widget code is on a remote server, but then it wouldn't work offline, which it should.

    By Blogger Jani, at 1:35 AM  

Post a Comment

<< Home