121 lines
4.6 KiB
JavaScript
121 lines
4.6 KiB
JavaScript
/**
|
|
* Reward System Module
|
|
*/
|
|
(function() {
|
|
function initReward() {
|
|
const btn = document.getElementById('reward-btn');
|
|
const modal = document.getElementById('reward-modal');
|
|
const close = document.getElementById('reward-close');
|
|
|
|
if (!btn || !modal) return;
|
|
|
|
// Global Click Handler
|
|
// We attach this to document only when modal is open to handle "click anywhere outside content"
|
|
// This is more robust than attaching to the modal container, which might have size/z-index issues.
|
|
|
|
const handleGlobalClick = (e) => {
|
|
const activeModal = document.getElementById('reward-modal');
|
|
if (!activeModal || !activeModal.classList.contains('show')) return;
|
|
|
|
// If click is inside the content, ignore
|
|
if (e.target.closest('.reward-content')) return;
|
|
|
|
// If click is on the open button, ignore (it has its own handler, or we might double-toggle)
|
|
if (e.target.closest('#reward-btn')) return;
|
|
|
|
// Otherwise, close it
|
|
hideModal();
|
|
};
|
|
|
|
// Helper to show modal
|
|
const showModal = (e) => {
|
|
if(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
}
|
|
modal.classList.add('show');
|
|
document.body.style.overflow = 'hidden'; // Prevent scrolling
|
|
|
|
// Attach global click listener with a slight delay to avoid current click triggering it
|
|
setTimeout(() => {
|
|
document.addEventListener('click', handleGlobalClick);
|
|
}, 10);
|
|
};
|
|
|
|
// Helper to hide modal
|
|
const hideModal = () => {
|
|
modal.classList.remove('show');
|
|
document.body.style.overflow = '';
|
|
document.removeEventListener('click', handleGlobalClick);
|
|
};
|
|
|
|
// Button click
|
|
btn.addEventListener('click', showModal);
|
|
|
|
// Close button click
|
|
if (close) {
|
|
close.addEventListener('click', (e) => {
|
|
e.stopPropagation(); // Prevent bubbling to global handler (though redundant as handler checks)
|
|
hideModal();
|
|
});
|
|
}
|
|
|
|
// Remove old direct listeners if any (cleaner approach replaces them)
|
|
|
|
// Escape key to close
|
|
if (!window.rewardKeyHandlerAttached) {
|
|
window.rewardKeyHandler = function(e) {
|
|
const activeModal = document.getElementById('reward-modal');
|
|
if (e.key === 'Escape' && activeModal && activeModal.classList.contains('show')) {
|
|
hideModal(); // Use the same hide function to clean up listeners
|
|
}
|
|
};
|
|
document.addEventListener('keydown', window.rewardKeyHandler);
|
|
window.rewardKeyHandlerAttached = true;
|
|
}
|
|
|
|
// Expose hideModal for destroy function if needed?
|
|
// We can just rely on the fact that destroyReward queries DOM.
|
|
// But we need to make sure destroyReward removes the global listener too.
|
|
// Since handleGlobalClick is local scope, we need a way to reference it or just define it outside?
|
|
// Or better: make handleGlobalClick a named function available to destroyReward via a shared scope or window.
|
|
// Let's attach it to window for safety in this module pattern.
|
|
window.rewardGlobalClickHandler = handleGlobalClick;
|
|
}
|
|
|
|
function destroyReward() {
|
|
// Cleanup keydown listener
|
|
if (window.rewardKeyHandlerAttached && window.rewardKeyHandler) {
|
|
document.removeEventListener('keydown', window.rewardKeyHandler);
|
|
window.rewardKeyHandlerAttached = false;
|
|
window.rewardKeyHandler = null;
|
|
}
|
|
|
|
// Cleanup global click listener
|
|
if (window.rewardGlobalClickHandler) {
|
|
document.removeEventListener('click', window.rewardGlobalClickHandler);
|
|
window.rewardGlobalClickHandler = null;
|
|
}
|
|
|
|
// Hide modal if open (restore body scroll)
|
|
const modal = document.getElementById('reward-modal');
|
|
if (modal && modal.classList.contains('show')) {
|
|
modal.classList.remove('show');
|
|
document.body.style.overflow = '';
|
|
}
|
|
}
|
|
|
|
// Initialize on load
|
|
document.addEventListener('DOMContentLoaded', initReward);
|
|
|
|
// Initialize on Pjax complete
|
|
document.addEventListener('pjax:complete', initReward);
|
|
|
|
// Destroy on Pjax send
|
|
document.addEventListener('pjax:send', destroyReward);
|
|
|
|
// Export
|
|
window.initReward = initReward;
|
|
window.destroyReward = destroyReward;
|
|
})();
|