From 769872e6c18fc633e15c89771f0c9c0aa54b4807 Mon Sep 17 00:00:00 2001 From: Luigi Pinca Date: Sat, 25 Aug 2012 14:56:37 +0200 Subject: [PATCH] each entry in the dropdown menu of rooms now also shows the number of players --- app.js | 7 +- package.json | 2 +- public/static/css/style.css | 11 +- public/static/js/home.js | 19 +- public/static/js/room.js | 1152 ++++++++++++++++++----------------- views/room.jade | 5 +- 6 files changed, 610 insertions(+), 586 deletions(-) diff --git a/app.js b/app.js index a0baa23..b0f700a 100644 --- a/app.js +++ b/app.js @@ -111,7 +111,7 @@ io.set('authorization', function(data, accept) { } else if (!session) { var debuginfos = { - address: data.address, + address: data.headers['x-forwarded-for'], ua: data.headers['user-agent'], cookie: data.headers.cookie }; @@ -197,5 +197,6 @@ for (var i=0; i/g, '>'); }; - // Prompt for name and send it. - var joinAnonymously = function(msg) { - if (/nickname\s*\=/.test(document.cookie) && !msg) { - var encodednickname = document.cookie.replace(/.*nickname\s*\=\s*([^;]*);?.*/, '$1'); - nickname = decodeURIComponent(encodednickname); - socket.emit('joinanonymously', nickname, roomname); - } - else { - if (!$('body').hasClass('modal-open')) { - var html = ''; - html += ''; - html += ''; - - $(html).appendTo(DOM.modal); - var login = $('#login'); - var button = $('#join'); - - button.click(function() { - var val = $.trim(login.val()); - if (val !== '') { - nickname = val; - socket.emit('joinanonymously', nickname, roomname); - } - else { - var txt = 'Nickname can\'t be empty.'; - invalidNickName(''+txt+''); - } - login.val(''); - }); - - login.keyup(function(event) { - if (event.keyCode === 13) { - button.click(); - } - }); - - DOM.modal.modal('show'); - DOM.modal.on('shown', function() { - login.focus(); - }); - } - else { - $('.modal-body p').html(msg); - $('#login').focus(); - } - } - }; - - // Submitted name was invalid - var invalidNickName = function(feedback) { - joinAnonymously(feedback+'
Try with another one:'); + // Add a chat entry, whether message, notification, etc. + var addChatEntry = function(childNode) { + var li = $('
  • '); + li.append(childNode); + DOM.chat.append(li); + DOM.chat[0].scrollTop = DOM.chat[0].scrollHeight; }; - /* Triggered when a logged user tries to join a room from another tab or another browser - and he is already in a room */ - var alreadyInARoom = function() { - var html = ''; - html += ''; - $(html).appendTo(DOM.modal); - DOM.modal.modal('show'); + var addFeedback = function(txt, style) { + if (typeof style === 'string') { + var fbspan = $(''); + fbspan.text(txt); + DOM.feedback.html(fbspan); + DOM.guessbox.addClass(style); + setTimeout(function() {DOM.guessbox.removeClass(style);}, 350); + return; + } + DOM.feedback.text(txt); }; - // Successfully joined the room - var ready = function(usersData, trackscount, loggedin) { - if (!loggedin && !/nickname\s*\=/.test(document.cookie)) { - document.cookie = 'nickname='+encodeURIComponent(nickname)+';path=/;'; + var addPrivate = function(usrname) { + if (pvtmsgto) { + clearPrivate(); } - - DOM.modal.modal('hide').empty(); - $('#total-tracks span').text(trackscount); - var msg = nickname+' joined the game'; - var joinspan = $(''); - joinspan.text(msg); - addChatEntry(joinspan); - updateUsers(usersData); - - DOM.messagebox.keydown(function(event) { - if (event.keyCode === 13) { - var val = $.trim(DOM.messagebox.val()); - if (val !== '') { - if (pvtmsgto) { - socket.emit('sendchatmsg', val, pvtmsgto); - } - else { - socket.emit('sendchatmsg', val); - } - } - DOM.messagebox.val(''); - } + if (nickname === usrname) { + return; + } + DOM.recipient.css('margin-right', '4px'); + DOM.recipient.text('To '+usrname+':'); + var width = DOM.recipient.outerWidth(true) + 1; + DOM.recipient.hide(); + DOM.messagebox.animate({'width':'-='+width+'px'}, 'fast', function() { + DOM.recipient.show(); }); - - DOM.guessbox.keydown(function(event) { - switch (event.keyCode) { - case 13: // return - var guess = $.trim(DOM.guessbox.val()); - if (guess !== '') { - socket.emit('guess', guess.toLowerCase()); - historyvalues.push(guess); - if (historyvalues.length > 20) { - historyvalues.splice(0, 1); - } - historycursor = historyvalues.length; - } - DOM.guessbox.val(''); - break; - case 38: // up-arrow - if (historycursor > 0) { - DOM.guessbox.val(historyvalues[--historycursor]); - } - break; - case 40: // down-arrow - if (historycursor < historyvalues.length - 1) { - DOM.guessbox.val(historyvalues[++historycursor]); - } - else { - historycursor = historyvalues.length; - DOM.guessbox.val(''); - } - } + var el = $('.name').filter(function(index) { + return $(this).text() === usrname; }); + el.prevAll('.private').show(); + el.unbind('click'); + el.click(clearPrivate); + pvtmsgto = usrname; + DOM.messagebox.focus(); + }; - DOM.guessbox.focus(); + // Add track info + var addTrackInfo = function(data) { + if (touchplay) { + touchplay.removeClass('btn-success').addClass('btn-danger disabled'); + touchplay.html(' Wait'); + } + cassetteAnimation(Date.now()+5000, false); - socket.on('newuser', userJoin); - socket.on('userleft', userLeft); - socket.on('updateusers', updateUsers); - socket.on('chatmsg', getChatMessage); - socket.on('loadtrack', loadTrack); - socket.on('playtrack', playTrack); - socket.on('trackinfo', addTrackInfo); - socket.on('artistmatched', function() { - var feedback = amstrings[Math.floor(Math.random()*amstrings.length)]; - addFeedback(feedback, 'correct'); - }); - socket.on('titlematched', function() { - var feedback = tmstrings[Math.floor(Math.random()*tmstrings.length)]; - addFeedback(feedback, 'correct'); - }); - socket.on('bothmatched', function() { - var feedback = bmstrings[Math.floor(Math.random()*bmstrings.length)]; - addFeedback(feedback, 'correct'); - }); - socket.on('nomatch', function() { - var feedback = nmstrings[Math.floor(Math.random()*nmstrings.length)]; - addFeedback(feedback, 'wrong'); - }); - socket.on('stoptrying', function() { - addFeedback('You guessed both artist and title. Please wait...'); - }); - socket.on('noguesstime', function() { - addFeedback('You have to wait the next song...'); - }); - socket.on('gameover', gameOver); - socket.on('status', setStatus); - socket.emit('getstatus'); - }; + var html = '
  • '; + html += '
    '+data.artistName+'
    '; - var setStatus = function(data) { - if (data.status === 0) { - cassetteAnimation(Date.now()+data.timeleft, true); + var titleattr = '' + , trackname = data.trackName + , attrs = '' + , rp = ''; + + if (data.trackName.length > 45) { + titleattr = data.trackName.replace(/"/g, '"'); + trackname = data.trackName.substring(0, 42) + '...'; } - else if (data.status === 1) { - loadTrack(data.previewUrl); + html += '
    '+trackname+'
    '; + + if (roundpoints > 0) { + rp = '+'+roundpoints; + if (roundpoints > 3) { + var stand = 7 - roundpoints; + attrs += 'class="round-rank stand'+stand+'"'; + } } - addFeedback(states[data.status]); - }; + html += '
    '+rp+'
    '; + html += ''; + html += '
  • '; - // A new player has joined the game - var userJoin = function(username, usersData) { - var msg = username+' joined the game'; - var joinspan = $(''); - joinspan.text(msg); - addChatEntry(joinspan); - updateUsers(usersData); + DOM.tracks.prepend($(html)); }; - // A player has left the game - var userLeft = function(username, usersData) { - var leftmsg = username+' left the game'; - var leftspan = $(''); - leftspan.text(leftmsg); - addChatEntry(leftspan); - updateUsers(usersData); - }; + var addVolumeControl = function() { + var volumebutton = $('
    '+ + '
    '+ + '
    '+ // Outer background + '
    '+ // Rail + '
    '+ // Current volume + '
    '+ // Handle + '
    ').appendTo('#volume'); - // Update the list of players - var updateUsers = function(usersData) { - DOM.users.empty(); - - var users = []; - for (var key in usersData) { - users.push(usersData[key]); - } - users.sort(function(a, b) {return b.points - a.points;}); - - // Flag to test if our private recipient is in the list of active users - var found = false; - for (var i=0; i') - , pvt = $('P') - , username = $('').text(user.nickname) - , points = $('('+user.points+')') - , roundrank = $('') - , roundpointsel = $('') - , guesstime = $(''); + var icon = volumebutton.find('#icon') + , volumeslider = volumebutton.find('#volume-slider') + , volumetotal = volumebutton.find('#volume-total') + , volumecurrent = volumebutton.find('#volume-current') + , volumehandle = volumebutton.find('#volume-handle') + , mouseisdown = false + , mouseisover = false + , oldvalue = 1 + , clicked = false; - li.append(pvt, username, points, roundrank, roundpointsel, guesstime); - if (user.registered) { - var href = 'href="/user/'+encodeURIComponent(user.nickname)+'"'; - pvt.after(''); + var positionVolumeHandle = function(volume) { + if (!volumeslider.is(':visible')) { + volumeslider.show(); + positionVolumeHandle(volume); + volumeslider.hide(); + return; + } + var totalheight = volumetotal.height(); + var totalposition = volumetotal.position(); + var newtop = totalheight - (totalheight * volume); + volumehandle.css('top', totalposition.top + newtop - (volumehandle.height() / 2)); + volumecurrent.height(totalheight - newtop ); + volumecurrent.css('top', totalposition.top + newtop); + }; + + var handleIcon = function (volume) { + if (volume === 0) { + icon.removeClass().addClass('volume-none'); + } + else if (volume <= 0.33) { + icon.removeClass().addClass('volume-low'); } - DOM.users.append(li); - - if (pvtmsgto === user.nickname) { - pvt.show(); - username.click(clearPrivate); - found = true; + else if (volume <= 0.66) { + icon.removeClass().addClass('volume-medium'); } else { - username.click(function() { - addPrivate($(this).text()); - }); + icon.removeClass().addClass('volume-high'); } - - if (nickname === user.nickname) { - username.addClass('you'); - roundpoints = user.roundpoints; - DOM.rank.text(i+1); - DOM.points.text(user.points); + }; + + var setVolume = function(volume) { + handleIcon(volume); + oldvalue = volume; + jplayer.jPlayer('volume', volume); + }; + + var handleVolumeMove = function(e) { + var totaloffset = volumetotal.offset() + , newy = e.pageY - totaloffset.top + , railheight = volumetotal.height() + , totalTop = parseInt(volumetotal.css('top').replace(/px/, ''), 10) + , volume = (railheight - newy) / railheight; + + if (newy < 0) { + newy = 0; } - - if (user.roundpoints > 0) { - roundpointsel.text('+'+user.roundpoints); - if (user.roundpoints === 1) { - username.addClass('matched'); - } - else { - if (user.roundpoints > 3) { - var stand = 7 - user.roundpoints; - roundrank.addClass('round-rank stand'+stand); - var gtime = (user.guesstime / 1000).toFixed(1); - guesstime.text(gtime+' s'); - } - username.addClass('correct'); - } + else if (newy > railheight) { + newy = railheight; } - } - - if (!found && pvtmsgto) { - var width = DOM.recipient.outerWidth(true) + 1; - DOM.recipient.css('margin-right', '0'); - DOM.recipient.text(''); - DOM.messagebox.animate({'width':'+='+width+'px'}, 'fast'); - pvtmsgto = null; - DOM.messagebox.focus(); - } - }; - var addPrivate = function(usrname) { - if (pvtmsgto) { - clearPrivate(); - } - if (nickname === usrname) { - return; - } - DOM.recipient.css('margin-right', '4px'); - DOM.recipient.text('To '+usrname+':'); - var width = DOM.recipient.outerWidth(true) + 1; - DOM.recipient.hide(); - DOM.messagebox.animate({'width':'-='+width+'px'}, 'fast', function() { - DOM.recipient.show(); - }); - var el = $('.name').filter(function(index) { - return $(this).text() === usrname; + volumehandle.css('top', totalTop + newy - (volumehandle.height() / 2)); + volumecurrent.height(railheight - newy); + volumecurrent.css('top', newy + totalTop); + + volume = Math.max(0, volume); + volume = Math.min(volume, 1); + + setVolume(volume); + + var d = new Date(); + d.setTime(d.getTime() + 31536000000); // One year in milliseconds + document.cookie = 'volume='+volume+';path=/;expires='+d.toGMTString()+';'; + }; + + var loadFromCookie = function() { + if (/volume\s*\=/.test(document.cookie)) { + var value = document.cookie.replace(/.*volume\s*\=\s*([^;]*);?.*/, '$1'); + value = parseFloat(value); + positionVolumeHandle(value); + setVolume(value); + return; + } + positionVolumeHandle(1); + }; + + volumebutton.hover(function() { + volumeslider.show(); + mouseisover = true; + }, function() { + mouseisover = false; + if (!mouseisdown) { + volumeslider.hide(); + } }); - el.prevAll('.private').show(); - el.unbind('click'); - el.click(clearPrivate); - pvtmsgto = usrname; - DOM.messagebox.focus(); - }; - var clearPrivate = function() { - var width = DOM.recipient.outerWidth(true) + 1; - DOM.recipient.css('margin-right', '0'); - DOM.recipient.text(''); - DOM.messagebox.animate({'width':'+='+width+'px'}, 'fast'); - var el = $('.name').filter(function(index) { - return $(this).text() === pvtmsgto; + volumeslider.on('mouseover', function() { + mouseisover = true; + }).on('mousedown', function (e) { + handleVolumeMove(e); + mouseisdown = true; + return false; }); - el.prevAll('.private').hide(); - el.unbind('click'); - el.click(function() { - addPrivate($(this).text()); + + $(document).on('mouseup', function (e) { + mouseisdown = false; + if (!mouseisover) { + volumeslider.hide(); + } + }).on('mousemove', function (e) { + if (mouseisdown) { + handleVolumeMove(e); + } }); - pvtmsgto = null; - DOM.messagebox.focus(); - }; - // Convert any URLs in text into clickable links. - var urlize = function(text) { - if (text.match(urlregex)) { - var html = ''; - var splits = text.split(urlregex); - for (var i=0; i'+escapedsplit+''; - continue; + volumebutton.find('.button').click(function() { + if (!clicked) { + clicked = true; + if (oldvalue !== 0) { + jplayer.jPlayer('volume', 0); + positionVolumeHandle(0); + handleIcon(0); } - html += escapedsplit; } - return html; - } - return text.encodeEntities(); - }; - - // Receive a chat message - var getChatMessage = function(chatmsg, from, to) { - var prefix = from; - var msgspan = $(''); - if (to) { - // Private Message - prefix = (nickname === from) ? '(To '+to+')' : '(From '+prefix+')'; - msgspan.addClass('private'); - } - var msg = prefix+': '+chatmsg; - msgspan.html(urlize(msg)); - addChatEntry(msgspan); - }; + else { + clicked = false; + if (oldvalue !== 0) { + jplayer.jPlayer('volume', oldvalue); + positionVolumeHandle(oldvalue); + handleIcon(oldvalue); + } + } + }); - var loadTrack = function(previewUrl) { - jplayer.jPlayer('mute'); - jplayer.jPlayer('setMedia', {m4a: previewUrl}); + loadFromCookie(); }; - // Play a track - var playTrack = function(data) { - if (touchplay) { - touchplay.removeClass('btn-danger disabled').addClass('btn-success'); - touchplay.html(' Play'); - } - jplayer.jPlayer('unmute'); - jplayer.jPlayer('play'); - updateUsers(data.users); - cassetteAnimation(Date.now()+30000, true); - if (data.counter === 1) { - DOM.modal.modal('hide').empty(); - DOM.tracks.empty(); - } - DOM.track.text(data.counter+'/'+data.tot); - addFeedback('What is this song?'); + /* Triggered when a logged user tries to join a room from another tab or another browser + and he is already in a room */ + var alreadyInARoom = function() { + var html = ''; + html += ''; + $(html).appendTo(DOM.modal); + DOM.modal.modal('show'); }; // Start cassette animation @@ -465,43 +340,24 @@ return; } - setTimeout(function() {cassetteAnimation(endtime, forward);}, 50); - }; - - // Add track info - var addTrackInfo = function(data) { - if (touchplay) { - touchplay.removeClass('btn-success').addClass('btn-danger disabled'); - touchplay.html(' Wait'); - } - cassetteAnimation(Date.now()+5000, false); - - var html = '
  • '; - html += '
    '+data.artistName+'
    '; - - var titleattr = '' - , trackname = data.trackName - , attrs = '' - , rp = ''; - - if (data.trackName.length > 45) { - titleattr = data.trackName.replace(/"/g, '"'); - trackname = data.trackName.substring(0, 42) + '...'; - } - html += '
    '+trackname+'
    '; - - if (roundpoints > 0) { - rp = '+'+roundpoints; - if (roundpoints > 3) { - var stand = 7 - roundpoints; - attrs += 'class="round-rank stand'+stand+'"'; - } - } - html += '
    '+rp+'
    '; - html += ''; - html += '
  • '; - - DOM.tracks.prepend($(html)); + setTimeout(function() {cassetteAnimation(endtime, forward);}, 50); + }; + + var clearPrivate = function() { + var width = DOM.recipient.outerWidth(true) + 1; + DOM.recipient.css('margin-right', '0'); + DOM.recipient.text(''); + DOM.messagebox.animate({'width':'+='+width+'px'}, 'fast'); + var el = $('.name').filter(function(index) { + return $(this).text() === pvtmsgto; + }); + el.prevAll('.private').hide(); + el.unbind('click'); + el.click(function() { + addPrivate($(this).text()); + }); + pvtmsgto = null; + DOM.messagebox.focus(); }; // Game over countdown @@ -515,6 +371,16 @@ setTimeout(function() {countDown(endtime);}, 200); }; + // Let the user know when he/she has disconnected + var disconnect = function() { + stopanimation = true; + jplayer.jPlayer('stop'); + var errorspan = $('ERROR: You have disconnected.'); + addChatEntry(errorspan); + addFeedback('Something wrong happened'); + DOM.users.empty(); + }; + var gameOver = function(podium) { var html = ''; html += '