diff --git a/app/views/lobby/jsI18n.scala.html b/app/views/lobby/jsI18n.scala.html
index 3ae26f2332..cb5806efcb 100644
--- a/app/views/lobby/jsI18n.scala.html
+++ b/app/views/lobby/jsI18n.scala.html
@@ -1,5 +1,12 @@
@()(implicit ctx: Context)
@Html(J.stringify(i18nJsObject(
trans.realTime,
-trans.correspondence
+trans.correspondence,
+trans.nbGamesInPlay,
+trans.player,
+trans.time,
+trans.joinTheGame,
+trans.cancel,
+trans.casual,
+trans.rated
)))
diff --git a/modules/lobby/src/main/Hook.scala b/modules/lobby/src/main/Hook.scala
index a47e8232d7..d01cb2ac78 100644
--- a/modules/lobby/src/main/Hook.scala
+++ b/modules/lobby/src/main/Hook.scala
@@ -58,7 +58,7 @@ case class Hook(
"username" -> username,
"rating" -> rating,
"variant" -> realVariant.shortName,
- "mode" -> realMode.toString,
+ "mode" -> realMode.id,
"clock" -> clock.show,
"time" -> clock.estimateTotalTime,
"speed" -> speed.id,
diff --git a/public/javascripts/big.js b/public/javascripts/big.js
index e2f9335681..fe27fcc875 100644
--- a/public/javascripts/big.js
+++ b/public/javascripts/big.js
@@ -287,6 +287,12 @@ var storage = {
});
}
+ if (lichess.round) startRound(document.getElementById('lichess'), lichess.round);
+ else if (lichess.prelude) startPrelude(document.querySelector('.lichess_game'), lichess.prelude);
+ else if (lichess.analyse) startAnalyse(document.getElementById('lichess'), lichess.analyse);
+ else if (lichess.user_analysis) startUserAnalysis(document.getElementById('lichess'), lichess.user_analysis);
+ else if (lichess.lobby) startLobby(document.getElementById('hooks_wrap'), lichess.lobby);
+
$('#lichess').on('click', '.socket-link:not(.disabled)', function() {
lichess.socket.send($(this).data('msg'), $(this).data('data'));
});
@@ -387,11 +393,6 @@ var storage = {
$('body').on('lichess.content_loaded', setBlindMode);
}
- if (lichess.round) startRound(document.getElementById('lichess'), lichess.round);
- else if (lichess.prelude) startPrelude(document.querySelector('.lichess_game'), lichess.prelude);
- else if (lichess.analyse) startAnalyse(document.getElementById('lichess'), lichess.analyse);
- else if (lichess.user_analysis) startUserAnalysis(document.getElementById('lichess'), lichess.user_analysis);
-
setTimeout(function() {
if (lichess.socket === null) {
lichess.socket = new lichess.StrongSocket("/socket", 0);
@@ -1243,6 +1244,468 @@ var storage = {
}, 100);
});
+ function startLobby(element, cfg) {
+ var $timeline = $("#timeline");
+ var $newposts = $("div.new_posts");
+ var nbPlayersElement = document.getElementById('site_baseline span');
+ var lobby;
+ // var $canvas = $wrap.find('.canvas');
+ // var $hooksList = $wrap.find('#hooks_list');
+ // var $tableWrap = $hooksList.find('div.table_wrap');
+ // var $table = $tableWrap.find('table').sortable();
+ // var $tbody = $table.find('tbody');
+ // var animation = 500;
+ // var hookPool = [];
+ // var nextHooks = [];
+
+ // var flushHooksTimeout;
+ // var flushHooksSchedule = function() {
+ // flushHooksTimeout = setTimeout(flushHooks, 8000);
+ // };
+ // var flushHooks = function() {
+ // clearTimeout(flushHooksTimeout);
+ // $tbody.fadeIn(500);
+ // $tableWrap.clone().attr('id', 'tableclone').appendTo($hooksList).fadeOut(500, function() {
+ // $(this).remove();
+ // });
+ // $tbody.find('tr.disabled').remove();
+ // $tbody.append(nextHooks);
+ // nextHooks = [];
+ // $table.trigger('sortable.sort');
+ // flushHooksSchedule();
+ // };
+ // flushHooksSchedule();
+ // $('body').on('lichess.hook-flush', flushHooks);
+
+ // $wrap.on('click', '>div.tabs>a', function() {
+ // var tab = $(this).data('tab');
+ // $(this).siblings().removeClass('active').end().addClass('active');
+ // $wrap.find('>.tab').hide().filter('.' + tab).show();
+ // storage.set('lobbytab', tab);
+ // reloadSeeksIfVisible();
+ // });
+ // var active = storage.get('lobbytab');
+ // if (['real_time', 'seeks', 'now_playing'].indexOf(active) === -1) active = 'real_time';
+ // if (!$wrap.find('>div.tabs>.' + active).length) active = 'real_time';
+ // $wrap.find('>div.tabs>.' + active).addClass('active');
+ // $wrap.find('>.' + active).show();
+
+ // $realTime.on('click', '.toggle', function() {
+ // var mode = $(this).data('mode');
+ // $realTime.children().hide().filter('#hooks_' + mode).show();
+ // storage.set('lobbymode', mode);
+ // });
+ // var mode = storage.get('lobbymode') || 'list';
+ // $('#hooks_' + mode).show();
+
+ // $wrap.find('a.filter').click(function() {
+ // var $a = $(this);
+ // var $div = $wrap.find('#hook_filter');
+ // setTimeout(function() {
+ // $div.click(function(e) {
+ // e.stopPropagation();
+ // });
+ // $('html').one('click', function(e) {
+ // $div.off('click').removeClass('active');
+ // $a.removeClass('active');
+ // });
+ // }, 10);
+ // if ($(this).toggleClass('active').hasClass('active')) {
+ // $div.addClass('active');
+ // if ($div.is(':empty')) {
+ // $.ajax({
+ // url: $(this).attr('href'),
+ // success: function(html) {
+ // var save = $.fp.debounce(function() {
+ // var $form = $div.find('form');
+ // $.ajax({
+ // url: $form.attr('action'),
+ // data: $form.serialize(),
+ // type: 'post',
+ // success: function(filter) {
+ // lichess_preload.filter = filter;
+ // drawHooks();
+ // $('body').trigger('lichess.hook-flush');
+ // }
+ // });
+ // }, 500);
+ // $div.html(html).find('input').change(save);
+ // $div.find('button.reset').click(function() {
+ // $div.find('label input').prop('checked', true).trigger('change');
+ // $div.find('.rating_range').each(function() {
+ // var s = $(this);
+ // s.slider('values', [s.slider('option', 'min'), s.slider('option', 'max')]).trigger('change');
+ // });
+ // });
+ // $div.find('button').click(function() {
+ // $wrap.find('a.filter').click();
+ // return false;
+ // });
+ // $div.find('.rating_range').each(function() {
+ // var $this = $(this);
+ // var $input = $this.find("input");
+ // var $span = $this.siblings(".range");
+ // var min = $input.data("min");
+ // var max = $input.data("max");
+ // var values = $input.val() ? $input.val().split("-") : [min, max];
+ // $span.text(values.join(' - '));
+
+ // function change() {
+ // setTimeout(function() {
+ // var values = $this.slider('values');
+ // $input.val(values[0] + "-" + values[1]);
+ // $span.text(values[0] + " - " + values[1]);
+ // save();
+ // }, 50);
+ // }
+ // $this.slider({
+ // range: true,
+ // min: min,
+ // max: max,
+ // values: values,
+ // step: 50,
+ // slide: change
+ // }).change(change);
+ // });
+ // }
+ // });
+ // }
+ // } else {
+ // $div.removeClass('active');
+ // }
+ // return false;
+ // });
+
+ function resizeTimeline() {
+ if ($timeline.length) {
+ var pos = $timeline.offset().top,
+ max = $('#lichess').offset().top + 536;
+ while (pos + $timeline.outerHeight() > max) {
+ $timeline.find('div.entry:last').remove();
+ }
+ }
+ }
+ resizeTimeline();
+
+ // lichess_preload.hookPool.forEach(addHook);
+ // drawHooks(true);
+ // $table.find('th:eq(2)').click().end();
+
+ lichess.socket = new lichess.StrongSocket(
+ '/lobby/socket/v1',
+ cfg.data.version, {
+ receive: function(t, d) {
+ if (lobby) lobby.socketReceive(t, d);
+ else console.log('missed', t, d);
+ },
+ events: {
+ reload_timeline: function() {
+ $.ajax({
+ url: $timeline.data('href'),
+ success: function(html) {
+ $timeline.html(html);
+ resizeTimeline();
+ $('body').trigger('lichess.content_loaded');
+ }
+ });
+ },
+ streams: function(html) {
+ $('#streams_on_air').html(html);
+ },
+ // hook_add: function(hook) {
+ // addHook(hook);
+ // drawHooks();
+ // if (hook.action == 'cancel') $('body').trigger('lichess.hook-flush');
+ // },
+ // hook_remove: removeHook,
+ // hook_list: syncHookIds,
+ featured: changeFeatured,
+ redirect: function(e) {
+ $.lichessOpeningPreventClicks();
+ $.redirect(e);
+ },
+ tournaments: function(data) {
+ $("#enterable_tournaments").html(data);
+ $('body').trigger('lichess.content_loaded');
+ },
+ reload_forum: function() {
+ setTimeout(function() {
+ $.ajax($newposts.data('url'), {
+ success: function(data) {
+ $newposts.find('ol').html(data).end().scrollTop(0);
+ $('body').trigger('lichess.content_loaded');
+ }
+ });
+ }, Math.round(Math.random() * 5000));
+ },
+ // reload_seeks: reloadSeeksIfVisible,
+ nbr: function(e) {
+ if (nbPlayersElement && e) {
+ var prev = parseInt(nbPlayersElement.textContent, 10);
+ var k = 5;
+ var interv = 2000 / k;
+ $.fp.range(k).forEach(function(it) {
+ setTimeout(function() {
+ var val = Math.round(((prev * (k - 1 - it)) + (e * (it + 1))) / k);
+ if (val != prev) {
+ nbPlayersElement.textContent = val;
+ prev = val;
+ }
+ }, Math.round(it * interv));
+ });
+ }
+ },
+ // override fen event to reload playing games list
+ // fen: function(e) {
+ // lichess.StrongSocket.defaults.events.fen(e);
+ // if ($nowPlaying.find('.mini_board_' + e.id).length) $.ajax({
+ // url: $nowPlaying.data('href'),
+ // success: function(html) {
+ // $nowPlaying.html(html);
+ // $('body').trigger('lichess.content_loaded');
+ // var nb = $nowPlaying.find('.my_turn').length;
+ // $wrap.find('.tabs .now_playing').toggleClass('hilight', nb).find('.unread').text(nb);
+ // }
+ // });
+ // }
+ },
+ options: {
+ name: 'lobby'
+ }
+ });
+
+ cfg.socketSend = lichess.socket.send.bind(lichess.socket);
+ lobby = LichessLobby(document.getElementById('hooks_wrap'), cfg);
+
+ // var variantConfirms = {
+ // '960': "This is a Chess960 game!\n\nThe starting position of the pieces on the players' home ranks is randomized.\nRead more: http://wikipedia.org/wiki/Chess960\n\nDo you want to play Chess960?",
+ // 'KotH': "This is a King of the Hill game!\n\nThe game can be won by bringing the king to the center.\nRead more: http://lichess.org/king-of-the-hill",
+ // '3+': "This is a Three-check game!\n\nThe game can be won by checking the opponent 3 times.\nRead more: http://en.wikipedia.org/wiki/Three-check_chess",
+ // "Anti": "This is an antichess chess game!\n\n If you can take a piece, you must. The game can be won by losing all your pieces."
+ // };
+
+ // function confirmVariant(variant) {
+ // return Object.keys(variantConfirms).every(function(key) {
+ // var v = variantConfirms[key]
+ // if (variant == key && !storage.get(key)) {
+ // var c = confirm(v);
+ // if (c) storage.set(key, 1);
+ // return c;
+ // } else return true;
+ // })
+ // }
+
+ // $seeks.on('click', 'tr', function() {
+ // if ($(this).hasClass('must_login')) {
+ // if (confirm($.trans('You need an account to do that'))) {
+ // location.href = '/signup';
+ // }
+ // return false;
+ // }
+ // if ($(this).data('action') != 'joinSeek' || confirmVariant($(this).data('variant'))) {
+ // lichess.socket.send($(this).data('action'), $(this).data('id'));
+ // }
+ // });
+
+ // function reloadSeeksIfVisible() {
+ // if ($seeks.is(':visible')) {
+ // $.ajax($seeks.data('reload-url'), {
+ // success: function(html) {
+ // $seeks.html(html);
+ // }
+ // });
+ // }
+ // }
+
+ function changeFeatured(o) {
+ $('#featured_game').html(o.html);
+ $('body').trigger('lichess.content_loaded');
+ }
+
+ // function removeHook(id) {
+ // hookPool = hookPool.filter(function(h) {
+ // return h.id != id;
+ // });
+ // drawHooks();
+ // }
+
+ // function syncHookIds(ids) {
+ // hookPool = hookPool.filter(function(h) {
+ // return $.fp.contains(ids, h.id);
+ // });
+ // drawHooks();
+ // }
+
+ // function addHook(hook) {
+ // hook.action = hook.uid == lichess.StrongSocket.sri ? "cancel" : "join";
+ // hookPool.push(hook);
+ // }
+
+ // function disableHook(id) {
+ // $tbody.children('.' + id).addClass('disabled').attr('title', '');
+ // destroyChartHook(id);
+ // }
+
+ // function destroyHook(id) {
+ // $tbody.children('.' + id).remove();
+ // destroyChartHook(id);
+ // }
+
+ // function destroyChartHook(id) {
+ // $('#' + id).not('.hiding').addClass('hiding').fadeOut(animation, function() {
+ // $.powerTip.destroy($(this));
+ // $(this).remove();
+ // });
+ // }
+
+ // function drawHooks(initial) {
+ // var filter = lichess_preload.filter;
+ // var seen = [];
+ // var hidden = 0;
+ // var visible = 0;
+ // hookPool.forEach(function(hook) {
+ // var hide = !$.fp.contains(filter.variant, hook.variant) || !$.fp.contains(filter.mode, hook.mode) || !$.fp.contains(filter.speed, hook.speed) ||
+ // (filter.rating && (!hook.rating || (hook.rating < filter.rating[0] || hook.rating > filter.rating[1])));
+ // var hash = hook.mode + hook.variant + hook.time + hook.rating;
+ // if (hide && hook.action != 'cancel') {
+ // destroyHook(hook.id);
+ // hidden++;
+ // } else if ($.fp.contains(seen, hash) && hook.action != 'cancel') {
+ // $('#' + hook.id).filter(':visible').hide();
+ // $tbody.children('.' + hook.id).hide();
+ // } else {
+ // visible++;
+ // if (!$('#' + hook.id).length) {
+ // $canvas.append($(renderPlot(hook)).fadeIn(animation));
+ // if (initial) $tbody.append(renderTr(hook));
+ // else nextHooks.push(renderTr(hook));
+ // } else {
+ // $('#' + hook.id).not(':visible').fadeIn(animation);
+ // $tbody.children('.' + hook.id).show();
+ // }
+ // }
+ // if (hook.action != 'cancel') seen.push(hash);
+ // });
+ // $.makeArray($canvas.find('>span.plot')).map(function(o) {
+ // return o.getAttribute('data-id');
+ // }).concat(
+ // $.makeArray($tbody.children()).map(function(o) {
+ // return o.getAttribute('data-id');
+ // })).forEach(function(id) {
+ // if (!$.fp.find(hookPool, function(x) {
+ // return x.id == id;
+ // })) disableHook(id);
+ // });
+
+ // $wrap
+ // .find('a.filter')
+ // .toggleClass('on', hidden > 0)
+ // .find('span.number').text('(' + hidden + ')');
+
+ // $('body').trigger('lichess.content_loaded');
+ // }
+
+ // function renderPlot(hook) {
+ // var bottom = Math.max(0, ratingY(hook.rating) - 7);
+ // var left = Math.max(0, clockX(hook.time) - 4);
+ // var klass = [
+ // 'plot',
+ // hook.mode == "Rated" ? 'rated' : 'casual',
+ // hook.action == 'cancel' ? 'cancel' : '',
+ // hook.variant != 'STD' ? 'variant' : ''
+ // ].join(' ');
+ // var $plot = $('');
+ // return $plot.data('hook', hook).powerTip({
+ // fadeInTime: 0,
+ // fadeOutTime: 0,
+ // placement: hook.rating > 2200 ? 'se' : 'ne',
+ // mouseOnToPopup: true,
+ // closeDelay: 200,
+ // intentPollInterval: 50,
+ // popupId: 'hook'
+ // }).data('powertipjq', $(renderHook(hook)));
+ // }
+
+ // function ratingY(e) {
+ // function ratingLog(a) {
+ // return Math.log(a / 150 + 1);
+ // }
+ // var rating = Math.max(800, Math.min(2800, e || 1500));
+ // var ratio;
+ // if (rating == 1500) {
+ // ratio = 0.25;
+ // } else if (rating > 1500) {
+ // ratio = 0.25 + (ratingLog(rating - 1500) / ratingLog(1300)) * 3 / 4;
+ // } else {
+ // ratio = 0.25 - (ratingLog(1500 - rating) / ratingLog(500)) / 4;
+ // }
+ // return Math.round(ratio * 489);
+ // }
+
+ // function clockX(dur) {
+ // function durLog(a) {
+ // return Math.log((a - 30) / 200 + 1);
+ // }
+ // var max = 2000;
+ // return Math.round(durLog(Math.min(max, dur || max)) / durLog(max) * 489);
+ // }
+
+ // function renderHook(hook) {
+ // var html = '';
+ // if (hook.rating) {
+ // html += '' + hook.username.substr(0, 14) + '';
+ // html += '' + hook.rating + '';
+ // } else {
+ // html += 'Anonymous';
+ // }
+ // html += '' + hook.clock + '';
+ // html += '' +
+ // '' + $.trans(hook.mode) + '';
+ // html += '';
+ // return html;
+ // }
+
+ // function renderTr(hook) {
+ // var title = (hook.action == "join") ? $.trans('Join the game') + ' - ' + hook.perf.name : $.trans('cancel');
+ // return '
' + [
+ // ['', ''],
+ // [hook.username, (hook.rating ? '' + hook.username + '' : 'Anonymous')],
+ // [hook.rating || 0, hook.rating ? hook.rating : ''],
+ // [hook.time, hook.clock],
+ // [hook.mode,
+ // '' +
+ // $.trans(hook.mode)
+ // ]
+ // ].map(function(x) {
+ // return '' + x[1] + ' | ';
+ // }).join('') + '
';
+ // }
+
+ // $('#hooks_chart').append(
+ // [1000, 1200, 1400, 1500, 1600, 1800, 2000, 2200, 2400].map(function(v) {
+ // var b = ratingY(v);
+ // return '' + v + '' +
+ // '';
+ // }).join('') + [1, 2, 3, 5, 7, 10, 15, 20, 30].map(function(v) {
+ // var l = clockX(v * 60);
+ // return '' + v + '' +
+ // '';
+ // }).join(''));
+
+ // $tbody.on('click', 'a.ulink', function(e) {
+ // e.stopPropagation();
+ // });
+ // $tbody.on('click', 'td:not(.disabled)', function() {
+ // $('#' + $(this).parent().data('id')).click();
+ // });
+ // $canvas.on('click', '>span.plot:not(.hiding)', function() {
+ // var data = $(this).data('hook');
+ // if (data.action != 'join' || confirmVariant(data.variant)) {
+ // lichess.socket.send(data.action, data.id);
+ // }
+ // });
+ }
+
////////////////
// lobby.js //
////////////////
@@ -1533,469 +1996,6 @@ var storage = {
$('#hooks_list, #hooks_chart').hide();
};
- // hooks
- $(function() {
-
- var $wrap = $('#hooks_wrap');
- if (!$wrap.length) return;
- if (!lichess.StrongSocket.available) return;
-
- var $nowPlaying = $('#now_playing');
- var $seeks = $('#seeks');
- var $timeline = $("#timeline");
- var $newposts = $("div.new_posts");
- var $realTime = $('#real_time');
- var nbPlayersElement = document.getElementById('site_baseline span');
- // var $canvas = $wrap.find('.canvas');
- // var $hooksList = $wrap.find('#hooks_list');
- // var $tableWrap = $hooksList.find('div.table_wrap');
- // var $table = $tableWrap.find('table').sortable();
- // var $tbody = $table.find('tbody');
- // var animation = 500;
- // var hookPool = [];
- // var nextHooks = [];
-
- // var flushHooksTimeout;
- // var flushHooksSchedule = function() {
- // flushHooksTimeout = setTimeout(flushHooks, 8000);
- // };
- // var flushHooks = function() {
- // clearTimeout(flushHooksTimeout);
- // $tbody.fadeIn(500);
- // $tableWrap.clone().attr('id', 'tableclone').appendTo($hooksList).fadeOut(500, function() {
- // $(this).remove();
- // });
- // $tbody.find('tr.disabled').remove();
- // $tbody.append(nextHooks);
- // nextHooks = [];
- // $table.trigger('sortable.sort');
- // flushHooksSchedule();
- // };
- // flushHooksSchedule();
- // $('body').on('lichess.hook-flush', flushHooks);
-
- // $wrap.on('click', '>div.tabs>a', function() {
- // var tab = $(this).data('tab');
- // $(this).siblings().removeClass('active').end().addClass('active');
- // $wrap.find('>.tab').hide().filter('.' + tab).show();
- // storage.set('lobbytab', tab);
- // reloadSeeksIfVisible();
- // });
- // var active = storage.get('lobbytab');
- // if (['real_time', 'seeks', 'now_playing'].indexOf(active) === -1) active = 'real_time';
- // if (!$wrap.find('>div.tabs>.' + active).length) active = 'real_time';
- // $wrap.find('>div.tabs>.' + active).addClass('active');
- // $wrap.find('>.' + active).show();
-
- // $realTime.on('click', '.toggle', function() {
- // var mode = $(this).data('mode');
- // $realTime.children().hide().filter('#hooks_' + mode).show();
- // storage.set('lobbymode', mode);
- // });
- // var mode = storage.get('lobbymode') || 'list';
- // $('#hooks_' + mode).show();
-
- // $wrap.find('a.filter').click(function() {
- // var $a = $(this);
- // var $div = $wrap.find('#hook_filter');
- // setTimeout(function() {
- // $div.click(function(e) {
- // e.stopPropagation();
- // });
- // $('html').one('click', function(e) {
- // $div.off('click').removeClass('active');
- // $a.removeClass('active');
- // });
- // }, 10);
- // if ($(this).toggleClass('active').hasClass('active')) {
- // $div.addClass('active');
- // if ($div.is(':empty')) {
- // $.ajax({
- // url: $(this).attr('href'),
- // success: function(html) {
- // var save = $.fp.debounce(function() {
- // var $form = $div.find('form');
- // $.ajax({
- // url: $form.attr('action'),
- // data: $form.serialize(),
- // type: 'post',
- // success: function(filter) {
- // lichess_preload.filter = filter;
- // drawHooks();
- // $('body').trigger('lichess.hook-flush');
- // }
- // });
- // }, 500);
- // $div.html(html).find('input').change(save);
- // $div.find('button.reset').click(function() {
- // $div.find('label input').prop('checked', true).trigger('change');
- // $div.find('.rating_range').each(function() {
- // var s = $(this);
- // s.slider('values', [s.slider('option', 'min'), s.slider('option', 'max')]).trigger('change');
- // });
- // });
- // $div.find('button').click(function() {
- // $wrap.find('a.filter').click();
- // return false;
- // });
- // $div.find('.rating_range').each(function() {
- // var $this = $(this);
- // var $input = $this.find("input");
- // var $span = $this.siblings(".range");
- // var min = $input.data("min");
- // var max = $input.data("max");
- // var values = $input.val() ? $input.val().split("-") : [min, max];
- // $span.text(values.join(' - '));
-
- // function change() {
- // setTimeout(function() {
- // var values = $this.slider('values');
- // $input.val(values[0] + "-" + values[1]);
- // $span.text(values[0] + " - " + values[1]);
- // save();
- // }, 50);
- // }
- // $this.slider({
- // range: true,
- // min: min,
- // max: max,
- // values: values,
- // step: 50,
- // slide: change
- // }).change(change);
- // });
- // }
- // });
- // }
- // } else {
- // $div.removeClass('active');
- // }
- // return false;
- // });
-
- function resizeTimeline() {
- if ($timeline.length) {
- var pos = $timeline.offset().top,
- max = $('#lichess').offset().top + 536;
- while (pos + $timeline.outerHeight() > max) {
- $timeline.find('div.entry:last').remove();
- }
- }
- }
- resizeTimeline();
-
- // lichess_preload.hookPool.forEach(addHook);
- // drawHooks(true);
- // $table.find('th:eq(2)').click().end();
-
- lichess.socket = new lichess.StrongSocket(
- '/lobby/socket/v1',
- lichess.lobby.data.version, {
- events: {
- reload_timeline: function() {
- $.ajax({
- url: $timeline.data('href'),
- success: function(html) {
- $timeline.html(html);
- resizeTimeline();
- $('body').trigger('lichess.content_loaded');
- }
- });
- },
- streams: function(html) {
- $('#streams_on_air').html(html);
- },
- // hook_add: function(hook) {
- // addHook(hook);
- // drawHooks();
- // if (hook.action == 'cancel') $('body').trigger('lichess.hook-flush');
- // },
- // hook_remove: removeHook,
- // hook_list: syncHookIds,
- featured: changeFeatured,
- redirect: function(e) {
- $.lichessOpeningPreventClicks();
- $.redirect(e);
- },
- tournaments: function(data) {
- $("#enterable_tournaments").html(data);
- $('body').trigger('lichess.content_loaded');
- },
- reload_forum: function() {
- setTimeout(function() {
- $.ajax($newposts.data('url'), {
- success: function(data) {
- $newposts.find('ol').html(data).end().scrollTop(0);
- $('body').trigger('lichess.content_loaded');
- }
- });
- }, Math.round(Math.random() * 5000));
- },
- // reload_seeks: reloadSeeksIfVisible,
- nbr: function(e) {
- if (nbPlayersElement && e) {
- var prev = parseInt(nbPlayersElement.textContent, 10);
- var k = 5;
- var interv = 2000 / k;
- $.fp.range(k).forEach(function(it) {
- setTimeout(function() {
- var val = Math.round(((prev * (k - 1 - it)) + (e * (it + 1))) / k);
- if (val != prev) {
- nbPlayersElement.textContent = val;
- prev = val;
- }
- }, Math.round(it * interv));
- });
- }
- },
- // override fen event to reload playing games list
- // fen: function(e) {
- // lichess.StrongSocket.defaults.events.fen(e);
- // if ($nowPlaying.find('.mini_board_' + e.id).length) $.ajax({
- // url: $nowPlaying.data('href'),
- // success: function(html) {
- // $nowPlaying.html(html);
- // $('body').trigger('lichess.content_loaded');
- // var nb = $nowPlaying.find('.my_turn').length;
- // $wrap.find('.tabs .now_playing').toggleClass('hilight', nb).find('.unread').text(nb);
- // }
- // });
- // }
- },
- options: {
- name: "lobby"
- }
- });
-
- // var variantConfirms = {
- // '960': "This is a Chess960 game!\n\nThe starting position of the pieces on the players' home ranks is randomized.\nRead more: http://wikipedia.org/wiki/Chess960\n\nDo you want to play Chess960?",
- // 'KotH': "This is a King of the Hill game!\n\nThe game can be won by bringing the king to the center.\nRead more: http://lichess.org/king-of-the-hill",
- // '3+': "This is a Three-check game!\n\nThe game can be won by checking the opponent 3 times.\nRead more: http://en.wikipedia.org/wiki/Three-check_chess",
- // "Anti": "This is an antichess chess game!\n\n If you can take a piece, you must. The game can be won by losing all your pieces."
- // };
-
- // function confirmVariant(variant) {
- // return Object.keys(variantConfirms).every(function(key) {
- // var v = variantConfirms[key]
- // if (variant == key && !storage.get(key)) {
- // var c = confirm(v);
- // if (c) storage.set(key, 1);
- // return c;
- // } else return true;
- // })
- // }
-
- // $seeks.on('click', 'tr', function() {
- // if ($(this).hasClass('must_login')) {
- // if (confirm($.trans('You need an account to do that'))) {
- // location.href = '/signup';
- // }
- // return false;
- // }
- // if ($(this).data('action') != 'joinSeek' || confirmVariant($(this).data('variant'))) {
- // lichess.socket.send($(this).data('action'), $(this).data('id'));
- // }
- // });
-
- // function reloadSeeksIfVisible() {
- // if ($seeks.is(':visible')) {
- // $.ajax($seeks.data('reload-url'), {
- // success: function(html) {
- // $seeks.html(html);
- // }
- // });
- // }
- // }
-
- function changeFeatured(o) {
- $('#featured_game').html(o.html);
- $('body').trigger('lichess.content_loaded');
- }
-
- // function removeHook(id) {
- // hookPool = hookPool.filter(function(h) {
- // return h.id != id;
- // });
- // drawHooks();
- // }
-
- // function syncHookIds(ids) {
- // hookPool = hookPool.filter(function(h) {
- // return $.fp.contains(ids, h.id);
- // });
- // drawHooks();
- // }
-
- // function addHook(hook) {
- // hook.action = hook.uid == lichess.StrongSocket.sri ? "cancel" : "join";
- // hookPool.push(hook);
- // }
-
- // function disableHook(id) {
- // $tbody.children('.' + id).addClass('disabled').attr('title', '');
- // destroyChartHook(id);
- // }
-
- // function destroyHook(id) {
- // $tbody.children('.' + id).remove();
- // destroyChartHook(id);
- // }
-
- // function destroyChartHook(id) {
- // $('#' + id).not('.hiding').addClass('hiding').fadeOut(animation, function() {
- // $.powerTip.destroy($(this));
- // $(this).remove();
- // });
- // }
-
- // function drawHooks(initial) {
- // var filter = lichess_preload.filter;
- // var seen = [];
- // var hidden = 0;
- // var visible = 0;
- // hookPool.forEach(function(hook) {
- // var hide = !$.fp.contains(filter.variant, hook.variant) || !$.fp.contains(filter.mode, hook.mode) || !$.fp.contains(filter.speed, hook.speed) ||
- // (filter.rating && (!hook.rating || (hook.rating < filter.rating[0] || hook.rating > filter.rating[1])));
- // var hash = hook.mode + hook.variant + hook.time + hook.rating;
- // if (hide && hook.action != 'cancel') {
- // destroyHook(hook.id);
- // hidden++;
- // } else if ($.fp.contains(seen, hash) && hook.action != 'cancel') {
- // $('#' + hook.id).filter(':visible').hide();
- // $tbody.children('.' + hook.id).hide();
- // } else {
- // visible++;
- // if (!$('#' + hook.id).length) {
- // $canvas.append($(renderPlot(hook)).fadeIn(animation));
- // if (initial) $tbody.append(renderTr(hook));
- // else nextHooks.push(renderTr(hook));
- // } else {
- // $('#' + hook.id).not(':visible').fadeIn(animation);
- // $tbody.children('.' + hook.id).show();
- // }
- // }
- // if (hook.action != 'cancel') seen.push(hash);
- // });
- // $.makeArray($canvas.find('>span.plot')).map(function(o) {
- // return o.getAttribute('data-id');
- // }).concat(
- // $.makeArray($tbody.children()).map(function(o) {
- // return o.getAttribute('data-id');
- // })).forEach(function(id) {
- // if (!$.fp.find(hookPool, function(x) {
- // return x.id == id;
- // })) disableHook(id);
- // });
-
- // $wrap
- // .find('a.filter')
- // .toggleClass('on', hidden > 0)
- // .find('span.number').text('(' + hidden + ')');
-
- // $('body').trigger('lichess.content_loaded');
- // }
-
- // function renderPlot(hook) {
- // var bottom = Math.max(0, ratingY(hook.rating) - 7);
- // var left = Math.max(0, clockX(hook.time) - 4);
- // var klass = [
- // 'plot',
- // hook.mode == "Rated" ? 'rated' : 'casual',
- // hook.action == 'cancel' ? 'cancel' : '',
- // hook.variant != 'STD' ? 'variant' : ''
- // ].join(' ');
- // var $plot = $('');
- // return $plot.data('hook', hook).powerTip({
- // fadeInTime: 0,
- // fadeOutTime: 0,
- // placement: hook.rating > 2200 ? 'se' : 'ne',
- // mouseOnToPopup: true,
- // closeDelay: 200,
- // intentPollInterval: 50,
- // popupId: 'hook'
- // }).data('powertipjq', $(renderHook(hook)));
- // }
-
- // function ratingY(e) {
- // function ratingLog(a) {
- // return Math.log(a / 150 + 1);
- // }
- // var rating = Math.max(800, Math.min(2800, e || 1500));
- // var ratio;
- // if (rating == 1500) {
- // ratio = 0.25;
- // } else if (rating > 1500) {
- // ratio = 0.25 + (ratingLog(rating - 1500) / ratingLog(1300)) * 3 / 4;
- // } else {
- // ratio = 0.25 - (ratingLog(1500 - rating) / ratingLog(500)) / 4;
- // }
- // return Math.round(ratio * 489);
- // }
-
- // function clockX(dur) {
- // function durLog(a) {
- // return Math.log((a - 30) / 200 + 1);
- // }
- // var max = 2000;
- // return Math.round(durLog(Math.min(max, dur || max)) / durLog(max) * 489);
- // }
-
- // function renderHook(hook) {
- // var html = '';
- // if (hook.rating) {
- // html += '' + hook.username.substr(0, 14) + '';
- // html += '' + hook.rating + '';
- // } else {
- // html += 'Anonymous';
- // }
- // html += '' + hook.clock + '';
- // html += '' +
- // '' + $.trans(hook.mode) + '';
- // html += '';
- // return html;
- // }
-
- // function renderTr(hook) {
- // var title = (hook.action == "join") ? $.trans('Join the game') + ' - ' + hook.perf.name : $.trans('cancel');
- // return '' + [
- // ['', ''],
- // [hook.username, (hook.rating ? '' + hook.username + '' : 'Anonymous')],
- // [hook.rating || 0, hook.rating ? hook.rating : ''],
- // [hook.time, hook.clock],
- // [hook.mode,
- // '' +
- // $.trans(hook.mode)
- // ]
- // ].map(function(x) {
- // return '' + x[1] + ' | ';
- // }).join('') + '
';
- // }
-
- // $('#hooks_chart').append(
- // [1000, 1200, 1400, 1500, 1600, 1800, 2000, 2200, 2400].map(function(v) {
- // var b = ratingY(v);
- // return '' + v + '' +
- // '';
- // }).join('') + [1, 2, 3, 5, 7, 10, 15, 20, 30].map(function(v) {
- // var l = clockX(v * 60);
- // return '' + v + '' +
- // '';
- // }).join(''));
-
- // $tbody.on('click', 'a.ulink', function(e) {
- // e.stopPropagation();
- // });
- // $tbody.on('click', 'td:not(.disabled)', function() {
- // $('#' + $(this).parent().data('id')).click();
- // });
- // $canvas.on('click', '>span.plot:not(.hiding)', function() {
- // var data = $(this).data('hook');
- // if (data.action != 'join' || confirmVariant(data.variant)) {
- // lichess.socket.send(data.action, data.id);
- // }
- // });
- });
-
///////////////////
// tournament.js //
///////////////////
diff --git a/public/stylesheets/home.css b/public/stylesheets/home.css
index ed1bed09c0..3d68a2bebd 100644
--- a/public/stylesheets/home.css
+++ b/public/stylesheets/home.css
@@ -42,6 +42,7 @@ div.lobby_and_ground {
display: inline-block;
text-decoration: none;
padding: 0px 8px;
+ margin-right: 3px;
border: 1px solid #ccc;
background: #dadada;
transition: 0.13s;
@@ -59,10 +60,7 @@ div.lobby_and_ground {
border-top: 2px solid #d85000;
}
#hooks_wrap > div.tabs .unread {
- display: none;
-}
-#hooks_wrap > div.tabs a.hilight .unread {
- display: inline;
+ margin-left: 3px;
}
#real_time .toggle {
cursor: pointer;
@@ -149,15 +147,12 @@ div.lobby_and_ground {
margin-left: 3px;
}
#hooks_wrap .table_wrap {
+ text-shadow: 0px 1px 0px #FFF;
width: 512px;
max-height: 512px;
- min-height: 200px;
+ min-height: 78px;
overflow: hidden;
}
-#hooks_wrap .table_wrap table {
- width: 512px;
- text-shadow: 0px 1px 0px #FFF;
-}
#hooks_wrap .table_wrap thead th {
padding: 14px 12px;
font-weight: lighter;
@@ -166,16 +161,6 @@ div.lobby_and_ground {
#hooks_list thead th {
cursor: pointer;
}
-#hooks_wrap .table_wrap th.reload span {
- display: block;
- cursor: pointer;
- margin-left: 2px;
- opacity: 0.5;
- transition: 0.13s;
-}
-#hooks_wrap .table_wrap th.reload:hover span {
- opacity: 0.8;
-}
#hooks_wrap .table_wrap th.sorting-asc,
#hooks_wrap .table_wrap th.sorting-desc {
font-weight: normal;
diff --git a/ui/analyse/src/ctrl.js b/ui/analyse/src/ctrl.js
index 55a4d589aa..376094620d 100644
--- a/ui/analyse/src/ctrl.js
+++ b/ui/analyse/src/ctrl.js
@@ -143,8 +143,8 @@ module.exports = function(cfg, router, i18n, onChange) {
this.router = router;
- this.trans = function() {
- var str = i18n[arguments[0]]
+ this.trans = function(key) {
+ var str = i18n[key] || key;
Array.prototype.slice.call(arguments, 1).forEach(function(arg) {
str = str.replace('%s', arg);
});
diff --git a/ui/lobby/src/ctrl.js b/ui/lobby/src/ctrl.js
index 5ca72a8b38..817d6bd50d 100644
--- a/ui/lobby/src/ctrl.js
+++ b/ui/lobby/src/ctrl.js
@@ -1,24 +1,40 @@
var m = require('mithril');
-var partial = chessground.util.partial;
+var socket = require('./socket');
+var variant = require('./variant');
+var lobby = require('./lobby');
-module.exports = function(opts) {
+module.exports = function(env) {
- this.data = data({}, opts.data);
+ this.data = env.data;
+ lobby.sortHooks(this.data.hooks);
+
+ this.socket = new socket(env.socketSend, this);
+
+ var fixTab = function(tab) {
+ if (['real_time', 'seeks', 'now_playing'].indexOf(tab) === -1) tab = 'real_time';
+ if (tab === 'now_playing' && this.data.nowPlaying.length === 0) tab = 'real_time';
+ return tab;
+ }.bind(this);
+
+ this.setTab = function(tab) {
+ this.vm.tab = fixTab(tab);
+ storage.set('lobbytab', this.vm.tab);
+ }.bind(this);
this.vm = {
+ tab: fixTab(storage.get('lobbytab'))
};
- this.socket = new socket(opts.socketSend, this);
+ this.clickHook = function(hook) {
+ if (hook.action === 'cancel' || variant.confirm(data.variant)) socket.send(hook.action, hook.id);
+ }.bind(this);
- this.router = opts.routes;
-
- this.trans = function() {
- var str = opts.i18n[arguments[0]]
+ this.router = env.routes;
+ this.trans = function(key) {
+ var str = env.i18n[key] || key;
Array.prototype.slice.call(arguments, 1).forEach(function(arg) {
str = str.replace('%s', arg);
});
return str;
};
-
- init(this);
};
diff --git a/ui/lobby/src/i18n.js b/ui/lobby/src/i18n.js
index 1791892eab..8bba5c6d84 100644
--- a/ui/lobby/src/i18n.js
+++ b/ui/lobby/src/i18n.js
@@ -1,6 +1,6 @@
module.exports = function(messages) {
return function(key) {
- var str = messages[key] || untranslated[key] || key;
+ var str = messages[key] || key;
Array.prototype.slice.call(arguments, 1).forEach(function(arg) {
str = str.replace('%s', arg);
});
diff --git a/ui/lobby/src/lobby.js b/ui/lobby/src/lobby.js
new file mode 100644
index 0000000000..57e3ac69bf
--- /dev/null
+++ b/ui/lobby/src/lobby.js
@@ -0,0 +1,9 @@
+function hookOrder(a, b) {
+ return a.rating > b.rating ? -1 : 1;
+};
+
+module.exports = {
+ sortHooks: function(hooks) {
+ hooks.sort(hookOrder);
+ }
+};
diff --git a/ui/lobby/src/main.js b/ui/lobby/src/main.js
index c416c3f8f2..5288766cac 100644
--- a/ui/lobby/src/main.js
+++ b/ui/lobby/src/main.js
@@ -1,16 +1,20 @@
var m = require('mithril');
-var realTime = require('./module/realTime');
+var ctrl = require('./ctrl');
+var view = require('./view/main');
-module.exports = function(element, env) {
+module.exports = function(element, opts) {
- //setup routes to start w/ the `#` symbol
- m.route.mode = 'hash';
+ var controller = new ctrl(opts);
- //define a route
- m.route(element, '/', {
- '/': realTime(env)
+ m.module(element, {
+ controller: function () { return controller; },
+ view: view
});
+
+ return {
+ socketReceive: controller.socket.receive
+ };
};
// lol, that's for the rest of lichess to access mithril
diff --git a/ui/lobby/src/module/realTime.js b/ui/lobby/src/module/realTime.js
deleted file mode 100644
index ad48b4308e..0000000000
--- a/ui/lobby/src/module/realTime.js
+++ /dev/null
@@ -1,28 +0,0 @@
-var m = require('mithril');
-
-var i18n = require('../i18n');
-
-module.exports = function(env) {
- return {
- controller: function() {
- this.data = env.data;
- this.trans = i18n(env.i18n);
- this.router = env.routes;
- },
- view: function(ctrl) {
- var myTurnPovsNb = ctrl.data.nowPlaying.povs.count(function(p) {
- return p.isMyTurn;
- });
- return [
- m('div.tabs', [
- m('a', ctrl.trans('realTime')),
- m('a', ctrl.trans('correspondence')),
- m('a', [
- ctrl.trans('nbGamesInPlay', ctrl.data.nowPlaying.povs.length),
- myTurnPovsNb.length > 0 ? m('span.unread', myTurnPovsNb.length) : null
- ])
- ])
- ];
- }
- };
-};
diff --git a/ui/lobby/src/variant.js b/ui/lobby/src/variant.js
new file mode 100644
index 0000000000..03816f206b
--- /dev/null
+++ b/ui/lobby/src/variant.js
@@ -0,0 +1,23 @@
+var variantConfirms = {
+ '960': "This is a Chess960 game!\n\nThe starting position of the pieces on the players' home ranks is randomized.\nRead more: http://wikipedia.org/wiki/Chess960\n\nDo you want to play Chess960?",
+ 'KotH': "This is a King of the Hill game!\n\nThe game can be won by bringing the king to the center.\nRead more: http://lichess.org/king-of-the-hill",
+ '3+': "This is a Three-check game!\n\nThe game can be won by checking the opponent 3 times.\nRead more: http://en.wikipedia.org/wiki/Three-check_chess",
+ "Anti": "This is an antichess chess game!\n\n If you can take a piece, you must. The game can be won by losing all your pieces."
+};
+
+function storageKey(key) {
+ return 'lichess.variant.' + key;
+}
+
+module.exports = {
+ confirm: function(variant) {
+ return Object.keys(variantConfirms).every(function(key) {
+ var v = variantConfirms[key]
+ if (variant === key && !storage.get(storageKey(key))) {
+ var c = confirm(v);
+ if (c) storage.set(storageKey(key), 1);
+ return c;
+ } else return true;
+ })
+ }
+};
diff --git a/ui/lobby/src/view.js b/ui/lobby/src/view.js
deleted file mode 100644
index 549ff5e2b6..0000000000
--- a/ui/lobby/src/view.js
+++ /dev/null
@@ -1,8 +0,0 @@
-var m = require('mithril');
-
-module.exports = function(ctrl) {
- return [
- m('div#hooks_wrap'),
- m('div#start_buttons')
- ];
-};
diff --git a/ui/lobby/src/view/main.js b/ui/lobby/src/view/main.js
new file mode 100644
index 0000000000..725859888c
--- /dev/null
+++ b/ui/lobby/src/view/main.js
@@ -0,0 +1,17 @@
+var m = require('mithril');
+
+var renderTabs = require('./tabs');
+var renderRealTime = require('./realTime');
+
+module.exports = function(ctrl) {
+ var body;
+ switch (ctrl.vm.tab) {
+ case 'real_time':
+ body = renderRealTime(ctrl);
+ break;
+ }
+ return [
+ m('div.tabs', renderTabs(ctrl)),
+ body
+ ];
+};
diff --git a/ui/lobby/src/view/realTime.js b/ui/lobby/src/view/realTime.js
new file mode 100644
index 0000000000..ea7e4eda58
--- /dev/null
+++ b/ui/lobby/src/view/realTime.js
@@ -0,0 +1,50 @@
+var m = require('mithril');
+var util = require('chessground').util;
+
+function tds(bits) {
+ return bits.map(function(bit) {
+ return {
+ tag: 'td',
+ children: [bit]
+ };
+ });
+}
+
+function renderHook(ctrl, hook) {
+ var title = (hook.action === 'join') ? ctrl.trans('joinTheGame') + ' - ' + hook.perf.name : ctrl.trans('cancel');
+ return m('tr', {
+ title: (hook.action === 'join') ? ctrl.trans('joinTheGame') + ' - ' + hook.perf.name : ctrl.trans('cancel'),
+ 'data-id': hook.id,
+ class: hook.action,
+ onclick: util.partial(ctrl.clickHook, hook)
+ }, tds([
+ m('span', {
+ class: 'is is2 color-icon ' + (hook.color || 'random')
+ }), (hook.rating ? m('a', {
+ href: '/@/' + hook.username
+ }, hook.username) : 'Anonymous'),
+ hook.rating ? hook.rating : '',
+ hook.clock, [m('span', {
+ class: 'varicon',
+ 'data-icon': hook.perf.icon
+ }), ctrl.trans(hook.mode === 1 ? 'rated' : 'casual')]
+ ]));
+};
+
+module.exports = function(ctrl) {
+ return m('table.table_wrap', [
+ m('thead',
+ m('tr', [
+ m('th', m('span', {
+ 'data-hint': ctrl.trans('graph'),
+ class: 'toggle hint--bottom'
+ }, m('span.chart[data-icon=9]'))),
+ m('th', ctrl.trans('player')),
+ m('th', 'Rating'),
+ m('th', ctrl.trans('time')),
+ m('th', ctrl.trans('mode'))
+ ])
+ ),
+ m('tbody', ctrl.data.hooks.map(util.partial(renderHook, ctrl)))
+ ]);
+};
diff --git a/ui/lobby/src/view/tabs.js b/ui/lobby/src/view/tabs.js
new file mode 100644
index 0000000000..f59a21a0f5
--- /dev/null
+++ b/ui/lobby/src/view/tabs.js
@@ -0,0 +1,26 @@
+var m = require('mithril');
+var util = require('chessground').util;
+
+function tab(ctrl, key, active, content) {
+ var attrs = {
+ onclick: util.partial(ctrl.setTab, key)
+ }
+ if (key === active) attrs.class = 'active';
+ return m('a', attrs, content);
+}
+
+module.exports = function(ctrl) {
+ var nowPlayingNb = ctrl.data.nowPlaying.length;
+ var myTurnPovsNb = ctrl.data.nowPlaying.filter(function(p) {
+ return p.isMyTurn;
+ }).length;
+ var active = ctrl.vm.tab;
+ return [
+ tab(ctrl, 'real_time', active, ctrl.trans('realTime')),
+ tab(ctrl, 'seeks', active, ctrl.trans('correspondence')),
+ nowPlayingNb > 0 ? tab(ctrl, 'now_playing', active, [
+ ctrl.trans('nbGamesInPlay', nowPlayingNb),
+ myTurnPovsNb > 0 ? m('span.unread', myTurnPovsNb) : null
+ ]) : null
+ ];
+};
diff --git a/ui/puzzle/src/ctrl.js b/ui/puzzle/src/ctrl.js
index 8da302890f..7d692d4e5b 100644
--- a/ui/puzzle/src/ctrl.js
+++ b/ui/puzzle/src/ctrl.js
@@ -153,8 +153,8 @@ module.exports = function(cfg, router, i18n) {
this.router = router;
- this.trans = function() {
- var str = i18n[arguments[0]]
+ this.trans = function(key) {
+ var str = i18n[key] || key;
Array.prototype.slice.call(arguments, 1).forEach(function(arg) {
str = str.replace('%s', arg);
});
diff --git a/ui/round/src/ctrl.js b/ui/round/src/ctrl.js
index 0470e9bf8c..5a3ef4bf72 100644
--- a/ui/round/src/ctrl.js
+++ b/ui/round/src/ctrl.js
@@ -118,8 +118,8 @@ module.exports = function(opts) {
this.router = opts.routes;
- this.trans = function() {
- var str = opts.i18n[arguments[0]]
+ this.trans = function(key) {
+ var str = opts.i18n[key] || key;
Array.prototype.slice.call(arguments, 1).forEach(function(arg) {
str = str.replace('%s', arg);
});