Mediator awareness
This commit is contained in:
parent
29d1799d56
commit
c74d265579
|
@ -0,0 +1,67 @@
|
|||
/* Usage:
|
||||
|
||||
channel.emit('audio:play',message);
|
||||
channel.emit('audio:on');
|
||||
channel.emit('audio:off');
|
||||
|
||||
*/
|
||||
|
||||
// Sounds module, used for emitting those annoying bl-up sounds when receiving a message
|
||||
define(['queue','mediator'], function (queue,mediator) {
|
||||
|
||||
var ac = false,
|
||||
enabled = true,
|
||||
|
||||
channel = mediator(),
|
||||
|
||||
// Recursive function for playing tones, takes an array of [tone,start_ms,duration_ms] - entries
|
||||
// i is only used for recursion
|
||||
playTones = function (tones, i) {
|
||||
|
||||
// Parameter defaults
|
||||
i = (i === undefined) ? 0 : i;
|
||||
|
||||
// Stop if we've reached the end of iteration, and require ac
|
||||
if( !(i < Object.keys(tones).length) || !ac || !enabled ) return;
|
||||
|
||||
// Add tones to execution queue
|
||||
var current_tones = tones[i],
|
||||
freqs = current_tones[0],
|
||||
start = current_tones[1],
|
||||
duration = current_tones[2];
|
||||
|
||||
var o = ac.createOscillator();
|
||||
var g = ac.createGain();
|
||||
o.frequency.value = freqs;
|
||||
o.connect(g);
|
||||
g.gain.value = 0.25;
|
||||
g.connect(ac.destination);
|
||||
queue.add_function_delayed(start,function() { o.noteOn(0); });
|
||||
queue.add_function_delayed(start+duration,function() { o.noteOff(0); });
|
||||
|
||||
// Iterate, or start playing
|
||||
i++;
|
||||
if( i < Object.keys(tones).length ) {
|
||||
playTones(tones,i);
|
||||
} else {
|
||||
queue.run();
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
on = function() {
|
||||
enabled = true;
|
||||
},
|
||||
|
||||
off = function() {
|
||||
enabled = false;
|
||||
};
|
||||
|
||||
if( window.AudioContext || window.webkitAudioContext ) ac = new ( window.AudioContext || window.webkitAudioContext );
|
||||
|
||||
channel.on('audio:play',function(message) { playTones(message) });
|
||||
channel.on('audio:on',function(message) { on(); });
|
||||
channel.on('audio:off',function(message) { off(); });
|
||||
|
||||
});
|
|
@ -1,7 +1,7 @@
|
|||
// Main cryptalk module
|
||||
define({
|
||||
compiles: ['$'],
|
||||
requires: ['hosts', 'templates', 'sound', 'fandango','notifications']
|
||||
requires: ['mediator','hosts', 'templates', 'audio', 'fandango','notifications','sounds']
|
||||
}, function ($, requires, data) {
|
||||
var socket,
|
||||
key,
|
||||
|
@ -9,7 +9,7 @@ define({
|
|||
room,
|
||||
hash,
|
||||
nick,
|
||||
mute,
|
||||
mute = false,
|
||||
|
||||
settings = {},
|
||||
|
||||
|
@ -29,8 +29,8 @@ define({
|
|||
hosts = requires.hosts,
|
||||
fandango = requires.fandango,
|
||||
templates = requires.templates,
|
||||
sound = requires.sound,
|
||||
notifications = requires.notifications,
|
||||
sounds = requires.sounds,
|
||||
channel = requires.mediator(),
|
||||
|
||||
lockInput = function () {
|
||||
components.input[0].setAttribute('disabled', 'disabled');
|
||||
|
@ -44,16 +44,21 @@ define({
|
|||
},
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
var title = (type!='message') ? 'Cryptalk' : nick,
|
||||
icon = (type == 'message') ? 'gfx/icon_128x128.png' : (type == 'error') ? 'gfx/icon_128x128_error.png' : 'gfx/icon_128x128_info.png';
|
||||
|
||||
// Emit notification
|
||||
channel.emit('notification:send',
|
||||
{
|
||||
title: title.substring(0, 20),
|
||||
body: text.substring(0, 80),
|
||||
icon: icon
|
||||
});
|
||||
|
||||
// Emit sound
|
||||
if ( type == 'message' ) channel.emit('audio:play',sounds.message);
|
||||
|
||||
},
|
||||
|
||||
// Adds a new message to the DOM
|
||||
|
@ -63,8 +68,7 @@ define({
|
|||
post,
|
||||
data = fandango.merge({}, settings, {
|
||||
nick: nick,
|
||||
room: room,
|
||||
mute: mute
|
||||
room: room
|
||||
});
|
||||
|
||||
data.text = $.template(text, data);
|
||||
|
@ -77,7 +81,6 @@ define({
|
|||
|
||||
showNotification(type, nick, text)
|
||||
|
||||
|
||||
// Append the post to the chat DOM element
|
||||
components.chat[clearChat ? 'html' : 'append'](post);
|
||||
},
|
||||
|
@ -214,7 +217,6 @@ define({
|
|||
post('error', templates.messages.unable_to_decrypt);
|
||||
} else {
|
||||
post('message', sanitized, false, false, nick);
|
||||
//if( !mute && !notifications.windowActive()) sound.playTones(sound.messages.message);
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -228,10 +230,6 @@ define({
|
|||
} else {
|
||||
post('server', templates.server[sanitized]);
|
||||
}
|
||||
|
||||
// Play sound
|
||||
//if (sound.messages[sanitized] !== undefined && !mute && !notifications.windowActive() ) sound.playTones(sound.messages[sanitized]);
|
||||
|
||||
} else {
|
||||
post('error', templates.server.bogus);
|
||||
}
|
||||
|
@ -347,11 +345,11 @@ define({
|
|||
},
|
||||
|
||||
mute: function () {
|
||||
// Invert mute
|
||||
mute = !mute;
|
||||
mute = true;
|
||||
},
|
||||
|
||||
// Inform that the key has been set
|
||||
post('info', $.template(templates.messages[mute ? 'muted' : 'unmuted']));
|
||||
unmute: function () {
|
||||
mute = false;
|
||||
},
|
||||
|
||||
join: function (payload) {
|
||||
|
@ -516,9 +514,17 @@ define({
|
|||
// Post the help/welcome message
|
||||
post('motd', templates.motd, true);
|
||||
|
||||
unlockInput();
|
||||
// Route mediator messages
|
||||
channel.on('window:focused',function() {
|
||||
channel.emit('audio:off');
|
||||
channel.emit('notification:off');
|
||||
});
|
||||
channel.on('window:blurred',function() {
|
||||
if( !mute ) channel.emit('audio:on');
|
||||
channel.emit('notification:on');
|
||||
});
|
||||
|
||||
notifications.enableNative();
|
||||
unlockInput();
|
||||
|
||||
// It's possible to provide room and key using the hashtag.
|
||||
// The room and key is then seperated by semicolon (room:key).
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
/*
|
||||
Usage
|
||||
|
||||
Native notifications without fallback:
|
||||
notification.enableNative(); // Once
|
||||
notification.notify("Woop Woop");
|
||||
// Send an notification
|
||||
channel.emit('notification:send',{
|
||||
title: 'Woop',
|
||||
body: 'Woop woop',
|
||||
icon: 'gfx/icon.png'
|
||||
});
|
||||
|
||||
Native notifications with fallback:
|
||||
notification.enableNative(); // Once
|
||||
notification.notify("Woop Woop",true); // True in 2nd parameter enables fallback
|
||||
// Turn notifications on
|
||||
channel.emit('notification:on');
|
||||
|
||||
Title blink only:
|
||||
notifications.blinkTitleUntilFocus("Woop Woop",1000);
|
||||
// Turn notifications off
|
||||
channel.emit('notification:off');
|
||||
|
||||
*/
|
||||
define(function (){
|
||||
define(['mediator','window'],function (mediator,win){
|
||||
|
||||
var exports = {},
|
||||
var enabled = true,
|
||||
|
||||
window_active,
|
||||
blur_delay_timer,
|
||||
native_supported = false,
|
||||
|
||||
new_title,
|
||||
|
@ -26,17 +26,21 @@ define(function (){
|
|||
blink_timer,
|
||||
interval,
|
||||
|
||||
channel = mediator(),
|
||||
|
||||
now = function () {
|
||||
return performance.now() || Date.now();
|
||||
},
|
||||
|
||||
focusCallback = function() {
|
||||
/* Reset everything after regaining focus */
|
||||
resetState();
|
||||
on = function () {
|
||||
enabled = true;
|
||||
},
|
||||
|
||||
off = function () {
|
||||
enabled = false;
|
||||
},
|
||||
|
||||
resetState = function() {
|
||||
clearTimeout(blur_delay_timer);
|
||||
clearTimeout(blink_timer);
|
||||
if (original_title !== undefined) setTitle(original_title);
|
||||
original_title = undefined;
|
||||
|
@ -44,53 +48,39 @@ define(function (){
|
|||
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 );
|
||||
if(enabled) {
|
||||
if( win.getTitle() == original_title )
|
||||
win.setTitle( new_title );
|
||||
else
|
||||
setTitle( original_title);
|
||||
win.setTitle( original_title);
|
||||
|
||||
blink_timer = setTimeout(doBlink,interval);
|
||||
} else {
|
||||
resetState();
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
exports.enableNative = function() {
|
||||
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) {
|
||||
blinkTitleUntilFocus = function(t,i) {
|
||||
interval = (i == undefined) ? 1000 : i;
|
||||
if (!window_active) {
|
||||
if ( enabled ) {
|
||||
new_title = t;
|
||||
original_title = getTitle();
|
||||
doBlink();
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
exports.notify = function(title,body,icon,fallback) {
|
||||
notify = function(title,body,icon,fallback) {
|
||||
// Only notify while in background
|
||||
if( !window_active ) {
|
||||
if( enabled) {
|
||||
|
||||
// Set default value for fallback parameter
|
||||
if ( fallback === undefined) fallback = false;
|
||||
|
@ -114,20 +104,15 @@ define(function (){
|
|||
|
||||
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);
|
||||
}
|
||||
channel.on('notification:send',function(data) { notify(data.title,data.body,data.icon,true); });
|
||||
channel.on('notification:on',function() { on(); });
|
||||
channel.on('notification:off',function() { off(); });
|
||||
|
||||
enableNative();
|
||||
|
||||
off();
|
||||
|
||||
// Make sure we are at square one
|
||||
resetState();
|
||||
|
||||
return exports;
|
||||
|
||||
});
|
|
@ -1,69 +0,0 @@
|
|||
// Sounds module, used for emitting those annoying bl-up sounds when receiving a message
|
||||
define(['queue'], function (queue) {
|
||||
|
||||
var exports = { messages: {} },
|
||||
|
||||
ac = false;
|
||||
|
||||
if( window.AudioContext || window.webkitAudioContext ) ac = new ( window.AudioContext || window.webkitAudioContext );
|
||||
|
||||
// Recursive function for playing tones, takes an array of [tone,start_ms,duration_ms] - entries
|
||||
// i is only used for recursion
|
||||
exports.playTones = function (tones, i) {
|
||||
|
||||
// Parameter defaults
|
||||
i = (i === undefined) ? 0 : i;
|
||||
|
||||
// Stop if we've reached the end of iteration, and require ac
|
||||
if( ac && !(i < Object.keys(tones).length) || !ac ) return;
|
||||
|
||||
// Add tones to execution queue
|
||||
var current_tones = tones[i],
|
||||
freqs = current_tones[0],
|
||||
start = current_tones[1],
|
||||
duration = current_tones[2];
|
||||
|
||||
var o = ac.createOscillator();
|
||||
var g = ac.createGain();
|
||||
o.frequency.value = freqs;
|
||||
o.connect(g);
|
||||
g.gain.value = 0.25;
|
||||
g.connect(ac.destination);
|
||||
queue.add_function_delayed(start,function() { o.noteOn(0); });
|
||||
queue.add_function_delayed(start+duration,function() { o.noteOff(0); });
|
||||
|
||||
// Iterate, or start playing
|
||||
i++;
|
||||
if( i < Object.keys(tones).length ) {
|
||||
exports.playTones(tones,i);
|
||||
} else {
|
||||
queue.run();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
exports.messages = {
|
||||
message: [
|
||||
[261.63*2,0,50],
|
||||
[261.63*3,0,50],
|
||||
[261.63*4,50,50],
|
||||
[261.63*5,50,50]
|
||||
],
|
||||
person_joined: [
|
||||
[261.63*3,0,200],
|
||||
[261.63*1,0,200],
|
||||
[261.63*3,200,500],
|
||||
[261.63*2,200,500]
|
||||
],
|
||||
person_left: [
|
||||
[261.63*3,0,200],
|
||||
[261.63*2,0,200],
|
||||
[261.63*3,200,500],
|
||||
[261.63*1,200,500]
|
||||
]
|
||||
};
|
||||
|
||||
return exports;
|
||||
|
||||
});
|
|
@ -0,0 +1,20 @@
|
|||
define({
|
||||
message: [
|
||||
[261.63*2,0,50],
|
||||
[261.63*3,0,50],
|
||||
[261.63*4,50,50],
|
||||
[261.63*5,50,50]
|
||||
],
|
||||
person_joined: [
|
||||
[261.63*3,0,200],
|
||||
[261.63*1,0,200],
|
||||
[261.63*3,200,500],
|
||||
[261.63*2,200,500]
|
||||
],
|
||||
person_left: [
|
||||
[261.63*3,0,200],
|
||||
[261.63*2,0,200],
|
||||
[261.63*3,200,500],
|
||||
[261.63*1,200,500]
|
||||
]
|
||||
});
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
|
||||
Emits:
|
||||
'window:focused'
|
||||
'window:blurred'
|
||||
|
||||
Exports:
|
||||
title = window.getTitle();
|
||||
window.setTitle(title);
|
||||
|
||||
*/
|
||||
define(['mediator'],function (mediator){
|
||||
|
||||
var exports = {},
|
||||
channel = mediator(),
|
||||
|
||||
focusCallback = function() {
|
||||
channel.emit('window:focused');
|
||||
},
|
||||
|
||||
blurCallback = function() {
|
||||
channel.emit('window:blurred');
|
||||
};
|
||||
|
||||
exports.getTitle = function(t) { document.title = t; },
|
||||
exports.setTitle = function() { return document.title; };
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
return exports;
|
||||
|
||||
});
|
Loading…
Reference in New Issue