diff --git a/app/controllers/User.scala b/app/controllers/User.scala index 270f4ccaa8..67e9875f15 100644 --- a/app/controllers/User.scala +++ b/app/controllers/User.scala @@ -392,12 +392,12 @@ object User extends LilaController { } ratingChart <- Env.history.ratingChartApi.apply(u) _ <- Env.user.lightUserApi preloadMany { u.id :: perfStat.userIds.map(_.value) } - data = Env.perfStat.jsonView(u, perfStat, ranks get perfType, percentile) response <- negotiate( - html = Ok(html.user.perfStat(u, ranks, perfType, percentile, perfStat, data, ratingChart)).fuccess, + html = Ok(html.user.perfStat(u, ranks, perfType, percentile, perfStat, ratingChart)).fuccess, api = _ => getBool("graph").?? { Env.history.ratingChartApi.singlePerf(u, perfType).map(_.some) } map { + val data = Env.perfStat.jsonView(u, perfStat, ranks get perfType, percentile) _.fold(data) { graph => data + ("graph" -> graph) } } map { Ok(_) } ) diff --git a/app/views/user/perfStat.scala b/app/views/user/perfStat.scala index 3e87770cbc..837b31b793 100644 --- a/app/views/user/perfStat.scala +++ b/app/views/user/perfStat.scala @@ -18,7 +18,6 @@ object perfStat { perfType: lila.rating.PerfType, percentile: Option[Double], stat: PerfStat, - data: play.api.libs.json.JsObject, ratingChart: Option[String] )(implicit ctx: Context) = views.html.base.layout( title = s"${u.username} ${perfType.name} stats", @@ -30,13 +29,7 @@ object perfStat { jsTag("chart/ratingHistory.js"), embedJsUnsafe(s"lichess.ratingHistoryChart($rc,'${perfType.name}');") ) - }, - jsAt(s"compiled/lichess.perfStat${isProd ?? (".min")}.js"), - embedJsUnsafe(s"""$$(function() { -if (false) LichessPerfStat(document.querySelector('.perf-stat__content'), { -data: ${safeJsonValue(data)} -}); -});""") + } ), moreCss = cssTag("perf-stat") ) { diff --git a/package.json b/package.json index 92550e55cb..2dd0f4e93c 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,6 @@ "ui/learn", "ui/lobby", "ui/notify", - "ui/perfStat", "ui/puzzle", "ui/round", "ui/simul", diff --git a/ui/build b/ui/build index 933f0fbe9d..3bf3f4a90b 100755 --- a/ui/build +++ b/ui/build @@ -13,7 +13,7 @@ mkdir -p public/compiled ts_apps1="common chess" ts_apps2="ceval game tree chat nvui" -apps="site chat cli challenge notify learn insight editor puzzle round analyse lobby tournament tournamentSchedule tournamentCalendar simul perfStat dasher speech palantir" +apps="site chat cli challenge notify learn insight editor puzzle round analyse lobby tournament tournamentSchedule tournamentCalendar simul dasher speech palantir" if [ $mode == "upgrade" ]; then yarn upgrade --non-interactive diff --git a/ui/perfStat/gulpfile.js b/ui/perfStat/gulpfile.js deleted file mode 100644 index 7de95fc088..0000000000 --- a/ui/perfStat/gulpfile.js +++ /dev/null @@ -1,3 +0,0 @@ -const lilaGulp = require('../gulp/jsProject.js'); - -lilaGulp('LichessPerfStat', 'lichess.perfStat', __dirname); diff --git a/ui/perfStat/package.json b/ui/perfStat/package.json deleted file mode 100644 index 1843da4dcf..0000000000 --- a/ui/perfStat/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "perfStat", - "version": "1.0.0", - "description": "lichess.org chess performance statistics", - "main": "src/main.js", - "repository": { - "type": "git", - "url": "https://github.com/ornicar/lila" - }, - "keywords": [ - "chess", - "lichess", - "performance", - "statistic" - ], - "author": "ornicar", - "license": "AGPL-3.0", - "bugs": { - "url": "https://github.com/ornicar/lila/issues" - }, - "homepage": "https://github.com/ornicar/lila", - "devDependencies": { - "browserify": "^16", - "gulp": "^4", - "gulp-terser": "^1", - "gulp-size": "^3", - "fancy-log": "^1", - "vinyl-source-stream": "^2", - "vinyl-buffer": "^1", - "watchify": "^3" - }, - "dependencies": { - "mithril": "github:ornicar/mithril.js#lila-1", - "numeral": "^1.5" - } -} diff --git a/ui/perfStat/src/counter.js b/ui/perfStat/src/counter.js deleted file mode 100644 index bd9b09352b..0000000000 --- a/ui/perfStat/src/counter.js +++ /dev/null @@ -1,71 +0,0 @@ -var m = require('mithril'); -var util = require('./util'); - -function percent(x, y) { - if (y === 0) return 0; - return Math.round(x * 100 / y); -} - -module.exports = function(d) { - var c = d.stat.count; - var per = function(x, y) { - return percent(x, y || c.all) + '%'; - }; - return [ - m('div', m('table', m('tbody', [ - m('tr', [ - m('th', 'Total games'), - m('td', c.all), - m('td'), - ]), - m('tr.full', [ - m('th', 'Rated games'), - m('td', c.rated), - m('td', per(c.rated)), - ]), - m('tr.full', [ - m('th', 'Tournament games'), - m('td', c.tour), - m('td', per(c.tour)), - ]), - m('tr.full', [ - m('th', 'Berserked games'), - m('td', c.berserk), - m('td', per(c.berserk, c.tour)), - ]), - c.seconds ? m('tr.full', [ - m('th', 'Time spent playing'), - m('td[colspan=2]', util.formatSeconds(c.seconds, 'short')) - ]) : null - ]))), - m('div', m('table', m('tbody', [ - m('tr', [ - m('th', 'Average opponent'), - m('td', c.opAvg), - m('td') - ]), - m('tr.full', [ - m('th', 'Victories'), - m('td', util.green(c.win)), - m('td', util.green(per(c.win))) - ]), - m('tr.full', [ - m('th', 'Draws'), - m('td', c.draw), - m('td', per(c.draw)) - ]), - m('tr.full', [ - m('th', 'Defeats'), - m('td', util.red(c.loss)), - m('td', util.red(per(c.loss))) - ]), - m('tr.full', (function(color) { - return [ - m('th', 'Disconnections'), - m('td', color(c.disconnects)), - m('td', color(per(c.disconnects, c.loss))) - ]; - })(percent(c.disconnects, c.loss) >= 15 ? util.red : util.identity)) - ]))) - ]; -}; diff --git a/ui/perfStat/src/glicko.js b/ui/perfStat/src/glicko.js deleted file mode 100644 index dbb3e020f5..0000000000 --- a/ui/perfStat/src/glicko.js +++ /dev/null @@ -1,47 +0,0 @@ -var m = require('mithril'); - -function provisional() { - return m('span', { - title: 'Not enough rated games have been played to establish a reliable rating.' - }, '(provisional)'); -} - -function percentile(d) { - return d.percentile === 0 ? '' : [ - ' Better than ', - m('a', { - href: '/stat/rating/distribution/' + d.stat.perfType.key - }, [ - m('strong', d.percentile + '%'), - ' of ' + d.stat.perfType.name + ' players.' - ]) - ]; -} - -function progress(p) { - if (p > 0) return m('green[data-icon=N]', p); - else if (p < 0) return m('red[data-icon=M]', -p); -} - -module.exports = function(d) { - return [ - m('h2', [ - 'Rating: ', - m('strong', { - title: 'Yes, ratings have decimal accuracy.' - }, d.perf.glicko.rating), - '. ', - m('span.details', d.perf.glicko.provisional ? provisional() : percentile(d)) - ]), - m('p', [ - 'Progression over the last twelve games: ', - m('span.progress', progress(d.perf.progress) || 'none'), - '. ', - 'Rating deviation: ', - m('strong', { - title: 'Lower value means the rating is more stable. Above 110, the rating is considered provisional.' - }, d.perf.glicko.deviation), - '. ' - ]) - ]; -}; diff --git a/ui/perfStat/src/highlow.js b/ui/perfStat/src/highlow.js deleted file mode 100644 index 904a109b5a..0000000000 --- a/ui/perfStat/src/highlow.js +++ /dev/null @@ -1,21 +0,0 @@ -var m = require('mithril'); -var util = require('./util'); - -function ratingAt(title, opt, color) { - return util.fMap(opt, function(r) { - return [ - m('h2', [title + ': ', m('strong', color(r.int))]), - util.gameLink(r.gameId, util.date(r.at)) - ]; - }, [ - m('h2', title + ': '), - m('span', util.noData) - ]); -} - -module.exports = function(d) { - return [ - m('div', ratingAt('Highest rating', d.stat.highest, util.green)), - m('div', ratingAt('Lowest rating', d.stat.lowest, util.red)) - ]; -}; diff --git a/ui/perfStat/src/main.js b/ui/perfStat/src/main.js deleted file mode 100644 index 00083ee25e..0000000000 --- a/ui/perfStat/src/main.js +++ /dev/null @@ -1,13 +0,0 @@ -var m = require('mithril'); - -module.exports = function(element, opts) { - - m.module(element, { - controller: function() { - return { - data: opts.data - }; - }, - view: require('./view') - }); -}; diff --git a/ui/perfStat/src/playStreak.js b/ui/perfStat/src/playStreak.js deleted file mode 100644 index 3a59a2f481..0000000000 --- a/ui/perfStat/src/playStreak.js +++ /dev/null @@ -1,49 +0,0 @@ -var m = require('mithril'); -var util = require('./util'); - -function streak(s, title, display) { - return m('div.streak', [ - m('h3', [ - title + ': ', - display(s.v) - ]), - util.fromTo(s) - ]); -} - -function streaks(s, display) { - return m('div.split', [ - m('div', streak(s.max, 'Longest streak', display)), - m('div', streak(s.cur, 'Current streak', display)) - ]); -} - -var lessThan = 'Less than one hour between games.'; - -module.exports = { - nb: function(d) { - return util.fMap(d.stat.playStreak.nb, function(s) { - return [ - m('h2', m('span', { - title: lessThan - }, 'Games played in a row')), - streaks(s, function(v) { - return v ? [ - m('strong', v), - ' game' + (v > 1 ? 's' : '') - ] : 'none'; - }) - ]; - }); - }, - time: function(d) { - return util.fMap(d.stat.playStreak.time, function(s) { - return [ - m('h2', m('span', { - title: lessThan - }, 'Max time spent playing')), - streaks(s, util.formatSeconds) - ]; - }); - } -}; diff --git a/ui/perfStat/src/result.js b/ui/perfStat/src/result.js deleted file mode 100644 index f76e2bfac7..0000000000 --- a/ui/perfStat/src/result.js +++ /dev/null @@ -1,21 +0,0 @@ -var m = require('mithril'); -var util = require('./util'); - -function resultTable(results, title) { - return m('table', [ - m('thead', m('tr', m('th[colspan=2]', m('h2', title)))), - m('tbody', results.map(function(r) { - return m('tr', [ - m('td', util.showUser(r.opId, r.opInt)), - m('td', util.gameLink(r.gameId, util.date(r.at))) - ]); - })) - ]); -} - -module.exports = function(d) { - return [ - m('div', resultTable(d.stat.bestWins.results, 'Best rated victories')), - m('div', resultTable(d.stat.worstLosses.results, 'Worst rated defeats')) - ]; -}; diff --git a/ui/perfStat/src/resultStreak.js b/ui/perfStat/src/resultStreak.js deleted file mode 100644 index c72938cfa7..0000000000 --- a/ui/perfStat/src/resultStreak.js +++ /dev/null @@ -1,37 +0,0 @@ -var m = require('mithril'); -var util = require('./util'); - -function streak(s, title, color) { - return m('div.streak', [ - m('h3', [ - title + ': ', - s.v > 0 ? color([ - m('strong', s.v), - ' game' + (s.v > 1 ? 's' : '') - ]) : 'none' - ]), - util.fromTo(s) - ]); -} - -function streaks(color) { - return function(s) { - return [ - streak(s.max, 'Longest', color), - streak(s.cur, 'Current', color) - ]; - }; -} - -module.exports = function(d) { - return [ - m('div', [ - m('h2', 'Winning streak'), - util.fMap(d.stat.resultStreak.win, streaks(util.green), util.noData) - ]), - m('div', [ - m('h2', 'Losing streak'), - util.fMap(d.stat.resultStreak.loss, streaks(util.red), util.noData) - ]) - ]; -}; diff --git a/ui/perfStat/src/util.js b/ui/perfStat/src/util.js deleted file mode 100644 index df4efdeb53..0000000000 --- a/ui/perfStat/src/util.js +++ /dev/null @@ -1,68 +0,0 @@ -var m = require('mithril'); - -function fMap(v, f, orDefault) { - return v ? f(v) : (orDefault || null); -} - -function gameLink(id, content) { - return m('a', { - class: 'glpt', - href: '/' + id - }, content); -} - -function absDate(d) { - return m('time', window.lichess.timeago.absolute(d)); -} - -function fromTo(s) { - return fMap(s.from, function(r) { - return [ - 'from ', - gameLink(r.gameId, absDate(r.at)), - ' to ', - fMap(s.to, function(r) { - return gameLink(r.gameId, absDate(r.at)); - }, 'now') - ]; - }, m.trust(' ')); -} - -module.exports = { - fMap: fMap, - gameLink: gameLink, - date: absDate, - showUser: function(u, rating) { - return m('a', { - class: 'ulpt', - href: '/@/' + u.name - }, (u.title ? (u.title + ' ') : '') + u.name + ' (' + rating + ')'); - }, - noData: 'Not enough games played.', - fromTo: fromTo, - streaks: function(s, f) { - return [ - m('div.streak', [ - m('h3', 'Longest: '), f(s.max) - ]), - m('div.streak', [ - m('h3', 'Current streak'), f(s.cur) - ]) - ]; - }, - green: function(v) { - return m('green', v); - }, - red: function(v) { - return m('red', v); - }, - identity: function(v) { - return v; - }, - formatSeconds: function(s, format) { - var hours = Math.floor(s / 3600); - var minutes = Math.floor((s % 3600) / 60); - if (format === 'short') return hours + 'h, ' + minutes + 'm'; - return hours + ' hours, ' + minutes + ' minutes'; - } -}; diff --git a/ui/perfStat/src/view.js b/ui/perfStat/src/view.js deleted file mode 100644 index ce17a595e9..0000000000 --- a/ui/perfStat/src/view.js +++ /dev/null @@ -1,16 +0,0 @@ -var m = require('mithril'); - -module.exports = function(ctrl) { - var d = ctrl.data; - return m('div', { - config: lichess.powertip.manualGameIn - }, [ - m('section.glicko', require('./glicko')(d)), - m('section.counter.split', require('./counter')(d)), - m('section.highlow.split', require('./highlow')(d)), - m('section.resultStreak.split', require('./resultStreak')(d)), - m('section.result.split', require('./result')(d)), - m('section.playStreak', require('./playStreak').nb(d)), - m('section.playStreak', require('./playStreak').time(d)) - ]); -}; diff --git a/ui/perfStat/css/_perf-stat.scss b/ui/site/css/_perf-stat.scss similarity index 100% rename from ui/perfStat/css/_perf-stat.scss rename to ui/site/css/_perf-stat.scss diff --git a/ui/perfStat/css/build/_perf-stat.scss b/ui/site/css/build/_perf-stat.scss similarity index 100% rename from ui/perfStat/css/build/_perf-stat.scss rename to ui/site/css/build/_perf-stat.scss diff --git a/ui/perfStat/css/build/perf-stat.dark.scss b/ui/site/css/build/perf-stat.dark.scss similarity index 100% rename from ui/perfStat/css/build/perf-stat.dark.scss rename to ui/site/css/build/perf-stat.dark.scss diff --git a/ui/perfStat/css/build/perf-stat.light.scss b/ui/site/css/build/perf-stat.light.scss similarity index 100% rename from ui/perfStat/css/build/perf-stat.light.scss rename to ui/site/css/build/perf-stat.light.scss diff --git a/ui/perfStat/css/build/perf-stat.transp.scss b/ui/site/css/build/perf-stat.transp.scss similarity index 100% rename from ui/perfStat/css/build/perf-stat.transp.scss rename to ui/site/css/build/perf-stat.transp.scss