implement lobby mithril hook chart

This commit is contained in:
Thibault Duplessis 2014-12-28 11:47:18 +01:00
parent 2d7ce82097
commit d84cc0520f
10 changed files with 205 additions and 64 deletions

View file

@ -1692,13 +1692,6 @@ var storage = {
// lichess.socket.send(data.action, data.id);
// }
// });
}
////////////////
// lobby.js //
////////////////
$(function() {
var $startButtons = $('#start_buttons');
@ -1708,10 +1701,6 @@ var storage = {
return;
}
if (!$startButtons.length) {
return;
}
function sliderTime(v) {
if (v <= 20) return v;
switch (v) {
@ -1978,7 +1967,7 @@ var storage = {
$(this).attr("href", $(this).attr("href") + location.search);
}).click();
}
});
};
$.lichessOpeningPreventClicks = function() {
$('#hooks_list, #hooks_chart').hide();

View file

@ -216,7 +216,7 @@ lichess.StrongSocket.prototype = {
},
debug: function(msg, always) {
if ((always || this.options.debug) && window.console && console.debug) {
console.debug("[" + this.options.name + " " + lichess.StrongSocket.sri + "]", msg);
console.debug("[" + this.options.name + " " + this.settings.params.sri + "]", msg);
}
},
destroy: function() {

View file

@ -26,6 +26,7 @@ div.lobby_and_ground {
min-width: 512px;
width: 512px;
height: 512px;
max-height: 512px;
overflow: hidden;
border: 1px solid #ccc;
background: #f0f0f0 url(../images/wN-bg.svg);
@ -62,13 +63,10 @@ div.lobby_and_ground {
#hooks_wrap > div.tabs .unread {
margin-left: 3px;
}
#real_time .toggle {
#hooks_wrap .toggle {
cursor: pointer;
}
#hooks_list, #hooks_chart {
display: none;
}
#hooks_chart .toggle {
#hooks_wrap .hooks_chart .toggle {
position: absolute;
top: 15px;
left: 13px;
@ -149,7 +147,6 @@ div.lobby_and_ground {
#hooks_wrap .table_wrap {
text-shadow: 0px 1px 0px #FFF;
width: 512px;
max-height: 512px;
min-height: 78px;
overflow: hidden;
}
@ -234,24 +231,14 @@ div.lobby_and_ground {
text-transform: uppercase;
letter-spacing: 3px;
}
#tableclone {
position: absolute;
top: 1px;
left: 1px;
max-height: 512px;
z-index: 19;
}
#tableclone thead {
opacity: 0;
}
#hooks_chart {
#hooks_wrap .hooks_chart {
position: absolute;
top: 0;
left: 0;
width: 512px;
height: 512px;
}
#hooks_chart > span.label {
#hooks_wrap .hooks_chart > span.label {
font-size: 8px;
position: absolute;
left: 3px;
@ -259,25 +246,25 @@ div.lobby_and_ground {
text-shadow: 0 0 3px #fff;
font-weight: bold;
}
#hooks_chart > div.grid {
#hooks_wrap .hooks_chart > div.grid {
position: absolute;
left: 0px;
bottom: 0px;
}
#hooks_chart > div.grid.horiz {
#hooks_wrap .hooks_chart > div.grid.horiz {
width: 100%;
border-top: 1px dashed #ccc;
}
#hooks_chart > div.grid.vert {
#hooks_wrap .hooks_chart > div.grid.vert {
height: 100%;
border-right: 1px dashed #ccc;
}
#hooks_chart .canvas {
#hooks_wrap .hooks_chart .canvas {
position: relative;
width: 512px;
height: 512px;
}
#hooks_chart .plot {
#hooks_wrap .hooks_chart .plot {
position: absolute;
width: 17px;
height: 17px;
@ -287,32 +274,32 @@ div.lobby_and_ground {
cursor: pointer;
z-index: 1;
}
#hooks_chart .plot:hover {
#hooks_wrap .hooks_chart .plot:hover {
z-index: 2;
}
#hooks_chart .plot.casual {
#hooks_wrap .hooks_chart .plot.casual {
border-radius: 16px;
}
#hooks_chart .plot.rated {
#hooks_wrap .hooks_chart .plot.rated {
border-radius: 3px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
width: 15px;
height: 15px;
}
#hooks_chart .plot.variant {
#hooks_wrap .hooks_chart .plot.variant {
border-style: double;
border-width: 5px;
}
#hooks_chart .plot.casual.variant {
#hooks_wrap .hooks_chart .plot.casual.variant {
width: 13px;
height: 13px;
}
#hooks_chart .plot.rated.variant {
#hooks_wrap .hooks_chart .plot.rated.variant {
width: 11px;
height: 11px;
}
#hooks_chart .plot.cancel {
#hooks_wrap .hooks_chart .plot.cancel {
background: #666;
}
#hook {
@ -325,10 +312,10 @@ div.lobby_and_ground {
box-shadow: 0 0 9px #333;
background: #d0d0d0;
}
#hooks_chart .plot:hover {
#hooks_wrap .hooks_chart .plot:hover {
background-color: #f6f6f6;
}
#hooks_chart .plot:hover {
#hooks_wrap .hooks_chart .plot:hover {
box-shadow: 0 0 9px #d85000 !important;
}
#hook .opponent {

View file

@ -3,6 +3,7 @@ var socket = require('./socket');
var variant = require('./variant');
var hookRepo = require('./hookRepo');
var store = require('./store');
var util = require('chessground').util;
module.exports = function(env) {
@ -13,6 +14,7 @@ module.exports = function(env) {
this.vm = {
tab: store.tab.get(),
mode: store.mode.get(),
stepHooks: hookRepo.stepSlice(this),
stepping: false
};
@ -31,15 +33,17 @@ module.exports = function(env) {
flushHooksSchedule();
}.bind(this);
var flushHooksSchedule = function() {
flushHooksTimeout = setTimeout(this.flushHooks, 8000);
}.bind(this);
var flushHooksSchedule = util.partial(setTimeout, this.flushHooks, 8000);
flushHooksSchedule();
this.setTab = function(tab) {
this.vm.tab = store.tab.set(tab);
}.bind(this);
this.setMode = function(mode) {
this.vm.mode = store.mode.set(mode);
}.bind(this);
this.clickHook = function(hook) {
if (this.vm.stepping) return;
if (hook.action === 'cancel' || variant.confirm(data.variant)) socket.send(hook.action, hook.id);

View file

@ -9,6 +9,7 @@ function sort(ctrl) {
module.exports = {
sort: sort,
add: function(ctrl, hook) {
hook.action = hook.uid === lichess.socket.settings.params.sri ? 'cancel' : 'join';
ctrl.data.hooks.push(hook);
sort(ctrl);
},

View file

@ -9,8 +9,8 @@ module.exports = function(send, ctrl) {
var handlers = {
hook_add: function(hook) {
hookRepo.add(ctrl, hook);
// if (hook.action == 'cancel') $('body').trigger('lichess.hook-flush');
m.redraw();
if (hook.action === 'cancel') ctrl.flushHooks();
else m.redraw();
},
hook_remove: function(id) {
hookRepo.remove(ctrl, id);

View file

@ -1,19 +1,37 @@
var tabKey = 'lichess.lobby.tab';
function fixTab(tab) {
if (['real_time', 'seeks', 'now_playing'].indexOf(tab) === -1) tab = 'real_time';
return tab;
var tab = {
key: 'lichess.lobby.tab',
fix: function(t) {
if (['real_time', 'seeks', 'now_playing'].indexOf(t) === -1) t = 'real_time';
return t;
}
};
var mode = {
key: 'lichess.lobby.mode',
fix: function(m) {
if (['list', 'chart'].indexOf(m) === -1) m = 'list';
return m;
}
};
module.exports = {
tab: {
set: function(tab) {
var tab = fixTab(tab);
storage.set(tabKey, tab);
return tab;
set: function(t) {
t = tab.fix(t);
storage.set(tab.key, t);
return t;
},
get: function() {
return fixTab(storage.get(tabKey));
return tab.fix(storage.get(tab.key));
}
},
mode: {
set: function(m) {
m = mode.fix(m);
storage.set(mode.key, m);
return m;
},
get: function() {
return mode.fix(storage.get(mode.key));
}
}
};

View file

@ -1,14 +1,20 @@
var m = require('mithril');
var renderTabs = require('./tabs');
var renderRealTime = require('./realTime');
var renderRealTimeList = require('./realTimeList');
var renderRealTimeChart = require('./realTimeChart');
module.exports = function(ctrl) {
var body;
switch (ctrl.vm.tab) {
case 'real_time':
body = renderRealTime(ctrl);
break;
switch (ctrl.vm.mode) {
case 'chart':
body = renderRealTimeChart(ctrl);
break;
default:
body = renderRealTimeList(ctrl);
}
}
return [
m('div.tabs', renderTabs(ctrl)),

View file

@ -0,0 +1,134 @@
var m = require('mithril');
var util = require('chessground').util;
function px(v) {
return v + 'px';
}
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 renderPlot(ctrl, 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(' ');
return m('span', {
id: hook.id,
key: hook.id,
class: klass,
style: {
bottom: px(bottom),
left: px(left)
},
config: function(el, isUpdate, ctx) {
if (isUpdate) return;
$(el).powerTip({
fadeInTime: 0,
fadeOutTime: 0,
placement: hook.rating > 2200 ? 'se' : 'ne',
mouseOnToPopup: true,
closeDelay: 200,
intentPollInterval: 50,
popupId: 'hook'
}).data('powertipjq', $(renderHook(ctrl, hook)));
ctx.onunload = function() {
$(el).data('powertipjq', null);
$.powerTip.destroy(el);
};
}
});
}
function renderHook(ctrl, hook) {
var html = '';
if (hook.rating) {
html += '<a class="opponent" href="/@/' + hook.username + '">' + hook.username.substr(0, 14) + '</a>';
html += '<span class="rating">' + hook.rating + '</span>';
} else {
html += '<span class="opponent anon">Anonymous</span>';
}
html += '<span class="clock">' + hook.clock + '</span>';
html += '<span class="mode">' +
'<span class="varicon" data-icon="' + hook.perf.icon + '"></span>' + ctrl.trans(hook.mode === 1 ? 'rated' : 'casual') + '</span>';
html += '<span class="is is2 color-icon ' + (hook.color || "random") + '"></span>';
return html;
}
function renderXAxis() {
return [1, 2, 3, 5, 7, 10, 15, 20, 30].map(function(v) {
var l = clockX(v * 60);
return [
m('span', {
class: 'x label',
style: {
left: px(l)
}
}, v),
m('div', {
class: 'grid vert',
style: {
width: px(l + 7)
}
})
];
});
}
function renderYAxis() {
return [1000, 1200, 1400, 1500, 1600, 1800, 2000, 2200, 2400].map(function(v) {
var b = ratingY(v);
return [
m('span', {
class: 'y label',
style: {
bottom: px(b + 5)
}
}, v),
m('div', {
class: 'grid horiz',
style: {
height: px(b + 4)
}
})
];
});
}
module.exports = function(ctrl) {
return m('div.hooks_chart', [
m('span', {
'data-hint': ctrl.trans('list'),
class: 'toggle hint--bottom',
onclick: util.partial(ctrl.setMode, 'list')
}, m('span.chart[data-icon=?]')),
m('div.canvas', ctrl.data.hooks.map(util.partial(renderPlot, ctrl))),
renderYAxis(),
renderXAxis()
]);
};

View file

@ -13,6 +13,7 @@ function tds(bits) {
function renderHook(ctrl, hook) {
var title = (hook.action === 'join') ? ctrl.trans('joinTheGame') + ' - ' + hook.perf.name : ctrl.trans('cancel');
return m('tr', {
key: hook.id,
title: (hook.action === 'join') ? ctrl.trans('joinTheGame') + ' - ' + hook.perf.name : ctrl.trans('cancel'),
'data-id': hook.id,
class: 'hook ' + hook.action + (hook.disabled ? ' disabled' : ''),
@ -45,7 +46,8 @@ module.exports = function(ctrl) {
m('tr', [
m('th', m('span', {
'data-hint': ctrl.trans('graph'),
class: 'toggle hint--bottom'
class: 'toggle hint--bottom',
onclick: util.partial(ctrl.setMode, 'chart')
}, m('span.chart[data-icon=9]'))),
m('th', ctrl.trans('player')),
m('th', 'Rating'),