From 46bc42393580a0342eeeae2090734fd6bfc3e90b Mon Sep 17 00:00:00 2001 From: Vitaly Date: Tue, 22 Aug 2023 05:01:24 +0300 Subject: [PATCH] refactor modal stacks so they are: 1. watchable for changes 2. can be used along with react --- src/chat.js | 6 +++--- src/globalState.js | 34 ++++++++++++++++++++++------------ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/chat.js b/src/chat.js index f60c883a..f4834c0d 100644 --- a/src/chat.js +++ b/src/chat.js @@ -1,7 +1,7 @@ //@ts-check const { LitElement, html, css } = require('lit') const { isMobile } = require('./menus/components/common') -const { activeModalStack, hideCurrentModal } = require('./globalState') +const { activeModalStack, hideCurrentModal, showModal } = require('./globalState') import { repeat } from 'lit/directives/repeat.js' import { classMap } from 'lit/directives/class-map.js' @@ -168,7 +168,7 @@ class ChatBox extends LitElement { this.shadowRoot.getElementById('chat-wrapper2').classList.toggle('input-mobile', isMobile()) this.shadowRoot.getElementById('chat-wrapper').classList.toggle('display-mobile', isMobile()) - activeModalStack.push(this) + showModal(this) // Exit the pointer lock document.exitPointerLock() @@ -187,7 +187,7 @@ class ChatBox extends LitElement { } get inChat () { - return activeModalStack.includes(this) + return activeModalStack.find(m => m.elem === this) !== undefined } /** diff --git a/src/globalState.js b/src/globalState.js index ca6f360c..e6b0be15 100644 --- a/src/globalState.js +++ b/src/globalState.js @@ -1,17 +1,17 @@ //@ts-check -import { proxy } from 'valtio' +import { proxy, ref } from 'valtio' import { pointerLock } from './utils' // todo: refactor structure with support of hideNext=false /** - * @typedef {(HTMLElement & Record)} Modal + * @typedef {({elem?: HTMLElement & Record} & {reactType?: string})} Modal * @typedef {{callback, label}} ContextMenuItem */ /** @type {Modal[]} */ -export const activeModalStack = [] +export const activeModalStack = proxy([]) export const replaceActiveModalStack = (name, newModalStack = activeModalStacks[name]) => { hideModal(undefined, undefined, { restorePrevious: false, force: true, }) @@ -26,18 +26,28 @@ window.activeModalStack = activeModalStack export const customDisplayManageKeyword = 'custom' +const defaultModalActions = { + show (/** @type {Modal} */modal) { + if (modal.elem) modal.elem.style.display = 'block' + }, + hide (/** @type {Modal} */modal) { + if (modal.elem) modal.elem.style.display = 'none' + } +} + const showModalInner = (/** @type {Modal} */ modal) => { - const cancel = modal.show?.() + const cancel = modal.elem?.show?.() if (cancel && cancel !== customDisplayManageKeyword) return false - if (cancel !== 'custom') modal.style.display = 'block' + if (cancel !== 'custom') defaultModalActions.show(modal) return true } -export const showModal = (/** @type {Modal} */ modal) => { +export const showModal = (/** @type {HTMLElement & Record | {reactType: string}} */ elem) => { + const resolved = elem instanceof HTMLElement ? { elem: ref(elem) } : elem const curModal = activeModalStack.slice(-1)[0] - if (modal === curModal || !showModalInner(modal)) return - if (curModal) curModal.style.display = 'none' - activeModalStack.push(modal) + if (elem === curModal?.elem || !showModalInner(resolved)) return + if (curModal) defaultModalActions.hide(curModal) + activeModalStack.push(resolved) } /** @@ -49,13 +59,13 @@ export const showModal = (/** @type {Modal} */ modal) => { export const hideModal = (modal = activeModalStack.slice(-1)[0], data = undefined, options = {}) => { const { force = false, restorePrevious = true } = options if (!modal) return - let cancel = modal.hide?.(data) + let cancel = modal.elem?.hide?.(data) if (force && cancel !== customDisplayManageKeyword) { cancel = undefined } if (!cancel || cancel === customDisplayManageKeyword) { - if (cancel !== customDisplayManageKeyword) modal.style.display = 'none' + if (cancel !== customDisplayManageKeyword) defaultModalActions.hide(modal) activeModalStack.pop() const newModal = activeModalStack.slice(-1)[0] if (newModal && restorePrevious) { @@ -91,7 +101,7 @@ export const showContextmenu = (/** @type {ContextMenuItem[]} */items, { clientX // --- -export const isGameActive = (foregroundCheck = false) => { +export const isGameActive = (foregroundCheck) => { if (foregroundCheck && activeModalStack.length) return false return document.getElementById('hud').style.display !== 'none' }