Skip to content

Instantly share code, notes, and snippets.

@boxmein
Created November 30, 2014 15:41
Show Gist options
  • Save boxmein/6f952583102f8307a241 to your computer and use it in GitHub Desktop.
Save boxmein/6f952583102f8307a241 to your computer and use it in GitHub Desktop.
userscript that displays web notifications for new conversations (almost) live
// ==UserScript==
// @name New Conversation Notifier (Beta!)
// @version 1.0.0
// @description Notifies you about new conversations live on powdertoy.co.uk
// @author boxmein
// @match *://powdertoy.co.uk/*
// ==/UserScript==
/*
1.0.0 : Sun Nov 30 2014 17:39:06 GMT+0200 (FLE Standard Time)
*/
(function() {
'use strict';
function contentEval(source) {
// We want web notification permissions!
Notification.requestPermission(function (status) {
// This allows to use Notification.permission with Chrome/Safari
if (Notification.permission !== status) {
Notification.permission = status;
}
});
// Check for function input.
if ('function' == typeof source) {
// Execute this function with no arguments, by adding parentheses.
// One set around the function, required for valid syntax, and a
// second empty set calls the surrounded function.
source = '(' + source + ')();'
}
// Create a script node holding this source code.
var script = document.createElement('script');
script.setAttribute("type", "application/javascript");
script.textContent = source;
// Insert the script node into the page, so it will run, and immediately
// remove it to clean up.
document.body.appendChild(script);
document.body.removeChild(script);
}
contentEval(function() {
// 5 minutes
var DELAY = 1000 * 60 * 5;
// Parse the unread conversation's DOM element.
// Fetch the actual message while at it.
function parseNotificationElement(d) {
var deferred = new $.Deferred();
var subjectLink = d.querySelector('.Subject');
var metadata = d.querySelector('.Meta');
var convid = subjectLink.href.match(/[0-9]+$/)[0];
var endobj = {
'subject': subjectLink.innerText,
'convid': convid,
'author': metadata.querySelector('.LastUsername').innerText,
'date': metadata.querySelector('.LastDate').innerText
};
$.ajax('/Conversations/View.json?ConvID='+convid,{
'dataType': 'html'
}).done(function(data){
var div = document.createElement('div');
div.innerHTML = data;
var post = div.querySelector('.MessageList .Post');
endobj.avatar = post.querySelector('.gravatar-inner img').src;
endobj.message = post.querySelector('.Message').innerText;
deferred.resolve(endobj);
}).fail(deferred.reject);
return deferred;
}
// Display a notification if the user is not logged in.
function userNotLoggedIn(msg) {
if (Notification.permission == 'granted') {
var n = new Notification("You seem to not be logged in!", {
body: msg
});
}
else {
alert('You seem to not be logged in!\n' + msg);
}
}
// Get unread messages from /Conversations.json's partial HTML
function getUnreads() {
$.ajax('/Conversations.json',{
'dataType': 'html'
}).done(function(data) {
var d = document.createElement('div');
d.innerHTML = data;
if (d.querySelector('.Warning.alert'))
userNotLoggedIn(d.querySelector('.Warning.alert').innerText);
var ds = d.getElementsByClassName('ConUnread');
if (ds.length > 1) {
// display a list notification
ds = ds.map(parseNotificationElement);
displayListNotification(ds);
}
else if (ds.length == 1)
parseNotificationElement(ds[0])
.done(displayNotification);
else return;
}).fail(function() {
console.error('failed to check for unread messages', arguments);
});
}
// Display a web notification with the unread message
function displayNotification(data) {
if (Notification.permission == 'granted') {
// Use web notifications API
var n = new Notification("New Conversation: " + data.subject, {
body: data.message,
icon: data.avatar
});
// yay click events!
n.onclick = function() {
window.location = '/Conversations/View.html?ConvID='+data.convid;
};
}
else {
if (confirm('New Conversation: ' + data.subject + ', click Confirm to view')){
window.location = '/Conversations/View.html?ConvID='+data.convid;
}
}
}
// Display a notification for a bunch of new conversations at once.
function displayListNotification(datas) {
var messages = datas.reduce(function(acc, each) {
return acc + '\n' + each.message;
}, "");
if (Notification.permission == 'granted') {
var n = new Notification('New Conversations (' + datas.length + ')', {
'body': messages
});
} else {
alert('New Conversations ('+datas.length+')\n'+messages);
}
}
// Check for messages right at the start, and then forever onward, 5 minutes
// at a time.
(function tick() {
getUnreads();
setTimeout(tick, DELAY);
})();
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment