@lumiastream/ui 0.2.9 → 0.3.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.js CHANGED
@@ -3129,7 +3129,13 @@ var SE_TO_LUMIA_PLACEHOLDER = {
3129
3129
  item: "firstItem.name",
3130
3130
  count: "amount",
3131
3131
  total: "total",
3132
- gifts: "giftAmount"
3132
+ gifts: "giftAmount",
3133
+ // Platform-agnostic streamer identity — SE exposes `{streamer}` in static
3134
+ // widgets and alert bodies. Lumia has no event-scoped equivalent (it's not
3135
+ // tied to an alert payload), so we route it at the *global* template
3136
+ // variable `{{streamer}}` populated by VariablesManager.refreshStreamerVariable
3137
+ // (Twitch → Kick → YouTube → Facebook → TikTok fallback chain).
3138
+ streamer: "streamer"
3133
3139
  };
3134
3140
  var TWITCH_CONTEXTS = {
3135
3141
  "follower-latest": { name: "twitch_last_follower", username: "twitch_last_follower" },
@@ -4252,6 +4258,63 @@ import {
4252
4258
  LumiaEventListTypes,
4253
4259
  LumiaMapAlertTypeToEventListType
4254
4260
  } from "@lumiastream/lumia-types";
4261
+
4262
+ // src/se-import/mappers/module-defaults.ts
4263
+ var CHATBOX_DEFAULT_CONTENT_FIELDS = {
4264
+ type: "lumia",
4265
+ src: "",
4266
+ userLevels: [1, 2, 3, 4, 5, 6, 7, 8, 9],
4267
+ permanent: true,
4268
+ maxItemsToShow: 20,
4269
+ removeAfter: 3e4,
4270
+ animations: {
4271
+ enterAnimation: "fadeIn",
4272
+ exitAnimation: "fadeOut",
4273
+ enterAnimationDuration: 1e3,
4274
+ exitAnimationDuration: 1e3,
4275
+ enterAnimationDelay: 0,
4276
+ exitAnimationDelay: 0
4277
+ },
4278
+ ignoredList: [],
4279
+ background: "transparent",
4280
+ theme: "simple",
4281
+ chatboxStreamingSite: {
4282
+ twitch: { message: "", icon: "", themeConfig: { primaryColor: "#915dff", showUsernameColors: true } },
4283
+ youtube: { message: "", icon: "", themeConfig: { primaryColor: "#ff0000", usePlatformColor: false } },
4284
+ facebook: { message: "", icon: "", themeConfig: { primaryColor: "#4267B2", usePlatformColor: false } },
4285
+ tiktok: { message: "", icon: "", themeConfig: { primaryColor: "#ff0050", usePlatformColor: false } },
4286
+ kick: { message: "", icon: "", themeConfig: { primaryColor: "#3AD305", usePlatformColor: false } },
4287
+ discord: { message: "", icon: "", themeConfig: { primaryColor: "#7289da", usePlatformColor: false } }
4288
+ },
4289
+ borderRadius: "10px",
4290
+ bgOpacity: 0.4,
4291
+ ignoredStreamingSites: [],
4292
+ horizontal: false,
4293
+ reverseFlow: false,
4294
+ showBadges: true,
4295
+ showSiteIcon: false,
4296
+ showEmotes: true,
4297
+ showAvatar: false,
4298
+ showTimestamp: false,
4299
+ hideAlerts: false,
4300
+ hyperClickableLinks: true,
4301
+ clickableChatterProfiles: false,
4302
+ previewMediaInChat: true,
4303
+ previewMediaUserLevels: ["streamer", "moderators", "vips", "tier3", "tier2", "subscribers", "regular", "follower", "anyone"],
4304
+ breakLine: true,
4305
+ fadeOutAfterDelay: false,
4306
+ fadeOutDelayTime: 5,
4307
+ useAnimatedEmotes: true,
4308
+ sites: ["twitch", "kick", "youtube", "facebook", "discord", "ffz", "seventv", "bttv"],
4309
+ border: "solid 1px transparent",
4310
+ itemGap: 8
4311
+ };
4312
+ var CHATBOX_DEFAULT_MODULE = {
4313
+ version: 7,
4314
+ content: CHATBOX_DEFAULT_CONTENT_FIELDS
4315
+ };
4316
+
4317
+ // src/se-import/mappers/misc.ts
4255
4318
  function mapChatboxTheme(seTheme) {
4256
4319
  const t = (seTheme ?? "").toString().toLowerCase();
4257
4320
  if (!t || t === "default") return "simple";
@@ -4311,6 +4374,8 @@ function paddingShorthand(message) {
4311
4374
  return `${px(t)} ${px(r)} ${px(b)} ${px(l)}`;
4312
4375
  }
4313
4376
  function mapChatbox(widget, ctx) {
4377
+ const chatboxDefaults = CHATBOX_DEFAULT_MODULE.content;
4378
+ const chatboxVersion = CHATBOX_DEFAULT_MODULE.version;
4314
4379
  const v = widget.variables ?? {};
4315
4380
  const textCss = widget.text?.css ?? {};
4316
4381
  const messageCss = textCss.message ?? {};
@@ -4345,59 +4410,58 @@ function mapChatbox(widget, ctx) {
4345
4410
  widget,
4346
4411
  "chatbox",
4347
4412
  {
4413
+ // Stamp the module version from the authoritative defaults so
4414
+ // Overlay-UI's per-module Settings.tsx migration check
4415
+ // (`module?.version !== currentVersion`) treats this import as
4416
+ // already-current. Without this, every freshly-imported chatbox
4417
+ // would trip the migration toast on first open even though the
4418
+ // content is already complete.
4419
+ version: chatboxVersion,
4348
4420
  // Visual styling (font / color / padding etc) lives on module.css, not
4349
4421
  // content. Lumia's TextStyle settings panel + the chatbox renderer both
4350
4422
  // read from here.
4351
4423
  css: moduleCss,
4352
4424
  content: {
4425
+ // `chatboxDefaults` resolves host-injected first (preferred), then
4426
+ // the local snapshot — see the top of this function. Spreading it
4427
+ // here guarantees every field the chatbox renderer expects is
4428
+ // present (`type`, `sites`, `useAnimatedEmotes`, etc.); the
4429
+ // SE-specific override block below wins for the opinions that
4430
+ // differ from a fresh-add.
4431
+ ...chatboxDefaults,
4432
+ // ─── SE-specific overrides ────────────────────────────────────────
4433
+ // The fresh-Lumia defaults assume the streamer is creating a new
4434
+ // chatbox; SE-imported ones have opinions that differ. Override
4435
+ // only those.
4353
4436
  theme: mapChatboxTheme(v.theme),
4354
4437
  fadeOutAfterDelay: fadeOutSeconds > 0,
4355
4438
  fadeOutDelayTime: fadeOutSeconds,
4356
- // Defaults Lumia's chatbox renderer + UI expect on every module.
4357
- // Without these the chatbox silently dropped messages (the
4358
- // `ignoredStreamingSites` truthy gate), rendered in the wrong
4359
- // theme (no theme → blank list), or showed missing controls in
4360
- // settings. `ignoredList` carries SE's per-user ignore list across.
4361
4439
  ignoredList: Array.isArray(v.ignored) ? v.ignored : [],
4362
- ignoredStreamingSites: [],
4363
- horizontal: false,
4364
- reverseFlow: false,
4365
- hideAlerts: false,
4366
- hideAlertMessage: false,
4440
+ // SE chat widgets default to showing avatars + site icons + tight
4441
+ // line wrapping; Lumia's fresh default is the opposite.
4367
4442
  showAvatar: true,
4368
- showBadges: true,
4369
- showEmotes: true,
4370
4443
  showSiteIcon: true,
4371
- showTimestamp: false,
4372
4444
  breakLine: false,
4373
- hyperClickableLinks: true,
4374
4445
  clickableChatterProfiles: true,
4375
- previewMediaInChat: true,
4376
- maxItemsToShow: 20,
4377
- removeAfter: 3e4,
4378
- itemGap: 8,
4379
- borderRadius: "10px",
4380
- bgOpacity: 0.4,
4381
- animations: {
4382
- enterAnimation: "fadeIn",
4383
- exitAnimation: "fadeOut",
4384
- enterAnimationDuration: 1e3,
4385
- exitAnimationDuration: 1e3,
4386
- enterAnimationDelay: 0,
4387
- exitAnimationDelay: 0
4388
- },
4446
+ hideAlertMessage: false,
4389
4447
  // Carry the SE message-level font override and the streamer's
4390
4448
  // accent color across so the imported chatbox looks right at
4391
4449
  // first paint. Background lives on `module.css.background`
4392
4450
  // above — `content.background` was a dead write the renderer
4393
4451
  // never read.
4394
4452
  ...messageFontFamily ? { messageFontFamily } : {},
4453
+ // Twitch primary color override — deep-merge into the full
4454
+ // chatboxStreamingSite map from the default (otherwise we'd
4455
+ // clobber the youtube/kick/facebook/tiktok/discord entries the
4456
+ // chatbox renderer reads for per-platform theming).
4395
4457
  ...accentColor ? {
4396
4458
  chatboxStreamingSite: {
4459
+ ...chatboxDefaults.chatboxStreamingSite,
4397
4460
  twitch: {
4461
+ ...chatboxDefaults.chatboxStreamingSite.twitch,
4398
4462
  themeConfig: {
4399
- primaryColor: accentColor,
4400
- showUsernameColors: true
4463
+ ...chatboxDefaults.chatboxStreamingSite.twitch.themeConfig,
4464
+ primaryColor: accentColor
4401
4465
  }
4402
4466
  }
4403
4467
  }
@@ -8472,7 +8536,11 @@ function SEImportWizard({
8472
8536
  );
8473
8537
  mirrorAbortRef.current?.abort();
8474
8538
  onClose();
8475
- if (lastUuid) onComplete({ overlayId: lastUuid });
8539
+ if (importsToSave.length === 1 && lastUuid) {
8540
+ onComplete({ overlayId: lastUuid });
8541
+ } else if (importsToSave.length > 1) {
8542
+ onComplete({});
8543
+ }
8476
8544
  } catch (error) {
8477
8545
  notify.error(`Import failed: ${extractErrorMessage(error)}`);
8478
8546
  } finally {
@@ -342,7 +342,7 @@ interface SEImportBindings {
342
342
  uuid: string;
343
343
  }>;
344
344
  onComplete: (result: {
345
- overlayId: string;
345
+ overlayId?: string;
346
346
  }) => void;
347
347
  onOverlayImported?: (result: {
348
348
  overlayId: string;
package/dist/se-import.js CHANGED
@@ -14,7 +14,13 @@ var SE_TO_LUMIA_PLACEHOLDER = {
14
14
  item: "firstItem.name",
15
15
  count: "amount",
16
16
  total: "total",
17
- gifts: "giftAmount"
17
+ gifts: "giftAmount",
18
+ // Platform-agnostic streamer identity — SE exposes `{streamer}` in static
19
+ // widgets and alert bodies. Lumia has no event-scoped equivalent (it's not
20
+ // tied to an alert payload), so we route it at the *global* template
21
+ // variable `{{streamer}}` populated by VariablesManager.refreshStreamerVariable
22
+ // (Twitch → Kick → YouTube → Facebook → TikTok fallback chain).
23
+ streamer: "streamer"
18
24
  };
19
25
  var TWITCH_CONTEXTS = {
20
26
  "follower-latest": { name: "twitch_last_follower", username: "twitch_last_follower" },
@@ -1137,6 +1143,63 @@ import {
1137
1143
  LumiaEventListTypes,
1138
1144
  LumiaMapAlertTypeToEventListType
1139
1145
  } from "@lumiastream/lumia-types";
1146
+
1147
+ // src/se-import/mappers/module-defaults.ts
1148
+ var CHATBOX_DEFAULT_CONTENT_FIELDS = {
1149
+ type: "lumia",
1150
+ src: "",
1151
+ userLevels: [1, 2, 3, 4, 5, 6, 7, 8, 9],
1152
+ permanent: true,
1153
+ maxItemsToShow: 20,
1154
+ removeAfter: 3e4,
1155
+ animations: {
1156
+ enterAnimation: "fadeIn",
1157
+ exitAnimation: "fadeOut",
1158
+ enterAnimationDuration: 1e3,
1159
+ exitAnimationDuration: 1e3,
1160
+ enterAnimationDelay: 0,
1161
+ exitAnimationDelay: 0
1162
+ },
1163
+ ignoredList: [],
1164
+ background: "transparent",
1165
+ theme: "simple",
1166
+ chatboxStreamingSite: {
1167
+ twitch: { message: "", icon: "", themeConfig: { primaryColor: "#915dff", showUsernameColors: true } },
1168
+ youtube: { message: "", icon: "", themeConfig: { primaryColor: "#ff0000", usePlatformColor: false } },
1169
+ facebook: { message: "", icon: "", themeConfig: { primaryColor: "#4267B2", usePlatformColor: false } },
1170
+ tiktok: { message: "", icon: "", themeConfig: { primaryColor: "#ff0050", usePlatformColor: false } },
1171
+ kick: { message: "", icon: "", themeConfig: { primaryColor: "#3AD305", usePlatformColor: false } },
1172
+ discord: { message: "", icon: "", themeConfig: { primaryColor: "#7289da", usePlatformColor: false } }
1173
+ },
1174
+ borderRadius: "10px",
1175
+ bgOpacity: 0.4,
1176
+ ignoredStreamingSites: [],
1177
+ horizontal: false,
1178
+ reverseFlow: false,
1179
+ showBadges: true,
1180
+ showSiteIcon: false,
1181
+ showEmotes: true,
1182
+ showAvatar: false,
1183
+ showTimestamp: false,
1184
+ hideAlerts: false,
1185
+ hyperClickableLinks: true,
1186
+ clickableChatterProfiles: false,
1187
+ previewMediaInChat: true,
1188
+ previewMediaUserLevels: ["streamer", "moderators", "vips", "tier3", "tier2", "subscribers", "regular", "follower", "anyone"],
1189
+ breakLine: true,
1190
+ fadeOutAfterDelay: false,
1191
+ fadeOutDelayTime: 5,
1192
+ useAnimatedEmotes: true,
1193
+ sites: ["twitch", "kick", "youtube", "facebook", "discord", "ffz", "seventv", "bttv"],
1194
+ border: "solid 1px transparent",
1195
+ itemGap: 8
1196
+ };
1197
+ var CHATBOX_DEFAULT_MODULE = {
1198
+ version: 7,
1199
+ content: CHATBOX_DEFAULT_CONTENT_FIELDS
1200
+ };
1201
+
1202
+ // src/se-import/mappers/misc.ts
1140
1203
  function mapChatboxTheme(seTheme) {
1141
1204
  const t = (seTheme ?? "").toString().toLowerCase();
1142
1205
  if (!t || t === "default") return "simple";
@@ -1196,6 +1259,8 @@ function paddingShorthand(message) {
1196
1259
  return `${px(t)} ${px(r)} ${px(b)} ${px(l)}`;
1197
1260
  }
1198
1261
  function mapChatbox(widget, ctx) {
1262
+ const chatboxDefaults = CHATBOX_DEFAULT_MODULE.content;
1263
+ const chatboxVersion = CHATBOX_DEFAULT_MODULE.version;
1199
1264
  const v = widget.variables ?? {};
1200
1265
  const textCss = widget.text?.css ?? {};
1201
1266
  const messageCss = textCss.message ?? {};
@@ -1230,59 +1295,58 @@ function mapChatbox(widget, ctx) {
1230
1295
  widget,
1231
1296
  "chatbox",
1232
1297
  {
1298
+ // Stamp the module version from the authoritative defaults so
1299
+ // Overlay-UI's per-module Settings.tsx migration check
1300
+ // (`module?.version !== currentVersion`) treats this import as
1301
+ // already-current. Without this, every freshly-imported chatbox
1302
+ // would trip the migration toast on first open even though the
1303
+ // content is already complete.
1304
+ version: chatboxVersion,
1233
1305
  // Visual styling (font / color / padding etc) lives on module.css, not
1234
1306
  // content. Lumia's TextStyle settings panel + the chatbox renderer both
1235
1307
  // read from here.
1236
1308
  css: moduleCss,
1237
1309
  content: {
1310
+ // `chatboxDefaults` resolves host-injected first (preferred), then
1311
+ // the local snapshot — see the top of this function. Spreading it
1312
+ // here guarantees every field the chatbox renderer expects is
1313
+ // present (`type`, `sites`, `useAnimatedEmotes`, etc.); the
1314
+ // SE-specific override block below wins for the opinions that
1315
+ // differ from a fresh-add.
1316
+ ...chatboxDefaults,
1317
+ // ─── SE-specific overrides ────────────────────────────────────────
1318
+ // The fresh-Lumia defaults assume the streamer is creating a new
1319
+ // chatbox; SE-imported ones have opinions that differ. Override
1320
+ // only those.
1238
1321
  theme: mapChatboxTheme(v.theme),
1239
1322
  fadeOutAfterDelay: fadeOutSeconds > 0,
1240
1323
  fadeOutDelayTime: fadeOutSeconds,
1241
- // Defaults Lumia's chatbox renderer + UI expect on every module.
1242
- // Without these the chatbox silently dropped messages (the
1243
- // `ignoredStreamingSites` truthy gate), rendered in the wrong
1244
- // theme (no theme → blank list), or showed missing controls in
1245
- // settings. `ignoredList` carries SE's per-user ignore list across.
1246
1324
  ignoredList: Array.isArray(v.ignored) ? v.ignored : [],
1247
- ignoredStreamingSites: [],
1248
- horizontal: false,
1249
- reverseFlow: false,
1250
- hideAlerts: false,
1251
- hideAlertMessage: false,
1325
+ // SE chat widgets default to showing avatars + site icons + tight
1326
+ // line wrapping; Lumia's fresh default is the opposite.
1252
1327
  showAvatar: true,
1253
- showBadges: true,
1254
- showEmotes: true,
1255
1328
  showSiteIcon: true,
1256
- showTimestamp: false,
1257
1329
  breakLine: false,
1258
- hyperClickableLinks: true,
1259
1330
  clickableChatterProfiles: true,
1260
- previewMediaInChat: true,
1261
- maxItemsToShow: 20,
1262
- removeAfter: 3e4,
1263
- itemGap: 8,
1264
- borderRadius: "10px",
1265
- bgOpacity: 0.4,
1266
- animations: {
1267
- enterAnimation: "fadeIn",
1268
- exitAnimation: "fadeOut",
1269
- enterAnimationDuration: 1e3,
1270
- exitAnimationDuration: 1e3,
1271
- enterAnimationDelay: 0,
1272
- exitAnimationDelay: 0
1273
- },
1331
+ hideAlertMessage: false,
1274
1332
  // Carry the SE message-level font override and the streamer's
1275
1333
  // accent color across so the imported chatbox looks right at
1276
1334
  // first paint. Background lives on `module.css.background`
1277
1335
  // above — `content.background` was a dead write the renderer
1278
1336
  // never read.
1279
1337
  ...messageFontFamily ? { messageFontFamily } : {},
1338
+ // Twitch primary color override — deep-merge into the full
1339
+ // chatboxStreamingSite map from the default (otherwise we'd
1340
+ // clobber the youtube/kick/facebook/tiktok/discord entries the
1341
+ // chatbox renderer reads for per-platform theming).
1280
1342
  ...accentColor ? {
1281
1343
  chatboxStreamingSite: {
1344
+ ...chatboxDefaults.chatboxStreamingSite,
1282
1345
  twitch: {
1346
+ ...chatboxDefaults.chatboxStreamingSite.twitch,
1283
1347
  themeConfig: {
1284
- primaryColor: accentColor,
1285
- showUsernameColors: true
1348
+ ...chatboxDefaults.chatboxStreamingSite.twitch.themeConfig,
1349
+ primaryColor: accentColor
1286
1350
  }
1287
1351
  }
1288
1352
  }
@@ -7342,7 +7406,11 @@ function SEImportWizard({
7342
7406
  );
7343
7407
  mirrorAbortRef.current?.abort();
7344
7408
  onClose();
7345
- if (lastUuid) onComplete({ overlayId: lastUuid });
7409
+ if (importsToSave.length === 1 && lastUuid) {
7410
+ onComplete({ overlayId: lastUuid });
7411
+ } else if (importsToSave.length > 1) {
7412
+ onComplete({});
7413
+ }
7346
7414
  } catch (error) {
7347
7415
  notify.error(`Import failed: ${extractErrorMessage(error)}`);
7348
7416
  } finally {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumiastream/ui",
3
- "version": "0.2.9",
3
+ "version": "0.3.0",
4
4
  "author": "Lumia Stream",
5
5
  "license": "ISC",
6
6
  "description": "Lumia UI Kit",
@@ -91,7 +91,8 @@
91
91
  "test:watch": "vitest",
92
92
  "release": "changeset && changeset tag && npm run build && npm publish",
93
93
  "prepublishOnly": "npm run build",
94
- "postpublish": "npm cache clean --force && node ./scripts/postpublish-install.mjs"
94
+ "postpublish": "npm cache clean --force && node ./scripts/postpublish-install.mjs",
95
+ "check-module-defaults": "tsx scripts/check-module-defaults.ts"
95
96
  },
96
97
  "peerDependencies": {
97
98
  "@codemirror/autocomplete": "^6.0.0",
@@ -121,12 +122,13 @@
121
122
  "sass-embedded": "^1.99.0",
122
123
  "storybook": "^10.2.17",
123
124
  "tsup": "^8.5.1",
125
+ "tsx": "^4.22.3",
124
126
  "typescript": "^5.9.3",
125
127
  "vite": "^8.0.8",
126
128
  "vitest": "^4.1.6"
127
129
  },
128
130
  "dependencies": {
129
- "@lumiastream/lumia-translations": "1.15.8",
131
+ "@lumiastream/lumia-translations": "1.15.9",
130
132
  "@lumiastream/lumia-types": "^3.3.7-alpha.2",
131
133
  "classnames": "^2.5.1",
132
134
  "globals": "^17.4.0",