Merge pull request #1 from Hexagon/hex-nottis

Notifications and stuff
This commit is contained in:
Robin Nilsson 2014-09-23 14:59:38 +02:00
commit 1b86e1feb6
12 changed files with 209 additions and 19 deletions

BIN
public/gfx/icon_128x128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

BIN
public/gfx/icon_16x16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 B

BIN
public/gfx/icon_32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
public/gfx/icon_64x64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -5,6 +5,11 @@
<title>Cryptalk</title>
<link rel="stylesheet" type="text/css" href="css/default.css">
<head profile="http://www.w3.org/2005/10/profile">
<link rel="icon"
type="image/png"
href="gfx/icon_32x32.png">
</head>
<body>

View File

@ -1,7 +1,7 @@
// Main cryptalk module
define({
compiles: ['$'],
requires: ['hosts', 'templates', 'sound', 'fandango']
requires: ['hosts', 'templates', 'sound', 'fandango','notifications']
}, function ($, requires, data) {
var socket,
key,
@ -26,10 +26,11 @@ define({
},
// Shortcut
hosts = requires.hosts.hosts;
fandango = requires.fandango;
templates = requires.templates;
sound = requires.sound;
hosts = requires.hosts.hosts,
fandango = requires.fandango,
templates = requires.templates,
sound = requires.sound,
notifications = requires.notifications,
lockInput = function () {
components.input[0].setAttribute('disabled', 'disabled');
@ -42,8 +43,22 @@ define({
components.input.focus();
},
showNotification = function (type, nick, text) {
if (!mute) {
if ( type == 'message') {
notifications.notify(nick.substring(0, 20), text.substring(0, 80),'gfx/icon_128x128.png',true);
} else if ( type == 'error' ) {
notifications.notify('Cryptalk', text.substring(0, 80),'gfx/icon_128x128_error.png',true);
} else {
notifications.notify('Cryptalk', text.substring(0, 80),'gfx/icon_128x128_info.png',true);
}
}
},
// Adds a new message to the DOM
post = function (type, text, clearChat, clearBuffer, nick) {
var tpl = templates.post[type],
post,
data = fandango.merge({}, settings, {
@ -60,6 +75,9 @@ define({
clearInput();
}
showNotification(type, nick, text)
// Append the post to the chat DOM element
components.chat[clearChat ? 'html' : 'append'](post);
},
@ -196,7 +214,7 @@ define({
post('error', templates.messages.unable_to_decrypt);
} else {
post('message', sanitized, false, false, nick);
if( !mute ) sound.playTones(sound.messages.message);
//if( !mute && !notifications.windowActive()) sound.playTones(sound.messages.message);
}
})
@ -212,7 +230,7 @@ define({
}
// Play sound
if (sound.messages[sanitized] !== undefined && !mute ) sound.playTones(sound.messages[sanitized]);
//if (sound.messages[sanitized] !== undefined && !mute && !notifications.windowActive() ) sound.playTones(sound.messages[sanitized]);
} else {
post('error', templates.server.bogus);
@ -500,9 +518,12 @@ define({
unlockInput();
notifications.enableNative();
// It's possible to provide room and key using the hashtag.
// The room and key is then seperated by semicolon (room:key).
// If there is no semicolon present, the complete hash will be treated as the room name and the key has to be set manually.
commands.connect(0, function() {
if (host && (hash = window.location.hash)) {
parts = hash.slice(1).split(':');
@ -510,3 +531,5 @@ define({
parts[1] && commands.key(parts[1]);
}
});
});

View File

@ -0,0 +1,133 @@
/*
Usage
Native notifications without fallback:
notification.enableNative(); // Once
notification.notify("Woop Woop");
Native notifications with fallback:
notification.enableNative(); // Once
notification.notify("Woop Woop",true); // True in 2nd parameter enables fallback
Title blink only:
notifications.blinkTitleUntilFocus("Woop Woop",1000);
*/
define(function (){
var exports = {},
window_active,
blur_delay_timer,
native_supported = false,
new_title,
original_title,
blink_timer,
interval,
now = function () {
return performance.now() || Date.now();
},
focusCallback = function() {
/* Reset everything after regaining focus */
resetState();
},
resetState = function() {
clearTimeout(blur_delay_timer);
clearTimeout(blink_timer);
if (original_title !== undefined) setTitle(original_title);
original_title = undefined;
new_title = undefined;
window_active = true;
},
blurCallback = function() {
/* Apply a slight delay to prevent notifications from popping when the notifications
cause the windows to lose focus */
clearTimeout(blur_delay_timer);
blur_delay_timer = setTimeout(function() { window_active = false; },1000);
},
setTitle = function(t) { document.title = t; },
getTitle = function() { return document.title; },
doBlink = function() {
if(!window_active) {
if( getTitle() == original_title )
setTitle( new_title );
else
setTitle( original_title);
blink_timer = setTimeout(doBlink,interval);
} else {
resetState();
}
};
exports.enableNative = function() {
if( native_supported && Notification.permission !== 'denied' ) {
Notification.requestPermission(function (status) {
Notification.permission = status;
});
}
};
exports.windowActive = function() {
return window_active;
};
exports.blinkTitleUntilFocus = function(t,i) {
interval = (i == undefined) ? 1000 : i;
if (!window_active) {
new_title = t;
original_title = getTitle();
doBlink();
}
};
exports.notify = function(title,body,icon,fallback) {
// Only notify while in background
if( !window_active ) {
// Set default value for fallback parameter
if ( fallback === undefined) fallback = false;
if ( native_supported && Notification.permission === "granted") {
// Create notification
var n = new Notification(title, {body: body, icon:icon});
// Handle on show event
n.onshow = function () {
// Automatically close the notification after 5000ms
setTimeout(function(){n.close();},3000);
}
} else if ( fallback ) {
exports.blinkTitleUntilFocus("Attention",1000);
}
}
};
native_supported = (window.Notification !== undefined);
// Keep track of document focus/blur
if (window.addEventListener){
// Normal browsers
window.addEventListener("focus", focusCallback, true);
window.addEventListener("blur", blurCallback, true);
} else {
// IE
window.observe("focusin", focusCallback);
window.observe("focusout", blurCallback);
}
// Make sure we are at square one
resetState();
return exports;
});

View File

@ -79,8 +79,8 @@ define({
leave_from_nowhere: 'How are you supposed to leave, while being nowhere?',
// Sounds
muted: 'Notification sounds is now muted.',
unmuted: 'Notifications sounds is now on.',
muted: 'Notifications and sounds are now muted.',
unmuted: 'Notifications and sounds are now on.',
// Extra variables: 'commandName'
unrecognized_command: 'Unrecognized command: "{commandName}"',

View File

@ -1,5 +1,5 @@
var express = require('express.io'),
uuid = require('node-uuid');
uuid = require('node-uuid'),
app = express();app.http().io();
@ -43,9 +43,38 @@ app.io.route('room', {
app.io.route('message', {
send: function(req) {
if(req.data && req.data.room) req.socket.broadcast.to(req.data.room).emit('message:send', { msg: req.data.msg, nick: req.data.nick} );
// Check that the user is in a room
if(req.data && req.data.room) {
// Check that the message size is within bounds
var total_msg_size = (req.data.msg) ? req.data.msg.length : 0 + (req.data.nick) ? req.data.nick.length : 0;
if( total_msg_size <= 4096) {
// Check that at least 100ms has passed since last message
if( req.socket.last_message === undefined || new Date().getTime() - req.socket.last_message > 100 ) {
req.socket.broadcast.to(req.data.room).emit('message:send', { msg: req.data.msg, nick: req.data.nick} );
req.socket.emit('message:send', { msg: req.data.msg, nick: req.data.nick} );
req.socket.last_message = new Date().getTime();
} else {
// Do not complain if message rate is too fast, that would only generate more traffic
}
} else {
// Message size is out of bounds, complain
req.socket.emit('message:server', {msg:'command_failed'} );
}
}
}
});
app.io.sockets.on('connection', function(socket) {