merge socket.js in big.js, move storage to lichess namespace

This commit is contained in:
Thibault Duplessis 2014-12-29 21:12:04 +01:00
parent 6d307cfed4
commit e62d461f72
7 changed files with 301 additions and 302 deletions

View file

@ -275,7 +275,6 @@ chessground: Boolean = true)(body: Html)(implicit ctx: Context)
@if(chessground) {@jsTag("vendor/chessground.min.js")}
@jsTag("deps.min.js")
@momentjsTag
@jsTagCompiled("socket.js")
@jsTagCompiled("big.js")
@moreJs
@jsAt(s"trans/${lang.language}.js")

View file

@ -5,7 +5,7 @@
mkdir -p public/compiled
for file in socket.js tv.js common.js big.js chart2.js user.js coordinate.js; do
for file in tv.js big.js chart2.js user.js coordinate.js; do
orig=public/javascripts/$file
comp=public/compiled/$file
if [[ ! -f $comp || $orig -nt $comp ]]; then

View file

@ -2,6 +2,279 @@
// @compilation_level ADVANCED_OPTIMIZATIONS
// ==/ClosureCompiler==
var lichess = window.lichess = window.lichess || {};
lichess.StrongSocket = function(url, version, settings) {
var self = this;
self.settings = $.extend(true, {}, lichess.StrongSocket.defaults, settings);
self.url = url;
self.version = version;
self.options = self.settings.options;
self.ws = null;
self.pingSchedule = null;
self.connectSchedule = null;
self.ackableMessages = [];
self.lastPingTime = self.now();
self.currentLag = 0;
self.averageLag = 0;
self.tryOtherUrl = false;
self.autoReconnect = true;
self.debug('Debug is enabled');
if (self.options.resetUrl || self.options.prodPipe) {
lichess.storage.remove(self.options.baseUrlKey);
}
if (self.options.prodPipe) {
self.options.baseUrls = ['socket.en.lichess.org:9021'];
}
self.connect();
window.addEventListener('unload', function() {
self.destroy();
});
};
lichess.StrongSocket.available = window.WebSocket || window.MozWebSocket;
lichess.StrongSocket.sri = Math.random().toString(36).substring(2);
lichess.StrongSocket.defaults = {
events: {
fen: function(e) {
$('.live_' + e.id).each(function() {
lichess.parseFen($(this).data("fen", e.fen).data("lastmove", e.lm));
});
}
},
params: {
sri: lichess.StrongSocket.sri
},
options: {
name: "unnamed",
pingMaxLag: 7000, // time to wait for pong before reseting the connection
pingDelay: 1000, // time between pong and ping
autoReconnectDelay: 1000,
lagTag: false, // jQuery object showing ping lag
ignoreUnknownMessages: false,
baseUrls: ['socket.' + document.domain].concat(
($('body').data('ports') + '').split(',').map(function(port) {
return 'socket.' + document.domain + ':' + port;
})),
baseUrlKey: 'surl3'
}
};
lichess.StrongSocket.prototype = {
connect: function() {
var self = this;
self.destroy();
self.autoReconnect = true;
var fullUrl = "ws://" + self.baseUrl() + self.url + "?" + $.param($.extend(self.settings.params, {
version: self.version
}));
self.debug("connection attempt to " + fullUrl, true);
try {
if (window.MozWebSocket) self.ws = new MozWebSocket(fullUrl);
else if (window.WebSocket) self.ws = new WebSocket(fullUrl);
else throw "[lila] no websockets found on this browser!";
self.ws.onerror = function(e) {
self.onError(e);
};
self.ws.onclose = function(e) {
if (self.autoReconnect) {
self.debug('Will autoreconnect in ' + self.options.autoReconnectDelay);
self.scheduleConnect(self.options.autoReconnectDelay);
}
};
self.ws.onopen = function() {
self.debug("connected to " + fullUrl, true);
self.onSuccess();
$('body').removeClass('offline');
self.pingNow();
$('body').trigger('socket.open');
if ($('#user_tag').length) setTimeout(function() {
self.send("following_onlines");
}, 500);
var resend = self.ackableMessages;
self.ackableMessages = [];
resend.forEach(function(x) {
self.send(x.t, x.d);
});
};
self.ws.onmessage = function(e) {
var m = JSON.parse(e.data);
if (m.t == "n") {
self.pong();
} else self.debug(e.data);
if (m.t == "b") {
m.d.forEach(function(mm) {
self.handle(mm);
});
} else self.handle(m);
};
} catch (e) {
self.onError(e);
}
self.scheduleConnect(self.options.pingMaxLag);
},
send: function(t, d, o) {
var self = this;
var data = d || {},
options = o || {};
if (options && options.ackable)
self.ackableMessages.push({
t: t,
d: d
});
var message = JSON.stringify({
t: t,
d: data
});
self.debug("send " + message);
try {
self.ws.send(message);
} catch (e) {
self.debug(e);
}
},
sendAckable: function(t, d) {
this.send(t, d, {
ackable: true
});
},
scheduleConnect: function(delay) {
var self = this;
// self.debug('schedule connect ' + delay);
clearTimeout(self.pingSchedule);
clearTimeout(self.connectSchedule);
self.connectSchedule = setTimeout(function() {
$('body').addClass('offline');
self.tryOtherUrl = true;
self.connect();
}, delay);
},
schedulePing: function(delay) {
var self = this;
clearTimeout(self.pingSchedule);
self.pingSchedule = setTimeout(function() {
self.pingNow();
}, delay);
},
pingNow: function() {
var self = this;
clearTimeout(self.pingSchedule);
clearTimeout(self.connectSchedule);
try {
self.ws.send(self.pingData());
self.lastPingTime = self.now();
} catch (e) {
self.debug(e, true);
}
self.scheduleConnect(self.options.pingMaxLag);
},
pong: function() {
var self = this;
clearTimeout(self.connectSchedule);
self.schedulePing(self.options.pingDelay);
self.currentLag = self.now() - self.lastPingTime;
if (!self.averageLag) self.averageLag = self.currentLag;
else self.averageLag = 0.2 * (self.currentLag - self.averageLag) + self.averageLag;
if (self.options.lagTag) {
self.options.lagTag.html(Math.round(self.averageLag));
}
},
pingData: function() {
return JSON.stringify({
t: "p",
v: this.version
});
},
handle: function(m) {
var self = this;
if (m.v) {
if (m.v <= self.version) {
self.debug("already has event " + m.v);
return;
}
if (m.v > self.version + 1) {
self.debug("event gap detected from " + self.version + " to " + m.v);
if (!self.options.prodPipe) return;
}
self.version = m.v;
}
switch (m.t || false) {
case false:
break;
case 'resync':
if (!self.options.prodPipe) lichess.reload();
break;
case 'ack':
self.ackableMessages = [];
break;
default:
if (self.settings.receive) self.settings.receive(m.t, m.d);
var h = self.settings.events[m.t];
if (h) h(m.d || null);
else if (!self.options.ignoreUnknownMessages) {
self.debug('Message not supported ' + JSON.stringify(m));
}
}
},
now: function() {
return new Date().getTime();
},
debug: function(msg, always) {
if ((always || this.options.debug) && window.console && console.debug) {
console.debug("[" + this.options.name + " " + this.settings.params.sri + "]", msg);
}
},
destroy: function() {
clearTimeout(this.pingSchedule);
clearTimeout(this.connectSchedule);
this.disconnect();
this.ws = null;
},
disconnect: function() {
if (this.ws) {
this.debug("Disconnect", true);
this.autoReconnect = false;
this.ws.onerror = $.noop();
this.ws.onclose = $.noop();
this.ws.onopen = $.noop();
this.ws.onmessage = $.noop();
this.ws.close();
}
},
onError: function(e) {
var self = this;
self.options.debug = true;
self.debug('error: ' + JSON.stringify(e));
self.tryOtherUrl = true;
setTimeout(function() {
if (!$('#network_error').length) {
var msg = "Your browser supports websockets, but cannot get a connection. Maybe you are behind a proxy that does not support websockets. Ask your system administrator to fix it!";
$('#nb_connected_players').after('<span id="network_error" title="' + msg + '" data-icon="j"> Network error</span>');
}
}, 1000);
clearTimeout(self.pingSchedule);
},
onSuccess: function() {
$('#network_error').remove();
},
baseUrl: function() {
var key = this.options.baseUrlKey;
var urls = this.options.baseUrls;
var url = lichess.storage.get(key);
if (!url) {
url = urls[0];
lichess.storage.set(key, url);
} else if (this.tryOtherUrl) {
this.tryOtherUrl = false;
url = urls[(urls.indexOf(url) + 1) % urls.length];
lichess.storage.set(key, url);
}
return url;
},
pingInterval: function() {
return this.options.pingDelay + this.averageLag;
}
};
// declare now, populate later in a distinct script.
var lichess_translations = lichess_translations || [];
@ -11,7 +284,7 @@ function withStorage(f) {
return !!window.localStorage ? f(window.localStorage) : null;
} catch (e) {}
}
var storage = {
lichess.storage = {
get: function(k) {
return withStorage(function(s) {
return s.getItem(k);
@ -94,7 +367,6 @@ var storage = {
};
};
var lichess = window.lichess = window.lichess || {};
lichess.socket = null;
lichess.idleTime = 20 * 60 * 1000;
$.extend(true, lichess.StrongSocket.defaults, {
@ -147,7 +419,7 @@ var storage = {
}
},
challengeReminder: function(data) {
if (!storage.get('challenge-refused-' + data.id)) {
if (!lichess.storage.get('challenge-refused-' + data.id)) {
var refreshButton = function() {
var nb = $('#challenge_notifications > div').length;
$('#nb_challenges').text(nb);
@ -158,7 +430,7 @@ var storage = {
var declineListener = function($a, callback) {
return $a.click(function() {
$.post($(this).attr("href"));
storage.set('challenge-refused-' + data.id, 1);
lichess.storage.set('challenge-refused-' + data.id, 1);
$('#' + htmlId).remove();
if ($.isFunction(callback)) callback();
refreshButton();
@ -171,10 +443,10 @@ var storage = {
$notif = $('#' + htmlId);
declineListener($notif.find('a.decline'));
$('body').trigger('lichess.content_loaded');
if (!storage.get('challenge-' + data.id)) {
if (!lichess.storage.get('challenge-' + data.id)) {
$('#top .challenge_notifications').addClass('shown');
$.sound.dong();
storage.set('challenge-' + data.id, 1);
lichess.storage.set('challenge-' + data.id, 1);
}
refreshButton();
}
@ -520,10 +792,10 @@ var storage = {
// Zoom
var getZoom = function() {
return storage.get('zoom') || 1;
return lichess.storage.get('zoom') || 1;
};
var setZoom = function(v) {
storage.set('zoom', v);
lichess.storage.set('zoom', v);
var $boardWrap = $(".lichess_game .cg-board-wrap");
var $lichessGame = $(".lichess_game");
@ -694,7 +966,7 @@ var storage = {
var canPlay = hasOgg || hasMp3;
var $control = $('#sound_control');
var $toggle = $('#sound_state');
$control.add($toggle).toggleClass('sound_state_on', storage.get('sound') == 1);
$control.add($toggle).toggleClass('sound_state_on', lichess.storage.get('sound') == 1);
var enabled = function() {
return $toggle.hasClass("sound_state_on");
};
@ -719,10 +991,10 @@ var storage = {
}
};
var getVolume = function() {
return storage.get('sound-volume') || 0.8;
return lichess.storage.get('sound-volume') || 0.8;
};
var setVolume = function(v) {
storage.set('sound-volume', v);
lichess.storage.set('sound-volume', v);
Object.keys(audio).forEach(function(k) {
audio[k].volume = v * (volumes[k] ? volumes[k] : 1);
});
@ -735,8 +1007,8 @@ var storage = {
if (canPlay) {
$toggle.click(function() {
$control.add($toggle).toggleClass('sound_state_on', !enabled());
if (enabled()) storage.set('sound', 1);
else storage.remove('sound');
if (enabled()) lichess.storage.set('sound', 1);
else lichess.storage.remove('sound');
play.dong();
return false;
});
@ -929,10 +1201,10 @@ var storage = {
self.$list = self.element.find("div.list");
self.$title = self.element.find('.title').click(function() {
self.element.find('.content_wrap').toggle(100, function() {
storage.set('friends-hide', $(this).is(':visible') ? 0 : 1);
lichess.storage.set('friends-hide', $(this).is(':visible') ? 0 : 1);
});
});
if (storage.get('friends-hide') == 1) self.$title.click();
if (lichess.storage.get('friends-hide') == 1) self.$title.click();
self.$nbOnline = self.$title.find('.online');
self.$nobody = self.element.find("div.nobody");
self.set(self.element.data('preload').split(','));
@ -1005,10 +1277,10 @@ var storage = {
$toggle.change(function() {
var enabled = $toggle.is(':checked');
self.element.toggleClass('hidden', !enabled);
if (!enabled) storage.set('nochat', 1);
else storage.remove('nochat');
if (!enabled) lichess.storage.set('nochat', 1);
else lichess.storage.remove('nochat');
});
$toggle[0].checked = storage.get('nochat') != 1;
$toggle[0].checked = lichess.storage.get('nochat') != 1;
if (!$toggle[0].checked) {
self.element.addClass('hidden');
}
@ -1776,12 +2048,12 @@ var storage = {
};
$menu.on('click', 'a', function() {
var panel = $(this).data('panel');
storage.set(storageKey, panel);
lichess.storage.set(storageKey, panel);
setPanel(panel);
});
if (cfg.data.analysis) setPanel('computer_analysis');
else {
var stored = storage.get(storageKey);
var stored = lichess.storage.get(storageKey);
if (stored && $menu.children('.' + stored).length) setPanel(stored);
else $menu.children('.crosstable').click();
}

View file

@ -1,272 +0,0 @@
var lichess = window.lichess = window.lichess || {};
lichess.StrongSocket = function(url, version, settings) {
var self = this;
self.settings = $.extend(true, {}, lichess.StrongSocket.defaults, settings);
self.url = url;
self.version = version;
self.options = self.settings.options;
self.ws = null;
self.pingSchedule = null;
self.connectSchedule = null;
self.ackableMessages = [];
self.lastPingTime = self.now();
self.currentLag = 0;
self.averageLag = 0;
self.tryOtherUrl = false;
self.autoReconnect = true;
self.debug('Debug is enabled');
if (self.options.resetUrl || self.options.prodPipe) {
storage.remove(self.options.baseUrlKey);
}
if (self.options.prodPipe) {
self.options.baseUrls = ['socket.en.lichess.org:9021'];
}
self.connect();
window.addEventListener('unload', function() {
self.destroy();
});
};
lichess.StrongSocket.available = window.WebSocket || window.MozWebSocket;
lichess.StrongSocket.sri = Math.random().toString(36).substring(2);
lichess.StrongSocket.defaults = {
events: {
fen: function(e) {
$('.live_' + e.id).each(function() {
lichess.parseFen($(this).data("fen", e.fen).data("lastmove", e.lm));
});
}
},
params: {
sri: lichess.StrongSocket.sri
},
options: {
name: "unnamed",
pingMaxLag: 7000, // time to wait for pong before reseting the connection
pingDelay: 1000, // time between pong and ping
autoReconnectDelay: 1000,
lagTag: false, // jQuery object showing ping lag
ignoreUnknownMessages: false,
baseUrls: ['socket.' + document.domain].concat(
($('body').data('ports') + '').split(',').map(function(port) {
return 'socket.' + document.domain + ':' + port;
})),
baseUrlKey: 'surl3'
}
};
lichess.StrongSocket.prototype = {
connect: function() {
var self = this;
self.destroy();
self.autoReconnect = true;
var fullUrl = "ws://" + self.baseUrl() + self.url + "?" + $.param($.extend(self.settings.params, {
version: self.version
}));
self.debug("connection attempt to " + fullUrl, true);
try {
if (window.MozWebSocket) self.ws = new MozWebSocket(fullUrl);
else if (window.WebSocket) self.ws = new WebSocket(fullUrl);
else throw "[lila] no websockets found on this browser!";
self.ws.onerror = function(e) {
self.onError(e);
};
self.ws.onclose = function(e) {
if (self.autoReconnect) {
self.debug('Will autoreconnect in ' + self.options.autoReconnectDelay);
self.scheduleConnect(self.options.autoReconnectDelay);
}
};
self.ws.onopen = function() {
self.debug("connected to " + fullUrl, true);
self.onSuccess();
$('body').removeClass('offline');
self.pingNow();
$('body').trigger('socket.open');
if ($('#user_tag').length) setTimeout(function() {
self.send("following_onlines");
}, 500);
var resend = self.ackableMessages;
self.ackableMessages = [];
resend.forEach(function(x) {
self.send(x.t, x.d);
});
};
self.ws.onmessage = function(e) {
var m = JSON.parse(e.data);
if (m.t == "n") {
self.pong();
} else self.debug(e.data);
if (m.t == "b") {
m.d.forEach(function(mm) {
self.handle(mm);
});
} else self.handle(m);
};
} catch (e) {
self.onError(e);
}
self.scheduleConnect(self.options.pingMaxLag);
},
send: function(t, d, o) {
var self = this;
var data = d || {},
options = o || {};
if (options && options.ackable)
self.ackableMessages.push({
t: t,
d: d
});
var message = JSON.stringify({
t: t,
d: data
});
self.debug("send " + message);
try {
self.ws.send(message);
} catch (e) {
self.debug(e);
}
},
sendAckable: function(t, d) {
this.send(t, d, {
ackable: true
});
},
scheduleConnect: function(delay) {
var self = this;
// self.debug('schedule connect ' + delay);
clearTimeout(self.pingSchedule);
clearTimeout(self.connectSchedule);
self.connectSchedule = setTimeout(function() {
$('body').addClass('offline');
self.tryOtherUrl = true;
self.connect();
}, delay);
},
schedulePing: function(delay) {
var self = this;
clearTimeout(self.pingSchedule);
self.pingSchedule = setTimeout(function() {
self.pingNow();
}, delay);
},
pingNow: function() {
var self = this;
clearTimeout(self.pingSchedule);
clearTimeout(self.connectSchedule);
try {
self.ws.send(self.pingData());
self.lastPingTime = self.now();
} catch (e) {
self.debug(e, true);
}
self.scheduleConnect(self.options.pingMaxLag);
},
pong: function() {
var self = this;
clearTimeout(self.connectSchedule);
self.schedulePing(self.options.pingDelay);
self.currentLag = self.now() - self.lastPingTime;
if (!self.averageLag) self.averageLag = self.currentLag;
else self.averageLag = 0.2 * (self.currentLag - self.averageLag) + self.averageLag;
if (self.options.lagTag) {
self.options.lagTag.html(Math.round(self.averageLag));
}
},
pingData: function() {
return JSON.stringify({
t: "p",
v: this.version
});
},
handle: function(m) {
var self = this;
if (m.v) {
if (m.v <= self.version) {
self.debug("already has event " + m.v);
return;
}
if (m.v > self.version + 1) {
self.debug("event gap detected from " + self.version + " to " + m.v);
if (!self.options.prodPipe) return;
}
self.version = m.v;
}
switch (m.t || false) {
case false:
break;
case 'resync':
if (!self.options.prodPipe) lichess.reload();
break;
case 'ack':
self.ackableMessages = [];
break;
default:
if (self.settings.receive) self.settings.receive(m.t, m.d);
var h = self.settings.events[m.t];
if (h) h(m.d || null);
else if (!self.options.ignoreUnknownMessages) {
self.debug('Message not supported ' + JSON.stringify(m));
}
}
},
now: function() {
return new Date().getTime();
},
debug: function(msg, always) {
if ((always || this.options.debug) && window.console && console.debug) {
console.debug("[" + this.options.name + " " + this.settings.params.sri + "]", msg);
}
},
destroy: function() {
clearTimeout(this.pingSchedule);
clearTimeout(this.connectSchedule);
this.disconnect();
this.ws = null;
},
disconnect: function() {
if (this.ws) {
this.debug("Disconnect", true);
this.autoReconnect = false;
this.ws.onerror = $.noop();
this.ws.onclose = $.noop();
this.ws.onopen = $.noop();
this.ws.onmessage = $.noop();
this.ws.close();
}
},
onError: function(e) {
var self = this;
self.options.debug = true;
self.debug('error: ' + JSON.stringify(e));
self.tryOtherUrl = true;
setTimeout(function() {
if (!$('#network_error').length) {
var msg = "Your browser supports websockets, but cannot get a connection. Maybe you are behind a proxy that does not support websockets. Ask your system administrator to fix it!";
$('#nb_connected_players').after('<span id="network_error" title="' + msg + '" data-icon="j"> Network error</span>');
}
}, 1000);
clearTimeout(self.pingSchedule);
},
onSuccess: function() {
$('#network_error').remove();
},
baseUrl: function() {
var key = this.options.baseUrlKey;
var urls = this.options.baseUrls;
var url = storage.get(key);
if (!url) {
url = urls[0];
storage.set(key, url);
} else if (this.tryOtherUrl) {
this.tryOtherUrl = false;
url = urls[(urls.indexOf(url) + 1) % urls.length];
storage.set(key, url);
}
return url;
},
pingInterval: function() {
return this.options.pingDelay + this.averageLag;
}
};

View file

@ -17,21 +17,21 @@ module.exports = {
tab: {
set: function(t) {
t = tab.fix(t);
storage.set(tab.key, t);
lichess.storage.set(tab.key, t);
return t;
},
get: function() {
return tab.fix(storage.get(tab.key));
return tab.fix(lichess.storage.get(tab.key));
}
},
mode: {
set: function(m) {
m = mode.fix(m);
storage.set(mode.key, m);
lichess.storage.set(mode.key, m);
return m;
},
get: function() {
return mode.fix(storage.get(mode.key));
return mode.fix(lichess.storage.get(mode.key));
}
}
};

View file

@ -13,9 +13,9 @@ module.exports = {
confirm: function(variant) {
return Object.keys(variantConfirms).every(function(key) {
var v = variantConfirms[key]
if (variant === key && !storage.get(storageKey(key))) {
if (variant === key && !lichess.storage.get(storageKey(key))) {
var c = confirm(v);
if (c) storage.set(storageKey(key), 1);
if (c) lichess.storage.set(storageKey(key), 1);
return c;
} else return true;
})

View file

@ -4,10 +4,10 @@ var m = require('mithril');
module.exports = function(ctrl, key) {
this.value = storage.get(key) === '1';
this.value = lichess.storage.get(key) === '1';
var store = function() {
storage.set(key, this.value ? '1' : '0');
lichess.storage.set(key, this.value ? '1' : '0');
}.bind(this);
this.toggle = function() {