@energy8platform/shell 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/html.cjs.js +11 -8
- package/dist/html.cjs.js.map +1 -1
- package/dist/html.d.ts +2 -2
- package/dist/html.esm.js +11 -8
- package/dist/html.esm.js.map +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.esm.js +1 -1
- package/dist/pixi.cjs.js +9 -2
- package/dist/pixi.cjs.js.map +1 -1
- package/dist/pixi.d.ts +2 -2
- package/dist/pixi.esm.js +9 -2
- package/dist/pixi.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/core/version.ts +1 -1
- package/src/ui/html/HtmlRenderer.ts +1 -1
- package/src/ui/html/components/GameInfo.ts +1 -1
- package/src/ui/html/components/Modal.ts +8 -4
- package/src/ui/html/components/Settings.ts +1 -1
- package/src/ui/pixi/PixiRenderer.ts +4 -1
- package/src/ui/pixi/primitives/scroll.ts +3 -0
package/package.json
CHANGED
package/src/core/version.ts
CHANGED
|
@@ -18,7 +18,7 @@ export interface GameInfoModal {
|
|
|
18
18
|
export function openGameInfoModal(host: ShellHost): GameInfoModal {
|
|
19
19
|
const { root, body, scroll } = createOverlay({
|
|
20
20
|
title: host.t('Game info'),
|
|
21
|
-
onClose: () =>
|
|
21
|
+
onClose: () => host.actions.closeOverlay(),
|
|
22
22
|
onBack: () => { root.remove(); host.actions.openSettings(); },
|
|
23
23
|
});
|
|
24
24
|
root.dataset.ge = 'info-modal';
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import type { ModalOptions } from '@/core/types';
|
|
2
|
+
import type { ShellHost } from '@/core/renderer';
|
|
2
3
|
import { contrastText } from '@/core/colors';
|
|
3
4
|
import { createCardModal } from '../primitives';
|
|
4
5
|
|
|
5
6
|
/** Build a generic, externally-triggered modal (title + body text + optional action buttons),
|
|
6
7
|
* on the shared card-modal chrome. Each action runs its `on` then closes; the ✕ (if
|
|
7
|
-
* `availableClose`) and the actions are the only ways to dismiss. See GameShell.openModal.
|
|
8
|
-
|
|
8
|
+
* `availableClose`) and the actions are the only ways to dismiss. See GameShell.openModal.
|
|
9
|
+
* Dismissals route through host.actions.closeOverlay() so the controller clears its overlay handle
|
|
10
|
+
* (a bare root.remove() leaves the handle stale → keydowns keep routing to a torn-down layer). */
|
|
11
|
+
export function buildModal(host: ShellHost, opts: ModalOptions): HTMLElement {
|
|
12
|
+
const close = () => host.actions.closeOverlay();
|
|
9
13
|
const ui = createCardModal({
|
|
10
14
|
ge: 'modal',
|
|
11
15
|
title: opts.title,
|
|
12
16
|
closable: opts.availableClose,
|
|
13
17
|
blur: opts.blurLevel,
|
|
14
|
-
onClose:
|
|
18
|
+
onClose: close,
|
|
15
19
|
});
|
|
16
20
|
|
|
17
21
|
const text = document.createElement('p');
|
|
@@ -27,7 +31,7 @@ export function buildModal(opts: ModalOptions): HTMLElement {
|
|
|
27
31
|
btn.textContent = a.title;
|
|
28
32
|
if (a.color) { btn.style.background = a.color; btn.style.color = contrastText(a.color); }
|
|
29
33
|
else btn.classList.add('ge-modal-btn--ghost');
|
|
30
|
-
btn.addEventListener('click', () => { a.on?.();
|
|
34
|
+
btn.addEventListener('click', () => { a.on?.(); close(); });
|
|
31
35
|
actions.appendChild(btn);
|
|
32
36
|
}
|
|
33
37
|
ui.card.appendChild(actions);
|
|
@@ -3,7 +3,7 @@ import { createOverlay } from '../primitives';
|
|
|
3
3
|
import { icon } from '../icons';
|
|
4
4
|
|
|
5
5
|
export function openSettingsModal(host: ShellHost): HTMLElement {
|
|
6
|
-
const { root, body } = createOverlay({ title: host.t('Settings'), onClose: () =>
|
|
6
|
+
const { root, body } = createOverlay({ title: host.t('Settings'), onClose: () => host.actions.closeOverlay() });
|
|
7
7
|
root.dataset.ge = 'settings-modal';
|
|
8
8
|
|
|
9
9
|
// Sound on/off — backed by the shell's shared `soundOn` state so this toggle and the Shift+M
|
|
@@ -340,7 +340,10 @@ export class PixiRenderer implements ShellRenderer {
|
|
|
340
340
|
get screenH() { return self.app.screen.height; },
|
|
341
341
|
render: () => self.renderBar(),
|
|
342
342
|
pushLayer: (node) => self.pushLayer(node),
|
|
343
|
-
|
|
343
|
+
// Route component-initiated closes through the controller (not straight to self.closeLayer) so
|
|
344
|
+
// it clears its OverlayHandle. Otherwise the handle goes stale: hasOpenLayer() stays true and
|
|
345
|
+
// keydowns keep routing to onKey on a destroyed overlay → write to a torn-down ScrollBox.
|
|
346
|
+
closeLayer: () => host.actions.closeOverlay(),
|
|
344
347
|
fitModals: () => self.fitModals(),
|
|
345
348
|
fmt: (n) => host.formatCurrency(n),
|
|
346
349
|
fmtWin: (n) => host.formatCurrency(n, true),
|
|
@@ -82,6 +82,9 @@ export class ScrollBox extends Container {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
private setScroll(y: number): void {
|
|
85
|
+
// Ignore late scrolls after teardown: a queued keydown (or resize) can route here once the modal
|
|
86
|
+
// has been destroyed, and writing to a torn-down content Container throws (use-after-destroy).
|
|
87
|
+
if (this.destroyed || !this.content || this.content.destroyed) return;
|
|
85
88
|
this.scrollY = Math.max(0, Math.min(this.maxScroll, y)) || 0; // || 0 converts -0 to 0
|
|
86
89
|
this.content.y = this.scrollY === 0 ? 0 : -this.scrollY;
|
|
87
90
|
}
|