@lumiastream/ui 0.2.8-alpha.26 → 0.2.8-alpha.27

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
@@ -3226,9 +3226,17 @@ var YOUTUBE_CONTEXTS = {
3226
3226
  "subscriber-week": { amount: "youtube_week_member_count", count: "youtube_week_member_count" },
3227
3227
  "subscriber-month": { amount: "youtube_month_member_count", count: "youtube_month_member_count" }
3228
3228
  };
3229
+ var RECENT_TO_LATEST_LISTENER = {
3230
+ "follower-recent": "follower-latest",
3231
+ "subscriber-recent": "subscriber-latest",
3232
+ "cheer-recent": "cheer-latest",
3233
+ "tip-recent": "tip-latest",
3234
+ "raid-recent": "raid-latest"
3235
+ };
3229
3236
  function listenerPlaceholderContext(listener, provider = "twitch") {
3237
+ const resolved = RECENT_TO_LATEST_LISTENER[listener] ?? listener;
3230
3238
  const platformTable = provider === "kick" ? KICK_CONTEXTS : provider === "youtube" ? YOUTUBE_CONTEXTS : null;
3231
- return platformTable?.[listener] ?? TWITCH_CONTEXTS[listener] ?? {};
3239
+ return platformTable?.[resolved] ?? TWITCH_CONTEXTS[resolved] ?? {};
3232
3240
  }
3233
3241
  var SE_WIDGET_TYPE_LABELS = {
3234
3242
  "subscriber-latest": "Latest subscriber",
@@ -3313,8 +3321,9 @@ var YOUTUBE_LISTENER_VARS = {
3313
3321
  };
3314
3322
  function listenerToLumiaVariable(listener, provider = "twitch") {
3315
3323
  if (typeof listener !== "string" || !listener) return "username";
3316
- if (provider === "kick" && KICK_LISTENER_VARS[listener]) return KICK_LISTENER_VARS[listener];
3317
- if (provider === "youtube" && YOUTUBE_LISTENER_VARS[listener]) return YOUTUBE_LISTENER_VARS[listener];
3324
+ const resolvedListener = RECENT_TO_LATEST_LISTENER[listener] ?? listener;
3325
+ if (provider === "kick" && KICK_LISTENER_VARS[resolvedListener]) return KICK_LISTENER_VARS[resolvedListener];
3326
+ if (provider === "youtube" && YOUTUBE_LISTENER_VARS[resolvedListener]) return YOUTUBE_LISTENER_VARS[resolvedListener];
3318
3327
  const m = {
3319
3328
  // Latest events
3320
3329
  "follower-latest": "twitch_last_follower",
@@ -3371,7 +3380,7 @@ function listenerToLumiaVariable(listener, provider = "twitch") {
3371
3380
  "cheer-alltime-top-donation": "twitch_alltime_top_cheerer_amount",
3372
3381
  "cheer-alltime-top-donator": "twitch_alltime_top_cheerer"
3373
3382
  };
3374
- return m[listener] ?? listener.replace(/-/g, "_");
3383
+ return m[resolvedListener] ?? resolvedListener.replace(/-/g, "_");
3375
3384
  }
3376
3385
  function seCssToBounds(css, defaults = { width: 600, height: 200 }, canvas) {
3377
3386
  let widthIsAuto = false;
@@ -4342,6 +4351,9 @@ function mapEventList(widget, ctx) {
4342
4351
  const filters = computeListenerFilters(widget.listeners, widget.listener);
4343
4352
  const maxItems = v.visibleEvents ?? v.visibleItems ?? 5;
4344
4353
  return buildUnit(widget, "eventlist", {
4354
+ // SE event-list widgets style per-event lines via widget.text.css; the
4355
+ // Lumia eventlist reads font/size/color from module.css.
4356
+ css: mapSeTextCssToModuleCss(widget, { fontSize: 18 }),
4345
4357
  content: {
4346
4358
  theme: v.theme ?? "simple",
4347
4359
  direction: v.direction ?? "top",
@@ -4775,14 +4787,10 @@ function mapMediaShare(widget, ctx) {
4775
4787
  // `durationSeconds + grace`).
4776
4788
  importMeta: buildImportMeta(widget, { timeLeft: v.timeLeft === true })
4777
4789
  },
4778
- css: {
4779
- fontFamily: "Roboto",
4780
- fontWeight: "bold",
4781
- color: "#ffffff",
4782
- textShadow: "rgb(0, 0, 0) 1px 1px 1px",
4783
- background: "transparent",
4784
- fontSize: 18
4785
- }
4790
+ // Lumia songrequest renders the queue list as styled text; pull SE's
4791
+ // widget.text.css so font/size/color carry across (defaults match the
4792
+ // previous hardcoded fallbacks for this widget specifically).
4793
+ css: mapSeTextCssToModuleCss(widget, { fontSize: 18 })
4786
4794
  }, ctx);
4787
4795
  }
4788
4796
  function mapKappagen(widget, ctx) {
@@ -4850,6 +4858,9 @@ function mapLeaderboardFromVariables(widget, currency, ctx) {
4850
4858
  const window = v.period === "weekly" ? "week" : v.period === "monthly" ? "month" : "alltime";
4851
4859
  const title = currency === "tips" ? "Top Tippers" : currency === "cheers" ? "Top Cheerers" : "Top Gifters";
4852
4860
  return buildUnit(widget, "loyaltyleaderboard", {
4861
+ // Carry SE text styling so the leaderboard list keeps the streamer's
4862
+ // chosen font / size / color.
4863
+ css: mapSeTextCssToModuleCss(widget, { fontSize: 18 }),
4853
4864
  content: {
4854
4865
  source: "variables",
4855
4866
  currency,
@@ -4876,6 +4887,8 @@ function mapGiveaway(widget, ctx) {
4876
4887
  const primary = v.colors?.primary ?? "#393853";
4877
4888
  const accent = v.colors?.accent ?? "#FF4076";
4878
4889
  return buildUnit(widget, "raffle", {
4890
+ // Raffle renders entrants/winner text via module.css.
4891
+ css: mapSeTextCssToModuleCss(widget),
4879
4892
  content: {
4880
4893
  version: 1,
4881
4894
  type: "basic",
@@ -4960,6 +4973,9 @@ function isHypetrainCustomWidget(widget) {
4960
4973
  function mapHypetrain(widget, ctx) {
4961
4974
  const v = widget.variables ?? {};
4962
4975
  return buildUnit(widget, "hypetrain", {
4976
+ // Hypetrain renders level / progress / contributor text — carry SE
4977
+ // styling so an imported hype-train widget keeps its font + accent.
4978
+ css: mapSeTextCssToModuleCss(widget),
4963
4979
  content: {
4964
4980
  // Twitch-native is the right default — SE hype-train widgets always
4965
4981
  // reflected the Twitch native train. Users can flip to 'synthetic'
@@ -5352,6 +5368,23 @@ var GOAL_TYPES = /* @__PURE__ */ new Set([
5352
5368
  "se-widget-merch-goal"
5353
5369
  ]);
5354
5370
  var EVENTLIST_TYPES = /* @__PURE__ */ new Set(["se-widget-event-list", "se-widget-follower-recent", "se-widget-subscriber-recent", "se-widget-cheer-recent", "se-widget-tip-recent"]);
5371
+ var SCROLLING_RECENT_TYPES = /* @__PURE__ */ new Set([
5372
+ "se-widget-follower-recent",
5373
+ "se-widget-subscriber-recent",
5374
+ "se-widget-cheer-recent",
5375
+ "se-widget-tip-recent"
5376
+ ]);
5377
+ var RECENT_TO_LATEST_FALLBACK_VAR = {
5378
+ "se-widget-follower-recent": "twitch_last_follower",
5379
+ "se-widget-subscriber-recent": "twitch_last_subscriber",
5380
+ "se-widget-cheer-recent": "twitch_last_bit",
5381
+ "se-widget-tip-recent": "latest_donator"
5382
+ };
5383
+ function isScrollingRecentWidget(widget) {
5384
+ if (!SCROLLING_RECENT_TYPES.has(widget.type)) return false;
5385
+ const scrolling = widget.text?.scrolling;
5386
+ return !!(scrolling && typeof scrolling === "object" && scrolling.enabled === true);
5387
+ }
5355
5388
  function dispatch(widget, ctx) {
5356
5389
  const t = widget.type;
5357
5390
  console.log("[SE-IMPORT] dispatch widget", {
@@ -5380,6 +5413,10 @@ function dispatch(widget, ctx) {
5380
5413
  if (t === "se-widget-donor-drive-alert") return { unit: mapSingleAlert(widget, "donordrive-donation", ctx), status: "direct", lumiaType: "alert" };
5381
5414
  if (t === "se-widget-extralife-alert") return { unit: mapSingleAlert(widget, "extralife-donation", ctx), status: "direct", lumiaType: "alert" };
5382
5415
  if (t === "se-widget-tiltify-alert") return { unit: mapSingleAlert(widget, "tiltify-campaignDonation", ctx), status: "direct", lumiaType: "alert" };
5416
+ if (isScrollingRecentWidget(widget)) {
5417
+ const fallbackVar = RECENT_TO_LATEST_FALLBACK_VAR[t] ?? "username";
5418
+ return { unit: mapReadout(widget, fallbackVar, ctx), status: "direct", lumiaType: "text" };
5419
+ }
5383
5420
  if (EVENTLIST_TYPES.has(t)) return { unit: mapEventList(widget, ctx), status: "direct", lumiaType: "eventlist" };
5384
5421
  if (t === "se-widget-top-tippers-list") return { unit: mapLeaderboardFromVariables(widget, "tips", ctx), status: "direct", lumiaType: "loyaltyleaderboard" };
5385
5422
  if (t === "se-widget-top-cheerers-list") return { unit: mapLeaderboardFromVariables(widget, "cheers", ctx), status: "direct", lumiaType: "loyaltyleaderboard" };
package/dist/se-import.js CHANGED
@@ -111,9 +111,17 @@ var YOUTUBE_CONTEXTS = {
111
111
  "subscriber-week": { amount: "youtube_week_member_count", count: "youtube_week_member_count" },
112
112
  "subscriber-month": { amount: "youtube_month_member_count", count: "youtube_month_member_count" }
113
113
  };
114
+ var RECENT_TO_LATEST_LISTENER = {
115
+ "follower-recent": "follower-latest",
116
+ "subscriber-recent": "subscriber-latest",
117
+ "cheer-recent": "cheer-latest",
118
+ "tip-recent": "tip-latest",
119
+ "raid-recent": "raid-latest"
120
+ };
114
121
  function listenerPlaceholderContext(listener, provider = "twitch") {
122
+ const resolved = RECENT_TO_LATEST_LISTENER[listener] ?? listener;
115
123
  const platformTable = provider === "kick" ? KICK_CONTEXTS : provider === "youtube" ? YOUTUBE_CONTEXTS : null;
116
- return platformTable?.[listener] ?? TWITCH_CONTEXTS[listener] ?? {};
124
+ return platformTable?.[resolved] ?? TWITCH_CONTEXTS[resolved] ?? {};
117
125
  }
118
126
  var SE_WIDGET_TYPE_LABELS = {
119
127
  "subscriber-latest": "Latest subscriber",
@@ -198,8 +206,9 @@ var YOUTUBE_LISTENER_VARS = {
198
206
  };
199
207
  function listenerToLumiaVariable(listener, provider = "twitch") {
200
208
  if (typeof listener !== "string" || !listener) return "username";
201
- if (provider === "kick" && KICK_LISTENER_VARS[listener]) return KICK_LISTENER_VARS[listener];
202
- if (provider === "youtube" && YOUTUBE_LISTENER_VARS[listener]) return YOUTUBE_LISTENER_VARS[listener];
209
+ const resolvedListener = RECENT_TO_LATEST_LISTENER[listener] ?? listener;
210
+ if (provider === "kick" && KICK_LISTENER_VARS[resolvedListener]) return KICK_LISTENER_VARS[resolvedListener];
211
+ if (provider === "youtube" && YOUTUBE_LISTENER_VARS[resolvedListener]) return YOUTUBE_LISTENER_VARS[resolvedListener];
203
212
  const m = {
204
213
  // Latest events
205
214
  "follower-latest": "twitch_last_follower",
@@ -256,7 +265,7 @@ function listenerToLumiaVariable(listener, provider = "twitch") {
256
265
  "cheer-alltime-top-donation": "twitch_alltime_top_cheerer_amount",
257
266
  "cheer-alltime-top-donator": "twitch_alltime_top_cheerer"
258
267
  };
259
- return m[listener] ?? listener.replace(/-/g, "_");
268
+ return m[resolvedListener] ?? resolvedListener.replace(/-/g, "_");
260
269
  }
261
270
  function seCssToBounds(css, defaults = { width: 600, height: 200 }, canvas) {
262
271
  let widthIsAuto = false;
@@ -1227,6 +1236,9 @@ function mapEventList(widget, ctx) {
1227
1236
  const filters = computeListenerFilters(widget.listeners, widget.listener);
1228
1237
  const maxItems = v.visibleEvents ?? v.visibleItems ?? 5;
1229
1238
  return buildUnit(widget, "eventlist", {
1239
+ // SE event-list widgets style per-event lines via widget.text.css; the
1240
+ // Lumia eventlist reads font/size/color from module.css.
1241
+ css: mapSeTextCssToModuleCss(widget, { fontSize: 18 }),
1230
1242
  content: {
1231
1243
  theme: v.theme ?? "simple",
1232
1244
  direction: v.direction ?? "top",
@@ -1660,14 +1672,10 @@ function mapMediaShare(widget, ctx) {
1660
1672
  // `durationSeconds + grace`).
1661
1673
  importMeta: buildImportMeta(widget, { timeLeft: v.timeLeft === true })
1662
1674
  },
1663
- css: {
1664
- fontFamily: "Roboto",
1665
- fontWeight: "bold",
1666
- color: "#ffffff",
1667
- textShadow: "rgb(0, 0, 0) 1px 1px 1px",
1668
- background: "transparent",
1669
- fontSize: 18
1670
- }
1675
+ // Lumia songrequest renders the queue list as styled text; pull SE's
1676
+ // widget.text.css so font/size/color carry across (defaults match the
1677
+ // previous hardcoded fallbacks for this widget specifically).
1678
+ css: mapSeTextCssToModuleCss(widget, { fontSize: 18 })
1671
1679
  }, ctx);
1672
1680
  }
1673
1681
  function mapKappagen(widget, ctx) {
@@ -1735,6 +1743,9 @@ function mapLeaderboardFromVariables(widget, currency, ctx) {
1735
1743
  const window = v.period === "weekly" ? "week" : v.period === "monthly" ? "month" : "alltime";
1736
1744
  const title = currency === "tips" ? "Top Tippers" : currency === "cheers" ? "Top Cheerers" : "Top Gifters";
1737
1745
  return buildUnit(widget, "loyaltyleaderboard", {
1746
+ // Carry SE text styling so the leaderboard list keeps the streamer's
1747
+ // chosen font / size / color.
1748
+ css: mapSeTextCssToModuleCss(widget, { fontSize: 18 }),
1738
1749
  content: {
1739
1750
  source: "variables",
1740
1751
  currency,
@@ -1761,6 +1772,8 @@ function mapGiveaway(widget, ctx) {
1761
1772
  const primary = v.colors?.primary ?? "#393853";
1762
1773
  const accent = v.colors?.accent ?? "#FF4076";
1763
1774
  return buildUnit(widget, "raffle", {
1775
+ // Raffle renders entrants/winner text via module.css.
1776
+ css: mapSeTextCssToModuleCss(widget),
1764
1777
  content: {
1765
1778
  version: 1,
1766
1779
  type: "basic",
@@ -1845,6 +1858,9 @@ function isHypetrainCustomWidget(widget) {
1845
1858
  function mapHypetrain(widget, ctx) {
1846
1859
  const v = widget.variables ?? {};
1847
1860
  return buildUnit(widget, "hypetrain", {
1861
+ // Hypetrain renders level / progress / contributor text — carry SE
1862
+ // styling so an imported hype-train widget keeps its font + accent.
1863
+ css: mapSeTextCssToModuleCss(widget),
1848
1864
  content: {
1849
1865
  // Twitch-native is the right default — SE hype-train widgets always
1850
1866
  // reflected the Twitch native train. Users can flip to 'synthetic'
@@ -2237,6 +2253,23 @@ var GOAL_TYPES = /* @__PURE__ */ new Set([
2237
2253
  "se-widget-merch-goal"
2238
2254
  ]);
2239
2255
  var EVENTLIST_TYPES = /* @__PURE__ */ new Set(["se-widget-event-list", "se-widget-follower-recent", "se-widget-subscriber-recent", "se-widget-cheer-recent", "se-widget-tip-recent"]);
2256
+ var SCROLLING_RECENT_TYPES = /* @__PURE__ */ new Set([
2257
+ "se-widget-follower-recent",
2258
+ "se-widget-subscriber-recent",
2259
+ "se-widget-cheer-recent",
2260
+ "se-widget-tip-recent"
2261
+ ]);
2262
+ var RECENT_TO_LATEST_FALLBACK_VAR = {
2263
+ "se-widget-follower-recent": "twitch_last_follower",
2264
+ "se-widget-subscriber-recent": "twitch_last_subscriber",
2265
+ "se-widget-cheer-recent": "twitch_last_bit",
2266
+ "se-widget-tip-recent": "latest_donator"
2267
+ };
2268
+ function isScrollingRecentWidget(widget) {
2269
+ if (!SCROLLING_RECENT_TYPES.has(widget.type)) return false;
2270
+ const scrolling = widget.text?.scrolling;
2271
+ return !!(scrolling && typeof scrolling === "object" && scrolling.enabled === true);
2272
+ }
2240
2273
  function dispatch(widget, ctx) {
2241
2274
  const t = widget.type;
2242
2275
  console.log("[SE-IMPORT] dispatch widget", {
@@ -2265,6 +2298,10 @@ function dispatch(widget, ctx) {
2265
2298
  if (t === "se-widget-donor-drive-alert") return { unit: mapSingleAlert(widget, "donordrive-donation", ctx), status: "direct", lumiaType: "alert" };
2266
2299
  if (t === "se-widget-extralife-alert") return { unit: mapSingleAlert(widget, "extralife-donation", ctx), status: "direct", lumiaType: "alert" };
2267
2300
  if (t === "se-widget-tiltify-alert") return { unit: mapSingleAlert(widget, "tiltify-campaignDonation", ctx), status: "direct", lumiaType: "alert" };
2301
+ if (isScrollingRecentWidget(widget)) {
2302
+ const fallbackVar = RECENT_TO_LATEST_FALLBACK_VAR[t] ?? "username";
2303
+ return { unit: mapReadout(widget, fallbackVar, ctx), status: "direct", lumiaType: "text" };
2304
+ }
2268
2305
  if (EVENTLIST_TYPES.has(t)) return { unit: mapEventList(widget, ctx), status: "direct", lumiaType: "eventlist" };
2269
2306
  if (t === "se-widget-top-tippers-list") return { unit: mapLeaderboardFromVariables(widget, "tips", ctx), status: "direct", lumiaType: "loyaltyleaderboard" };
2270
2307
  if (t === "se-widget-top-cheerers-list") return { unit: mapLeaderboardFromVariables(widget, "cheers", ctx), status: "direct", lumiaType: "loyaltyleaderboard" };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumiastream/ui",
3
- "version": "0.2.8-alpha.26",
3
+ "version": "0.2.8-alpha.27",
4
4
  "author": "Lumia Stream",
5
5
  "license": "ISC",
6
6
  "description": "Lumia UI Kit",