Files
justice/www/html/Game/public/js/profile-popup.js
T
2026-05-27 08:02:22 +00:00

310 lines
19 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
(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();
}
})();