210 lines
8.2 KiB
JavaScript
210 lines
8.2 KiB
JavaScript
(function () {
|
|
'use strict';
|
|
|
|
function checkLoginStatus() {
|
|
const isLoggedIn = localStorage.getItem('isLoggedIn');
|
|
if (!isLoggedIn || isLoggedIn !== 'true') {
|
|
window.location.href = typeof appPath === 'function' ? appPath('/Login/') : '/Login/';
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
if (!checkLoginStatus()) {
|
|
return;
|
|
}
|
|
|
|
const BASE = typeof appPath === 'function' ? appPath('/Game') : '/Game';
|
|
const SERVER = (typeof GAME_SERVER !== 'undefined' ? GAME_SERVER : '') + (typeof appPath === 'function' ? appPath('/Game') : '/Game');
|
|
const IMG = {
|
|
publishOn: 'IMAGE/btn-publish-room-h.png',
|
|
publishOff: 'IMAGE/btn-publish-room.png',
|
|
privateOn: 'IMAGE/btn-private-room-h.png',
|
|
privateOff: 'IMAGE/btn-private-room.png',
|
|
joinOn: 'IMAGE/btn-join-room.png',
|
|
joinOff: 'IMAGE/btn-join-room-2.png',
|
|
};
|
|
const USE_PUBLIC_ROOM_MOCK = false;
|
|
const MOCK_PUBLIC_ROOMS = [
|
|
{ spaceId: 'JD-001', spaceName: '[JUSTICE DIVERS #01]', mapName: 'Neo City', peerCount: 2, maxPlayers: 4 },
|
|
{ spaceId: 'JD-002', spaceName: '[JUSTICE DIVERS #02]', mapName: 'Cyber Lab', peerCount: 5, maxPlayers: 6 },
|
|
{ spaceId: 'JD-003', spaceName: '[JUSTICE DIVERS #03]', mapName: 'Sky Deck', peerCount: 5, maxPlayers: 5 },
|
|
{ spaceId: 'JD-004', spaceName: '[JUSTICE DIVERS #04]', mapName: 'Dockyard', peerCount: 2, maxPlayers: 4 },
|
|
{ spaceId: 'JD-005', spaceName: '[JUSTICE DIVERS #05]', mapName: 'Temple', peerCount: 3, maxPlayers: 4 },
|
|
{ spaceId: 'JD-006', spaceName: '[JUSTICE DIVERS #06]', mapName: 'Arena', peerCount: 6, maxPlayers: 6 },
|
|
{ spaceId: 'JD-007', spaceName: '[JUSTICE DIVERS #07]', mapName: 'Outpost', peerCount: 1, maxPlayers: 4 }
|
|
];
|
|
|
|
function getNick() {
|
|
if (typeof window.jdReadDisplayName === 'function') {
|
|
return window.jdReadDisplayName();
|
|
}
|
|
try {
|
|
return (localStorage.getItem('roomLobbyDisplayName') || localStorage.getItem('playerName') || '').trim() || 'ผู้เล่น';
|
|
} catch (e) {
|
|
return 'ผู้เล่น';
|
|
}
|
|
}
|
|
|
|
function escapeHtml(s) {
|
|
var div = document.createElement('div');
|
|
div.textContent = s;
|
|
return div.innerHTML;
|
|
}
|
|
|
|
var btnBack = document.getElementById('btn-back');
|
|
var tabPublic = document.getElementById('tab-public');
|
|
var tabPrivate = document.getElementById('tab-private');
|
|
var imgPublic = document.getElementById('tab-img-public');
|
|
var imgPrivate = document.getElementById('tab-img-private');
|
|
var viewPublic = document.getElementById('join-public-view');
|
|
var viewPrivate = document.getElementById('join-private-view');
|
|
var listPublic = document.getElementById('room-list-public');
|
|
var publicScrollThumb = document.getElementById('join-scrollbar-thumb');
|
|
var tplRow = document.getElementById('tpl-room-row');
|
|
var passPrivate = document.getElementById('join-private-password');
|
|
var idPrivate = document.getElementById('join-private-room-id');
|
|
var btnPrivateJoin = document.getElementById('btn-private-join');
|
|
|
|
btnBack?.addEventListener('click', function () {
|
|
window.location.href = typeof appPath === 'function' ? appPath('/Main-Menu/') : '/Main-Menu/';
|
|
});
|
|
|
|
passPrivate?.addEventListener('input', function (e) {
|
|
e.target.value = e.target.value.replace(/[^0-9]/g, '').slice(0, 4);
|
|
});
|
|
|
|
function goToRoom(spaceId) {
|
|
window.location.href = BASE + '/room-lobby.html?space=' + encodeURIComponent(spaceId) + '&nick=' + encodeURIComponent(getNick());
|
|
}
|
|
|
|
function renderPublicRooms(list) {
|
|
if (!listPublic || !tplRow) return;
|
|
listPublic.innerHTML = '';
|
|
if (!Array.isArray(list) || list.length === 0) {
|
|
listPublic.innerHTML = '<div class="join-list-status">ยังไม่มีห้อง</div>';
|
|
return;
|
|
}
|
|
list.forEach(function (room) {
|
|
var code = room.spaceId || ('room-' + Math.random().toString(36).slice(2, 8));
|
|
var name = room.spaceName || code;
|
|
var mapName = room.mapName || '—';
|
|
var count = room.peerCount != null ? room.peerCount : 0;
|
|
var max = room.maxPlayers != null ? room.maxPlayers : 10;
|
|
var full = count >= max;
|
|
var node = tplRow.content.cloneNode(true);
|
|
var nameEl = node.querySelector('.join-room-name');
|
|
var playersEl = node.querySelector('.join-room-players');
|
|
var btn = node.querySelector('.join-room-btn');
|
|
var img = node.querySelector('.join-room-btn-img');
|
|
|
|
nameEl.textContent = 'ห้อง : ' + name + ' [' + mapName + ']';
|
|
playersEl.textContent = 'ผู้เล่น : ' + count + '/' + max;
|
|
img.src = IMG.joinOn;
|
|
img.alt = full ? 'เต็ม' : 'เข้าร่วม';
|
|
|
|
if (full) {
|
|
btn.disabled = true;
|
|
} else {
|
|
btn.addEventListener('click', function () {
|
|
goToRoom(room.spaceId);
|
|
});
|
|
}
|
|
listPublic.appendChild(node);
|
|
});
|
|
syncPublicScrollbarThumb();
|
|
}
|
|
|
|
function syncPublicScrollbarThumb() {
|
|
if (!listPublic || !publicScrollThumb) return;
|
|
var total = listPublic.scrollHeight;
|
|
var visible = listPublic.clientHeight;
|
|
var track = listPublic.parentElement ? listPublic.parentElement.clientHeight : visible;
|
|
var styles = window.getComputedStyle(publicScrollThumb);
|
|
var topInset = parseFloat(styles.top) || 0;
|
|
var bottomInset = topInset;
|
|
var minThumb = parseFloat(styles.minHeight) || 40;
|
|
var innerTrack = Math.max(0, track - topInset - bottomInset);
|
|
if (!total || total <= visible || track <= 0) {
|
|
publicScrollThumb.style.opacity = '0';
|
|
return;
|
|
}
|
|
|
|
var thumbH = Math.max(minThumb, (visible / total) * innerTrack);
|
|
var maxY = Math.max(0, innerTrack - thumbH);
|
|
var ratio = listPublic.scrollTop / Math.max(1, total - visible);
|
|
var y = topInset + (maxY * ratio);
|
|
var clampedY = Math.min(topInset + maxY, Math.max(topInset, y));
|
|
|
|
publicScrollThumb.style.height = thumbH + 'px';
|
|
publicScrollThumb.style.transform = 'translateY(' + clampedY + 'px)';
|
|
publicScrollThumb.style.opacity = '1';
|
|
}
|
|
|
|
function refreshPublicRooms() {
|
|
if (!listPublic || !tplRow) return;
|
|
if (USE_PUBLIC_ROOM_MOCK) {
|
|
renderPublicRooms(MOCK_PUBLIC_ROOMS);
|
|
return;
|
|
}
|
|
listPublic.innerHTML = '<div class="join-list-status" id="room-list-status">โหลดรายการห้อง...</div>';
|
|
var statusEl = document.getElementById('room-list-status');
|
|
fetch(SERVER + '/api/spaces?_=' + Date.now())
|
|
.then(function (r) { return r.json(); })
|
|
.then(function (list) {
|
|
if (!Array.isArray(list)) {
|
|
if (statusEl) statusEl.textContent = 'โหลดรายการห้องไม่ได้';
|
|
return;
|
|
}
|
|
renderPublicRooms(list);
|
|
})
|
|
.catch(function () {
|
|
if (statusEl) statusEl.textContent = 'โหลดรายการห้องไม่ได้';
|
|
});
|
|
}
|
|
|
|
function setTab(mode) {
|
|
var isPublic = mode === 'public';
|
|
if (imgPublic) imgPublic.src = isPublic ? IMG.publishOn : IMG.publishOff;
|
|
if (imgPrivate) imgPrivate.src = isPublic ? IMG.privateOff : IMG.privateOn;
|
|
tabPublic?.setAttribute('aria-selected', isPublic ? 'true' : 'false');
|
|
tabPrivate?.setAttribute('aria-selected', isPublic ? 'false' : 'true');
|
|
if (viewPublic) viewPublic.classList.toggle('join-view--hidden', !isPublic);
|
|
if (viewPrivate) viewPrivate.classList.toggle('join-view--hidden', isPublic);
|
|
}
|
|
|
|
tabPublic?.addEventListener('click', function () {
|
|
setTab('public');
|
|
});
|
|
|
|
tabPrivate?.addEventListener('click', function () {
|
|
setTab('private');
|
|
});
|
|
|
|
btnPrivateJoin?.addEventListener('click', function () {
|
|
var code = (idPrivate?.value || '').trim();
|
|
var pass = (passPrivate?.value || '').trim();
|
|
if (!code) {
|
|
alert('กรุณากรอกรหัสห้อง');
|
|
idPrivate?.focus();
|
|
return;
|
|
}
|
|
if (pass && pass.length !== 4) {
|
|
alert('รหัสผ่านต้องเป็นตัวเลข 4 หลัก');
|
|
passPrivate?.focus();
|
|
return;
|
|
}
|
|
goToRoom(code);
|
|
});
|
|
|
|
if (USE_PUBLIC_ROOM_MOCK) {
|
|
renderPublicRooms(MOCK_PUBLIC_ROOMS);
|
|
} else {
|
|
refreshPublicRooms();
|
|
setInterval(refreshPublicRooms, 8000);
|
|
}
|
|
listPublic?.addEventListener('scroll', syncPublicScrollbarThumb);
|
|
window.addEventListener('resize', syncPublicScrollbarThumb);
|
|
setTab('public');
|
|
})();
|