@open-slot-ui/core 0.1.1 → 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/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 resolved = this.messages[this._locale]?.[key] ?? openuiDefaults[key] ?? key;
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 === "rules") {
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. In
1861
- * social mode, a `<key>.social` variant wins when one resolves so gambling
1862
- * wording (Bet/Buy feature) swaps to sweepstakes terms automatically. */
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). Swaps gambling wording
1873
- * (Bet/Buy feature social terms via `<key>.social` i18n) AND, when a `coin` is
1874
- * given (e.g. `'GC'`/`'SC'`/`'XGC'`), shows balance/bet/net in that coin. Wording
1875
- * re-renders live; the host can still override any `.social` key.
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 === "superTurbo" && !!j.disabledSuperTurbo || feature === "fullscreen" && !!j.disabledFullscreen || feature === "slamstop" && !!j.disabledSlamstop || feature === "spacebar" && !!j.disabledSpacebar;
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: "callout", id: "rc-body", tone: "info", text: this.t(opts.message ?? "openui.realityCheck.message", vars) }
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;