-
Notifications
You must be signed in to change notification settings - Fork 16
/
miniboard.js
114 lines (96 loc) · 3.45 KB
/
miniboard.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
const m = require('mithril');
const { Chessground } = require('chessground');
const timeAgo = require('./timeAgo')();
module.exports = (gameSummaryObservable, summary, identPerspective, opts) => {
let chessground = null;
let observables = [];
let lastActivityTimestamp = summary.lastUpdateTime;
// An observer might not be in the 'players' list so we need a default
// perspective of white for them.
const playerColour = (summary.players[identPerspective]
&& summary.players[identPerspective].colour) ? summary.players[identPerspective].colour : 'white';
function renderPlayerName(player) {
return m(`a[href=/player/${btoa(player.id)}]`, {
class: 'ssb-chess-miniboard-name',
oncreate: m.route.link,
},
player.name.substring(0, 10));
}
function renderSummaryBottom() {
if (!(opts && opts.small)) {
const coloursNames = summary.coloursToPlayer();
const otherPlayerColour = playerColour == 'white' ? 'black' : 'white';
const leftPlayer = coloursNames[playerColour];
const rightPlayer = coloursNames[otherPlayerColour];
return m('div', {
class: 'ssb-chess-miniboard-bottom',
}, [m('center', {
class: 'ssb-chess-miniboard-name',
}, renderPlayerName(leftPlayer)),
m('small', {
class: 'ssb-chess-miniboard-time-ago',
}, lastActivityTimestamp ? timeAgo(lastActivityTimestamp)() : ''),
m('center', {
class: 'ssb-chess-miniboard-name',
}, renderPlayerName(rightPlayer)),
]);
}
return m('div');
}
function renderSummary() {
const observing = Object.keys(summary.players).indexOf(identPerspective) === -1;
const boardSizeClass = opts && opts.small ? 'ssb-chess-board-small' : 'ssb-chess-board-medium';
return m('div', {
class: 'ssb-chess-miniboard ssb-chess-board-background-blue3 merida',
}, [
m(`${'a[href=/games/'}${btoa(summary.gameId)}?observing=${observing}]`, {
class: `ssb-chessground-container cg-board-wrap ${boardSizeClass}`,
title: summary.gameId,
id: summary.gameId,
oncreate: m.route.link,
}), renderSummaryBottom(),
]);
}
function summaryToChessgroundConfig(s) {
const config = {
fen: s.fen,
viewOnly: true,
orientation: playerColour,
turnColor: s.players[s.toMove].colour,
check: s.check,
coordinates: false,
};
if (s.lastMove) {
config.lastMove = [s.lastMove.orig, s.lastMove.dest];
}
return config;
}
return {
view() {
return renderSummary();
},
oncreate(vNode) {
// This lifecycle event tells us that the DOM is ready. That means we
// can attach chessground to our chessground container element that was
// prepared for it during the 'view' lifecycle method.
const config = summaryToChessgroundConfig(summary);
const { dom } = vNode;
const chessGroundParent = dom.querySelector('.ssb-chessground-container');
chessground = Chessground(chessGroundParent, config);
// Listen for game updates
const situationObs = gameSummaryObservable((newSummary) => {
const newConfig = summaryToChessgroundConfig(newSummary);
chessground.set(newConfig);
lastActivityTimestamp = newSummary.lastUpdateTime;
});
observables.push(situationObs);
},
onremove() {
if (chessground) {
chessground.destroy();
}
observables.forEach(w => w());
observables = [];
},
};
};