Files
justice/www/html/Main-Lobby/lobby.js
T

446 lines
14 KiB
JavaScript

(function () {
'use strict';
var BASE = '/Game';
var CHAR_KEY = 'gameCharacterId';
var GUIDE_KEY = 'mainLobbyGuideDone';
var MAX_GUIDE = 5;
var ML_GUIDE = '/Main-Lobby/IMAGE/guide';
function checkLogin() {
if (localStorage.getItem('isLoggedIn') !== 'true') {
window.location.href = '/Login/';
return false;
}
return true;
}
if (!checkLogin()) return;
function toast(msg) {
var el = document.getElementById('lobby-toast');
if (!el) return;
el.textContent = msg;
el.classList.add('lobby-toast--show');
clearTimeout(toast._t);
toast._t = setTimeout(function () {
el.classList.remove('lobby-toast--show');
}, 2600);
}
function padAgent(n) {
var s = String(n);
while (s.length < 6) s = '0' + s;
return s;
}
function ensureAgentId() {
var k = 'agentDisplayId';
var v = localStorage.getItem(k);
if (!v || !/^\d{6}$/.test(v)) {
v = padAgent(100000 + Math.floor(Math.random() * 899999));
try {
localStorage.setItem(k, v);
} catch (e) { /* ignore */ }
}
return v;
}
function getSelectedCharacterId() {
try {
return (localStorage.getItem(CHAR_KEY) || '').trim();
} catch (e) {
return '';
}
}
function characterDownUrls(id) {
var enc = encodeURIComponent(id);
var q = '?ch=' + encodeURIComponent(id);
return [
BASE + '/img/characters/' + enc + '_down.png' + q,
BASE + '/img/characters/' + enc + '_down_0.png' + q
];
}
var PLAYER_KEY = 'jdPlayerKey';
function ensurePlayerKey() {
var k;
try {
k = localStorage.getItem(PLAYER_KEY);
} catch (e) {
k = '';
}
if (!k || String(k).length < 8) {
k = 'p_' + Date.now() + '_' + Math.random().toString(36).slice(2, 14);
try {
localStorage.setItem(PLAYER_KEY, k);
} catch (e2) { /* ignore */ }
}
return k;
}
/** ดึง COINS จากเซิร์ฟ (บัญชี guest สร้างอัตโนมัติถ้ายังไม่มี) */
function syncCoinsFromServer() {
var key = ensurePlayerKey();
fetch('/Admin/api/player-coins.php?playerKey=' + encodeURIComponent(key), { credentials: 'omit' })
.then(function (r) { return r.json(); })
.then(function (d) {
if (!d || !d.ok) return;
var c = String(Math.max(0, parseInt(d.coins, 10) || 0));
try {
localStorage.setItem('jdCoins', c);
} catch (e) { /* ignore */ }
var coinsEl = document.getElementById('lobby-profile-coins');
if (coinsEl) coinsEl.textContent = c;
})
.catch(function () { /* offline */ });
}
/** รีเฟรชหลังเลือกตัวละคร / สลับแท็บ / ย้อนกลับบน tablet (bfcache) */
function syncMainLobbyCharacterUi() {
applyProfile();
applyCenterCharacter();
syncCoinsFromServer();
}
function probeImage(url, onOk, onFail) {
var probe = new Image();
probe.onload = function () { onOk(url); };
probe.onerror = onFail;
probe.src = url;
}
function applyCenterCharacter() {
var centerEl = document.getElementById('lobby-character-img');
if (!centerEl) return;
function showSceneOnly() {
centerEl.classList.remove('lobby-character-img--visible');
centerEl.removeAttribute('src');
}
function revealChar() {
centerEl.classList.add('lobby-character-img--visible');
}
function showWithChar(url) {
centerEl.onload = revealChar;
centerEl.onerror = showSceneOnly;
centerEl.src = url;
if (centerEl.complete && centerEl.naturalWidth > 0) {
revealChar();
}
}
var id = getSelectedCharacterId();
if (!id) {
showSceneOnly();
return;
}
var urls = characterDownUrls(id);
probeImage(urls[0], showWithChar, function () {
probeImage(urls[1], showWithChar, showSceneOnly);
});
}
function applyProfile() {
var name = (localStorage.getItem('playerName') || '').trim() || 'MONE';
var coins = localStorage.getItem('jdCoins') || '0';
var nameEl = document.getElementById('lobby-profile-name');
var agentEl = document.getElementById('lobby-profile-agent-id');
var coinsEl = document.getElementById('lobby-profile-coins');
var av = document.getElementById('lobby-profile-avatar');
if (nameEl) nameEl.textContent = name.toUpperCase();
if (agentEl) agentEl.textContent = ensureAgentId();
if (coinsEl) coinsEl.textContent = coins;
if (av) {
var cid = getSelectedCharacterId();
if (!cid) {
av.onerror = null;
av.src = '/Main-Menu/char-main.png';
} else {
var urls = characterDownUrls(cid);
var avStep = 0;
av.onerror = function () {
avStep += 1;
if (avStep === 1) av.src = urls[1];
else {
av.onerror = null;
av.src = '/Main-Menu/char-main.png';
}
};
av.src = urls[0];
}
}
}
var guideStep = 1;
var guideImg = document.getElementById('guide-img');
var guideBar = document.getElementById('lobby-guide-bar');
var guideDim = document.getElementById('lobby-guide-dim');
function syncGuideBodyClass() {
if (!guideBar) return;
var open = !guideBar.classList.contains('hidden');
if (open) {
document.body.classList.add('lobby-guide-active');
document.body.classList.toggle('lobby-guide-top-step', guideStep >= 4);
} else {
document.body.classList.remove('lobby-guide-active');
document.body.classList.remove('lobby-guide-top-step');
}
if (guideDim) {
guideDim.classList.toggle('hidden', !open);
}
}
function showGuideStep(n) {
if (!guideImg || !guideBar) return;
if (n < 1 || n > MAX_GUIDE) {
guideBar.classList.add('hidden');
guideBar.classList.remove('lobby-guide-bar--top');
try {
localStorage.setItem(GUIDE_KEY, '1');
} catch (e) { /* ignore */ }
syncGuideBodyClass();
return;
}
guideStep = n;
guideImg.src = ML_GUIDE + '/guide-' + (n < 10 ? '0' + n : String(n)) + '.png';
guideImg.alt = 'คำแนะนำ ขั้นที่ ' + n;
guideBar.classList.toggle('lobby-guide-bar--top', n >= 4);
var nextBtn = document.getElementById('btn-guide-next');
if (nextBtn) {
nextBtn.setAttribute('aria-label', n >= MAX_GUIDE ? 'รับทราบ' : 'ถัดไป');
}
syncGuideBodyClass();
}
function initGuide() {
if (!guideBar || !guideImg) return;
try {
if (localStorage.getItem(GUIDE_KEY) === '1') {
guideBar.classList.add('hidden');
syncGuideBodyClass();
return;
}
} catch (e) { /* ignore */ }
guideBar.classList.remove('hidden');
showGuideStep(1);
}
document.getElementById('btn-guide-next')?.addEventListener('click', function () {
if (guideStep >= MAX_GUIDE) {
if (guideBar) {
guideBar.classList.add('hidden');
guideBar.classList.remove('lobby-guide-bar--top');
}
try {
localStorage.setItem(GUIDE_KEY, '1');
} catch (e) { /* ignore */ }
syncGuideBodyClass();
return;
}
showGuideStep(guideStep + 1);
});
document.addEventListener('keydown', function (e) {
if (e.key !== 'Escape') return;
if (!guideBar || guideBar.classList.contains('hidden')) return;
e.preventDefault();
guideBar.classList.add('hidden');
guideBar.classList.remove('lobby-guide-bar--top');
syncGuideBodyClass();
});
/* ใช้ capture + data-href บน .lobby-footer-center — ลดโอกาสถูกเลเยอร์อื่นแย่งคลิกก่อนถึงปุ่ม */
var footerCenter = document.querySelector('.lobby-footer-center');
if (footerCenter) {
footerCenter.addEventListener('click', function (e) {
var btn = e.target.closest('button[data-href]');
if (!btn || !footerCenter.contains(btn)) return;
var href = btn.getAttribute('data-href');
if (!href) return;
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
window.location.href = href;
}, true);
}
document.getElementById('btn-cloth')?.addEventListener('click', function () {
window.location.href = BASE + '/character.html';
});
document.getElementById('btn-daily')?.addEventListener('click', function () {
toast('รางวัลประจำวัน — เข้าเกมทุกวันเพื่อรับรางวัลต่อเนื่อง!');
});
document.getElementById('btn-myprofile')?.addEventListener('click', function () {
window.location.href = '/Main-Menu/';
});
function getMlAiSessionId() {
try {
var k = 'mlAiChatSession';
var v = localStorage.getItem(k);
if (!v) {
v = 'ml-' + Date.now() + '-' + Math.random().toString(36).slice(2, 11);
localStorage.setItem(k, v);
}
return v;
} catch (e) {
return 'ml-' + String(Date.now());
}
}
var aiChatCloseBtn = document.getElementById('lobby-ai-chat-close-btn');
var aiChatPanel = document.getElementById('lobby-ai-chat-panel');
var aiChatToggleImg = document.getElementById('lobby-ai-chat-toggle-img');
var btnAiChat = document.getElementById('btn-ai-chat');
function updateAiChatHeaderUi() {
if (!aiChatPanel || !aiChatToggleImg || !aiChatCloseBtn) return;
var hidden = aiChatPanel.classList.contains('lobby-ai-chat-hidden');
if (!hidden) {
aiChatToggleImg.src = BASE + '/img/chat-close-btn.png';
aiChatToggleImg.alt = 'ปิด';
aiChatCloseBtn.setAttribute('title', 'ปิดแชท AI');
aiChatCloseBtn.setAttribute('aria-label', 'ปิดแชท AI');
}
}
if (aiChatCloseBtn && aiChatPanel) {
aiChatCloseBtn.addEventListener('click', function () {
aiChatPanel.classList.add('lobby-ai-chat-hidden');
aiChatPanel.classList.remove('chat-panel-collapsed');
});
}
if (btnAiChat && aiChatPanel) {
btnAiChat.addEventListener('click', function () {
if (aiChatPanel.classList.contains('lobby-ai-chat-hidden')) {
aiChatPanel.classList.remove('lobby-ai-chat-hidden');
aiChatPanel.classList.remove('chat-panel-collapsed');
updateAiChatHeaderUi();
var inp = document.getElementById('lobby-ai-chat-input');
if (inp) {
try {
inp.focus();
} catch (e) { /* ignore */ }
}
} else {
aiChatPanel.classList.add('lobby-ai-chat-hidden');
}
});
}
var aiChatForm = document.getElementById('lobby-ai-chat-form');
var aiChatInput = document.getElementById('lobby-ai-chat-input');
var aiChatSendBtn = aiChatForm ? aiChatForm.querySelector('button[type="submit"]') : null;
var aiChatLoadingEl = null;
function appendAiMessage(text, isAi) {
var el = document.getElementById('lobby-ai-chat-messages');
if (!el) return;
if (isAi) removeAiChatLoading();
var div = document.createElement('div');
div.className = 'lobby-ai-chat-msg ' + (isAi ? 'lobby-ai-chat-msg-ai' : 'lobby-ai-chat-msg-user');
div.textContent = (isAi ? 'AI: ' : '') + text;
el.appendChild(div);
el.scrollTop = 1e9;
}
function showAiChatLoading() {
var el = document.getElementById('lobby-ai-chat-messages');
if (!el || aiChatLoadingEl) return;
aiChatLoadingEl = document.createElement('div');
aiChatLoadingEl.className = 'lobby-ai-chat-msg lobby-ai-chat-msg-ai lobby-ai-chat-typing';
aiChatLoadingEl.setAttribute('aria-label', 'กำลังพิมพ์');
aiChatLoadingEl.innerHTML = '<span class="lobby-ai-typing-dot"></span><span class="lobby-ai-typing-dot"></span><span class="lobby-ai-typing-dot"></span>';
el.appendChild(aiChatLoadingEl);
el.scrollTop = 1e9;
}
function removeAiChatLoading() {
if (aiChatLoadingEl && aiChatLoadingEl.parentNode) {
aiChatLoadingEl.parentNode.removeChild(aiChatLoadingEl);
aiChatLoadingEl = null;
}
}
function setAiChatWaiting(waiting) {
if (aiChatInput) aiChatInput.disabled = waiting;
if (aiChatSendBtn) aiChatSendBtn.disabled = waiting;
if (waiting) showAiChatLoading();
else removeAiChatLoading();
}
if (aiChatForm && aiChatInput) {
aiChatForm.addEventListener('submit', function (e) {
e.preventDefault();
var text = (aiChatInput.value || '').trim();
if (!text) return;
appendAiMessage(text, false);
setAiChatWaiting(true);
aiChatInput.value = '';
fetch(BASE + '/api/ai-chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: text, sessionId: getMlAiSessionId() }),
})
.then(function (r) { return r.json(); })
.then(function (data) {
if (data.response != null) appendAiMessage(data.response, true);
else if (data.error) appendAiMessage('[ข้อผิดพลาด: ' + data.error + ']', true);
})
.catch(function () {
appendAiMessage('[ส่งไม่สำเร็จ]', true);
})
.finally(function () {
setAiChatWaiting(false);
});
});
}
var howto = document.getElementById('lobby-howto-overlay');
function openHowto() {
if (howto) howto.classList.remove('hidden');
}
function closeHowto() {
if (howto) howto.classList.add('hidden');
}
/** ปุ่ม ? — คู่มือทีละขั้น ตาม /Main-Lobby/IMAGE/guide */
function openGuideTutorial() {
if (!guideBar || !guideImg) return;
closeHowto();
guideBar.classList.remove('hidden');
showGuideStep(1);
}
document.getElementById('btn-tutorial')?.addEventListener('click', openGuideTutorial);
document.getElementById('btn-howto-got-it')?.addEventListener('click', closeHowto);
howto?.addEventListener('click', function (e) {
if (e.target === howto) closeHowto();
});
syncMainLobbyCharacterUi();
initGuide();
window.addEventListener('pageshow', function () {
syncMainLobbyCharacterUi();
});
document.addEventListener('visibilitychange', function () {
if (document.visibilityState === 'visible') syncMainLobbyCharacterUi();
});
window.addEventListener('storage', function (e) {
if (e.key == null || e.key === CHAR_KEY || e.key === 'playerName') {
syncMainLobbyCharacterUi();
}
});
})();