@open-slot-ui/core 0.1.1 → 0.2.0
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/index.cjs +32 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -15
- package/dist/index.d.ts +31 -15
- package/dist/index.js +32 -43
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1311,7 +1311,6 @@ function applyJurisdiction(ui, jur) {
|
|
|
1311
1311
|
lockHidden("bonus");
|
|
1312
1312
|
ui.bonusButton.disable();
|
|
1313
1313
|
}
|
|
1314
|
-
if (jur.disabledSuperTurbo && ui.turbo.modeCount > 2) ui.turbo.setModes(["off", "on"]);
|
|
1315
1314
|
if (jur.disabledSlamstop) ui.spin.allowSlamStop.set(false);
|
|
1316
1315
|
if (jur.disabledSpacebar) {
|
|
1317
1316
|
ui.spin.holdToSpin = false;
|
|
@@ -1385,13 +1384,6 @@ var openuiDefaults = {
|
|
|
1385
1384
|
"openui.buyFeature.title": "Buy feature",
|
|
1386
1385
|
"openui.buyFeature.message": "Buy this feature now?",
|
|
1387
1386
|
"openui.freeSpins": "FS",
|
|
1388
|
-
// ── social / sweepstakes wording (used when `ui.social` is on; see OpenUI.t) ──
|
|
1389
|
-
// open-ui resolves `<key>.social` first in social mode, falling back to the base
|
|
1390
|
-
// key. These are the gambling-loaded terms a sweepstakes jurisdiction must avoid;
|
|
1391
|
-
// override any of them (or add `openui.bet.social` etc.) in your messages dict.
|
|
1392
|
-
"openui.buyFeature.title.social": "Play bonus",
|
|
1393
|
-
"openui.buyFeature.message.social": "Play this bonus now?",
|
|
1394
|
-
"openui.win.social": "Prize",
|
|
1395
1387
|
// reality check (RTS 13) — {{minutes}} is interpolated by open-ui's scheduler
|
|
1396
1388
|
"openui.realityCheck.title": "Reality check",
|
|
1397
1389
|
"openui.realityCheck.message": "You've been playing for {{minutes}} minutes. Take a moment before continuing.",
|
|
@@ -1413,17 +1405,27 @@ var openuiDefaults = {
|
|
|
1413
1405
|
"openui.err.connection.title": "Connection lost",
|
|
1414
1406
|
"openui.err.connection.message": "A stable connection is required. Reload to finish any open round."
|
|
1415
1407
|
};
|
|
1408
|
+
var openuiSocialDefaults = {
|
|
1409
|
+
"openui.bet": "Play",
|
|
1410
|
+
"openui.balance": "Credits",
|
|
1411
|
+
"openui.win": "Prize",
|
|
1412
|
+
"openui.buyFeature.title": "Play bonus",
|
|
1413
|
+
"openui.buyFeature.message": "Play this bonus now?"
|
|
1414
|
+
};
|
|
1416
1415
|
function interpolate(template, vars) {
|
|
1417
1416
|
if (!vars) return template;
|
|
1418
1417
|
return template.replace(/\{\{(\w+)\}\}/g, (_m, k) => String(vars[k] ?? `{{${k}}}`));
|
|
1419
1418
|
}
|
|
1420
1419
|
var DictionaryTranslator = class {
|
|
1421
|
-
constructor(messages, locale) {
|
|
1420
|
+
constructor(messages, locale, socialMessages = {}) {
|
|
1422
1421
|
this.messages = messages;
|
|
1422
|
+
this.socialMessages = socialMessages;
|
|
1423
1423
|
this._locale = locale;
|
|
1424
1424
|
}
|
|
1425
1425
|
messages;
|
|
1426
|
+
socialMessages;
|
|
1426
1427
|
_locale;
|
|
1428
|
+
_social = false;
|
|
1427
1429
|
subs = /* @__PURE__ */ new Set();
|
|
1428
1430
|
get locale() {
|
|
1429
1431
|
return this._locale;
|
|
@@ -1433,8 +1435,12 @@ var DictionaryTranslator = class {
|
|
|
1433
1435
|
this._locale = next;
|
|
1434
1436
|
for (const cb of [...this.subs]) cb(next);
|
|
1435
1437
|
}
|
|
1438
|
+
setSocial(on) {
|
|
1439
|
+
this._social = on;
|
|
1440
|
+
}
|
|
1436
1441
|
t(key, vars) {
|
|
1437
|
-
const
|
|
1442
|
+
const social = this._social ? this.socialMessages[this._locale]?.[key] ?? openuiSocialDefaults[key] : void 0;
|
|
1443
|
+
const resolved = social ?? this.messages[this._locale]?.[key] ?? openuiDefaults[key] ?? key;
|
|
1438
1444
|
return interpolate(resolved, vars);
|
|
1439
1445
|
}
|
|
1440
1446
|
onChange(cb) {
|
|
@@ -1444,8 +1450,8 @@ var DictionaryTranslator = class {
|
|
|
1444
1450
|
};
|
|
1445
1451
|
}
|
|
1446
1452
|
};
|
|
1447
|
-
function dictionary(messages, locale) {
|
|
1448
|
-
return new DictionaryTranslator(messages, locale);
|
|
1453
|
+
function dictionary(messages, locale, socialMessages) {
|
|
1454
|
+
return new DictionaryTranslator(messages, locale, socialMessages);
|
|
1449
1455
|
}
|
|
1450
1456
|
|
|
1451
1457
|
// src/format/currency.ts
|
|
@@ -1551,9 +1557,6 @@ var OpenUI = class {
|
|
|
1551
1557
|
settingsPanel;
|
|
1552
1558
|
musicSlider;
|
|
1553
1559
|
sfxSlider;
|
|
1554
|
-
rulesButton;
|
|
1555
|
-
infoPanel;
|
|
1556
|
-
infoClose;
|
|
1557
1560
|
turbo;
|
|
1558
1561
|
autoplay;
|
|
1559
1562
|
bonusButton;
|
|
@@ -1608,9 +1611,6 @@ var OpenUI = class {
|
|
|
1608
1611
|
);
|
|
1609
1612
|
this.musicSlider = new SliderControl({ id: "music", label: "Music", layout: { anchor: "center" }, initial: 0.7 }, this.bus);
|
|
1610
1613
|
this.sfxSlider = new SliderControl({ id: "sfx", label: "Sound", layout: { anchor: "center" }, initial: 0.5 }, this.bus);
|
|
1611
|
-
this.rulesButton = new ButtonControl({ id: "rules", label: "Rules", layout: { anchor: "center" } }, this.bus);
|
|
1612
|
-
this.infoPanel = new PanelControl({ id: "info-panel", variant: "modal", title: "Game Info", layout: { anchor: "center" } }, this.bus);
|
|
1613
|
-
this.infoClose = new ButtonControl({ id: "info-close", layout: { anchor: "top-right" } }, this.bus);
|
|
1614
1614
|
this.bonusButton = new ButtonControl({ id: "bonus", layout: { anchor: "bottom-center", offset: [-400, -440] } }, this.bus);
|
|
1615
1615
|
this.autoplay = new AutoplayControl(
|
|
1616
1616
|
{ id: "autoplay", layout: { anchor: "bottom-center", offset: [-225, -440] }, options: [5, 10, 25, 50, 100, Infinity] },
|
|
@@ -1634,9 +1634,6 @@ var OpenUI = class {
|
|
|
1634
1634
|
this.settingsPanel,
|
|
1635
1635
|
this.musicSlider,
|
|
1636
1636
|
this.sfxSlider,
|
|
1637
|
-
this.rulesButton,
|
|
1638
|
-
this.infoPanel,
|
|
1639
|
-
this.infoClose,
|
|
1640
1637
|
this.bonusButton,
|
|
1641
1638
|
this.autoplay,
|
|
1642
1639
|
this.turbo,
|
|
@@ -1657,12 +1654,7 @@ var OpenUI = class {
|
|
|
1657
1654
|
this.hidden.add("session-timer");
|
|
1658
1655
|
this.bus.on("buttonActivated", ({ id }) => {
|
|
1659
1656
|
if (id === "settings") this.settingsPanel.toggle();
|
|
1660
|
-
else if (id === "
|
|
1661
|
-
this.settingsPanel.closePanel();
|
|
1662
|
-
this.infoPanel.openPanel();
|
|
1663
|
-
} else if (id === "info-close") {
|
|
1664
|
-
this.infoPanel.closePanel();
|
|
1665
|
-
} else if (id === "bet-plus") {
|
|
1657
|
+
else if (id === "bet-plus") {
|
|
1666
1658
|
this.betStepper.inc();
|
|
1667
1659
|
} else if (id === "bet-minus") {
|
|
1668
1660
|
this.betStepper.dec();
|
|
@@ -1857,26 +1849,23 @@ var OpenUI = class {
|
|
|
1857
1849
|
setLocale(next) {
|
|
1858
1850
|
this.translator.setLocale(next);
|
|
1859
1851
|
}
|
|
1860
|
-
/** Translate a key (or pass plain text through) via the active translator.
|
|
1861
|
-
*
|
|
1862
|
-
*
|
|
1852
|
+
/** Translate a key (or pass plain text through) via the active translator. Social
|
|
1853
|
+
* wording is resolved by the translator from a SEPARATE social dictionary (see
|
|
1854
|
+
* `setSocial`), so gambling and social copy can never be mixed by accident. */
|
|
1863
1855
|
t(key, vars) {
|
|
1864
|
-
if (this.social.get()) {
|
|
1865
|
-
const sk = `${key}.social`;
|
|
1866
|
-
const s = this.translator.t(sk, vars);
|
|
1867
|
-
if (s !== sk) return s;
|
|
1868
|
-
}
|
|
1869
1856
|
return this.translator.t(key, vars);
|
|
1870
1857
|
}
|
|
1871
1858
|
/**
|
|
1872
|
-
* Turn social / sweepstakes mode on or off (one switch).
|
|
1873
|
-
* (Bet
|
|
1874
|
-
* given (e.g. `'GC'`/`'SC'
|
|
1875
|
-
* re-renders live
|
|
1859
|
+
* Turn social / sweepstakes mode on or off (one switch). Flips the translator to
|
|
1860
|
+
* its SEPARATE social dictionary (Bet→Play, Buy feature→Play bonus, etc.) and,
|
|
1861
|
+
* when a `coin` is given (e.g. `'GC'`/`'SC'`), shows balance/bet/net in that coin.
|
|
1862
|
+
* Wording re-renders live. Social copy lives in `locale.socialMessages` — kept
|
|
1863
|
+
* apart from your normal `locale.messages` by design.
|
|
1876
1864
|
*/
|
|
1877
1865
|
setSocial(on, coin) {
|
|
1878
1866
|
if (on !== this.social.get()) {
|
|
1879
1867
|
this.social.set(on);
|
|
1868
|
+
this.translator.setSocial?.(on);
|
|
1880
1869
|
this.locale.update(() => {
|
|
1881
1870
|
});
|
|
1882
1871
|
}
|
|
@@ -1891,7 +1880,7 @@ var OpenUI = class {
|
|
|
1891
1880
|
* just a hide — `confirmBuy`/autoplay entry points consult this). */
|
|
1892
1881
|
isDisabled(feature) {
|
|
1893
1882
|
const j = this.jurisdiction;
|
|
1894
|
-
return feature === "autoplay" && !!j.disabledAutoplay || feature === "buyFeature" && !!j.disabledBuyFeature || feature === "turbo" && !!j.disabledTurbo || feature === "
|
|
1883
|
+
return feature === "autoplay" && !!j.disabledAutoplay || feature === "buyFeature" && !!j.disabledBuyFeature || feature === "turbo" && !!j.disabledTurbo || feature === "fullscreen" && !!j.disabledFullscreen || feature === "slamstop" && !!j.disabledSlamstop || feature === "spacebar" && !!j.disabledSpacebar;
|
|
1895
1884
|
}
|
|
1896
1885
|
/**
|
|
1897
1886
|
* Start a reality-check reminder (RTS 13). Every `everyMinutes` (WALL-CLOCK, so a
|
|
@@ -1935,7 +1924,7 @@ var OpenUI = class {
|
|
|
1935
1924
|
this.showNotice(
|
|
1936
1925
|
[
|
|
1937
1926
|
{ kind: "heading", id: "rc-title", text: this.t(opts.title ?? "openui.realityCheck.title", vars) },
|
|
1938
|
-
{ kind: "
|
|
1927
|
+
{ kind: "text", id: "rc-body", text: this.t(opts.message ?? "openui.realityCheck.message", vars) }
|
|
1939
1928
|
],
|
|
1940
1929
|
opts.actions ?? [{ label: "openui.continue", variant: "primary" }]
|
|
1941
1930
|
);
|
|
@@ -2024,7 +2013,7 @@ var ANALYTICS_EVENTS = [
|
|
|
2024
2013
|
function createUI(spec = {}, hooks = {}) {
|
|
2025
2014
|
const { issues } = validateSpec(spec);
|
|
2026
2015
|
for (const issue of issues) hooks.onDataIssue?.(issue);
|
|
2027
|
-
const translator = spec.locale ? new DictionaryTranslator(spec.locale.messages, spec.locale.locale) : void 0;
|
|
2016
|
+
const translator = spec.locale ? new DictionaryTranslator(spec.locale.messages, spec.locale.locale, spec.locale.socialMessages) : void 0;
|
|
2028
2017
|
const theme = resolveTheme(spec.theme, (i) => hooks.onDataIssue?.(i));
|
|
2029
2018
|
const ui = new OpenUI({ theme, layout: spec.layout, translator, startMuted: spec.audio?.startMuted });
|
|
2030
2019
|
if (spec.currency) {
|
|
@@ -2314,6 +2303,7 @@ exports.integerDigits = integerDigits;
|
|
|
2314
2303
|
exports.isSafeColor = isSafeColor;
|
|
2315
2304
|
exports.isSocialCurrency = isSocialCurrency;
|
|
2316
2305
|
exports.openuiDefaults = openuiDefaults;
|
|
2306
|
+
exports.openuiSocialDefaults = openuiSocialDefaults;
|
|
2317
2307
|
exports.resolveCurrency = resolveCurrency;
|
|
2318
2308
|
exports.resolvePlacement = resolvePlacement;
|
|
2319
2309
|
exports.resolveTheme = resolveTheme;
|