Skip to content

Commit 11d662e

Browse files
committed
nojs search and leaderboards
1 parent 8f90fca commit 11d662e

3 files changed

Lines changed: 354 additions & 85 deletions

File tree

public_html/lib/module/rpcn/inc-rpcn-game.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,13 @@ public function handle_ajax(string $commId, ?string $boardIdParam): void
292292
echo "</tbody></table></div>";
293293
}
294294

295+
public function get_board_html(string $commId, int $boardId): string
296+
{
297+
ob_start();
298+
$this->handle_ajax($commId, (string)$boardId);
299+
return ob_get_clean() ?: '';
300+
}
301+
295302
public function load_page_data(string $commId, RPCNStats $stats, ?mysqli $db): void
296303
{
297304
// Basic game info from the stats object

public_html/rpcn-game.php

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,18 @@ function rpcn_build_svg(array $data, string $gradId): string
118118
$autoShowBoard = ($hasLeaderboard && !empty($boards) && count($boards) === 1)
119119
? (int)array_key_first($boards)
120120
: null;
121+
122+
// nojs leaderboard
123+
$lb_back_url = 'rpcn-game.php?comm_id=' . urlencode($commId);
124+
$nojsBoardId = null;
125+
$nojsBoardHtml = '';
126+
if ($hasLeaderboard && !empty($boards) && isset($_GET['board_id'])) {
127+
$bid = (int)$_GET['board_id'];
128+
if (array_key_exists($bid, $boards)) {
129+
$nojsBoardId = $bid;
130+
$nojsBoardHtml = $rpcn_game->get_board_html($commId, $bid);
131+
}
132+
}
121133
?>
122134
<!DOCTYPE html>
123135
<html lang="en">
@@ -451,6 +463,7 @@ function rpcn_build_svg(array $data, string $gradId): string
451463
gap: 8px;
452464
transition: all .15s;
453465
user-select: none;
466+
text-decoration: none;
454467
}
455468
.rpcn-board-btn:hover {
456469
background: var(--rpcn-accent-bg);
@@ -477,6 +490,7 @@ function rpcn_build_svg(array $data, string $gradId): string
477490
transition: color .2s, border-color .2s;
478491
font-family: inherit;
479492
user-select: none;
493+
text-decoration: none;
480494
}
481495
.rpcn-btn-back-lb:hover { color: var(--rpcn-accent); border-color: var(--rpcn-accent); }
482496

@@ -606,9 +620,9 @@ class="rpcn-game-icon"
606620
</div>
607621
</div>
608622

609-
<input type="radio" name="rpcn-tab" id="tab-charts" class="rpcn-sr" checked>
623+
<input type="radio" name="rpcn-tab" id="tab-charts" class="rpcn-sr" <?= (!$hasLeaderboard || $nojsBoardId === null) ? 'checked' : '' ?>>
610624
<?php if ($hasLeaderboard): ?>
611-
<input type="radio" name="rpcn-tab" id="tab-lb" class="rpcn-sr">
625+
<input type="radio" name="rpcn-tab" id="tab-lb" class="rpcn-sr" <?= $nojsBoardId !== null ? 'checked' : '' ?>>
612626
<?php endif; ?>
613627

614628
<div class="rpcn-tabs-nav">
@@ -650,27 +664,28 @@ class="rpcn-game-icon"
650664
<div id="panel-lb" class="rpcn-tab-panel">
651665

652666
<!-- Board selection grid -->
653-
<div id="rpcn-board-selection">
667+
<div id="rpcn-board-selection" <?= $nojsBoardId !== null ? 'style="display:none"' : '' ?>>
654668
<?php if (count($boards) > 1): ?>
655669
<p class="rpcn-lb-section-title">Choose Scoreboard</p>
656670
<?php endif; ?>
657671
<div class="rpcn-board-grid">
658672
<?php foreach ($boards as $boardId => $boardName): ?>
659-
<button class="rpcn-board-btn"
660-
data-board-id="<?= (int)$boardId ?>"
661-
data-board-name="<?= htmlspecialchars($boardName) ?>">
673+
<a href="rpcn-game.php?comm_id=<?= urlencode($commId) ?>&amp;board_id=<?= (int)$boardId ?>"
674+
class="rpcn-board-btn"
675+
data-board-id="<?= (int)$boardId ?>"
676+
data-board-name="<?= htmlspecialchars($boardName) ?>">
662677
<?= htmlspecialchars($boardName) ?>
663-
</button>
678+
</a>
664679
<?php endforeach; ?>
665680
</div>
666681
</div>
667682

668683
<!-- Board content pane (shown after a board is selected) -->
669-
<div id="rpcn-board-view">
684+
<div id="rpcn-board-view" <?= $nojsBoardId !== null ? 'style="display:block"' : '' ?>>
670685
<?php if (count($boards) > 1): ?>
671-
<button class="rpcn-btn-back-lb" id="rpcn-back-lb">&#8592; Back to boards</button>
686+
<a href="<?= htmlspecialchars($lb_back_url) ?>" class="rpcn-btn-back-lb" id="rpcn-back-lb">&#8592; Back to boards</a>
672687
<?php endif; ?>
673-
<div id="rpcn-board-content"></div>
688+
<div id="rpcn-board-content"><?= $nojsBoardHtml ?></div>
674689
</div>
675690

676691
</div><!-- /#panel-lb -->
@@ -680,58 +695,71 @@ class="rpcn-game-icon"
680695

681696
</div><!-- /.rpcn-page-wrap -->
682697
<script>
683-
(function () {
684-
const commId = <?= json_encode($commId) ?>;
685-
const autoBoard = <?= json_encode($autoShowBoard) ?>;
686-
const multiBoard = <?= json_encode(count($boards) > 1) ?>;
698+
(function ()
699+
{
700+
document.documentElement.classList.add('js-ready');
701+
702+
const commId = <?= json_encode($commId) ?>;
703+
const autoBoard = <?= json_encode($autoShowBoard) ?>;
687704

688-
const selection = document.getElementById('rpcn-board-selection');
689-
const view = document.getElementById('rpcn-board-view');
690-
const content = document.getElementById('rpcn-board-content');
691-
const backBtn = document.getElementById('rpcn-back-lb');
705+
const selection = document.getElementById('rpcn-board-selection');
706+
const view = document.getElementById('rpcn-board-view');
707+
const content = document.getElementById('rpcn-board-content');
708+
const backBtn = document.getElementById('rpcn-back-lb');
692709

693710
if (!selection || !view || !content) return;
694711

695-
function loadBoard(boardId) {
712+
function loadBoard(boardId)
713+
{
696714
selection.style.display = 'none';
697715
view.style.display = 'block';
698716
content.innerHTML = '<div class="rpcn-lb-loading">Loading scores</div>';
699717

700718
fetch('rpcn-game.php?comm_id=' + encodeURIComponent(commId) + '&ajax=1&board_id=' + encodeURIComponent(boardId))
701-
.then(function (r) {
719+
.then(function (r)
720+
{
702721
if (!r.ok) throw new Error('HTTP ' + r.status);
703722
return r.text();
704723
})
705-
.then(function (html) {
724+
.then(function (html)
725+
{
706726
content.innerHTML = html;
707727
})
708-
.catch(function () {
728+
.catch(function ()
729+
{
709730
content.innerHTML = "<p class='rpcn-error'>Failed to load scores. Please try again.</p>";
710731
});
711732
}
712733

713-
document.querySelectorAll('.rpcn-board-btn').forEach(function (btn) {
714-
btn.addEventListener('click', function () {
734+
document.querySelectorAll('.rpcn-board-btn').forEach(function (btn)
735+
{
736+
btn.addEventListener('click', function (e)
737+
{
738+
e.preventDefault();
715739
loadBoard(btn.dataset.boardId);
716740
});
717741
});
718742

719743
// Back button
720744
if (backBtn) {
721-
backBtn.addEventListener('click', function () {
745+
backBtn.addEventListener('click', function (e)
746+
{
747+
e.preventDefault();
722748
view.style.display = 'none';
723749
content.innerHTML = '';
724750
selection.style.display = 'block';
725751
});
726752
}
727753

728754
// Autoload when there is only one board
729-
if (autoBoard !== null) {
730-
// Trigger when user switches to the Leaderboards tab
755+
if (autoBoard !== null)
756+
{
731757
var tabLb = document.getElementById('tab-lb');
732-
if (tabLb) {
733-
var loaded = false;
734-
tabLb.addEventListener('change', function () {
758+
if (tabLb)
759+
{
760+
var loaded = content.innerHTML.trim() !== '';
761+
tabLb.addEventListener('change', function ()
762+
{
735763
if (!loaded) { loaded = true; loadBoard(autoBoard); }
736764
});
737765
}

0 commit comments

Comments
 (0)