Last active
June 9, 2020 09:03
-
-
Save haukex/33da4e0d4f3c7a1e2be8d1cffe75dc76 to your computer and use it in GitHub Desktop.
PerlMonks Browser Notifications for New Nodes
This file contains 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
"use strict"; | |
// Documented at: https://www.perlmonks.org/?node_id=11116369 | |
$(function () { | |
var CB_FETCHTIME_MS = 15 * 1000; | |
var GERNERAL_REFRESHTIME_MS = 60 * 1000; | |
// AJAX CB Refresh | |
var refresh = function () { | |
$.ajax({ url: '/', dataType: 'html', | |
// testing shows the table rendered here is the same as in the nodelet | |
data: { node: 'showchatmessages', displaytype: 'raw', ticker: 'yes' } }) | |
.done(function (data) { | |
var source = $('<div/>').html(data).find('table.cb_table, .cb_quiet'); | |
$('#Chatterbox table.cb_table, #Chatterbox .cb_quiet').replaceWith(source); | |
$('#Chatterbox table.cb_table + br, #Chatterbox .cb_quiet + br').remove(); | |
$('#Chatterbox .cb_quiet').append('<br/>'); | |
}) | |
.fail(function (jqXHR, textStatus, errorThrown) { | |
console.warn("AJAX error: " + textStatus + " / " + jqXHR.status + " " + errorThrown); | |
}); | |
}; | |
// Refresh "Other Users" (followed by CB refresh!) | |
var refresh_all = function () { | |
$.ajax({ url: '/', dataType: 'html', | |
// testing shows the body rendered here is the same as in the nodelet | |
data: { node: 'showotherusers', displaytype: 'raw', ticker: 'yes' } }) | |
.done(function (data) { | |
// sadly, the <body> tag is not preserved, so we need to do some funky parsing here | |
var inSection = false; | |
var source = $.grep( $('<div/>').html(data).contents().toArray(), function (obj) { | |
if (inSection) { | |
if ( $(obj).is('.update-time') ) inSection = false; | |
return true; | |
} | |
else if ( $(obj).is('.other-users-text') ) | |
{ inSection = true; return true; } | |
return false; | |
}); | |
$('#Other_Users .nodelet_body').empty(); | |
$('#Other_Users .nodelet_body').append(source); | |
}) | |
.fail(function (jqXHR, textStatus, errorThrown) { | |
console.warn("AJAX error: " + textStatus + " / " + jqXHR.status + " " + errorThrown); | |
}) | |
.always(refresh); | |
}; | |
// AJAX Message Fetching | |
var notify_cb = $('<input/>', { type: 'checkbox' }); | |
var ajax_cb = $('<input/>', { type: 'checkbox', checked: !window["AJAXCB_DEFAULTOFF"] }); | |
var fetch_timer; | |
var fetchit; | |
var start_fetch = function () { | |
if ( ajax_cb[0].checked ) | |
fetch_timer = setTimeout(fetchit, CB_FETCHTIME_MS); | |
}; | |
var lastid; | |
fetchit = function () { | |
if (fetch_timer) clearTimeout(fetch_timer); | |
fetch_timer = null; | |
if ( !ajax_cb[0].checked ) return; | |
var query = { node_id: '207304', xmlstyle: 'modern', ticker: 'yes' }; | |
if ( lastid ) query['fromid'] = lastid; | |
$.ajax({ url: '/', dataType: 'xml', data: query }) | |
.done(function (data) { | |
var count = parseInt($("info", data).attr("count")); | |
if ( count>0 ) { | |
refresh(); | |
if ( notify_cb[0].checked ) { | |
var authors = {}; | |
$('message author', data).each(function () { authors[ $(this).text() ] = 1; }); | |
authors = Object.keys(authors).sort().join(", "); | |
var notification = new Notification('New PerlMonks Chatter', | |
{ body: count+" new messages by "+authors, | |
tag: "PerlMonksChatter", icon: "/favicon.ico", badge: "/favicon.ico" }); | |
} | |
} | |
var li = $("info", data).attr("lastid"); | |
if ( li ) lastid = li; | |
}) | |
.fail(function (jqXHR, textStatus, errorThrown) { | |
console.warn("AJAX error: " + textStatus + " / " + jqXHR.status + " " + errorThrown); | |
}) | |
.always(start_fetch); | |
}; | |
var all_refresh_timer; | |
if ( !window["AJAXCB_DEFAULTOFF"] ) { | |
start_fetch(); | |
all_refresh_timer = setInterval(refresh_all, GERNERAL_REFRESHTIME_MS); | |
} | |
// AJAX Form Submission | |
var form = $('#Chatterbox form'); | |
form.on('submit', function (evt) { | |
evt.preventDefault(); | |
// use the frame from the FullPage Chat as it renders faster | |
var thedata = { op: 'message', node_id: '3193', | |
displaytype: 'raw', message: $('#talkbox').val() }; | |
$(":input",form).prop("disabled", true); | |
$.ajax({ url: form.attr("action"), method: 'post', data: thedata }) | |
.done(function (data) { | |
$('#talkbox').val(""); | |
// want to use fetchit() if possible here to update the lastid | |
if ( ajax_cb[0].checked ) fetchit(); else refresh(); | |
}) | |
.fail(function ( jqXHR, textStatus, errorThrown ) { | |
alert("CB submission error: "+textStatus+" / "+jqXHR.status+" "+errorThrown); | |
}) | |
.always(function () { | |
$(":input",form).prop("disabled", false); | |
}); | |
}); | |
// Checkboxes | |
var cb_div = $('<div/>', { style: "font-size: 12px; display: inline-block;" }); | |
cb_div.append( $('<label/>', { text: "AJAX Refresh" }).prepend(ajax_cb) ); | |
form.after($("<br/>"), cb_div); | |
ajax_cb.change(function () { | |
if ( this.checked ) { | |
start_fetch(); | |
all_refresh_timer = setInterval(refresh_all, GERNERAL_REFRESHTIME_MS); | |
refresh_all(); | |
} | |
else { | |
if (fetch_timer) clearTimeout(fetch_timer); | |
fetch_timer = null; | |
if (all_refresh_timer) clearInterval(all_refresh_timer); | |
all_refresh_timer = null; | |
} | |
}); | |
if ( "Notification" in window ) { | |
cb_div.append( $('<label/>', { text: "Notifications" }).prepend(notify_cb) ); | |
notify_cb.change(function () { | |
if ( !this.checked ) return; | |
if ( Notification.permission == "default" ) { | |
notify_cb.attr("disabled", true); | |
Notification.requestPermission(function (result) { | |
notify_cb.removeAttr("disabled"); | |
if ( result != "granted" ) notify_cb[0].checked = false; | |
}); | |
} | |
else if ( Notification.permission != "granted" ) { | |
alert("You've denied this page the ability to send notifications, please change this via your browser's settings."); | |
this.checked = false; | |
} | |
}); | |
} | |
}); |
This file contains 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
"use strict"; | |
// Documented at: https://www.perlmonks.org/?node_id=11116375 | |
$(function () { | |
$("<style type='text/css'> .CodeMirror { border: 1px solid lightgrey; height: auto; resize: both; } </style>") | |
.appendTo("body"); | |
var opts = { | |
lineNumbers: true, indentWithTabs: true, tabSize: 4, indentUnit: 4, | |
viewportMargin: Infinity, lineWrapping: true, | |
mode: { | |
name: "htmlmixed", // text/html | |
tags: { | |
style: [ ["type", /^text\/(x-)?scss$/, "text/x-scss"], | |
[null, null, "css"] ], | |
script: [[null, null, "text/javascript"]], | |
c: [[null, null, "text/x-perl"]] | |
} | |
} | |
}; | |
if ( window["CM_THEME"] ) opts.theme = window.CM_THEME; | |
var opts_codeblock = JSON.parse(JSON.stringify(opts)); // deep copy | |
opts_codeblock['readOnly'] = true; | |
opts_codeblock['mode'] = 'text/x-perl'; | |
$('textarea').each(function () { | |
var myCodeMirror = CodeMirror.fromTextArea(this, opts); | |
}); | |
$('.codeblock:has(.codetext)').each(function () { | |
var div = this; | |
var text = $(div).text().trimEnd(); | |
var myCodeMirror = CodeMirror( function(elt) { | |
div.parentNode.replaceChild(elt, div); | |
}, opts_codeblock); | |
myCodeMirror.setValue(text); | |
}); | |
}); |
This file contains 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
"use strict"; | |
// Documented at: https://www.perlmonks.org/?node_id=11116359 | |
$(function () { | |
if ( !("Notification" in window) ) { | |
console.warn("You've enabled the notifications plugin, but this browser doesn't seem to support them."); | |
return; | |
} | |
var DEFAULT_FETCHTIME_MS = 30 * 1000; | |
var cb = $('<input/>', { type: 'checkbox' }); | |
if ( !( window["NOTIFICATIONS_ENABLE"] && window["NOTIFICATIONS_HIDECB"] ) ) | |
$('#nodelet_container').before( | |
$('<div/>', { style: "font-size: 12px;" }).append( | |
$('<label/>', { text: "New Node Notifications" }).prepend(cb) ) ); | |
var notifications_timer; | |
var start_notifications = function () { | |
var lastfetchtime = Math.round((new Date()).getTime() / 1000); | |
var fetchit = function () { | |
$.ajax({ url: "/", dataType: "xml", | |
data: { node_id: '30175', xmlstyle: 'flat', | |
sinceunixtime: lastfetchtime, ticker: 'yes' } }) | |
.done(function (data) { | |
$("NODE", data).each(function () { | |
var node = $(this); | |
var type = node.attr("nodetype"); | |
var author = node.attr("authortitle"); | |
if ( type == "user" || author == "NodeReaper" ) return; | |
var text = author + " posted a new " + type + ": " + node.text(); // node.attr("createtime") | |
var uri = "/?" + $.param({ node_id: node.attr("node_id") }); | |
console.debug(text, uri); | |
var notification = new Notification('New PerlMonks Node', { | |
body: text, icon: "/favicon.ico", badge: "/favicon.ico", | |
requireInteraction: true }); | |
notification.onclick = function (event) { | |
window.location = uri; | |
}; | |
}); | |
notifications_timer = setTimeout(fetchit, | |
parseInt($("INFO", data).attr("min_poll_seconds")) * 1000 + 1000); | |
}) | |
.fail(function (jqXHR, textStatus, errorThrown) { | |
console.warn("AJAX error: " + textStatus + " / " + jqXHR.status + " " + errorThrown); | |
notifications_timer = setTimeout(fetchit, DEFAULT_FETCHTIME_MS); | |
}); | |
lastfetchtime = Math.round((new Date()).getTime() / 1000); | |
}; | |
notifications_timer = setTimeout(fetchit, DEFAULT_FETCHTIME_MS); | |
console.debug("Notifications initialized. Timer", | |
notifications_timer, "will fire in", DEFAULT_FETCHTIME_MS, "ms"); | |
} | |
cb.change(function () { | |
if ( this.checked ) { | |
if ( Notification.permission == "default" ) { | |
cb.attr("disabled", true); | |
Notification.requestPermission(function (result) { | |
cb.removeAttr("disabled"); | |
if ( result == "granted" ) start_notifications(); | |
else cb[0].checked = false; | |
}); | |
} | |
else if ( Notification.permission == "granted" ) | |
start_notifications(); | |
else { | |
alert("You've denied this page the ability to send notifications, please change this via your browser's settings."); | |
this.checked = false; | |
} | |
} | |
else { | |
clearTimeout(notifications_timer); | |
console.debug("Notifications stopped."); | |
} | |
}); | |
if ( window["NOTIFICATIONS_ENABLE"] ) | |
cb.prop("checked", true).trigger("change"); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment