Thursday, March 28, 2024

Site Pinning: Rotating Overlay Icons for Multiple Service Notifications

By Rey Bango

Site Pinning provides a unique way to build engagement from your users through out-of-browser notifications.  Previously, I went over how to use IE9′s Site Pinning API to implement overlay icons to enhance user notifications. The demo focused on how to display a numeric icon to indicate when a specific event (e.g.: messages in an inbox) had occurred.

Pinned site with overlay icon

It’s a really great way of letting your users know that there’s pending information for them to check into. But what happens if your site offers multiple types of notifications? With websites offering so much functionality nowadays, it’s pretty common for them to also serve up multiple types of notifications, from friend requests and event reminders to new messages and game invites.

 

Rotating Multiple Overlays Icons

The great thing about the Site Pinning API is that it’s very flexible and through some JavaScript magic, you can easily display multiple overlay icons for the various services you have. In this demo, I want to rotate through 3 different overlay icons that alert the user to pending messages, requests and actions.

As before, I had to flex some of my artistic talent by creating the overlay icons using the x-icon editor. I created 5 of each and here’s how the first three look:

The code changed slightly from the last demo in order to accommodate multiple bits of data per fetch. While previously, I was only fetching one piece of data, in this demo, I’m returning 3, one for each notification type:

myPin.init([{ "data" : [{ "label" : "Messages", "ntype" : "M", "num": 2 }, { "label" : "Requests", "ntype" : "R", "num": 1 }, { "label" : "Actions", "ntype" : "A", "num": 3 }] },

{ "data" : [{ "label" : "Messages", "ntype" : "M", "num": 1 }, { "label" : "Requests", "ntype" : "R", "num": 5 }, { "label" : "Actions", "ntype" : "A", "num": 2 }] },

{ "data" : [{ "label" : "Messages", "ntype" : "M", "num": 5 }, { "label" : "Requests", "ntype" : "R", "num": 1 }, { "label" : "Actions", "ntype" : "A", "num": 4 }] }

]);

As a reminder, the method getData() simulates grabbing remote data. So if we look at the data above, we can simulate pulling back three distinct bits of data. This is why we call the method every 10 seconds using setInterval. This allows us to see how notifications might look over a period of time.

setInterval(function () { myPin.getData() }, 10000);

The next thing that changed is the use of a timer to allow a slight delay while rendering the overlay icons. Using setTimeout() provides enough of delay so that an individual overlay icon is visible to the user before rotating on to the next icon. If we didn’t have this delay, the rotation would be way too fast to provide any useful notification. If we look at the following image, we can see what the notification will look like:

Overlay icon showing numeric notification

This is accomplished via the following code:

// Grab the current set of data...

currData = this.dataBin[this.currIndex++].data;

/* We're going to display a new overlay every x number of seconds to display a new overlay icon so

let's loop through the data elements for the current set of data... */

for (var i=0; i < currData.length; i++ ){

(function(idx) { setTimeout( function(){ myPin.dispOverlay( currData[idx] ); }, 1000 * idx); }( i ));

}

Here’s what’s happening. In the first line, I grab the current set of data that holds all of the notification information (messages, requests & actions). That data looks like this:

[{ "label" : "Messages", "ntype" : "M", "num": 2 },

{ "label" : "Requests", "ntype" : "R", "num": 1 },

{ "label" : "Actions", "ntype" : "A", "num": 3 }]

I loop through each group of data and assign a timer using setTimeout() that will call dispOverlay() at ~1 second intervals. That’s the magic code that allows for the gradual icon rendering delay I mentioned before. The expected functionality is that the “messages” icon will render followed by the “requests” icon 1 second later, and then finally the “actions” icon.

Now, you might be wondering why I have an anonymous function wrapping the setTimeout(). It’s because I have a closure within setTimeout which can cause a common scoping issue in which the variable ‘i’, which I use to grab the current index of data, will only be updated to the last index value. James Padolsey has a great explanation on it and thanks to John David Dalton for helping me troubleshoot this.

The final change is in dispOverlay() in which I need to determine which overlay icon needs to display. Since I now have three different types of notifications, I need a conditional statement to determine the type and build the correct icon name:

if (theData.ntype == "M") {

oImg = "images/messages-" + theData.num + ".ico";

} else if (theData.ntype == "R") {

oImg = "images/requests-" + theData.num + ".ico";

} else if (theData.ntype == "A") {

oImg = "images/actions-" + theData.num + ".ico";

}

This checks the type and serves up the right icon based on the type and the number of notifications pending for that type.

 

The Demo and Final Code

You can check out the demo by going here in IE9:

My newest adventure is joining Microsoft to help promote client-side development using JavaScript, CSS & HTML. Yep you heard right! Microsoft is definitely interested in this space and I’m going to help push information out to developers. I’m extremely excited about working for one of the most influential technology companies in the world.

Evangelism is one of my main strengths and when I’m passionate about something, you’ll know. But by the same token, I’m objective enough (in most cases) to listen & explore other possibilities. It’s an ability that’s allowed me to create some amazing relationships with very smart people who many times don’t see eye to eye with the things that I support but we respect each other nonetheless.

 

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Popular Articles

Featured