Notifications and stuff
This commit is contained in:
parent
f90869e370
commit
0eca4081d2
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 |
Binary file not shown.
After Width: | Height: | Size: 628 B |
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
|
@ -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>
|
||||
|
||||
|
|
|
@ -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);
|
||||
},
|
||||
|
@ -192,7 +210,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);
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -208,7 +226,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);
|
||||
|
@ -496,13 +514,18 @@ 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.
|
||||
if (host && (hash = window.location.hash)) {
|
||||
parts = hash.slice(1).split(':');
|
||||
commands.connect(0, function() {
|
||||
if (host && (hash = window.location.hash)) {
|
||||
parts = hash.slice(1).split(':');
|
||||
|
||||
parts[0] && commands.join(parts[0]);
|
||||
parts[1] && commands.key(parts[1]);
|
||||
}
|
||||
});
|
||||
|
||||
parts[0] && commands.join(parts[0]);
|
||||
parts[1] && commands.key(parts[1]);
|
||||
}
|
||||
});
|
|
@ -12,4 +12,4 @@ define({
|
|||
path: 'http://localhost:8080/js/cryptalk_modules/settings.js'
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
|
||||
});
|
|
@ -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}"',
|
||||
|
|
37
server.js
37
server.js
|
@ -1,7 +1,7 @@
|
|||
var express = require('express.io'),
|
||||
uuid = require('node-uuid');
|
||||
uuid = require('node-uuid'),
|
||||
|
||||
app = express();app.http().io();
|
||||
app = express();app.http().io();
|
||||
|
||||
app.use(express.static(__dirname + '/public'));
|
||||
|
||||
|
@ -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} );
|
||||
req.socket.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) {
|
||||
|
|
Loading…
Reference in New Issue