Commit | Line | Data |
---|---|---|
e71161fb BA |
1 | <template lang="pug"> |
2 | div | |
5b3dc10e BA |
3 | input#modalAdjust.modal(type="checkbox") |
4 | div#adjuster( | |
5 | role="dialog" | |
6 | data-checkbox="modalAdjust" | |
7 | ) | |
8 | .card.text-center | |
9 | label.modal-close(for="modalAdjust") | |
10 | label(for="boardSize") {{ st.tr["Board size"] }} | |
11 | input#boardSize.slider( | |
12 | type="range" | |
13 | min="0" | |
14 | max="100" | |
15 | value="50" | |
16 | @input="adjustBoard()" | |
17 | ) | |
feaf1bf7 BA |
18 | #aboveMoves |
19 | // NOTE: variants pages already have a "Rules" link on top | |
20 | span#rulesBtn( | |
21 | v-if="!$route.path.match('/variants/')" | |
57078452 BA |
22 | @click="clickRulesBtn()" |
23 | :class="btnRulesClass" | |
feaf1bf7 BA |
24 | ) |
25 | | {{ st.tr["Rules"] }} | |
1e02d16d | 26 | button( |
659a9bd2 | 27 | :class="btnTooltipClass()" |
feaf1bf7 BA |
28 | onClick="window.doClick('modalAdjust')" |
29 | :aria-label="st.tr['Resize board']" | |
30 | ) | |
31 | img.inline(src="/images/icons/resize.svg") | |
1e02d16d BA |
32 | button#analyzeBtn( |
33 | v-if="canAnalyze" | |
659a9bd2 | 34 | :class="btnTooltipClass()" |
b83a675a BA |
35 | @click="$emit('analyze')" |
36 | :aria-label="st.tr['Analyse']" | |
37 | ) | |
38 | img.inline(src="/images/icons/analyse.svg") | |
feaf1bf7 BA |
39 | #downloadDiv(v-if="canDownload") |
40 | a#download(href="#") | |
1e02d16d | 41 | button( |
659a9bd2 | 42 | :class="btnTooltipClass()" |
feaf1bf7 BA |
43 | @click="$emit('download')" |
44 | :aria-label="st.tr['Download'] + ' PGN'" | |
45 | ) | |
46 | img.inline(src="/images/icons/download.svg") | |
e71161fb | 47 | #scoreInfo(v-if="score!='*'") |
feaf1bf7 BA |
48 | span.score {{ score }} |
49 | span.score-msg {{ st.tr[message] }} | |
90df90bc | 50 | .moves-list |
e71161fb | 51 | .tr(v-for="moveIdx in evenNumbers") |
fef153df | 52 | .td {{ firstNum + moveIdx / 2 }} |
90df90bc | 53 | .td( |
e71161fb BA |
54 | :class="{'highlight-lm': cursor == moveIdx}" |
55 | @click="() => gotoMove(moveIdx)" | |
737a5daf | 56 | v-html="notation(moveIdx)") |
e71161fb BA |
57 | .td( |
58 | v-if="moveIdx < moves.length-1" | |
90df90bc | 59 | :class="{'highlight-lm': cursor == moveIdx+1}" |
e71161fb | 60 | @click="() => gotoMove(moveIdx+1)" |
737a5daf | 61 | v-html="notation(moveIdx + 1)") |
e71161fb BA |
62 | </template> |
63 | ||
cf2343ce | 64 | <script> |
fcd299a3 | 65 | import { store } from "@/store"; |
e71161fb | 66 | import { getFullNotation } from "@/utils/notation"; |
5b3dc10e | 67 | import { processModalClick } from "@/utils/modalClick"; |
cf2343ce | 68 | export default { |
6808d7a1 | 69 | name: "my-move-list", |
feaf1bf7 BA |
70 | props: [ |
71 | "moves", "show", "canAnalyze", "canDownload", | |
57078452 | 72 | "vname", "cursor", "score", "message", "firstNum"], |
311cba76 BA |
73 | data: function() { |
74 | return { | |
75 | st: store.state | |
76 | }; | |
77 | }, | |
5b3dc10e | 78 | mounted: function() { |
42a92848 BA |
79 | document.getElementById("adjuster") |
80 | .addEventListener("click", processModalClick); | |
5b3dc10e | 81 | // Take full width on small screens: |
5b3dc10e | 82 | const movesWidth = window.innerWidth >= 768 ? 280 : 0; |
be4b9421 BA |
83 | const winBound = Math.min(window.innerWidth - movesWidth, window.innerHeight); |
84 | let boardSize = (window.innerWidth >= 768 ? 0.7 : 1.0) * winBound; | |
5b3dc10e BA |
85 | document.getElementById("boardContainer").style.width = boardSize + "px"; |
86 | let gameContainer = document.getElementById("gameContainer"); | |
87 | gameContainer.style.width = boardSize + movesWidth + "px"; | |
be4b9421 BA |
88 | const minBoardWidth = |
89 | (window.innerWidth <= 767 || "ontouchstart" in window) ? 160 : 240; | |
90 | document.getElementById("boardSize").value = (boardSize - minBoardWidth) * 100 / (winBound - minBoardWidth); | |
4665d3c6 | 91 | window.addEventListener("resize", () => this.adjustBoard()); |
107dc1bd BA |
92 | }, |
93 | beforeDestroy: function() { | |
94 | window.removeEventListener("resize", this.adjustBoard); | |
5b3dc10e | 95 | }, |
c6b8d37f BA |
96 | watch: { |
97 | cursor: function(newCursor) { | |
98 | if (window.innerWidth <= 767) return; //scrolling would hide chessboard | |
c6b8d37f BA |
99 | // $nextTick to wait for table > tr to be rendered |
100 | this.$nextTick(() => { | |
3c186115 | 101 | let curMove = document.querySelector(".td.highlight-lm"); |
2c5d7b20 | 102 | if (!curMove && this.moves.length > 0) { |
c51c301f | 103 | // Cursor is before game beginning, and some moves were made: |
2c5d7b20 BA |
104 | curMove = |
105 | document.querySelector(".moves-list > .tr:first-child > .td"); | |
106 | } | |
3c186115 BA |
107 | if (!!curMove) { |
108 | curMove.scrollIntoView({ | |
c6b8d37f BA |
109 | behavior: "auto", |
110 | block: "nearest" | |
111 | }); | |
112 | } | |
113 | }); | |
114 | } | |
115 | }, | |
e71161fb BA |
116 | computed: { |
117 | evenNumbers: function() { | |
118 | return [...Array(this.moves.length).keys()].filter(i => i%2==0); | |
57078452 BA |
119 | }, |
120 | btnRulesClass: function() { | |
121 | // "rr" for "rules read" | |
77a37196 BA |
122 | return { |
123 | highlightRules: | |
124 | !!this.vname && !localStorage.getItem("rr_" + this.vname) | |
125 | }; | |
e71161fb BA |
126 | } |
127 | }, | |
430a2038 | 128 | methods: { |
90df90bc BA |
129 | notation: function(moveIdx) { |
130 | const move = this.moves[moveIdx]; | |
131 | if (this.score != "*") return getFullNotation(move); | |
132 | if ( | |
133 | ['none','highlight'].includes(this.show) || | |
e6bcc1d8 | 134 | ( |
e6bcc1d8 | 135 | this.show == "byrow" && |
90df90bc BA |
136 | moveIdx == this.moves.length-1 && |
137 | moveIdx % 2 == 0 | |
e6bcc1d8 | 138 | ) |
90df90bc BA |
139 | ) { |
140 | return "?"; | |
141 | } | |
142 | return getFullNotation(move); | |
08a5069c | 143 | }, |
1e02d16d BA |
144 | btnTooltipClass: function() { |
145 | return { tooltip: !("ontouchstart" in window) }; | |
146 | }, | |
57078452 BA |
147 | clickRulesBtn: function() { |
148 | const key = "rr_" + this.vname; | |
149 | if (!localStorage.getItem(key)) { | |
150 | localStorage.setItem(key, '1'); | |
151 | document.getElementById("rulesBtn").classList.remove("highlightRules"); | |
152 | } | |
153 | this.$emit("showrules"); | |
154 | }, | |
dac39588 | 155 | gotoMove: function(index) { |
107dc1bd BA |
156 | // Goto move except if click on current move: |
157 | if (this.cursor != index) this.$emit("goto-move", index); | |
5b3dc10e | 158 | }, |
75f009f4 | 159 | adjustBoard: function(vertical) { |
5b3dc10e BA |
160 | const boardContainer = document.getElementById("boardContainer"); |
161 | if (!boardContainer) return; //no board on page | |
5b3dc10e | 162 | const movesWidth = window.innerWidth >= 768 ? 280 : 0; |
75f009f4 BA |
163 | let gameContainer = document.getElementById("gameContainer"); |
164 | if (vertical) { | |
165 | const bRect = | |
166 | document.getElementById("rootBoardElement").getBoundingClientRect(); | |
167 | if (bRect.bottom > window.innerHeight) { | |
168 | const maxHeight = window.innerHeight - 20; | |
be4b9421 | 169 | document.getElementById("boardContainer").style.height = maxHeight + "px"; |
75f009f4 | 170 | const boardSize = maxHeight * bRect.width / bRect.height; |
be4b9421 | 171 | boardContainer.style.width = Math.min(boardSize, boardContainer.style.width) + "px"; |
75f009f4 BA |
172 | gameContainer.style.width = boardSize + movesWidth + "px"; |
173 | this.$emit("redraw-board"); | |
174 | setTimeout( () => window.scroll(0, bRect.top), 1000); | |
175 | } | |
176 | } | |
177 | else { | |
178 | const k = document.getElementById("boardSize").value; | |
bc1e1f2a BA |
179 | // TODO: these 160 and 280 are arbitrary... |
180 | const minBoardWidth = | |
181 | (window.innerWidth <= 767 || "ontouchstart" in window) ? 160 : 240; | |
75f009f4 | 182 | // Value of 0 is board min size; 100 is window.width [- movesWidth] |
bc1e1f2a BA |
183 | const maxWidth = |
184 | Math.min(window.innerHeight, window.innerWidth - movesWidth); | |
75f009f4 | 185 | const boardSize = |
bc1e1f2a | 186 | minBoardWidth + (k * (maxWidth - minBoardWidth)) / 100; |
75f009f4 BA |
187 | boardContainer.style.width = boardSize + "px"; |
188 | gameContainer.style.width = boardSize + movesWidth + "px"; | |
189 | this.$emit("redraw-board"); | |
190 | } | |
6808d7a1 BA |
191 | } |
192 | } | |
430a2038 BA |
193 | }; |
194 | </script> | |
195 | ||
196 | <style lang="sass" scoped> | |
197 | .moves-list | |
28b32b4f | 198 | user-select: none |
8477e53d BA |
199 | cursor: pointer |
200 | min-height: 1px | |
201 | max-height: 500px | |
202 | overflow: auto | |
203 | background-color: white | |
204 | width: 280px | |
205 | & > .tr | |
206 | clear: both | |
207 | border-bottom: 1px solid lightgrey | |
208 | & > .td | |
209 | float: left | |
f9c36b2d | 210 | padding: 2% 0 2% 2% |
8477e53d BA |
211 | &:first-child |
212 | color: grey | |
f9c36b2d | 213 | width: 13% |
8477e53d | 214 | &:not(first-child) |
f9c36b2d | 215 | width: 40.5% |
8477e53d BA |
216 | |
217 | @media screen and (max-width: 767px) | |
218 | .moves-list | |
219 | width: 100% | |
910d631b | 220 | |
8477e53d | 221 | .td.highlight-lm |
430a2038 | 222 | background-color: plum |
5b3dc10e | 223 | |
57078452 BA |
224 | .highlightRules |
225 | padding: 3px 5px | |
226 | background-color: yellow | |
227 | ||
5b3dc10e BA |
228 | #boardSizeBtnContainer |
229 | width: 100% | |
230 | text-align: center | |
231 | ||
5b3dc10e BA |
232 | [type="checkbox"]#modalAdjust+div .card |
233 | padding: 5px | |
feaf1bf7 BA |
234 | |
235 | img.inline | |
54ec15eb | 236 | height: 22px |
feaf1bf7 BA |
237 | @media screen and (max-width: 767px) |
238 | height: 18px | |
239 | ||
0cc44e58 BA |
240 | #scoreInfo |
241 | margin: 10px 0 | |
242 | @media screen and (max-width: 767px) | |
243 | margin: 5px 0 | |
244 | ||
feaf1bf7 BA |
245 | span.score |
246 | display: inline-block | |
247 | margin-left: 10px | |
248 | font-weight: bold | |
249 | ||
250 | span.score-msg | |
251 | display: inline-block | |
252 | margin-left: 10px | |
253 | font-style: italic | |
254 | ||
255 | #downloadDiv | |
256 | display: inline-block | |
257 | margin: 0 | |
258 | ||
259 | span#rulesBtn | |
260 | cursor: pointer | |
261 | display: inline-block | |
262 | margin: 0 10px | |
263 | font-weight: bold | |
264 | ||
265 | button | |
266 | margin: 0 | |
07052665 | 267 | &.active |
236485b5 | 268 | background-color: #48C9B0 |
5b4de147 | 269 | |
42a92848 | 270 | #aboveMoves button |
5b4de147 | 271 | padding-bottom: 5px |
430a2038 | 272 | </style> |