Created
November 30, 2014 15:41
-
-
Save boxmein/6f952583102f8307a241 to your computer and use it in GitHub Desktop.
userscript that displays web notifications for new conversations (almost) live
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==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