1095 lines
39 KiB
JavaScript
1095 lines
39 KiB
JavaScript
(function () {
|
||
'use strict';
|
||
|
||
var BASE = typeof appPath === 'function' ? appPath('/Game') : '/Game';
|
||
var SERVER = (typeof GAME_SERVER !== 'undefined' ? GAME_SERVER : '') + '/Game';
|
||
var CHAR_KEY = 'gameCharacterId';
|
||
/** รูป composite idle ทิศ down จากหน้า Character (preview-idle-layer-down) — ตรงกับ character.js */
|
||
var LOBBY_IDLE_DOWN_PREFIX = 'jdCharLobbyIdleDown:';
|
||
|
||
function getStoredLobbyIdleDownDataUrl(safeId) {
|
||
if (!safeId) return '';
|
||
try {
|
||
var v = localStorage.getItem(LOBBY_IDLE_DOWN_PREFIX + safeId) || '';
|
||
if (typeof v === 'string' && v.indexOf('data:image/') === 0 && v.length > 80) return v;
|
||
} catch (e) { /* ignore */ }
|
||
return '';
|
||
}
|
||
|
||
var GUIDE_KEY = 'mainLobbyGuideDone';
|
||
var MAX_GUIDE = 5;
|
||
var ML_GUIDE = typeof appPath === 'function' ? appPath('/Main-Lobby/IMAGE/guide') : '/Main-Lobby/IMAGE/guide';
|
||
|
||
/**
|
||
* ตำแหน่งแถบคำแนะนำ + จุดไฮไลต์ต่อ guide-01…05 (ปรับลำดับให้ตรงไฟล์รูป)
|
||
* position: 'bottom' | 'top' — ตาม mock แถบล่าง/บน
|
||
* highlight: selector ของปุ่มใน lobby (null = ไม่วงกรอบ)
|
||
*/
|
||
var GUIDE_STEPS = [
|
||
{ position: 'bottom', highlight: null, pad: 10 },
|
||
{ position: 'top', highlight: '.lobby-footer-center', pad: 10 },
|
||
{ position: 'top', highlight: '#btn-ai-chat', pad: 8 },
|
||
{ position: 'bottom', highlight: '#btn-cloth', pad: 10 },
|
||
{ position: 'bottom', highlight: '#btn-daily', pad: 10 },
|
||
];
|
||
|
||
function checkLogin() {
|
||
if (localStorage.getItem('isLoggedIn') !== 'true') {
|
||
window.location.href = typeof appPath === 'function' ? appPath('/Login/') : '/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 '';
|
||
}
|
||
}
|
||
|
||
/** ใช้เฉพาะ id ที่ปลอดเป็น segment ใน URL — กันพาธแปลก/อักขระที่เซิร์ฟไม่มีไฟล์ */
|
||
function normalizeCharacterAssetId(id) {
|
||
var s = String(id == null ? '' : id).trim();
|
||
if (!s) return '';
|
||
if (s === 'Chatest') return ''; // legacy placeholder — ไม่มี sprite จริง ถือเป็นว่าง (fallback ไปตัวจริงจาก API) กัน 404 รัว
|
||
if (s.length > 96) s = s.slice(0, 96);
|
||
if (!/^[a-zA-Z0-9._-]+$/.test(s)) return '';
|
||
return s;
|
||
}
|
||
|
||
function mainMenuCharFallbackUrl() {
|
||
return typeof appPath === 'function' ? appPath('/Main-Menu/char-main.png') : '/Main-Menu/char-main.png';
|
||
}
|
||
|
||
/**
|
||
* URL รูปโลบี้ — ลองทิศ down ก่อน (idle แล้ว walk) เพื่อไม่ยิง _up_idle_ ฯลฯ โดยไม่จำเป็น
|
||
* ถ้า down ไม่มีค่อยลอง up / left / right
|
||
* @param {string} safeId
|
||
* @param {boolean} preferIdle
|
||
*/
|
||
function characterSpriteCandidateUrls(safeId, preferIdle) {
|
||
if (!safeId) return [];
|
||
var enc = encodeURIComponent(safeId);
|
||
var q = '?ch=' + encodeURIComponent(safeId);
|
||
var dirsPrimary = ['down'];
|
||
var dirsFallback = ['up', 'left', 'right'];
|
||
var wantIdle = preferIdle !== false;
|
||
var urls = [];
|
||
|
||
function pushForDir(d) {
|
||
if (wantIdle) {
|
||
urls.push(SERVER + '/img/characters/' + enc + '_' + d + '_idle.png' + q);
|
||
urls.push(SERVER + '/img/characters/' + enc + '_' + d + '_idle_0.png' + q);
|
||
}
|
||
urls.push(SERVER + '/img/characters/' + enc + '_' + d + '.png' + q);
|
||
urls.push(SERVER + '/img/characters/' + enc + '_' + d + '_0.png' + q);
|
||
}
|
||
|
||
for (var a = 0; a < dirsPrimary.length; a++) pushForDir(dirsPrimary[a]);
|
||
for (var b = 0; b < dirsFallback.length; b++) pushForDir(dirsFallback[b]);
|
||
return urls;
|
||
}
|
||
|
||
/** หลังลองครบแล้วไม่มีรูป — ลดการยิงซ้ำในเซสชัน (ไม่บล็อกการลองใหม่หลังอัปโหลดไฟล์แล้ว — ลบคีย์ตอนโหลดสำเร็จ) */
|
||
var CHAR_ASSET_MISS_PREFIX = 'jdCharAssetMissing:';
|
||
|
||
function markCharacterDownAssetMissing(safeId) {
|
||
if (!safeId) return;
|
||
try {
|
||
sessionStorage.setItem(CHAR_ASSET_MISS_PREFIX + safeId, '1');
|
||
} catch (e) { /* ignore */ }
|
||
}
|
||
|
||
function clearCharacterDownAssetMissing(safeId) {
|
||
if (!safeId) return;
|
||
try {
|
||
sessionStorage.removeItem(CHAR_ASSET_MISS_PREFIX + safeId);
|
||
} catch (e) { /* ignore */ }
|
||
}
|
||
|
||
/**
|
||
* ลอง URL ตามลำดับด้วย Image — ตรงกับพฤติกรรม <img> ใน character-grid
|
||
* @param {string[]} urls
|
||
* @param {(url: string | null) => void} cb
|
||
*/
|
||
function probeFirstLoadableImageUrl(urls, cb) {
|
||
var i = 0;
|
||
function next() {
|
||
if (i >= urls.length) {
|
||
cb(null);
|
||
return;
|
||
}
|
||
var u = urls[i++];
|
||
var img = new Image();
|
||
img.onload = function () {
|
||
if (img.naturalWidth > 0) cb(u);
|
||
else next();
|
||
};
|
||
img.onerror = function () {
|
||
next();
|
||
};
|
||
img.src = u;
|
||
}
|
||
next();
|
||
}
|
||
|
||
/**
|
||
* @param {string} safeId
|
||
* @param {(url: string | null) => void} cb
|
||
*/
|
||
function characterLobbySpriteFirstLiveUrl(safeId, cb) {
|
||
if (!safeId) {
|
||
cb(null);
|
||
return;
|
||
}
|
||
var urls = characterSpriteCandidateUrls(safeId, true);
|
||
if (!urls.length) {
|
||
cb(null);
|
||
return;
|
||
}
|
||
probeFirstLoadableImageUrl(urls, function (url) {
|
||
if (url) {
|
||
clearCharacterDownAssetMissing(safeId);
|
||
cb(url);
|
||
} else {
|
||
markCharacterDownAssetMissing(safeId);
|
||
cb(null);
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* id จาก localStorage หรือถ้าว่าง — ตัวสุดท้ายในรายการ API (ใหม่สุดตามลำดับเซิร์ฟ)
|
||
* @param {(safeId: string) => void} callback
|
||
*/
|
||
function resolveLobbyCharacterId(callback) {
|
||
var norm = normalizeCharacterAssetId(getSelectedCharacterId());
|
||
if (norm) {
|
||
callback(norm);
|
||
return;
|
||
}
|
||
fetch(BASE + '/api/characters', { credentials: 'same-origin', cache: 'no-store' })
|
||
.then(function (r) { return r.json(); })
|
||
.then(function (list) {
|
||
if (!Array.isArray(list) || !list.length) {
|
||
callback('');
|
||
return;
|
||
}
|
||
var last = list[list.length - 1];
|
||
var id = last && last.id ? normalizeCharacterAssetId(String(last.id)) : '';
|
||
callback(id || '');
|
||
})
|
||
.catch(function () {
|
||
callback('');
|
||
});
|
||
}
|
||
|
||
var PLAYER_KEY = 'jdPlayerKey';
|
||
var DISPLAY_NAME_STORAGE_KEY = 'roomLobbyDisplayName';
|
||
|
||
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((typeof appPath === 'function' ? appPath('/Admin/api/player-coins.php') : '/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 */ });
|
||
}
|
||
|
||
function lbEscapeHtml(s) {
|
||
return String(s == null ? '' : s).replace(/[&<>"']/g, function (c) {
|
||
return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c];
|
||
});
|
||
}
|
||
|
||
/** วาดกระดานผู้นำจากข้อมูลจริง (top = [{rank,name,score,coins}]) */
|
||
function renderLeaderboardRows(top) {
|
||
var listEl = document.querySelector('.lobby-leaderboard-list');
|
||
if (!listEl || !Array.isArray(top) || !top.length) return; /* ว่าง → คงตัวอย่างเดิมไว้ */
|
||
var html = '';
|
||
for (var i = 0; i < top.length; i++) {
|
||
var r = top[i] || {};
|
||
var rank = parseInt(r.rank, 10) || (i + 1);
|
||
var name = lbEscapeHtml(r.name || 'ผู้เล่น');
|
||
var score = Math.max(0, parseInt(r.score, 10) || 0);
|
||
var caseName = lbEscapeHtml((r.caseName || '').toString());
|
||
var caseLabel = caseName ? ('(คดี : ' + caseName + ')') : '';
|
||
var head = rank <= 3
|
||
? '<img src="IMAGE/leaderboard-' + rank + '.png" alt="" class="lobby-rank-icon" role="presentation" decoding="async">'
|
||
: '<span class="lobby-rank-num">' + rank + '</span>';
|
||
html += '<li>' + head +
|
||
'<div class="lobby-rank-info">' +
|
||
'<span class="lobby-rank-name">' + name + '</span>' +
|
||
'<span class="lobby-rank-case">' + caseLabel + '</span>' +
|
||
'</div>' +
|
||
'<span class="lobby-rank-score">' + score + '</span>' +
|
||
'</li>';
|
||
}
|
||
listEl.innerHTML = html;
|
||
scheduleLeaderboardPlacement();
|
||
}
|
||
|
||
/** ดึงกระดานผู้นำจากเซิร์ฟเวอร์ (อันดับตามคะแนนสะสม high score) */
|
||
function fetchAndRenderLeaderboard() {
|
||
var base = (typeof appPath === 'function' ? appPath('/Admin/api/leaderboard.php') : '/Admin/api/leaderboard.php');
|
||
var url = base + '?limit=50&playerKey=' + encodeURIComponent(ensurePlayerKey());
|
||
fetch(url, { credentials: 'omit' })
|
||
.then(function (r) { return r.json(); })
|
||
.then(function (d) {
|
||
if (!d || !d.ok || !Array.isArray(d.top)) return;
|
||
renderLeaderboardRows(d.top);
|
||
})
|
||
.catch(function () { /* ออฟไลน์ → คงตัวอย่างเดิม */ });
|
||
}
|
||
|
||
/** สีที่เลือกไว้ใน localStorage (เครื่องนี้) — index theme 1–8 / skin 1–3 */
|
||
function getLocalLobbyStyle() {
|
||
var theme = 0, skin = 0;
|
||
try {
|
||
theme = parseInt(localStorage.getItem('lobbyThemeColor') || '', 10) || 0;
|
||
skin = parseInt(localStorage.getItem('lobbySkinTone') || '', 10) || 0;
|
||
} catch (e) { /* ignore */ }
|
||
return { theme: theme, skin: skin };
|
||
}
|
||
|
||
function mirrorLobbyStyleToLocal(theme, skin) {
|
||
try {
|
||
if (theme >= 1 && theme <= 8) localStorage.setItem('lobbyThemeColor', String(theme));
|
||
if (skin >= 1 && skin <= 3) localStorage.setItem('lobbySkinTone', String(skin));
|
||
} catch (e) { /* ignore */ }
|
||
}
|
||
|
||
/** ดึงสีที่เลือกจากเซิร์ฟเวอร์ (cross-device) ตาม jdPlayerKey */
|
||
function fetchServerLobbyStyle(cb) {
|
||
var key;
|
||
try { key = ensurePlayerKey(); } catch (e) { key = ''; }
|
||
if (!key) { cb(null); return; }
|
||
var base = (typeof appPath === 'function' ? appPath('/Admin/api/player-lobby-style.php') : '/Admin/api/player-lobby-style.php');
|
||
fetch(base + '?playerKey=' + encodeURIComponent(key), { credentials: 'omit', cache: 'no-store' })
|
||
.then(function (r) { return r.ok ? r.json() : null; })
|
||
.then(function (d) {
|
||
if (!d || !d.ok) { cb(null); return; }
|
||
cb({ theme: parseInt(d.colorThemeIndex, 10) || 0, skin: parseInt(d.skinToneIndex, 10) || 0 });
|
||
})
|
||
.catch(function () { cb(null); });
|
||
}
|
||
|
||
/** รีเฟรชหลังเลือกตัวละคร / สลับแท็บ / ย้อนกลับบน tablet (bfcache) */
|
||
function syncMainLobbyCharacterUi() {
|
||
applyProfileTexts();
|
||
syncCoinsFromServer();
|
||
fetchAndRenderLeaderboard();
|
||
function applyCharAssets(urlOrNull) {
|
||
applyProfileAvatar(urlOrNull);
|
||
applyCenterCharacterResolved(urlOrNull);
|
||
}
|
||
resolveLobbyCharacterId(function (id) {
|
||
if (!id) {
|
||
applyCharAssets(null);
|
||
return;
|
||
}
|
||
var idleCached = getStoredLobbyIdleDownDataUrl(id);
|
||
// วาด cache ทันทีกันจอว่าง แล้วค่อย recompute จากสีจริง (cross-device) ทับ
|
||
if (idleCached) applyCharAssets(idleCached);
|
||
|
||
function fallbackToSprite() {
|
||
if (idleCached) return; // วาดไปแล้ว
|
||
characterLobbySpriteFirstLiveUrl(id, applyCharAssets);
|
||
}
|
||
|
||
// สีจาก server เป็นแหล่งความจริงข้ามเครื่อง, ถ้าไม่มีค่อยใช้ local
|
||
fetchServerLobbyStyle(function (server) {
|
||
var local = getLocalLobbyStyle();
|
||
var theme = (server && server.theme) || local.theme || 0;
|
||
var skin = (server && server.skin) || local.skin || 0;
|
||
if (theme >= 1 && theme <= 8) mirrorLobbyStyleToLocal(theme, skin);
|
||
|
||
// ยังไม่เคยเลือกสี → ใช้รูปตามเดิม (ไม่ recolor)
|
||
if (!(theme >= 1 && theme <= 8) || typeof window.jdComposeTintedCharacter !== 'function') {
|
||
fallbackToSprite();
|
||
return;
|
||
}
|
||
|
||
window.jdComposeTintedCharacter(id, theme, skin).then(function (dataUrl) {
|
||
if (dataUrl && typeof dataUrl === 'string' && dataUrl.indexOf('data:image/') === 0) {
|
||
try { localStorage.setItem(LOBBY_IDLE_DOWN_PREFIX + id, dataUrl); } catch (e) { /* ignore */ }
|
||
applyCharAssets(dataUrl);
|
||
} else {
|
||
fallbackToSprite();
|
||
}
|
||
}).catch(function () { fallbackToSprite(); });
|
||
});
|
||
});
|
||
}
|
||
|
||
function getProfileDisplayName() {
|
||
if (typeof window.jdReadDisplayName === 'function') {
|
||
return window.jdReadDisplayName();
|
||
}
|
||
var fromRoomLobby = '';
|
||
var fromPlayerName = '';
|
||
try {
|
||
fromRoomLobby = (localStorage.getItem(DISPLAY_NAME_STORAGE_KEY) || '').trim();
|
||
fromPlayerName = (localStorage.getItem('playerName') || '').trim();
|
||
} catch (e) { /* ignore */ }
|
||
return fromRoomLobby || fromPlayerName || 'MONE';
|
||
}
|
||
|
||
function applyProfileTexts() {
|
||
var name = getProfileDisplayName();
|
||
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');
|
||
if (nameEl) nameEl.textContent = name.toUpperCase();
|
||
if (agentEl) agentEl.textContent = ensureAgentId();
|
||
if (coinsEl) coinsEl.textContent = coins;
|
||
}
|
||
|
||
/** @param {string | null} urlOrNull — URL ที่ HEAD ผ่านแล้ว หรือ null = ใช้ char-main */
|
||
function applyProfileAvatar(urlOrNull) {
|
||
var av = document.getElementById('lobby-profile-avatar');
|
||
if (!av) return;
|
||
var fb = mainMenuCharFallbackUrl();
|
||
av.onerror = null;
|
||
if (!urlOrNull) {
|
||
av.src = fb;
|
||
return;
|
||
}
|
||
av.onerror = function () {
|
||
av.onerror = null;
|
||
av.src = fb;
|
||
};
|
||
av.src = urlOrNull;
|
||
}
|
||
|
||
function applyCenterCharacterResolved(urlOrNull) {
|
||
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 showFallbackCenterCharacter() {
|
||
var fb = mainMenuCharFallbackUrl();
|
||
centerEl.onload = revealChar;
|
||
centerEl.onerror = function () {
|
||
centerEl.onerror = null;
|
||
showSceneOnly();
|
||
};
|
||
centerEl.src = fb;
|
||
if (centerEl.complete && centerEl.naturalWidth > 0) {
|
||
revealChar();
|
||
}
|
||
}
|
||
|
||
function showWithChar(url) {
|
||
centerEl.onload = revealChar;
|
||
centerEl.onerror = function () {
|
||
showFallbackCenterCharacter();
|
||
};
|
||
centerEl.src = url;
|
||
if (centerEl.complete && centerEl.naturalWidth > 0) {
|
||
revealChar();
|
||
}
|
||
}
|
||
|
||
if (!urlOrNull) {
|
||
showFallbackCenterCharacter();
|
||
return;
|
||
}
|
||
showWithChar(urlOrNull);
|
||
}
|
||
|
||
// คำนวณ offset จากความสูงจอด้วย linear interpolation:
|
||
// 1080 -> 18cqh, 650 -> 25cqh
|
||
function applyCharacterFootOffsetByViewport() {
|
||
var root = document.documentElement;
|
||
if (!root) return;
|
||
var h = Math.max(1, window.innerHeight || 0);
|
||
var h1 = 650;
|
||
var y1 = 25;
|
||
var h2 = 1080;
|
||
var y2 = 18;
|
||
var t = (h - h1) / (h2 - h1);
|
||
var cqhValue = y1 + ((y2 - y1) * t);
|
||
// กันหลุดช่วงเมื่อจอเล็ก/ใหญ่เกินช่วงอ้างอิง
|
||
cqhValue = Math.max(18, Math.min(25, cqhValue));
|
||
root.style.setProperty('--lobby-character-foot-offset', cqhValue.toFixed(3) + 'cqh');
|
||
}
|
||
|
||
function syncLeaderboardScrollbarThumb() {
|
||
var scrollEl = document.querySelector('.lobby-leaderboard-scroll');
|
||
var thumbEl = document.getElementById('lobby-leaderboard-scroll-thumb');
|
||
var trackEl = document.getElementById('lobby-leaderboard-scroll-track');
|
||
if (!scrollEl || !thumbEl) return;
|
||
|
||
var styles = window.getComputedStyle(thumbEl);
|
||
var topInset = parseFloat(styles.top) || 0;
|
||
var minThumb = parseFloat(styles.minHeight) || 18;
|
||
var maxScroll = Math.max(0, scrollEl.scrollHeight - scrollEl.clientHeight);
|
||
if (maxScroll <= 0) {
|
||
thumbEl.style.display = 'none';
|
||
if (trackEl) trackEl.style.display = 'none';
|
||
return;
|
||
}
|
||
if (trackEl) trackEl.style.display = 'block';
|
||
thumbEl.style.display = 'block';
|
||
|
||
var trackHeight = (trackEl && trackEl.clientHeight) ? trackEl.clientHeight : scrollEl.clientHeight;
|
||
var visibleRatio = scrollEl.clientHeight / Math.max(1, scrollEl.scrollHeight);
|
||
var thumbHeight = Math.max(minThumb, Math.round(trackHeight * visibleRatio));
|
||
var maxY = Math.max(0, trackHeight - topInset - thumbHeight);
|
||
var y = topInset + (maxY * (scrollEl.scrollTop / maxScroll));
|
||
|
||
thumbEl.style.height = thumbHeight + 'px';
|
||
thumbEl.style.transform = 'translateY(' + y.toFixed(2) + 'px)';
|
||
}
|
||
|
||
// วาง leaderboard ให้ต่อจากปุ่ม daily โดยไม่ทับกัน
|
||
function placeLeaderboardBelowDaily() {
|
||
var dailyBtn = document.getElementById('btn-daily');
|
||
var leaderboard = document.querySelector('.lobby-leaderboard');
|
||
var lobbyUi = document.querySelector('.lobby-ui');
|
||
if (!dailyBtn || !leaderboard || !lobbyUi) return;
|
||
|
||
var boardStyle = window.getComputedStyle(leaderboard);
|
||
if (boardStyle.position !== 'absolute') {
|
||
leaderboard.style.top = '';
|
||
return;
|
||
}
|
||
|
||
var uiRect = lobbyUi.getBoundingClientRect();
|
||
var dailyRect = dailyBtn.getBoundingClientRect();
|
||
var boardRect = leaderboard.getBoundingClientRect();
|
||
|
||
var cssGap = boardStyle.getPropertyValue('--lobby-daily-leaderboard-gap').trim();
|
||
var gapPx = 8;
|
||
if (cssGap) {
|
||
var n = parseFloat(cssGap);
|
||
if (!Number.isNaN(n)) {
|
||
if (cssGap.endsWith('cqh')) gapPx = (uiRect.height * n) / 100;
|
||
else if (cssGap.endsWith('px') || /^[+-]?\d+(\.\d+)?$/.test(cssGap)) gapPx = n;
|
||
else if (cssGap.endsWith('vh')) gapPx = ((window.innerHeight || 0) * n) / 100;
|
||
else if (cssGap.endsWith('%')) gapPx = (uiRect.height * n) / 100;
|
||
}
|
||
}
|
||
|
||
var nextTop = (dailyRect.bottom - uiRect.top) + gapPx;
|
||
var maxTop = Math.max(0, uiRect.height - boardRect.height - Math.max(0, gapPx));
|
||
var clampedTop = Math.max(0, Math.min(nextTop, maxTop));
|
||
|
||
leaderboard.style.top = clampedTop.toFixed(2) + 'px';
|
||
}
|
||
|
||
var leaderboardLayoutRaf = 0;
|
||
function scheduleLeaderboardPlacement() {
|
||
if (leaderboardLayoutRaf) cancelAnimationFrame(leaderboardLayoutRaf);
|
||
leaderboardLayoutRaf = requestAnimationFrame(function () {
|
||
leaderboardLayoutRaf = 0;
|
||
placeLeaderboardBelowDaily();
|
||
syncLeaderboardScrollbarThumb();
|
||
});
|
||
}
|
||
|
||
function bindLeaderboardScrollSync() {
|
||
var scrollEl = document.querySelector('.lobby-leaderboard-scroll');
|
||
if (!scrollEl || scrollEl.dataset.scrollSyncBound === '1') return;
|
||
scrollEl.addEventListener('scroll', syncLeaderboardScrollbarThumb, { passive: true });
|
||
scrollEl.dataset.scrollSyncBound = '1';
|
||
}
|
||
|
||
function bindLeaderboardWheelSupport() {
|
||
var scrollEl = document.querySelector('.lobby-leaderboard-scroll');
|
||
if (!scrollEl || scrollEl.dataset.wheelSupportBound === '1') return;
|
||
|
||
scrollEl.addEventListener('wheel', function (e) {
|
||
var maxScroll = Math.max(0, scrollEl.scrollHeight - scrollEl.clientHeight);
|
||
if (maxScroll <= 0) return;
|
||
scrollEl.scrollTop += e.deltaY;
|
||
syncLeaderboardScrollbarThumb();
|
||
e.preventDefault();
|
||
}, { passive: false });
|
||
|
||
scrollEl.dataset.wheelSupportBound = '1';
|
||
}
|
||
|
||
function bindLeaderboardThumbDrag() {
|
||
var scrollEl = document.querySelector('.lobby-leaderboard-scroll');
|
||
var thumbEl = document.getElementById('lobby-leaderboard-scroll-thumb');
|
||
var trackEl = document.getElementById('lobby-leaderboard-scroll-track');
|
||
if (!scrollEl || !thumbEl || !trackEl || thumbEl.dataset.dragBound === '1') return;
|
||
|
||
var dragging = false;
|
||
var dragOffsetY = 0;
|
||
|
||
function getThumbMetrics() {
|
||
var styles = window.getComputedStyle(thumbEl);
|
||
var topInset = parseFloat(styles.top) || 0;
|
||
var thumbHeight = thumbEl.clientHeight || parseFloat(thumbEl.style.height) || 18;
|
||
var trackHeight = trackEl.clientHeight || scrollEl.clientHeight || 1;
|
||
var maxTranslate = Math.max(topInset, trackHeight - thumbHeight);
|
||
var travel = Math.max(1, maxTranslate - topInset);
|
||
return { topInset: topInset, thumbHeight: thumbHeight, trackHeight: trackHeight, maxTranslate: maxTranslate, travel: travel };
|
||
}
|
||
|
||
function stopDrag() {
|
||
if (!dragging) return;
|
||
dragging = false;
|
||
thumbEl.classList.remove('is-dragging');
|
||
document.body.classList.remove('lobby-leaderboard-dragging');
|
||
}
|
||
|
||
thumbEl.addEventListener('mousedown', function (e) {
|
||
if (e.button !== 0) return;
|
||
var maxScroll = Math.max(0, scrollEl.scrollHeight - scrollEl.clientHeight);
|
||
if (maxScroll <= 0) return;
|
||
var metrics = getThumbMetrics();
|
||
var thumbRect = thumbEl.getBoundingClientRect();
|
||
dragOffsetY = Math.max(0, Math.min(metrics.thumbHeight, e.clientY - thumbRect.top));
|
||
dragging = true;
|
||
thumbEl.classList.add('is-dragging');
|
||
document.body.classList.add('lobby-leaderboard-dragging');
|
||
e.preventDefault();
|
||
e.stopPropagation();
|
||
});
|
||
|
||
window.addEventListener('mousemove', function (e) {
|
||
if (!dragging) return;
|
||
var maxScroll = Math.max(0, scrollEl.scrollHeight - scrollEl.clientHeight);
|
||
if (maxScroll <= 0) {
|
||
stopDrag();
|
||
return;
|
||
}
|
||
var metrics = getThumbMetrics();
|
||
var trackRect = trackEl.getBoundingClientRect();
|
||
var pointerY = e.clientY - trackRect.top;
|
||
var nextTranslate = pointerY - dragOffsetY;
|
||
nextTranslate = Math.max(metrics.topInset, Math.min(metrics.maxTranslate, nextTranslate));
|
||
var ratio = (nextTranslate - metrics.topInset) / metrics.travel;
|
||
scrollEl.scrollTop = ratio * maxScroll;
|
||
syncLeaderboardScrollbarThumb();
|
||
e.preventDefault();
|
||
});
|
||
|
||
window.addEventListener('mouseup', stopDrag);
|
||
window.addEventListener('blur', stopDrag);
|
||
|
||
thumbEl.dataset.dragBound = '1';
|
||
}
|
||
|
||
function bindLeaderboardDragScroll() {
|
||
var scrollEl = document.querySelector('.lobby-leaderboard-scroll');
|
||
if (!scrollEl || scrollEl.dataset.dragScrollBound === '1') return;
|
||
|
||
var dragging = false;
|
||
var moved = false;
|
||
var startY = 0;
|
||
var startScrollTop = 0;
|
||
|
||
function stopDrag() {
|
||
if (!dragging) return;
|
||
dragging = false;
|
||
window.setTimeout(function () { moved = false; }, 0);
|
||
document.body.classList.remove('lobby-leaderboard-dragging');
|
||
scrollEl.classList.remove('is-dragging');
|
||
}
|
||
|
||
scrollEl.addEventListener('mousedown', function (e) {
|
||
if (e.button !== 0) return;
|
||
var maxScroll = Math.max(0, scrollEl.scrollHeight - scrollEl.clientHeight);
|
||
if (maxScroll <= 0) return;
|
||
dragging = true;
|
||
moved = false;
|
||
startY = e.clientY;
|
||
startScrollTop = scrollEl.scrollTop;
|
||
document.body.classList.add('lobby-leaderboard-dragging');
|
||
scrollEl.classList.add('is-dragging');
|
||
e.preventDefault();
|
||
});
|
||
|
||
window.addEventListener('mousemove', function (e) {
|
||
if (!dragging) return;
|
||
var deltaY = e.clientY - startY;
|
||
if (Math.abs(deltaY) > 2) moved = true;
|
||
scrollEl.scrollTop = startScrollTop - deltaY;
|
||
syncLeaderboardScrollbarThumb();
|
||
e.preventDefault();
|
||
});
|
||
|
||
window.addEventListener('mouseup', stopDrag);
|
||
window.addEventListener('blur', stopDrag);
|
||
scrollEl.addEventListener('mouseleave', function (e) {
|
||
if (!dragging) return;
|
||
if (e.buttons === 0) stopDrag();
|
||
});
|
||
|
||
scrollEl.addEventListener('click', function (e) {
|
||
if (!moved) return;
|
||
e.preventDefault();
|
||
e.stopPropagation();
|
||
}, true);
|
||
|
||
scrollEl.dataset.dragScrollBound = '1';
|
||
}
|
||
|
||
var guideStep = 1;
|
||
var guideImg = document.getElementById('guide-img');
|
||
var guideBar = document.getElementById('lobby-guide-bar');
|
||
var guideDim = document.getElementById('lobby-guide-dim');
|
||
var guideFocus = document.getElementById('lobby-guide-focus');
|
||
|
||
function getGuideStepConfig(step) {
|
||
return GUIDE_STEPS[step - 1] || { position: 'bottom', highlight: null, pad: 10 };
|
||
}
|
||
|
||
function hideGuideFocus() {
|
||
if (!guideFocus) return;
|
||
guideFocus.classList.add('hidden');
|
||
guideFocus.style.left = '0';
|
||
guideFocus.style.top = '0';
|
||
guideFocus.style.width = '0';
|
||
guideFocus.style.height = '0';
|
||
}
|
||
|
||
function scheduleGuideFocusUpdate() {
|
||
requestAnimationFrame(function () {
|
||
requestAnimationFrame(updateGuideFocus);
|
||
});
|
||
}
|
||
|
||
function updateGuideFocus() {
|
||
if (!guideFocus || !guideBar || guideBar.classList.contains('hidden')) {
|
||
hideGuideFocus();
|
||
return;
|
||
}
|
||
var cfg = getGuideStepConfig(guideStep);
|
||
if (!cfg.highlight) {
|
||
hideGuideFocus();
|
||
return;
|
||
}
|
||
var target = document.querySelector(cfg.highlight);
|
||
if (!target) {
|
||
hideGuideFocus();
|
||
return;
|
||
}
|
||
var pad = typeof cfg.pad === 'number' ? cfg.pad : 8;
|
||
var r = target.getBoundingClientRect();
|
||
if (r.width < 4 || r.height < 4) {
|
||
hideGuideFocus();
|
||
return;
|
||
}
|
||
var cs = window.getComputedStyle(target);
|
||
var br = parseInt(cs.borderRadius, 10) || 0;
|
||
var radius = Math.max(br + 4, 14);
|
||
|
||
guideFocus.classList.remove('hidden');
|
||
guideFocus.style.left = (r.left - pad) + 'px';
|
||
guideFocus.style.top = (r.top - pad) + 'px';
|
||
guideFocus.style.width = (r.width + pad * 2) + 'px';
|
||
guideFocus.style.height = (r.height + pad * 2) + 'px';
|
||
guideFocus.style.borderRadius = radius + 'px';
|
||
}
|
||
|
||
function syncGuideBodyClass() {
|
||
if (!guideBar) return;
|
||
var open = !guideBar.classList.contains('hidden');
|
||
if (open) {
|
||
document.body.classList.add('lobby-guide-active');
|
||
var cfg = getGuideStepConfig(guideStep);
|
||
document.body.classList.toggle('lobby-guide-top-step', cfg.position === 'top');
|
||
var hasFocus = !!cfg.highlight;
|
||
if (guideDim) guideDim.classList.toggle('hidden', hasFocus);
|
||
} else {
|
||
document.body.classList.remove('lobby-guide-active');
|
||
document.body.classList.remove('lobby-guide-top-step');
|
||
if (guideDim) guideDim.classList.add('hidden');
|
||
}
|
||
if (open) {
|
||
scheduleGuideFocusUpdate();
|
||
} else {
|
||
hideGuideFocus();
|
||
}
|
||
}
|
||
|
||
function showGuideStep(n) {
|
||
if (!guideImg || !guideBar) return;
|
||
if (n < 1 || n > MAX_GUIDE) {
|
||
guideBar.classList.add('hidden');
|
||
guideBar.classList.remove('lobby-guide-bar--top');
|
||
hideGuideFocus();
|
||
try {
|
||
localStorage.setItem(GUIDE_KEY, '1');
|
||
} catch (e) { /* ignore */ }
|
||
syncGuideBodyClass();
|
||
return;
|
||
}
|
||
guideStep = n;
|
||
var cfg = getGuideStepConfig(guideStep);
|
||
guideImg.src = ML_GUIDE + '/guide-' + (n < 10 ? '0' + n : String(n)) + '.png';
|
||
guideImg.alt = 'คำแนะนำ ขั้นที่ ' + n;
|
||
guideBar.classList.toggle('lobby-guide-bar--top', cfg.position === 'top');
|
||
var nextBtn = document.getElementById('btn-guide-next');
|
||
if (nextBtn) {
|
||
nextBtn.setAttribute('aria-label', n >= MAX_GUIDE ? 'รับทราบ' : 'ถัดไป');
|
||
}
|
||
syncGuideBodyClass();
|
||
guideImg.onload = function () {
|
||
scheduleGuideFocusUpdate();
|
||
};
|
||
guideImg.onerror = function () {
|
||
scheduleGuideFocusUpdate();
|
||
};
|
||
scheduleGuideFocusUpdate();
|
||
}
|
||
|
||
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');
|
||
hideGuideFocus();
|
||
syncGuideBodyClass();
|
||
});
|
||
|
||
window.addEventListener('resize', function () {
|
||
if (guideBar && !guideBar.classList.contains('hidden')) {
|
||
scheduleGuideFocusUpdate();
|
||
}
|
||
});
|
||
window.addEventListener('orientationchange', function () {
|
||
setTimeout(scheduleGuideFocusUpdate, 350);
|
||
});
|
||
|
||
/* ใช้ 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 () {
|
||
if (typeof window.openCustomizePopup === 'function') {
|
||
window.openCustomizePopup();
|
||
return;
|
||
}
|
||
window.location.href = BASE + '/character.html';
|
||
});
|
||
|
||
document.getElementById('btn-daily')?.addEventListener('click', function () {
|
||
if (typeof window.openDailyPopup === 'function') {
|
||
window.openDailyPopup();
|
||
return;
|
||
}
|
||
toast('รางวัลประจำวัน — เข้าเกมทุกวันเพื่อรับรางวัลต่อเนื่อง!');
|
||
});
|
||
|
||
document.getElementById('btn-myprofile')?.addEventListener('click', function () {
|
||
if (typeof window.openProfilePopup === 'function') {
|
||
window.openProfilePopup();
|
||
return;
|
||
}
|
||
window.location.href = typeof appPath === 'function' ? appPath('/Main-Menu/') : '/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 syncAiChatPanelUi() {
|
||
if (!aiChatPanel) return;
|
||
var hidden = aiChatPanel.classList.contains('lobby-ai-chat-hidden');
|
||
if (btnAiChat) btnAiChat.style.display = hidden ? '' : 'none';
|
||
if (hidden || !aiChatToggleImg || !aiChatCloseBtn) return;
|
||
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');
|
||
syncAiChatPanelUi();
|
||
});
|
||
}
|
||
|
||
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');
|
||
syncAiChatPanelUi();
|
||
var inp = document.getElementById('lobby-ai-chat-input');
|
||
if (inp) {
|
||
try {
|
||
inp.focus();
|
||
} catch (e) { /* ignore */ }
|
||
}
|
||
} else {
|
||
aiChatPanel.classList.add('lobby-ai-chat-hidden');
|
||
syncAiChatPanelUi();
|
||
}
|
||
});
|
||
}
|
||
syncAiChatPanelUi();
|
||
|
||
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(SERVER + '/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();
|
||
});
|
||
|
||
applyCharacterFootOffsetByViewport();
|
||
syncMainLobbyCharacterUi();
|
||
bindLeaderboardScrollSync();
|
||
bindLeaderboardWheelSupport();
|
||
bindLeaderboardDragScroll();
|
||
bindLeaderboardThumbDrag();
|
||
scheduleLeaderboardPlacement();
|
||
initGuide();
|
||
|
||
window.addEventListener('pageshow', function () {
|
||
applyCharacterFootOffsetByViewport();
|
||
syncMainLobbyCharacterUi();
|
||
scheduleLeaderboardPlacement();
|
||
});
|
||
window.addEventListener('resize', function () {
|
||
applyCharacterFootOffsetByViewport();
|
||
bindLeaderboardScrollSync();
|
||
bindLeaderboardWheelSupport();
|
||
bindLeaderboardDragScroll();
|
||
bindLeaderboardThumbDrag();
|
||
scheduleLeaderboardPlacement();
|
||
});
|
||
window.addEventListener('orientationchange', function () {
|
||
setTimeout(function () {
|
||
applyCharacterFootOffsetByViewport();
|
||
scheduleLeaderboardPlacement();
|
||
}, 250);
|
||
});
|
||
window.addEventListener('load', function () {
|
||
bindLeaderboardScrollSync();
|
||
bindLeaderboardWheelSupport();
|
||
bindLeaderboardDragScroll();
|
||
bindLeaderboardThumbDrag();
|
||
scheduleLeaderboardPlacement();
|
||
});
|
||
document.addEventListener('visibilitychange', function () {
|
||
if (document.visibilityState === 'visible') {
|
||
applyCharacterFootOffsetByViewport();
|
||
syncMainLobbyCharacterUi();
|
||
scheduleLeaderboardPlacement();
|
||
}
|
||
});
|
||
window.addEventListener('storage', function (e) {
|
||
if (e.key == null || e.key === CHAR_KEY || e.key === 'playerName' || e.key === DISPLAY_NAME_STORAGE_KEY) {
|
||
syncMainLobbyCharacterUi();
|
||
return;
|
||
}
|
||
if (e.key && String(e.key).indexOf(LOBBY_IDLE_DOWN_PREFIX) === 0) {
|
||
syncMainLobbyCharacterUi();
|
||
}
|
||
});
|
||
})();
|