X-Git-Url: https://git.sesse.net/?p=remoteglot;a=blobdiff_plain;f=www%2Fjs%2Fremoteglot.js;h=be53c978f777a9b5df37c54e908548d92361a2fe;hp=43b2e1ddbb7c304b2450349fbaef79e23e355d92;hb=3797e272b3764680e81afaa1744fabca3314d9c9;hpb=ab94a7c05a495c1d8f9ea30e2268bbc72f17b303 diff --git a/www/js/remoteglot.js b/www/js/remoteglot.js index 43b2e1d..be53c97 100644 --- a/www/js/remoteglot.js +++ b/www/js/remoteglot.js @@ -1,5 +1,14 @@ (function() { +/** + * Version of this script. If the server returns a version larger than + * this, it is a sign we should reload to upgrade ourselves. + * + * @type {Number} + * @const + * @private */ +var SCRIPT_VERSION = 2015062104; + /** @type {window.ChessBoard} @private */ var board = null; @@ -144,6 +153,13 @@ var request_update = function() { } else { new_data = data; } + + var minimum_version = xhr.getResponseHeader('X-RGMV'); + if (minimum_version && minimum_version > SCRIPT_VERSION) { + // Upgrade to latest version with a force-reload. + location.reload(true); + } + possibly_play_sound(current_analysis_data, new_data); current_analysis_data = new_data; update_board(current_analysis_data, displayed_analysis_data); @@ -692,10 +708,9 @@ var update_board = function(current_data, display_data) { if (display_data) { // Displaying some non-current position, pick out the last move // from the history. This will work even if the fetch failed. - last_move = format_move_with_number( + last_move = format_halfmove_with_number( current_display_line.pretty_pv[current_display_move], - Math.floor((current_display_move + 1) / 2) + 1, - (current_display_move % 2 == 1)); + current_display_move + 1); headline += ' after ' + last_move; } else if (data['position']['last_move'] !== 'none') { last_move = format_move_with_number( @@ -853,6 +868,69 @@ var update_board = function(current_data, display_data) { toplay = data['position']['toplay']; refutation_lines = data['refutation_lines']; update_refutation_lines(); + + // Update the sparkline last, since its size depends on how everything else reflowed. + update_sparkline(data); +} + +var update_sparkline = function(data) { + if (data && data['score_history']) { + var first_move_num = undefined; + for (var halfmove_num in data['score_history']) { + halfmove_num = parseInt(halfmove_num); + if (first_move_num === undefined || halfmove_num < first_move_num) { + first_move_num = halfmove_num; + } + } + if (first_move_num !== undefined) { + var last_move_num = data['position']['move_num'] * 2 - 3; + if (data['position']['toplay'] === 'B') { + ++last_move_num; + } + + // Possibly truncate some moves if we don't have enough width. + // FIXME: Sometimes width() for #scorecontainer (and by extent, + // #scoresparkcontainer) on Chrome for mobile seems to start off + // at something very small, and then suddenly snap back into place. + // Figure out why. + var max_moves = Math.floor($("#scoresparkcontainer").width() / 5) - 5; + if (last_move_num - first_move_num > max_moves) { + first_move_num = last_move_num - max_moves; + } + + var min_score = -100; + var max_score = 100; + var last_score = null; + var scores = []; + for (var halfmove_num = first_move_num; halfmove_num <= last_move_num; ++halfmove_num) { + if (data['score_history'][halfmove_num]) { + var score = data['score_history'][halfmove_num][0]; + if (score < min_score) min_score = score; + if (score > max_score) max_score = score; + last_score = data['score_history'][halfmove_num][0]; + } + scores.push(last_score); + } + if (data['plot_score']) { + scores.push(data['plot_score']); + } + // FIXME: at some widths, calling sparkline() seems to push + // #scorecontainer under the board. + $("#scorespark").sparkline(scores, { + type: 'bar', + zeroColor: 'gray', + chartRangeMin: min_score, + chartRangeMax: max_score, + tooltipFormatter: function(sparkline, options, fields) { + return format_tooltip(data, fields[0].offset + first_move_num); + } + }); + } else { + $("#scorespark").text(""); + } + } else { + $("#scorespark").text(""); + } } /** @@ -1011,6 +1089,46 @@ var format_move_with_number = function(move, move_num, white_to_play) { return ret; } +/** + * @param {string} move + * @param {Number} halfmove_num + */ +var format_halfmove_with_number = function(move, halfmove_num) { + return format_move_with_number( + move, + Math.floor(halfmove_num / 2) + 1, + halfmove_num % 2 == 0); +} + +/** + * @param {Object} data + * @param {Number} halfmove_num + */ +var format_tooltip = function(data, halfmove_num) { + if (data['score_history'][halfmove_num] || + halfmove_num === data['position']['pretty_history'].length) { + var move; + var short_score; + if (halfmove_num === data['position']['pretty_history'].length) { + move = data['position']['last_move']; + short_score = data['short_score']; + } else { + move = data['position']['pretty_history'][halfmove_num]; + short_score = data['score_history'][halfmove_num][1]; + } + var move_with_number = format_halfmove_with_number(move, halfmove_num); + + return "After " + move_with_number + ": " + short_score; + } else { + for (var i = halfmove_num; i --> 0; ) { + if (data['score_history'][i]) { + var move = data['position']['pretty_history'][i]; + return "[Analysis kept from " + format_halfmove_with_number(move, i) + "]"; + } + } + } +} + /** * @param {boolean} sort_by_score */ @@ -1218,6 +1336,7 @@ var init = function() { request_update(); $(window).resize(function() { board.resize(); + update_sparkline(displayed_analysis_data || current_analysis_data); update_highlight(); redraw_arrows(); });