<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description></description><title>Prettybrd Notes</title><generator>Tumblr (3.0; @prettybrd)</generator><link>http://blog.prettybrd.com/</link><item><title>Yes!</title><description>&lt;img src="http://29.media.tumblr.com/tumblr_lgevo2ZTzC1qcwqtbo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Yes!&lt;/p&gt;</description><link>http://blog.prettybrd.com/post/3217876036</link><guid>http://blog.prettybrd.com/post/3217876036</guid><pubDate>Thu, 10 Feb 2011 12:09:38 -0500</pubDate></item><item><title>Whoa! Alice on the Kindle 3</title><description>&lt;img src="http://25.media.tumblr.com/tumblr_l8v3x35dsS1qcwqtbo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Whoa! &lt;a href="http://www.usealice.org"&gt;Alice&lt;/a&gt; on the Kindle 3&lt;/p&gt;</description><link>http://blog.prettybrd.com/post/1134181324</link><guid>http://blog.prettybrd.com/post/1134181324</guid><pubDate>Thu, 16 Sep 2010 19:00:39 -0400</pubDate></item><item><title>Creating desktop notifications from your web app</title><description>&lt;p&gt;There are a number of applications that can be used to turn a web application into a standalone desktop application. These applications are commonly referred to as Site Specific Browsers, or &lt;strong&gt;SSB&lt;/strong&gt;s. The best way to generate an SSB is with Fluid (for Mac OS X) or Chrome (for Linux and Windows.)&lt;/p&gt;
&lt;p&gt;People often create SSBs for sites that they keep open all day and don’t want hidden in one of their browser tabs (e.g. Gmail.) By isolating the website in its own application you no longer have to worry about browser crashes or accidentally closing a tab.&lt;/p&gt;
&lt;p&gt;Beyond stability, there is another advantage to putting your web application in an SSB. Some SSBs provide special javascript APIs that let your web application integrate more closely with the desktop; blurring the line even more between web and desktop application. The most interesting of these new features is notifications.&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Notifications from a Fluid app&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;&lt;img src="http://prettybrd.com/~leedo/b/growl.png" alt="a Fluid based Growl notification" width="322" height="88"/&gt;&lt;br/&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Using notifications in a Fluid generated application is very simple. Fluid provides a new &lt;em&gt;window.fluid&lt;/em&gt; object. This new object gives us access to Growl, dock badges, and even dock menu items. To emit a notification, simply test for the existence of the &lt;em&gt;window.fluid&lt;/em&gt; object, and then use the &lt;em&gt;showGrowlNotification&lt;/em&gt; method.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function notify (title, body, id) {
  if (window.fluid) {
    window.fluid.showGrowlNotification({
      title: title,
      description: body,
      priority: 1,
      sticky: false,
      identifier: id
    });
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above javascript will show a temporary Growl notification (note: the msgid variable needs to be set to some unique identifier.) Beyond Growl notifications, we can also add a dock badge counter to the application’s icon.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://prettybrd.com/~leedo/b/badge.png" alt="a dock badge in Fluid" width="433" height="225"/&gt;&lt;/p&gt;
&lt;p&gt;This is done through the &lt;em&gt;window.fluid.dockBadge&lt;/em&gt; property. There are a few quirks with the Fluid dock badge methods, so look closely.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function increaseBadgeCount () {
  if (!window.fluid) return;
  window.fluid.dockBadge ? window.fluid.dockBadge++
                         : window.fluid.dockBadge = 1;
}

function clearDockBadge () {
  if (!window.fluid) return;
  window.fluid.dockBadge = "";
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The Fluid dock badge strangeness comes into play when trying to remove the dock badge from the icon. We can’t just set &lt;em&gt;window.fluid.dockBadge&lt;/em&gt; to 0, because then it will show a “0” in the badge. If we set it to &lt;em&gt;undefined&lt;/em&gt; or &lt;em&gt;null&lt;/em&gt; it will display &lt;em&gt;NaN&lt;/em&gt; (Not a Number.) The only way to remove the dock badge is to set it to “”. Because a blank dock badge is set to “”, we can’t simply do a &lt;em&gt;window.fluid.dockBadge++&lt;/em&gt; when we want to increase it.&lt;/p&gt;
&lt;p&gt;Check out the &lt;a href="http://fluidapp.com/developer/"&gt;Fluid developer page&lt;/a&gt; to find out more about the Fluid API.&lt;/p&gt;
&lt;h2&gt;&lt;strong&gt;Notifications in Chrome&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;As you can see, the Fluid API is not fully thought out and can be inconsistent at times. Luckily, the Chrome notification API is much more sane. Another nice thing about Chrome’s API is that it is also available from the regular Chrome browser, not just Chrome generated SSBs.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://prettybrd.com/~leedo/b/chrome.png" alt="a Chrome notification" width="326" height="120"/&gt;&lt;/p&gt;
&lt;p&gt;Because Chrome’s notifications are not limited to SSBs, you must request permission before displaying anything. This makes things somewhat more complicated, but not terribly so. Lets add Chrome support to the &lt;span&gt;notify&lt;/span&gt; function from above:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function notify (title, body, id) {
    if (window.fluid) {
      window.fluid.showGrowlNotification({
        title: title,
        description: body,
        priority: 1, 
        sticky: false,
        identifier: id
      }); 
    }   
    else if (window.webkitNotifications) {
      if (window.webkitNotifications.checkPermission() == 0) {
        var popup = window.webkitNotifications.createNotification(
          "http://www.yoursite.com/an_icon.png",
          title,
          body
        );
    
        popup.ondisplay = function() {
          setTimeout(function () {popup.cancel();}, 3000);
        };
  
        popup.show();
      }
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here we have extended our &lt;em&gt;notify&lt;/em&gt; function to work on both Chrome and Fluid. Now we test for &lt;em&gt;window.webkitNotifications&lt;/em&gt; to see if Chrome’s notifications are available. Then we check if we have permission to display notifications with the &lt;em&gt;checkPermission&lt;/em&gt; method. This method will return 0 if we have permission (which seems backwards to me.) Finally, once we know we have permission we can use the &lt;em&gt;createNotification&lt;/em&gt; method. This is somewhat different from Fluid’s notification method in that it takes an image URL, and does not require an ID.&lt;/p&gt;
&lt;p&gt;One annoyance with Chrome’s notifications is that they don’t automatically disappear. We use the returned popup object to hide the notification on our own. This is done above by creating a 3 second timeout inside the popup’s &lt;em&gt;ondisplay&lt;/em&gt; event. If we don’t set this up in the &lt;em&gt;ondisplay&lt;/em&gt; event the timing will be off, since it takes a few seconds for the popup to appear.&lt;/p&gt;
&lt;p&gt;You may be wondering how we actually get permission to show a notification in Chrome. We request permission with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;window.webkitNotifications.requestPermission()&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;However, we can’t just use this method at any time. In my few experiments it only works inside a click event, though I suspect it will also work in a load event.&lt;/p&gt;
&lt;p&gt;Check the &lt;a href="http://dev.w3.org/2006/webapi/WebNotifications/publish/"&gt;Web Notifications spec&lt;/a&gt; to learn more about notifications in Chrome.&lt;/p&gt;</description><link>http://blog.prettybrd.com/post/969679648</link><guid>http://blog.prettybrd.com/post/969679648</guid><pubDate>Tue, 17 Aug 2010 21:57:00 -0400</pubDate></item></channel></rss>

