Permalink
Browse files

Desktop notifications for Chrome users.

  • Loading branch information...
1 parent 2a0c018 commit 2ce4b2018f1d801e427bfc3710c33957bcc38ffd @rchern rchern committed Dec 25, 2010
Showing with 87 additions and 65 deletions.
  1. +87 −65 SEChatModifications.user.js
View
@@ -27,6 +27,19 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0;
};
+ $.expr[':'].regex = function (elem, index, match) {
+ var matchParams = match[3].split(','),
+ validLabels = /^(data|css):/,
+ attr = {
+ method: matchParams[0].match(validLabels) ?
+ matchParams[0].split(':')[0] : 'attr',
+ property: matchParams.shift().replace(validLabels, '')
+ },
+ regexFlags = 'ig',
+ regex = new RegExp(matchParams.join('').replace(/^\s+|\s+$/g, ''), regexFlags);
+ return regex.test(jQuery(elem)[attr.method](attr.property));
+ };
+
$.fn.extend({
bindAs: function (nth, type, data, fn) {
if (typeof type == "object") {
@@ -138,14 +151,14 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
n = n.toLowerCase();
var retVal;
- if (typeof prefix == 'undefined') { prefix = '' }
+ if (typeof prefix == 'undefined') { prefix = ''; }
if (n.indexOf('meta') === 0) {
n = n.substring(4);
- if (n.indexOf('.') === 0) { n = n.substring(1) }
+ if (n.indexOf('.') === 0) { n = n.substring(1); }
prefix = prefix + 'meta.';
- };
+ }
switch (n) {
case 'so':
@@ -193,7 +206,7 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
function isNumber(n) {
return !isNaN(parseInt(n, 10)) && isFinite(n);
}
-
+
function isCtrl(event) {
return event.ctrlKey || (!event.altKey && event.metaKey);
}
@@ -244,11 +257,9 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
command: 'star',
jump: true
},
- 'ctrl': {
-
- }
+ 'ctrl': {}
},
-
+
deselect: function () {
Navigation._active = false;
Navigation.unpeek();
@@ -269,7 +280,7 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
return false;
}
},
-
+
handles: function (key, isCtrl) {
return (!isCtrl ? Navigation._actions : $.extend({}, Navigation._actions, Navigation._actions.ctrl))[key];
},
@@ -287,7 +298,7 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
if (!Navigation._active) {
return true;
}
-
+
if (n === 0) {
return false;
}
@@ -351,7 +362,7 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
} else {
var action = Navigation.handles(event.which, isCtrl(event)),
message = selected[0].id.replace("message-", ""),
- parent = selected.data('info').parent_id,
+ parent = selected.data('info').parent_id,
replied,
command = action ? action.command : null;
@@ -371,7 +382,7 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
if ((replied = $('#message-' + parent + ' > .content')).length) {
Navigation.peek(message, replied.html());
} else {
- $.get('/message/' + parent, function(text) {
+ $.get('/message/' + parent, function (text) {
Navigation.peek(message, text);
}, 'text');
}
@@ -401,11 +412,11 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
})
.data('reply', reply.attr('id'))
.appendTo(document.body);
-
+
Navigation.update();
}
},
-
+
suppress: function (event) {
if (Navigation._active && Navigation.handles((event.which < 123 && event.which > 96 ? event.which - 32 : event.which), isCtrl(event))) {
event.stopImmediatePropagation();
@@ -417,7 +428,7 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
$('.easy-navigation-peekable').remove();
},
- update: function() {
+ update: function () {
var peekable = $('body > .easy-navigation-peekable'),
reply,
scrollTopOffset = $(document).scrollTop(),
@@ -427,8 +438,8 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
peekableTopOffset = reply.offset().top - peekable.outerHeight(true) - 3;
peekable.css({
- 'top': peekableTopOffset + 'px',
- });
+ 'top': peekableTopOffset + 'px'
+ });
if (peekableTopOffset < scrollTopOffset) {
$(document).scrollTo(peekable);
@@ -466,12 +477,12 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
this.items.push(match);
localStorage[this.storageName] = JSON.stringify(this.items);
}
- }
+ };
this.remove = function (match) {
this.items.splice($.inArray(match, this.items), 1);
localStorage[this.storageName] = JSON.stringify(this.items);
- }
+ };
};
var highlightStore = new Storage(),
@@ -487,11 +498,11 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
//factor out highlighting stuff to avoid repeating myself
function getHighlightSelector(match) {
- if (isNumber(match)) {
- return Selectors.getMessage(match);
- } else {
- return Selectors.getSignature(match);
- }
+ if (isNumber(match)) {
+ return Selectors.getMessage(match);
+ } else {
+ return Selectors.getSignature(match);
+ }
}
function addhl(match) {
var selector = getHighlightSelector(match);
@@ -509,12 +520,12 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
var cmds = [];
for (var c in commands) cmds.push(c); //convert to array for sort to alphabetical order
cmds.sort();
- for(var i = 0; i < cmds.length; i++) {
+ for (var i = 0; i < cmds.length; i++) {
(function (current) {
- $('<a />').click(function () {
- $('#input').val('/' + current).focus();
- return false;
- }).attr('href', '#')
+ $('<a />').click(function () {
+ $('#input').val('/' + current).focus();
+ return false;
+ }).attr('href', '#')
.text(current)
.wrap('<li />')
.parent()
@@ -523,7 +534,7 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
}
return ul;
}
-
+
function createClipItem(index, room, display, hide) {
var html = index + '. <em>' + room + '</em>';
@@ -634,9 +645,9 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
return CommandState.SucceededDoClear;
},
hl: function (match) {
- if(typeof match == 'undefined') { //no parameters = show list
+ if (typeof match == 'undefined') { //no parameters = show list
var ul = $('<ul />').addClass('gm_room_list');
-
+
if (highlightStore.items.length > 0) {
for (var i = 0; i < highlightStore.items.length; i++) {
(function (current) {
@@ -653,11 +664,11 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
} else {
ul = $('<p />').text('Currently there are no highlighted users or messages');
}
-
+
showNotification(ul, 10E3);
} else { //if already in list, remove - else add
match = $.makeArray(match).join(" ");
- if($.inArray(match, highlightStore.items) >= 0) {
+ if ($.inArray(match, highlightStore.items) >= 0) {
highlightStore.remove(match);
delhl(match);
} else {
@@ -795,36 +806,36 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
cache: true,
success: function (data) {
var response = '';
-
- function buildOb(data){
+
+ function buildOb(data) {
var ob = $('<div />').css({
- textAlign: 'left',
- padding: '10px 20px 20px',
- overflow: 'hidden'
- }),
- userInfo = $('<div />').css('float', 'left').appendTo(ob),
- title = $('<div />').text(', ' + data.location).appendTo(userInfo),
- stat = $('<div />').appendTo(userInfo),
+ textAlign: 'left',
+ padding: '10px 20px 20px',
+ overflow: 'hidden'
+ }),
+ userInfo = $('<div />').css('float', 'left').appendTo(ob),
+ title = $('<div />').text(', ' + data.location).appendTo(userInfo),
+ stat = $('<div />').appendTo(userInfo),
name = data.display_name + (data.user_type === 'moderator' ? '' : '');
-
+
$('<a />').attr('href', currentSite + '/users/' + data.user_id)
.addClass('ob-user-username')
.text(name)
.prependTo(title);
-
+
// repNumber: Chat function for displaying rep - adds in k for 10k+ reps
$('<span />').addClass('reputation-score').text(repNumber(data.reputation)).appendTo(stat);
-
+
$('<img />').css({
- float: 'left',
+ float: 'left',
marginRight: 10
}).attr({
- src: 'http://www.gravatar.com/avatar/' + data.email_hash + '?s=64&d=identicon',
+ src: 'http://www.gravatar.com/avatar/' + data.email_hash + '?s=64&d=identicon',
alt: ''
}).prependTo(ob);
-
+
$.ajax({
- 'url': url + data.user_id + '/tags',
+ 'url': url + data.user_id + '/tags',
dataType: 'jsonp',
jsonp: 'jsonp',
data: {
@@ -833,40 +844,40 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
cache: true,
success: function (data) {
var wrapper = $('<div />').appendTo(userInfo).css('margin-top', 4);
- for(var i = 0; i < data.tags.length; i++){
+ for (var i = 0; i < data.tags.length; i++) {
var outer = $('<a />')
.attr('href', currentSite + '/tagged/' + data.tags[i].name)
.appendTo(wrapper).css('text-decoration', 'none');
-
+
$('<span />')
.addClass('ob-user-tag')
.text(data.tags[i].name)
.appendTo(outer)
.css({
- borderStyle: 'solid',
+ borderStyle: 'solid',
marginRight: 5
});
}
}
});
-
+
var badgeN = 1;
- for(var i in data.badge_counts){
+ for (var i in data.badge_counts) {
$('<span />').addClass('badge' + badgeN++).appendTo(stat);
$('<span />').addClass('badgecount').text(data.badge_counts[i]).appendTo(stat);
}
-
+
return ob;
}
-
+
if (data.total === 0) {
response = $('<p />').text('There are no user that match your search');
} else if (data.total === 1) {
$('#input').val(currentSite + '/users/' + data.users[0].user_id);
response = buildOb(data.users[0]);
} else {
response = $('<ul />').addClass('gm_room_list profile');
-
+
for (var i = 0; i < data.users.length; i++) {
(function (current) {
var anchor = $('<a />').click(function () {
@@ -887,8 +898,8 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
anchor.parent().appendTo(response);
})(data.users[i]);
}
-
- if(data.total > 50){
+
+ if (data.total > 50) {
$('<li />').append($('<h3 />').text('Your query returned too many results. Currently showing the top 50 sorted by reputation')).prependTo(response);
}
}
@@ -998,7 +1009,7 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
}
});
}
- },
+ },
history: function (id) {
validateArgs(1, ["number"]);
$("<div>").addClass("gm_room_list").load("/messages/" + id + "/history #content", function () {
@@ -1010,7 +1021,7 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
validateArgs(0);
try {
window.location = "http://github.com/rchern/StackExchangeScripts/raw/master/SEChatModifications.user.js";
- } catch(e) { if(console) console.log(e) } //do nothing, swallow 'Unknown exception 0x805e000a'
+ } catch (e) { if (console) console.log(e) } //do nothing, swallow 'Unknown exception 0x805e000a'
return CommandState.SucceededDoClear;
},
help: function () {
@@ -1027,7 +1038,7 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
// ctrl+space retry
page.bindAs(0, 'keydown', function (evt) {
- if (evt.which == 32 && isCtrl(evt)) {
+ if (evt.which == 32 && isCtrl(event)) {
var value = input.val();
// This apparently removes the input's text
@@ -1042,7 +1053,7 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
// show the message ids on each
$(".message:not(.pending):not(.posted)").livequery(function () {
var id = this.id.replace("message-", "");
-
+
if (!$(this).siblings('#id-' + id).length) {
var timestamp = new Date($(this).data().info.time * 1000);
timestamp = "" + timestamp.getHours() + ":" + (timestamp.getMinutes() < 10 ? "0" + timestamp.getMinutes() : timestamp.getMinutes()) + ":" + (timestamp.getSeconds() < 10 ? "0" + timestamp.getSeconds() : timestamp.getSeconds());
@@ -1052,12 +1063,20 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
.addClass('timestamp')
.attr('id', 'id-' + id);
}
+
+ if ($(this).find(".mention").length > 0) {
+ if (window.webkitNotifications && (window.webkitNotifications.checkPermission() === 0)) {
+ var n = window.webkitNotifications.createNotification($("#footer-logo img").attr("src").replace("logo.png", "apple-touch-icon.png"), $("#roomname").text(), $(this).find(".content").text());
+ n.show();
+ setTimeout(function () { n.cancel(); }, 10E3);
+ }
+ }
});
// handle commands
input.bindAs(0, 'keydown', function (evt) {
if (evt.which == 13 && input.val().substring(0, 1) == "/") {
- if(input.val().substring(1, 2) == "/") { //double slash to escape commands
+ if (input.val().substring(1, 2) == "/") { //double slash to escape commands
input.val(input.val().substring(1)); //remove the escaping slash
} else {
var args = input.val().split(" ");
@@ -1234,5 +1253,8 @@ with_plugin("http://stackflair.com/jquery.livequery.js", function ($) {
}
}
);
+
+ // ask for notification permissions if we don't already have it
+ if (window.webkitNotifications && (window.webkitNotifications.checkPermission() !== 0)) { $('<button />').text('desktop @mentions').addClass('button').appendTo('#chat-buttons').click(function () { window.webkitNotifications.requestPermission(function () { $("#chat-buttons").remove(this); }); }); }
});
});

0 comments on commit 2ce4b20

Please sign in to comment.