310 lines
19 KiB
JavaScript
310 lines
19 KiB
JavaScript
(function () {
|
||
'use strict';
|
||
|
||
var script = document.currentScript;
|
||
var triggerSelector = (script && script.getAttribute('data-profile-trigger')) || '#btn-myprofile,#btn-profile-set';
|
||
var assetBase = (script && script.getAttribute('data-profile-asset-base')) || 'img/03-6-Profile';
|
||
var DISPLAY_NAME_KEY = 'roomLobbyDisplayName';
|
||
var overlayId = 'room-lobby-profile-overlay';
|
||
|
||
if (typeof window !== 'undefined') window.__USE_SHARED_PROFILE_POPUP = true;
|
||
|
||
function resolveAssetBase(raw) {
|
||
var base = String(raw || 'img/03-6-Profile').replace(/\/$/, '');
|
||
if (/^\/(Game|img)\//i.test(base)) {
|
||
return typeof window.appPath === 'function' ? window.appPath(base) : base;
|
||
}
|
||
try {
|
||
return new URL(base + '/', window.location.href).pathname.replace(/\/$/, '');
|
||
} catch (e) {
|
||
return base;
|
||
}
|
||
}
|
||
|
||
var resolvedAssetBase = resolveAssetBase(assetBase);
|
||
|
||
function asset(name) {
|
||
return resolvedAssetBase + '/' + name;
|
||
}
|
||
|
||
function appRel(path) {
|
||
if (typeof window.appPath === 'function') return window.appPath(path);
|
||
return path;
|
||
}
|
||
|
||
function readName() {
|
||
try { return (localStorage.getItem(DISPLAY_NAME_KEY) || localStorage.getItem('playerName') || 'MONE').trim() || 'MONE'; } catch (e) { return 'MONE'; }
|
||
}
|
||
function readAgentId() {
|
||
try { return (localStorage.getItem('agentDisplayId') || '001998').trim() || '001998'; } catch (e) { return '001998'; }
|
||
}
|
||
function readCoins() {
|
||
try { return String(Math.max(0, parseInt(localStorage.getItem('jdCoins') || '0', 10) || 0)); } catch (e) { return '0'; }
|
||
}
|
||
|
||
var refs = {
|
||
overlay: null,
|
||
backdrop: null,
|
||
dialog: null,
|
||
closeBtn: null,
|
||
avatarEl: null,
|
||
nameEl: null,
|
||
agentEl: null,
|
||
coinsEl: null,
|
||
musicBtn: null,
|
||
sfxBtn: null,
|
||
groupBtns: [],
|
||
archivListEl: null,
|
||
archivScrollEl: null,
|
||
archivScrollBarEl: null,
|
||
editBtn: null,
|
||
logoutBtn: null
|
||
};
|
||
|
||
function createMarkupIfNeeded() {
|
||
if (document.getElementById(overlayId)) return;
|
||
var overlay = document.createElement('div');
|
||
overlay.id = overlayId;
|
||
overlay.className = 'room-lobby-profile-overlay is-hidden';
|
||
overlay.setAttribute('aria-hidden', 'true');
|
||
overlay.innerHTML = '' +
|
||
'<div class="room-lobby-profile-backdrop" id="room-lobby-profile-backdrop" aria-hidden="true"></div>' +
|
||
'<div class="room-lobby-profile-dialog" role="dialog" aria-modal="true" aria-label="โปรไฟล์ผู้เล่น">' +
|
||
' <button type="button" class="room-lobby-profile-close" id="room-lobby-profile-close" aria-label="ปิดโปรไฟล์">×</button>' +
|
||
' <div class="room-lobby-profile-content">' +
|
||
' <section class="room-lobby-profile-left-pane">' +
|
||
' <div class="room-lobby-profile-inner-frame">' +
|
||
' <p class="room-lobby-profile-coins">' +
|
||
' <img src="' + asset('profile-pop-coin.png') + '" alt="My Coins" class="room-lobby-profile-coins-label" decoding="async">' +
|
||
' <strong id="room-lobby-profile-coins-val">150</strong>' +
|
||
' </p>' +
|
||
' <div class="room-lobby-profile-char-card">' +
|
||
' <img id="room-lobby-profile-overlay-avatar" src="" alt="ตัวละครผู้เล่น" decoding="async">' +
|
||
' <div class="room-lobby-profile-overlay-name-row">' +
|
||
' <div class="room-lobby-profile-overlay-name" id="room-lobby-profile-overlay-name">PLAYER</div>' +
|
||
' <button type="button" class="room-lobby-profile-edit-btn" id="room-lobby-profile-edit-btn" title="แก้ไขชื่อผู้เล่น" aria-label="แก้ไขชื่อผู้เล่น">' +
|
||
' <img src="' + asset('btn-edit.png') + '" alt="" decoding="async">' +
|
||
' </button>' +
|
||
' </div>' +
|
||
' <img src="' + asset('profile-char-frame-2.png') + '" alt="" class="room-lobby-profile-name-sep" decoding="async">' +
|
||
' <div class="room-lobby-profile-overlay-agent" id="room-lobby-profile-overlay-agent">AGENT ID : 001998</div>' +
|
||
' </div>' +
|
||
' </div>' +
|
||
' <button type="button" class="room-lobby-profile-logout" id="room-lobby-profile-logout" aria-label="ออกจากระบบ">' +
|
||
' <img src="' + asset('btn-ex.png') + '" alt="ออกจากระบบ" decoding="async">' +
|
||
' </button>' +
|
||
' </section>' +
|
||
' <section class="room-lobby-profile-right-pane">' +
|
||
' <div class="room-lobby-profile-archiv-groups" id="room-lobby-profile-archiv-groups">' +
|
||
' <button type="button" class="room-lobby-profile-archiv-group-btn is-active" data-group="1"><img src="' + asset('archiv-group-01-a.png') + '" alt=""></button>' +
|
||
' <button type="button" class="room-lobby-profile-archiv-group-btn" data-group="2"><img src="' + asset('archiv-group-02.png') + '" alt=""></button>' +
|
||
' <button type="button" class="room-lobby-profile-archiv-group-btn" data-group="3"><img src="' + asset('archiv-group-03.png') + '" alt=""></button>' +
|
||
' <button type="button" class="room-lobby-profile-archiv-group-btn" data-group="4"><img src="' + asset('archiv-group-04.png') + '" alt=""></button>' +
|
||
' <button type="button" class="room-lobby-profile-archiv-group-btn" data-group="5"><img src="' + asset('archiv-group-05.png') + '" alt=""></button>' +
|
||
' </div>' +
|
||
' <div class="room-lobby-profile-archiv-frame">' +
|
||
' <ul class="room-lobby-profile-achievements-list" id="room-lobby-profile-achievements-list">' +
|
||
' <li class="room-lobby-profile-archiv-item"><img class="room-lobby-profile-archiv-icon-bg" src="' + asset('archiv-icon-bg.png') + '" alt=""><div class="room-lobby-profile-archiv-main"><div class="room-lobby-profile-archiv-title-row"><img class="room-lobby-profile-archiv-name" src="' + asset('archiv-name-1.png') + '" alt=""><strong class="room-lobby-profile-archiv-count">1/1</strong></div><div class="room-lobby-profile-archiv-progress-wrap"><img class="room-lobby-profile-archiv-progress-bg" src="' + asset('archiv-progress-bg.png') + '" alt=""><img class="room-lobby-profile-archiv-progress" src="' + asset('archiv-progress.png') + '" alt="" style="--archiv-progress:100%"></div><img class="room-lobby-profile-archiv-line" src="' + asset('archiv-line.png') + '" alt=""></div></li>' +
|
||
' <li class="room-lobby-profile-archiv-item"><img class="room-lobby-profile-archiv-icon-bg" src="' + asset('archiv-icon-bg.png') + '" alt=""><div class="room-lobby-profile-archiv-main"><div class="room-lobby-profile-archiv-title-row"><img class="room-lobby-profile-archiv-name" src="' + asset('archiv-name-2.png') + '" alt=""><strong class="room-lobby-profile-archiv-count">2/5</strong></div><div class="room-lobby-profile-archiv-progress-wrap"><img class="room-lobby-profile-archiv-progress-bg" src="' + asset('archiv-progress-bg.png') + '" alt=""><img class="room-lobby-profile-archiv-progress" src="' + asset('archiv-progress.png') + '" alt="" style="--archiv-progress:40%"></div><img class="room-lobby-profile-archiv-line" src="' + asset('archiv-line.png') + '" alt=""></div></li>' +
|
||
' <li class="room-lobby-profile-archiv-item"><img class="room-lobby-profile-archiv-icon-bg" src="' + asset('archiv-icon-bg.png') + '" alt=""><div class="room-lobby-profile-archiv-main"><div class="room-lobby-profile-archiv-title-row"><img class="room-lobby-profile-archiv-name" src="' + asset('archiv-name-3.png') + '" alt=""><strong class="room-lobby-profile-archiv-count">3/10</strong></div><div class="room-lobby-profile-archiv-progress-wrap"><img class="room-lobby-profile-archiv-progress-bg" src="' + asset('archiv-progress-bg.png') + '" alt=""><img class="room-lobby-profile-archiv-progress" src="' + asset('archiv-progress.png') + '" alt="" style="--archiv-progress:30%"></div><img class="room-lobby-profile-archiv-line" src="' + asset('archiv-line.png') + '" alt=""></div></li>' +
|
||
' <li class="room-lobby-profile-archiv-item"><img class="room-lobby-profile-archiv-icon-bg" src="' + asset('archiv-icon-bg.png') + '" alt=""><div class="room-lobby-profile-archiv-main"><div class="room-lobby-profile-archiv-title-row"><img class="room-lobby-profile-archiv-name" src="' + asset('archiv-name-1.png') + '" alt=""><strong class="room-lobby-profile-archiv-count">4/10</strong></div><div class="room-lobby-profile-archiv-progress-wrap"><img class="room-lobby-profile-archiv-progress-bg" src="' + asset('archiv-progress-bg.png') + '" alt=""><img class="room-lobby-profile-archiv-progress" src="' + asset('archiv-progress.png') + '" alt="" style="--archiv-progress:40%"></div><img class="room-lobby-profile-archiv-line" src="' + asset('archiv-line.png') + '" alt=""></div></li>' +
|
||
' <li class="room-lobby-profile-archiv-item"><img class="room-lobby-profile-archiv-icon-bg" src="' + asset('archiv-icon-bg.png') + '" alt=""><div class="room-lobby-profile-archiv-main"><div class="room-lobby-profile-archiv-title-row"><img class="room-lobby-profile-archiv-name" src="' + asset('archiv-name-2.png') + '" alt=""><strong class="room-lobby-profile-archiv-count">5/10</strong></div><div class="room-lobby-profile-archiv-progress-wrap"><img class="room-lobby-profile-archiv-progress-bg" src="' + asset('archiv-progress-bg.png') + '" alt=""><img class="room-lobby-profile-archiv-progress" src="' + asset('archiv-progress.png') + '" alt="" style="--archiv-progress:50%"></div><img class="room-lobby-profile-archiv-line" src="' + asset('archiv-line.png') + '" alt=""></div></li>' +
|
||
' </ul>' +
|
||
' <div class="room-lobby-profile-archiv-scroll is-hidden"><div class="room-lobby-profile-archiv-scroll-bg"></div><div class="room-lobby-profile-archiv-scroll-bar"></div></div>' +
|
||
' </div>' +
|
||
' <div class="room-lobby-profile-settings"><img class="room-lobby-profile-settings-frame" src="' + asset('setting-frame.png') + '" alt=""><div class="room-lobby-profile-settings-row">' +
|
||
' <div class="room-lobby-profile-setting-item"><img class="room-lobby-profile-setting-label" src="' + asset('setting-txt-1.png') + '" alt="Music"><button type="button" class="room-lobby-profile-toggle" id="room-lobby-profile-music" data-on="true"><img src="' + asset('btn-on.png') + '" alt=""></button></div>' +
|
||
' <div class="room-lobby-profile-setting-item"><img class="room-lobby-profile-setting-label" src="' + asset('setting-txt-2.png') + '" alt="SFX"><button type="button" class="room-lobby-profile-toggle" id="room-lobby-profile-sfx" data-on="false"><img src="' + asset('btn-off.png') + '" alt=""></button></div>' +
|
||
' </div></div>' +
|
||
' </section>' +
|
||
' </div>' +
|
||
'</div>';
|
||
document.body.appendChild(overlay);
|
||
}
|
||
|
||
function bindRefs() {
|
||
refs.overlay = document.getElementById(overlayId);
|
||
refs.backdrop = document.getElementById('room-lobby-profile-backdrop');
|
||
refs.dialog = refs.overlay ? refs.overlay.querySelector('.room-lobby-profile-dialog') : null;
|
||
refs.closeBtn = document.getElementById('room-lobby-profile-close');
|
||
refs.avatarEl = document.getElementById('room-lobby-profile-overlay-avatar');
|
||
refs.nameEl = document.getElementById('room-lobby-profile-overlay-name');
|
||
refs.agentEl = document.getElementById('room-lobby-profile-overlay-agent');
|
||
refs.coinsEl = document.getElementById('room-lobby-profile-coins-val');
|
||
refs.musicBtn = document.getElementById('room-lobby-profile-music');
|
||
refs.sfxBtn = document.getElementById('room-lobby-profile-sfx');
|
||
refs.groupBtns = Array.prototype.slice.call(document.querySelectorAll('.room-lobby-profile-archiv-group-btn'));
|
||
refs.archivListEl = document.getElementById('room-lobby-profile-achievements-list');
|
||
refs.archivScrollEl = document.querySelector('.room-lobby-profile-archiv-scroll');
|
||
refs.archivScrollBarEl = document.querySelector('.room-lobby-profile-archiv-scroll-bar');
|
||
refs.editBtn = document.getElementById('room-lobby-profile-edit-btn');
|
||
refs.logoutBtn = document.getElementById('room-lobby-profile-logout');
|
||
}
|
||
|
||
function syncArchivScroll() {
|
||
if (!refs.archivListEl || !refs.archivScrollEl || !refs.archivScrollBarEl) return;
|
||
var total = refs.archivListEl.scrollHeight || 0;
|
||
var visible = refs.archivListEl.clientHeight || 0;
|
||
var overflow = total > visible + 1;
|
||
refs.archivScrollEl.classList.toggle('is-hidden', !overflow);
|
||
if (!overflow) return;
|
||
var max = Math.max(1, total - visible);
|
||
var ratio = Math.max(0, Math.min(1, refs.archivListEl.scrollTop / max));
|
||
var barPct = Math.max(18, Math.min(42, (visible / Math.max(1, total)) * 100));
|
||
refs.archivScrollBarEl.style.height = barPct.toFixed(2) + '%';
|
||
refs.archivScrollBarEl.style.top = ((100 - barPct) * ratio).toFixed(2) + '%';
|
||
}
|
||
|
||
function syncProfileScale() {
|
||
if (!refs.dialog) return;
|
||
var rect = refs.dialog.getBoundingClientRect();
|
||
if (!rect.width || !rect.height) return;
|
||
var scaleW = rect.width / 1701;
|
||
var scaleH = rect.height / 951;
|
||
var scale = Math.max(0.35, Math.min(1, Math.min(scaleW, scaleH)));
|
||
refs.dialog.style.setProperty('--rp-scale', String(scale.toFixed(4)));
|
||
}
|
||
|
||
function setGroup(index) {
|
||
refs.groupBtns.forEach(function (btn) {
|
||
var id = parseInt(btn.getAttribute('data-group'), 10) || 1;
|
||
var active = id === index;
|
||
btn.classList.toggle('is-active', active);
|
||
var img = btn.querySelector('img');
|
||
if (img) img.src = active ? asset('archiv-group-0' + id + '-a.png') : asset('archiv-group-0' + id + '.png');
|
||
});
|
||
syncArchivScroll();
|
||
}
|
||
|
||
function toggleChip(btn) {
|
||
if (!btn) return;
|
||
var on = String(btn.getAttribute('data-on') || '').toLowerCase() === 'true';
|
||
on = !on;
|
||
btn.setAttribute('data-on', on ? 'true' : 'false');
|
||
var img = btn.querySelector('img');
|
||
if (img) img.src = on ? asset('btn-on.png') : asset('btn-off.png');
|
||
}
|
||
|
||
function setProfileData(data) {
|
||
var payload = data || {};
|
||
var lobbyAvatar = document.getElementById('lobby-profile-avatar');
|
||
var roomAvatar = document.getElementById('room-lobby-profile-avatar');
|
||
var src = payload.avatarSrc || (lobbyAvatar && lobbyAvatar.getAttribute('src')) || (roomAvatar && roomAvatar.getAttribute('src')) || '';
|
||
if (refs.avatarEl && src) refs.avatarEl.src = src;
|
||
if (refs.nameEl) refs.nameEl.textContent = (payload.displayName || readName()).toUpperCase();
|
||
if (refs.agentEl) refs.agentEl.textContent = payload.agentIdLabel || ('AGENT ID : ' + readAgentId());
|
||
if (refs.coinsEl) refs.coinsEl.textContent = String(payload.coins != null ? payload.coins : readCoins());
|
||
}
|
||
|
||
function openPopup(data) {
|
||
if (!refs.overlay) return;
|
||
setProfileData(data);
|
||
refs.overlay.classList.remove('is-hidden');
|
||
refs.overlay.setAttribute('aria-hidden', 'false');
|
||
syncProfileScale();
|
||
syncArchivScroll();
|
||
if (refs.closeBtn) refs.closeBtn.focus();
|
||
}
|
||
|
||
function closePopup() {
|
||
if (!refs.overlay) return;
|
||
refs.overlay.classList.add('is-hidden');
|
||
refs.overlay.setAttribute('aria-hidden', 'true');
|
||
}
|
||
|
||
function bindEvents() {
|
||
if (refs.backdrop) refs.backdrop.addEventListener('click', closePopup);
|
||
if (refs.closeBtn) refs.closeBtn.addEventListener('click', closePopup);
|
||
if (refs.musicBtn) refs.musicBtn.addEventListener('click', function () { toggleChip(refs.musicBtn); });
|
||
if (refs.sfxBtn) refs.sfxBtn.addEventListener('click', function () { toggleChip(refs.sfxBtn); });
|
||
refs.groupBtns.forEach(function (btn) {
|
||
btn.addEventListener('click', function () { setGroup(parseInt(btn.getAttribute('data-group'), 10) || 1); });
|
||
});
|
||
if (refs.archivListEl) refs.archivListEl.addEventListener('scroll', syncArchivScroll, { passive: true });
|
||
if (refs.editBtn) refs.editBtn.addEventListener('click', function () {
|
||
var runApply = function (draft) {
|
||
if (draft == null) return;
|
||
var applyFn = typeof window.jdApplyDisplayNameChange === 'function'
|
||
? window.jdApplyDisplayNameChange
|
||
: null;
|
||
if (applyFn) {
|
||
var result = applyFn(draft, { socket: window.__jdGameSocket || null });
|
||
if (!result.ok) return;
|
||
if (refs.nameEl) refs.nameEl.textContent = result.displayName.toUpperCase();
|
||
return;
|
||
}
|
||
try {
|
||
localStorage.setItem(DISPLAY_NAME_KEY, draft);
|
||
localStorage.setItem('playerName', draft);
|
||
} catch (e) { /* ignore */ }
|
||
if (refs.nameEl) refs.nameEl.textContent = draft.toUpperCase();
|
||
var headerName = document.getElementById('lobby-profile-name');
|
||
if (headerName) headerName.textContent = draft.toUpperCase();
|
||
};
|
||
|
||
if (window.jdDisplayName && typeof window.jdDisplayName.openEditor === 'function') {
|
||
window.jdDisplayName.openEditor({
|
||
initialValue: typeof window.jdReadDisplayName === 'function' ? window.jdReadDisplayName() : readName()
|
||
}).then(runApply);
|
||
return;
|
||
}
|
||
if (typeof window.jdPromptAndApplyDisplayName === 'function') {
|
||
window.jdPromptAndApplyDisplayName({ socket: window.__jdGameSocket || null }).then(function (result) {
|
||
if (result && result.ok && refs.nameEl) refs.nameEl.textContent = result.displayName.toUpperCase();
|
||
});
|
||
return;
|
||
}
|
||
var draft = window.prompt('แก้ไขชื่อผู้เล่น', readName() || '');
|
||
runApply(draft == null ? null : String(draft).trim() || null);
|
||
});
|
||
if (refs.logoutBtn) refs.logoutBtn.addEventListener('click', function () {
|
||
if (document.getElementById('btn-back')) {
|
||
window.location.href = appRel('/Login/');
|
||
return;
|
||
}
|
||
window.location.href = appRel('/Create%20Room/');
|
||
});
|
||
document.addEventListener('keydown', function (e) {
|
||
if (e.key !== 'Escape') return;
|
||
var nameEditor = document.getElementById('jd-display-name-editor-overlay');
|
||
if (nameEditor && !nameEditor.classList.contains('is-hidden')) return;
|
||
if (refs.overlay && !refs.overlay.classList.contains('is-hidden')) closePopup();
|
||
});
|
||
window.addEventListener('resize', function () {
|
||
syncProfileScale();
|
||
syncArchivScroll();
|
||
});
|
||
document.querySelectorAll(triggerSelector).forEach(function (el) {
|
||
el.addEventListener('click', function (e) {
|
||
e.preventDefault();
|
||
openPopup();
|
||
});
|
||
});
|
||
}
|
||
|
||
function isRoomLobbyPage() {
|
||
return /room-lobby\.html$/i.test(String(window.location.pathname || ''));
|
||
}
|
||
|
||
function init() {
|
||
if (isRoomLobbyPage()) {
|
||
return;
|
||
}
|
||
createMarkupIfNeeded();
|
||
bindRefs();
|
||
bindEvents();
|
||
syncProfileScale();
|
||
setGroup(1);
|
||
window.openProfilePopup = openPopup;
|
||
window.closeProfilePopup = closePopup;
|
||
window.roomLobbyProfileOverlay = { open: openPopup, close: closePopup };
|
||
window.mainLobbyProfileOverlay = { open: openPopup, close: closePopup };
|
||
}
|
||
|
||
if (document.readyState === 'loading') {
|
||
document.addEventListener('DOMContentLoaded', init, { once: true });
|
||
} else {
|
||
init();
|
||
}
|
||
})();
|