@energy8platform/shell 0.2.0 → 0.2.3
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 +22 -8
- package/dist/html.cjs.js.map +1 -1
- package/dist/html.d.ts +2 -2
- package/dist/html.esm.js +22 -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 +28 -11
- package/dist/pixi.cjs.js.map +1 -1
- package/dist/pixi.d.ts +2 -2
- package/dist/pixi.esm.js +28 -11
- 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/html/shell.css.ts +11 -0
- package/src/ui/pixi/PixiRenderer.ts +4 -1
- package/src/ui/pixi/components/BuyBonus.ts +21 -10
- package/src/ui/pixi/primitives/scroll.ts +3 -0
package/dist/index.d.ts
CHANGED
|
@@ -471,7 +471,7 @@ declare class ShellController extends EventEmitter<ShellEvents> implements Shell
|
|
|
471
471
|
tokens: ShellTokens;
|
|
472
472
|
layout: ShellLayoutMode;
|
|
473
473
|
soundOn: boolean;
|
|
474
|
-
readonly engineVersion = "0.2.
|
|
474
|
+
readonly engineVersion = "0.2.3";
|
|
475
475
|
readonly actions: ShellActions;
|
|
476
476
|
private renderer;
|
|
477
477
|
private i18n;
|
|
@@ -537,7 +537,7 @@ interface I18n {
|
|
|
537
537
|
declare function createI18n(opts: I18nOptions): I18n;
|
|
538
538
|
|
|
539
539
|
/** The @energy8platform/shell package version, stamped into the game-info footer. */
|
|
540
|
-
declare const PACKAGE_VERSION = "0.2.
|
|
540
|
+
declare const PACKAGE_VERSION = "0.2.3";
|
|
541
541
|
|
|
542
542
|
/** A shell: the renderer-agnostic controller plus the surface facade (safeArea/barHeight/setVisible)
|
|
543
543
|
* an embedding host reads. `createShell`, `createGameShell` and `createPixiShell` all return this. */
|
package/dist/index.esm.js
CHANGED
|
@@ -1324,7 +1324,7 @@ class KeyboardController {
|
|
|
1324
1324
|
|
|
1325
1325
|
// AUTO-GENERATED by scripts/gen-version.mjs — do not edit. Mirrors package.json "version".
|
|
1326
1326
|
/** The @energy8platform/shell package version, stamped into the game-info footer. */
|
|
1327
|
-
const PACKAGE_VERSION = '0.2.
|
|
1327
|
+
const PACKAGE_VERSION = '0.2.3';
|
|
1328
1328
|
|
|
1329
1329
|
/** Apply defaults to the raw config (the mount target lives on the renderer, not here). */
|
|
1330
1330
|
function resolveConfig(config) {
|
package/dist/pixi.cjs.js
CHANGED
|
@@ -1354,7 +1354,7 @@ class KeyboardController {
|
|
|
1354
1354
|
|
|
1355
1355
|
// AUTO-GENERATED by scripts/gen-version.mjs — do not edit. Mirrors package.json "version".
|
|
1356
1356
|
/** The @energy8platform/shell package version, stamped into the game-info footer. */
|
|
1357
|
-
const PACKAGE_VERSION = '0.2.
|
|
1357
|
+
const PACKAGE_VERSION = '0.2.3';
|
|
1358
1358
|
|
|
1359
1359
|
/** Apply defaults to the raw config (the mount target lives on the renderer, not here). */
|
|
1360
1360
|
function resolveConfig(config) {
|
|
@@ -3311,6 +3311,10 @@ class ScrollBox extends pixi_js.Container {
|
|
|
3311
3311
|
this.setScroll(this.scrollY + dy);
|
|
3312
3312
|
}
|
|
3313
3313
|
setScroll(y) {
|
|
3314
|
+
// Ignore late scrolls after teardown: a queued keydown (or resize) can route here once the modal
|
|
3315
|
+
// has been destroyed, and writing to a torn-down content Container throws (use-after-destroy).
|
|
3316
|
+
if (this.destroyed || !this.content || this.content.destroyed)
|
|
3317
|
+
return;
|
|
3314
3318
|
this.scrollY = Math.max(0, Math.min(this.maxScroll, y)) || 0; // || 0 converts -0 to 0
|
|
3315
3319
|
this.content.y = this.scrollY === 0 ? 0 : -this.scrollY;
|
|
3316
3320
|
}
|
|
@@ -4271,6 +4275,10 @@ function imageBox(url, w, h) {
|
|
|
4271
4275
|
return c;
|
|
4272
4276
|
}
|
|
4273
4277
|
|
|
4278
|
+
/** Below this frame height (px), a wide/landscape popout (e.g. Popout S 400×225) stacks its cards
|
|
4279
|
+
* vertically and scrolls — like mobile — so descriptions stay readable instead of shrinking to a
|
|
4280
|
+
* ~4px floor. Wide + taller frames (Popout L and up) keep the centred horizontal row. */
|
|
4281
|
+
const SHORT_STACK_H = 340;
|
|
4274
4282
|
/** Buy-bonus overlay — art-forward cards (one per option), a live bet footer, and a confirm modal.
|
|
4275
4283
|
* Returns null when there are no bonus options. */
|
|
4276
4284
|
function openBuyBonus(host) {
|
|
@@ -4300,6 +4308,8 @@ class BuyBonusOverlay extends pixi_js.Container {
|
|
|
4300
4308
|
cardEntries = [];
|
|
4301
4309
|
/** Keyboard focus index into the affordable subset of cardEntries. -1 = none. */
|
|
4302
4310
|
focusIndex = -1;
|
|
4311
|
+
/** true when cards are stacked vertically (mobile, or a short landscape popout). */
|
|
4312
|
+
stack = false;
|
|
4303
4313
|
// Drag-scroll state. The drag is handled on the (unmasked) overlay, not the masked strip — a mask
|
|
4304
4314
|
// prunes pointer events outside its band, stalling globalpointermove mid-drag so later cards never
|
|
4305
4315
|
// scroll into reach. The overlay sees the whole screen, so the scroll runs the full range.
|
|
@@ -4409,7 +4419,10 @@ class BuyBonusOverlay extends pixi_js.Container {
|
|
|
4409
4419
|
}
|
|
4410
4420
|
buildCards() {
|
|
4411
4421
|
this.strip.removeChildren().forEach((c) => c.destroy({ children: true }));
|
|
4412
|
-
|
|
4422
|
+
// Stack (readable vertical list + scroll) on mobile OR on a short landscape popout; a shrink-to-fit
|
|
4423
|
+
// horizontal row on wide + tall frames. See SHORT_STACK_H.
|
|
4424
|
+
const stack = this.host.layout === 'mobile' || this.h <= SHORT_STACK_H;
|
|
4425
|
+
this.stack = stack;
|
|
4413
4426
|
const top = this.headerH + 6;
|
|
4414
4427
|
const areaH = this.h - top - this.footerH - 6;
|
|
4415
4428
|
const gap = 14;
|
|
@@ -4420,12 +4433,12 @@ class BuyBonusOverlay extends pixi_js.Container {
|
|
|
4420
4433
|
// N cards (+ gaps + 24px side margins) fit the frame width. min() of the two = the binding fit.
|
|
4421
4434
|
// Floor 4 is a last-resort so a 400×225 popout still shows the CTA (then X-drag scrolls the slack).
|
|
4422
4435
|
const emH = 3.4 * (areaH / 100);
|
|
4423
|
-
const emW =
|
|
4436
|
+
const emW = stack
|
|
4424
4437
|
? (this.w - 48) / 18 // vertical stack: a single card spans the width
|
|
4425
4438
|
: (this.w - 48 - (n - 1) * gap) / (18 * n); // row: N cards + gaps fit the frame width
|
|
4426
|
-
const em =
|
|
4439
|
+
const em = stack ? Math.min(12, emW) : clamp(4, Math.min(emH, emW), 12);
|
|
4427
4440
|
const cardW = Math.min(18 * em, this.w - 48);
|
|
4428
|
-
const cards = this.bonuses.map((b) => this.buildCard(b, cardW, em,
|
|
4441
|
+
const cards = this.bonuses.map((b) => this.buildCard(b, cardW, em, stack, areaH));
|
|
4429
4442
|
const cardH = Math.max(...cards.map((c) => c.height));
|
|
4430
4443
|
for (const c of cards)
|
|
4431
4444
|
c.setHeight(cardH);
|
|
@@ -4448,7 +4461,7 @@ class BuyBonusOverlay extends pixi_js.Container {
|
|
|
4448
4461
|
this.focusIndex = -1;
|
|
4449
4462
|
}
|
|
4450
4463
|
this.stripMask.clear();
|
|
4451
|
-
if (
|
|
4464
|
+
if (stack) {
|
|
4452
4465
|
// vertical stack — scroll vertically if it overflows (simple drag)
|
|
4453
4466
|
let y = 0;
|
|
4454
4467
|
const colX = (this.w - cardW) / 2;
|
|
@@ -4475,7 +4488,7 @@ class BuyBonusOverlay extends pixi_js.Container {
|
|
|
4475
4488
|
}
|
|
4476
4489
|
}
|
|
4477
4490
|
// ── one card ──────────────────────────────────────────────────────────────
|
|
4478
|
-
buildCard(bonus, cardW, em,
|
|
4491
|
+
buildCard(bonus, cardW, em, stack, areaH) {
|
|
4479
4492
|
const accent = effectiveAccent(bonus);
|
|
4480
4493
|
const ink = contrastText(accent);
|
|
4481
4494
|
const price = bonus.priceMultiplier * this.host.state.bet;
|
|
@@ -4677,7 +4690,8 @@ class BuyBonusOverlay extends pixi_js.Container {
|
|
|
4677
4690
|
* Browse phase: arrows move focus; +/- step bet; Enter/Space opens confirm; Escape closes.
|
|
4678
4691
|
* Confirm phase: Enter/Space buys/activates; Escape returns to browse. */
|
|
4679
4692
|
onKey(e) {
|
|
4680
|
-
|
|
4693
|
+
// Vertical stack (mobile / short popout) → Up/Down navigate; horizontal row → Left/Right.
|
|
4694
|
+
const stack = this.stack;
|
|
4681
4695
|
if (this.confirm && this.confirmBonus) {
|
|
4682
4696
|
// ── Confirm phase ──
|
|
4683
4697
|
switch (e.code) {
|
|
@@ -4711,8 +4725,8 @@ class BuyBonusOverlay extends pixi_js.Container {
|
|
|
4711
4725
|
return true;
|
|
4712
4726
|
}
|
|
4713
4727
|
// Determine navigation direction from key code + layout
|
|
4714
|
-
const fwdKey = e.code === 'ArrowRight' || (
|
|
4715
|
-
const bwdKey = e.code === 'ArrowLeft' || (
|
|
4728
|
+
const fwdKey = e.code === 'ArrowRight' || (stack && e.code === 'ArrowDown');
|
|
4729
|
+
const bwdKey = e.code === 'ArrowLeft' || (stack && e.code === 'ArrowUp');
|
|
4716
4730
|
if (fwdKey) {
|
|
4717
4731
|
if (last < 0)
|
|
4718
4732
|
return true;
|
|
@@ -5694,7 +5708,10 @@ class PixiRenderer {
|
|
|
5694
5708
|
get screenH() { return self.app.screen.height; },
|
|
5695
5709
|
render: () => self.renderBar(),
|
|
5696
5710
|
pushLayer: (node) => self.pushLayer(node),
|
|
5697
|
-
|
|
5711
|
+
// Route component-initiated closes through the controller (not straight to self.closeLayer) so
|
|
5712
|
+
// it clears its OverlayHandle. Otherwise the handle goes stale: hasOpenLayer() stays true and
|
|
5713
|
+
// keydowns keep routing to onKey on a destroyed overlay → write to a torn-down ScrollBox.
|
|
5714
|
+
closeLayer: () => host.actions.closeOverlay(),
|
|
5698
5715
|
fitModals: () => self.fitModals(),
|
|
5699
5716
|
fmt: (n) => host.formatCurrency(n),
|
|
5700
5717
|
fmtWin: (n) => host.formatCurrency(n, true),
|