implement lobby mithril hook chart
This commit is contained in:
parent
2d7ce82097
commit
d84cc0520f
|
@ -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();
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
},
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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)),
|
||||
|
|
134
ui/lobby/src/view/realTimeChart.js
Normal file
134
ui/lobby/src/view/realTimeChart.js
Normal 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()
|
||||
]);
|
||||
};
|
|
@ -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'),
|
Loading…
Reference in a new issue