/** * 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; })();