chess / static /app.js
christopher's picture
Update static/app.js
365937e
raw
history blame
4.17 kB
const RESULTS_PER_PAGE = 20;
let allResults = [];
let currentPage = 0;
var board = Chessboard("board", {
draggable: true,
dropOffBoard: "trash",
sparePieces: true,
pieceTheme: "/static/img/chesspieces/wikipedia/{piece}.png",
onSnapEnd: updateInfo,
});
function updateInfo() {
document.getElementById('fen').value = board.fen();
let pos = board.position();
let pieces = Object.keys(pos).length;
}
// function search() {
// let pos = board.position();
// if (Object.keys(pos).length < 3) {
// document.getElementById("results").innerHTML =
// "<p>Add at least 3 pieces to search.</p>";
// return;
// }
// document.getElementById("results").innerHTML = "<p>Searching...</p>";
// fetch("/search", {
// method: "POST",
// headers: { "Content-Type": "application/json" },
// body: JSON.stringify({ fen: board.fen() }),
// })
// .then((r) => r.json())
// .then((data) => {
// allResults = data.results;
// window.searchTimeMs = data.time_ms;
// currentPage = 0;
// displayPage();
// });
// }
function search() {
let pos = board.position();
if (Object.keys(pos).length < 3) {
document.getElementById("results").innerHTML = "<p>Add at least 3 pieces to search.</p>";
return;
}
allResults = [];
document.getElementById("results").innerHTML = "<p>Searching...</p>";
const startTime = performance.now();
fetch("/search", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ fen: board.fen() }),
})
.then(r => r.body.getReader())
.then(reader => {
const decoder = new TextDecoder();
let buffer = '';
function read() {
reader.read().then(({done, value}) => {
if (done) {
window.searchTimeMs = performance.now() - startTime;
currentPage = 0;
displayPage();
return;
}
buffer += decoder.decode(value, {stream: true});
const lines = buffer.split('\n');
buffer = lines.pop();
lines.forEach(line => {
if (line.trim()) {
allResults.push(JSON.parse(line));
if (allResults.length === 1 || allResults.length % 20 === 0) displayPage();
}
});
read();
});
}
read();
});
}
function displayPage() {
const start = currentPage * RESULTS_PER_PAGE,
end = start + RESULTS_PER_PAGE,
pageResults = allResults.slice(start, end),
totalPages = Math.ceil(allResults.length / RESULTS_PER_PAGE);
const paginationHtml = allResults.length > 0 ? `<div class="pagination"><button onclick="prevPage()" ${currentPage === 0 ? "disabled" : ""}>&lt;</button><button onclick="nextPage()" ${end >= allResults.length ? "disabled" : ""}>&gt;</button></div>` : "";
let html = `<p>Found ${allResults.length} puzzles${allResults.length > 0 ? ` in ${window.searchTimeMs.toFixed(0)}ms (page ${currentPage + 1} of ${totalPages})` : ""}</p>`;
html += paginationHtml;
html += `<div class="puzzle-grid">`;
pageResults.forEach((p, i) => {
const idx = start + i;
html += `<div class="puzzle"><div class="puzzle-board" id="result-board-${idx}"></div><div class="puzzle-info"><h3><a href="https://lichess.org/training/${p.PuzzleId}" target="_blank">${p.PuzzleId}</a></h3><p>Rating: ${p.Rating} | Pop: ${p.Popularity}%</p><div class="themes">${p.Themes.map((t) => `<span class="theme">${t}</span>`).join(" ")}</div><p>Move ${p.MatchedMove}</p></div></div>`;
});
html += `</div>`;
html += paginationHtml;
document.getElementById("results").innerHTML = html;
pageResults.forEach((p, i) =>
Chessboard(`result-board-${start + i}`, {
position: p.FEN,
pieceTheme: "/static/img/chesspieces/wikipedia/{piece}.png",
})
);
}
function nextPage() {
if ((currentPage + 1) * RESULTS_PER_PAGE < allResults.length) {
currentPage++;
displayPage();
}
}
function prevPage() {
if (currentPage > 0) {
currentPage--;
displayPage();
}
}
updateInfo();