/* Accepts: mediator.on('console:clear', clear); mediator.on('console:torch', ttl) mediator.on('console:motd', motd); mediator.on('console:info', info); mediator.on('console:error', error); mediator.on('console:server', server); mediator.on('console:message', message); mediator.on('console:lockinput', lockInput); mediator.on('console:unlockInput', unlockInput); mediator.on('console:param', param); Emits: mediator.emit('notification:send',...); mediator.emit('audio:play',...); ToDo */ import $ from './$.js'; export default function(mediator,settings,templates, sounds) { var // Collection of DOM components components = { chat: $('#chat'), input: $('#input'), inputWrapper: $('#input_wrapper') }, // Collection of parameters parameters = {}, // Adds a new message to the DOM commands = { post: function (type, text, nick) { var tpl = templates.post[type], uniqueId = 'msg_' + new Date().getTime() + '_' + Math.round(Math.random()*1000000), post, data = Object.assign({}, settings, { nick: nick, timestamp: new Date().toLocaleTimeString(), id: uniqueId }); data.text = $.template(text, data); post = $.template(tpl, data); // Request a notification commands.showNotification(type, nick, text); // Expire message setTimeout(function() { var parent = components.chat.first(), child = $('#'+uniqueId).first(); parent.removeChild(child); }, settings.ttl); // Append the post to the chat DOM element components.chat.append(post); }, torch: function (ttl) { ttl = parseInt(ttl, 10); if( ttl > 0 && ttl < 3600) { mediator.emit('console:info', $.template(templates.messages.torch_is_now, { ttl: ttl }) ); settings.ttl = ttl*1000; } else { mediator.emit('console:error', $.template(templates.messages.torch_not_set) ); } }, param: function (p) { parameters = Object.assign({}, parameters, p); }, showNotification: function (type, nick, text) { 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 mediator.emit('notification:send', { title: title.substring(0, 20), body: text.substring(0, 80), icon: icon }); // Emit sound if (type === 'message') { mediator.emit('audio:play', sounds.message); } }, motd: function (message) { commands.post('motd', message); }, info: function (message) { commands.post('info', message); }, error: function (message) { commands.post('error', message); }, server: function (message) { commands.post('server', message); }, message: function (data) { commands.post('message', data.message, data.nick); }, clearInput: function () { components.input[0].value = ''; }, clear: function () { components.chat[0].innerHTML = ''; }, lockInput: function () { components.input[0].setAttribute('disabled', 'disabled'); components.inputWrapper[0].className = 'loading'; }, unlockInput: function () { components.input[0].removeAttribute('disabled'); components.inputWrapper[0].className = ''; components.input.focus(); } }, // Handler for the document`s keyDown-event. onKeyDown = function (e) { var buffer, parts, payload, command; // The Document object is bound to this element. // If the active element is not the input, focus on it and exit the function. // Ignore this when ctrl and/or alt is pressed! if (!e.ctrlKey && !e.altKey && components.input[0] !== $.activeElement()) { return components.input.focus(); } // Return immediatly if the buffer is empty or if the hit key was not if (e.keyCode !== 13 || !(buffer = components.input[0].value)) { return; } // Handle command if ((buffer[0] || buffer.slice(0, 1)) === '/') { parts = $.ssplit(buffer.slice(1), ' '); command = parts[0]; payload = parts[1]; // Shout this command to all modules mediator.emit( 'command:' + command, payload, function(retvals, recipients) { if(!recipients) { return commands.post('error', $.template(templates.messages.unrecognized_command, { commandName: command })); } else { commands.clearInput(); } } ); } else /* Handle ordinary message */ { if(!parameters.room || !parameters.key ) { // Make sure that the user has joined a room and the key is set return (!parameters.room) ? commands.post('error', templates.messages.msg_no_room) : commands.post('error', templates.messages.msg_no_key); } // Before sending the message. // Encrypt message using room UUID as salt and key as pepper. mediator.emit( 'socket:emit', { data: 'message:send', payload: { room: $.SHA1(parameters.room), msg: $.AES.encrypt(buffer, $.SHA1(parameters.room) + parameters.key).toString(), nick: parameters.nick ? $.AES.encrypt(parameters.nick, $.SHA1(parameters.room) + parameters.key).toString() : false } } ); // And clear the the buffer commands.clearInput(); } }; // Bind the necessary DOM events $(document).on('keydown', onKeyDown); // Put focus on the message input components.input.focus(); // Connect events for (var commandName in commands) { if (commandName !== 'post') { mediator.on('console:' + commandName, commands[commandName]); } } mediator.on('console:post', function (data) { commands.post(data.type, data.data, data.nick); }); }