@lumiastream/ui 0.4.0 → 0.4.2
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 +87 -57
- package/dist/se-import.d.ts +1 -1
- package/dist/se-import.js +87 -57
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3878,7 +3878,11 @@ var LUMIA_DEFAULT_SIZES = {
|
|
|
3878
3878
|
// card + 5-item queue list needs a bit more vertical room, so we add ~80px
|
|
3879
3879
|
// for the queue list. Users can hide the queue list and shrink back to
|
|
3880
3880
|
// just the card if they want SE's exact footprint.
|
|
3881
|
-
songrequest: { width: 480, height: 380 }
|
|
3881
|
+
songrequest: { width: 480, height: 380 },
|
|
3882
|
+
// Train: slim horizontal bar. SE train widgets vary in size but Lumia's
|
|
3883
|
+
// layout is always a single-line ticker, so we fix the import footprint.
|
|
3884
|
+
// (mapTrain also forces dimensions directly so this is a backstop only.)
|
|
3885
|
+
train: { width: 540, height: 60 }
|
|
3882
3886
|
};
|
|
3883
3887
|
function translateVariationCondition(seType, seCondition, requirement, seEventType) {
|
|
3884
3888
|
if (seType === "gift") return { conditionType: "IS_GIFT", condition: 1 };
|
|
@@ -4609,6 +4613,8 @@ function mapGoal(widget, ctx) {
|
|
|
4609
4613
|
goalAnimationLoop: true,
|
|
4610
4614
|
unfilledColor: v.backgroundColor ?? "#400022",
|
|
4611
4615
|
filledColor: v.fillColor ?? "#ff0055",
|
|
4616
|
+
condensed: !!v.dense,
|
|
4617
|
+
showPercentComplete: !!v.percent,
|
|
4612
4618
|
alignItemsToEdges: false,
|
|
4613
4619
|
border: "solid 1px transparent",
|
|
4614
4620
|
borderRadius: "40px",
|
|
@@ -4744,10 +4750,7 @@ function mapCustom(widget, ctx) {
|
|
|
4744
4750
|
}
|
|
4745
4751
|
|
|
4746
4752
|
// src/se-import/mappers/misc.ts
|
|
4747
|
-
import {
|
|
4748
|
-
LumiaEventListTypes,
|
|
4749
|
-
LumiaMapAlertTypeToEventListType
|
|
4750
|
-
} from "@lumiastream/lumia-types";
|
|
4753
|
+
import { LumiaEventListTypes, LumiaMapAlertTypeToEventListType } from "@lumiastream/lumia-types";
|
|
4751
4754
|
|
|
4752
4755
|
// src/se-import/mappers/module-defaults.ts
|
|
4753
4756
|
var CHATBOX_DEFAULT_CONTENT_FIELDS = {
|
|
@@ -4808,13 +4811,24 @@ var CHATBOX_DEFAULT_MODULE = {
|
|
|
4808
4811
|
function mapChatboxTheme(seTheme) {
|
|
4809
4812
|
const t = (seTheme ?? "").toString().toLowerCase();
|
|
4810
4813
|
if (!t || t === "default") return "simple";
|
|
4811
|
-
if (t.includes("flipin") || t.includes("bubble") || t.includes("bubbly"))
|
|
4812
|
-
return "bubbly";
|
|
4814
|
+
if (t.includes("flipin") || t.includes("bubble") || t.includes("bubbly")) return "bubbly";
|
|
4813
4815
|
if (t.includes("glass") || t.includes("transparent")) return "glass";
|
|
4814
4816
|
if (t.includes("boxy") || t.includes("checker")) return "boxy";
|
|
4815
4817
|
if (t.includes("basic")) return "basic";
|
|
4816
4818
|
return "simple";
|
|
4817
4819
|
}
|
|
4820
|
+
function defaultChatboxBackgroundForSeTheme(seTheme) {
|
|
4821
|
+
const t = (seTheme ?? "").toString().toLowerCase();
|
|
4822
|
+
if (!t || t === "default") return "transparent";
|
|
4823
|
+
if (t === "custom") return "transparent";
|
|
4824
|
+
if (t.includes("glass") || t.includes("transparent") || t.includes("flipin") || t.includes("bubble") || t.includes("bubbly"))
|
|
4825
|
+
return "transparent";
|
|
4826
|
+
if (t.includes("white") || t.includes("light") || t.includes("clean") && !t.includes("dark"))
|
|
4827
|
+
return "transparent";
|
|
4828
|
+
if (t.includes("dark") || t.includes("boxy") || t.includes("checker") || t.includes("black"))
|
|
4829
|
+
return "#1e1e1e";
|
|
4830
|
+
return "#1e1e1e";
|
|
4831
|
+
}
|
|
4818
4832
|
var KAPPAGEN_EVENT_CATEGORIES = {
|
|
4819
4833
|
tip: [LumiaEventListTypes.DONATION],
|
|
4820
4834
|
cheer: [
|
|
@@ -4830,9 +4844,7 @@ var KAPPAGEN_EVENT_CATEGORIES = {
|
|
|
4830
4844
|
subscriber: [LumiaEventListTypes.SUBSCRIBERS],
|
|
4831
4845
|
purchase: [LumiaEventListTypes.PURCHASES]
|
|
4832
4846
|
};
|
|
4833
|
-
var alertKeysByEventListType = Object.entries(
|
|
4834
|
-
LumiaMapAlertTypeToEventListType
|
|
4835
|
-
).reduce(
|
|
4847
|
+
var alertKeysByEventListType = Object.entries(LumiaMapAlertTypeToEventListType).reduce(
|
|
4836
4848
|
(acc, [alertKey, eventListType]) => {
|
|
4837
4849
|
acc[eventListType] = acc[eventListType] ?? [];
|
|
4838
4850
|
acc[eventListType].push(alertKey);
|
|
@@ -4877,21 +4889,15 @@ function mapChatbox(widget, ctx) {
|
|
|
4877
4889
|
const messagePadding = paddingShorthand(messageCss);
|
|
4878
4890
|
const DEFAULT_CHATBOX_FONT_SIZE = 14;
|
|
4879
4891
|
const moduleCss = {};
|
|
4880
|
-
if (textCss["font-family"] != null)
|
|
4881
|
-
moduleCss.fontFamily = textCss["font-family"];
|
|
4892
|
+
if (textCss["font-family"] != null) moduleCss.fontFamily = textCss["font-family"];
|
|
4882
4893
|
moduleCss.fontSize = textCss["font-size"] != null ? textCss["font-size"] : DEFAULT_CHATBOX_FONT_SIZE;
|
|
4883
4894
|
if (textCss["color"] != null) moduleCss.color = textCss["color"];
|
|
4884
|
-
if (textCss["font-weight"] != null)
|
|
4885
|
-
|
|
4886
|
-
if (textCss["text-
|
|
4887
|
-
|
|
4888
|
-
if (textCss["text-align"] != null)
|
|
4889
|
-
moduleCss.textAlign = textCss["text-align"];
|
|
4890
|
-
if (textCss["line-height"] != null)
|
|
4891
|
-
moduleCss.lineHeight = textCss["line-height"];
|
|
4895
|
+
if (textCss["font-weight"] != null) moduleCss.fontWeight = textCss["font-weight"];
|
|
4896
|
+
if (textCss["text-shadow"] != null) moduleCss.textShadow = textCss["text-shadow"];
|
|
4897
|
+
if (textCss["text-align"] != null) moduleCss.textAlign = textCss["text-align"];
|
|
4898
|
+
if (textCss["line-height"] != null) moduleCss.lineHeight = textCss["line-height"];
|
|
4892
4899
|
if (messagePadding) moduleCss.padding = messagePadding;
|
|
4893
|
-
const
|
|
4894
|
-
const messageBackground = typeof messageCss["background"] === "string" && messageCss["background"].length > 0 ? messageCss["background"] : DEFAULT_CHATBOX_BG;
|
|
4900
|
+
const messageBackground = typeof messageCss["background"] === "string" && messageCss["background"].length > 0 ? messageCss["background"] : defaultChatboxBackgroundForSeTheme(v.theme);
|
|
4895
4901
|
moduleCss.background = messageBackground;
|
|
4896
4902
|
const messageFontFamily = typeof messageCss["font-family"] === "string" && messageCss["font-family"].length > 0 ? messageCss["font-family"] : void 0;
|
|
4897
4903
|
const highlightBackground = v.highlight && typeof v.highlight === "object" && typeof v.highlight["background"] === "string" ? v.highlight["background"] : void 0;
|
|
@@ -5001,9 +5007,7 @@ var SE_LISTENER_TO_LUMIA_CATEGORY = {
|
|
|
5001
5007
|
function computeAllowedEventsFromSEListeners(seListeners, explicitListener) {
|
|
5002
5008
|
const enabled = [];
|
|
5003
5009
|
if (seListeners && typeof seListeners === "object" && !Array.isArray(seListeners)) {
|
|
5004
|
-
for (const [k, v] of Object.entries(
|
|
5005
|
-
seListeners
|
|
5006
|
-
)) {
|
|
5010
|
+
for (const [k, v] of Object.entries(seListeners)) {
|
|
5007
5011
|
if (v) enabled.push(k);
|
|
5008
5012
|
}
|
|
5009
5013
|
} else if (Array.isArray(seListeners)) {
|
|
@@ -5021,6 +5025,7 @@ function computeAllowedEventsFromSEListeners(seListeners, explicitListener) {
|
|
|
5021
5025
|
if (allowedCategories.size === 0) return [];
|
|
5022
5026
|
const allowedAlerts = [];
|
|
5023
5027
|
Object.keys(LumiaMapAlertTypeToEventListType).forEach((alertKey) => {
|
|
5028
|
+
if (alertKey.includes("session")) return;
|
|
5024
5029
|
const mappedCategory = LumiaMapAlertTypeToEventListType[alertKey];
|
|
5025
5030
|
if (mappedCategory && allowedCategories.has(mappedCategory)) {
|
|
5026
5031
|
allowedAlerts.push(alertKey);
|
|
@@ -5038,10 +5043,7 @@ function seTemplateToMarqueeTemplate(seTemplate) {
|
|
|
5038
5043
|
}
|
|
5039
5044
|
function mapEventList(widget, ctx) {
|
|
5040
5045
|
const v = widget.variables ?? {};
|
|
5041
|
-
const allowedEvents = computeAllowedEventsFromSEListeners(
|
|
5042
|
-
widget.listeners,
|
|
5043
|
-
widget.listener
|
|
5044
|
-
);
|
|
5046
|
+
const allowedEvents = computeAllowedEventsFromSEListeners(widget.listeners, widget.listener);
|
|
5045
5047
|
const maxItems = v.visibleEvents ?? v.visibleItems ?? 5;
|
|
5046
5048
|
const seText = widget.text;
|
|
5047
5049
|
const scrolling = seText?.scrolling;
|
|
@@ -5328,10 +5330,7 @@ function mapSlideshow(widget, ctx) {
|
|
|
5328
5330
|
const url = typeof raw === "string" ? raw : raw.url ?? raw.src ?? "";
|
|
5329
5331
|
if (!url) return null;
|
|
5330
5332
|
return {
|
|
5331
|
-
type: inferSlideshowMediaType(
|
|
5332
|
-
typeof raw === "object" ? raw?.type : void 0,
|
|
5333
|
-
url
|
|
5334
|
-
),
|
|
5333
|
+
type: inferSlideshowMediaType(typeof raw === "object" ? raw?.type : void 0, url),
|
|
5335
5334
|
src: url,
|
|
5336
5335
|
name: nameFromUrl(url)
|
|
5337
5336
|
};
|
|
@@ -5376,6 +5375,46 @@ function mapSlideshow(widget, ctx) {
|
|
|
5376
5375
|
ctx
|
|
5377
5376
|
);
|
|
5378
5377
|
}
|
|
5378
|
+
function mapTrain(widget, ctx) {
|
|
5379
|
+
const v = widget.variables ?? {};
|
|
5380
|
+
const allowedEvents = computeAllowedEventsFromSEListeners(widget.listeners, widget.listener);
|
|
5381
|
+
const TRAIN_WIDTH = 540;
|
|
5382
|
+
const TRAIN_HEIGHT = v.vertical === true ? 200 : 60;
|
|
5383
|
+
const widgetWithSize = {
|
|
5384
|
+
...widget,
|
|
5385
|
+
css: { ...widget.css, width: TRAIN_WIDTH, height: TRAIN_HEIGHT }
|
|
5386
|
+
};
|
|
5387
|
+
return buildUnit(
|
|
5388
|
+
widgetWithSize,
|
|
5389
|
+
"train",
|
|
5390
|
+
{
|
|
5391
|
+
css: mapSeTextCssToModuleCss(widget, {
|
|
5392
|
+
fontSize: 24,
|
|
5393
|
+
fontFamily: "Nunito",
|
|
5394
|
+
fontWeight: "bold",
|
|
5395
|
+
color: "#ffffff",
|
|
5396
|
+
textShadow: "rgb(0, 0, 0) 1px 1px 1px",
|
|
5397
|
+
textAlign: "left",
|
|
5398
|
+
lineHeight: 1.3,
|
|
5399
|
+
background: "transparent"
|
|
5400
|
+
}),
|
|
5401
|
+
content: {
|
|
5402
|
+
version: 1,
|
|
5403
|
+
// SE stores train duration in minutes; Lumia stores it in seconds.
|
|
5404
|
+
duration: typeof v.duration === "number" && v.duration > 0 ? v.duration * 60 : 300,
|
|
5405
|
+
autoHide: false,
|
|
5406
|
+
showCount: v.showCount !== false,
|
|
5407
|
+
showTime: v.showTime !== false,
|
|
5408
|
+
showLatest: v.show_latest !== false,
|
|
5409
|
+
showIcons: v.icons !== false,
|
|
5410
|
+
vertical: v.vertical === true,
|
|
5411
|
+
...allowedEvents !== void 0 ? { allowedEvents } : { allowedEvents: [] }
|
|
5412
|
+
}
|
|
5413
|
+
},
|
|
5414
|
+
ctx,
|
|
5415
|
+
{ width: 540, height: 60 }
|
|
5416
|
+
);
|
|
5417
|
+
}
|
|
5379
5418
|
function mapTimer(widget, ctx) {
|
|
5380
5419
|
const v = widget.variables ?? {};
|
|
5381
5420
|
const textValue = typeof widget.text?.value === "string" ? widget.text.value : void 0;
|
|
@@ -5402,9 +5441,7 @@ function mapTimer(widget, ctx) {
|
|
|
5402
5441
|
resolved = true;
|
|
5403
5442
|
}
|
|
5404
5443
|
}
|
|
5405
|
-
if (!resolved && [v.days, v.hours, v.minutes, v.seconds].some(
|
|
5406
|
-
(part) => typeof part === "number"
|
|
5407
|
-
)) {
|
|
5444
|
+
if (!resolved && [v.days, v.hours, v.minutes, v.seconds].some((part) => typeof part === "number")) {
|
|
5408
5445
|
days = typeof v.days === "number" ? v.days : 0;
|
|
5409
5446
|
hours = typeof v.hours === "number" ? v.hours : 0;
|
|
5410
5447
|
minutes = typeof v.minutes === "number" ? v.minutes : 0;
|
|
@@ -5512,8 +5549,7 @@ function mapNowPlaying(widget, ctx) {
|
|
|
5512
5549
|
};
|
|
5513
5550
|
if (typeof seTextCss["text-transform"] === "string")
|
|
5514
5551
|
importedCss.textTransform = seTextCss["text-transform"];
|
|
5515
|
-
if (typeof seTextCss["font-style"] === "string")
|
|
5516
|
-
importedCss.fontStyle = seTextCss["font-style"];
|
|
5552
|
+
if (typeof seTextCss["font-style"] === "string") importedCss.fontStyle = seTextCss["font-style"];
|
|
5517
5553
|
if (typeof seTextCss["text-decoration"] === "string")
|
|
5518
5554
|
importedCss.textDecoration = seTextCss["text-decoration"];
|
|
5519
5555
|
if (typeof seTextCss["letter-spacing"] === "string" || typeof seTextCss["letter-spacing"] === "number") {
|
|
@@ -5738,10 +5774,11 @@ function mapViewerProfilesLeaderboard(widget, currency, ctx) {
|
|
|
5738
5774
|
// chosen font / size / color.
|
|
5739
5775
|
css: mapSeTextCssToModuleCss(widget, { fontSize: 18 }),
|
|
5740
5776
|
content: {
|
|
5777
|
+
theme: "list",
|
|
5741
5778
|
sortBy: TOP_LIST_SORT_BY[currency],
|
|
5742
5779
|
count,
|
|
5743
5780
|
title: TOP_LIST_TITLE[currency],
|
|
5744
|
-
showTitle:
|
|
5781
|
+
showTitle: false,
|
|
5745
5782
|
showAvatar: true,
|
|
5746
5783
|
showPlatform: true,
|
|
5747
5784
|
// Hide noisy columns that aren't relevant for a single-metric
|
|
@@ -6542,6 +6579,12 @@ function dispatch(widget, ctx) {
|
|
|
6542
6579
|
status: "direct",
|
|
6543
6580
|
lumiaType: "image"
|
|
6544
6581
|
};
|
|
6582
|
+
if (t === "se-widget-train")
|
|
6583
|
+
return {
|
|
6584
|
+
unit: mapTrain(widget, ctx),
|
|
6585
|
+
status: "direct",
|
|
6586
|
+
lumiaType: "train"
|
|
6587
|
+
};
|
|
6545
6588
|
return {
|
|
6546
6589
|
unit: mapUnsupportedAsText(widget, ctx),
|
|
6547
6590
|
status: "placeholder",
|
|
@@ -9577,7 +9620,6 @@ var REVIEW_REASONS = {
|
|
|
9577
9620
|
// `tipjar` module (see dispatcher.ts) and lands with `partial` status, so it
|
|
9578
9621
|
// never reaches the placeholder-reason fallback. If a future feature flag
|
|
9579
9622
|
// disables tipjar auto-import, add an entry to FLAG_OFF_REASONS instead.
|
|
9580
|
-
"se-widget-train": "No native Lumia equivalent \u2014 animated subscriber/event train.",
|
|
9581
9623
|
"se-widget-media-share": "No native Lumia equivalent \u2014 viewer-submitted media player.",
|
|
9582
9624
|
"se-widget-contest": "No native Lumia equivalent \u2014 SE-specific contest widget.",
|
|
9583
9625
|
"se-widget-giveaway": "No native Lumia equivalent \u2014 SE giveaway service.",
|
|
@@ -9608,9 +9650,7 @@ function extractSEOverlayId(input) {
|
|
|
9608
9650
|
}
|
|
9609
9651
|
function extractSEPreviewParts(input) {
|
|
9610
9652
|
const trimmed = input.trim();
|
|
9611
|
-
const m = trimmed.match(
|
|
9612
|
-
/streamelements\.com\/overlay\/([0-9a-f]{24})(?:\/([A-Za-z0-9_-]+))?/i
|
|
9613
|
-
);
|
|
9653
|
+
const m = trimmed.match(/streamelements\.com\/overlay\/([0-9a-f]{24})(?:\/([A-Za-z0-9_-]+))?/i);
|
|
9614
9654
|
if (!m) return null;
|
|
9615
9655
|
const overlayId = m[1];
|
|
9616
9656
|
const second = m[2];
|
|
@@ -9645,9 +9685,7 @@ async function fetchSEBootstrap({
|
|
|
9645
9685
|
}
|
|
9646
9686
|
const json = await res.json();
|
|
9647
9687
|
if (!isSEBootstrap(json)) {
|
|
9648
|
-
throw new Error(
|
|
9649
|
-
"Server returned a response that does not look like an SE bootstrap payload."
|
|
9650
|
-
);
|
|
9688
|
+
throw new Error("Server returned a response that does not look like an SE bootstrap payload.");
|
|
9651
9689
|
}
|
|
9652
9690
|
return json;
|
|
9653
9691
|
}
|
|
@@ -9690,11 +9728,7 @@ function importSEBootstrap(bootstrap) {
|
|
|
9690
9728
|
const lumiaGroupId = seUidToLumiaGroupId[uid];
|
|
9691
9729
|
const parentUid = typeof w.group === "string" ? w.group : null;
|
|
9692
9730
|
const parentLumiaGroupId = parentUid ? seUidToLumiaGroupId[parentUid] ?? null : null;
|
|
9693
|
-
const bounds = seCssToBounds(
|
|
9694
|
-
w.css,
|
|
9695
|
-
{ width: 200, height: 200 },
|
|
9696
|
-
importCanvas
|
|
9697
|
-
);
|
|
9731
|
+
const bounds = seCssToBounds(w.css, { width: 200, height: 200 }, importCanvas);
|
|
9698
9732
|
const layer = {
|
|
9699
9733
|
id: lumiaGroupId,
|
|
9700
9734
|
type: "group",
|
|
@@ -9827,9 +9861,7 @@ function applyReviewAction(result, moduleId, action, payload) {
|
|
|
9827
9861
|
if (action === "skip") {
|
|
9828
9862
|
delete modules[moduleId];
|
|
9829
9863
|
const nextLayers = layers.filter((l) => l.id !== moduleId);
|
|
9830
|
-
const reviewItems2 = result.reviewItems.filter(
|
|
9831
|
-
(r) => r.moduleId !== moduleId
|
|
9832
|
-
);
|
|
9864
|
+
const reviewItems2 = result.reviewItems.filter((r) => r.moduleId !== moduleId);
|
|
9833
9865
|
return {
|
|
9834
9866
|
...result,
|
|
9835
9867
|
overlay: {
|
|
@@ -9878,9 +9910,7 @@ function applyReviewAction(result, moduleId, action, payload) {
|
|
|
9878
9910
|
modules[extra.module.id] = extra.module;
|
|
9879
9911
|
}
|
|
9880
9912
|
modules[moduleId] = newModule;
|
|
9881
|
-
const reviewItems2 = result.reviewItems.filter(
|
|
9882
|
-
(r) => r.moduleId !== moduleId
|
|
9883
|
-
);
|
|
9913
|
+
const reviewItems2 = result.reviewItems.filter((r) => r.moduleId !== moduleId);
|
|
9884
9914
|
return {
|
|
9885
9915
|
...result,
|
|
9886
9916
|
overlay: {
|
package/dist/se-import.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ComponentType, ReactNode } from 'react';
|
|
3
3
|
|
|
4
|
-
type ModuleType = 'alert' | 'emotebox' | 'emotealert' | 'text' | 'image' | 'audio' | 'video' | 'camera' | 'slideshow' | 'shape' | 'svg' | 'colorbox' | 'goal' | 'timer' | 'gradientlight' | 'browsersource' | 'chatbox' | 'credits' | 'eventlist' | 'eventrotate' | 'hfx' | 'hfxalert' | 'clip' | 'youtube' | 'spinwheel' | 'raffle' | 'viewerqueue' | 'loyaltyleaderboard' | 'viewerprofiles' | 'achievements' | 'poll' | 'tournaments' | 'spotify' | 'nowplaying' | 'youtubemusic' | 'brbscreen' | 'vlc' | 'tts' | 'livecaption' | 'custom' | 'tipjar' | 'hypetrain' | 'streamboss' | 'songrequest' | 'group';
|
|
4
|
+
type ModuleType = 'alert' | 'emotebox' | 'emotealert' | 'text' | 'image' | 'audio' | 'video' | 'camera' | 'slideshow' | 'shape' | 'svg' | 'colorbox' | 'goal' | 'timer' | 'gradientlight' | 'browsersource' | 'chatbox' | 'credits' | 'eventlist' | 'eventrotate' | 'hfx' | 'hfxalert' | 'clip' | 'youtube' | 'spinwheel' | 'raffle' | 'viewerqueue' | 'loyaltyleaderboard' | 'viewerprofiles' | 'achievements' | 'poll' | 'tournaments' | 'spotify' | 'nowplaying' | 'youtubemusic' | 'brbscreen' | 'vlc' | 'tts' | 'livecaption' | 'custom' | 'tipjar' | 'hypetrain' | 'streamboss' | 'songrequest' | 'train' | 'group';
|
|
5
5
|
type OverlayLayerType = 'layer' | 'group';
|
|
6
6
|
type OverlayLayerBounds = {
|
|
7
7
|
height: number;
|
package/dist/se-import.js
CHANGED
|
@@ -744,7 +744,11 @@ var LUMIA_DEFAULT_SIZES = {
|
|
|
744
744
|
// card + 5-item queue list needs a bit more vertical room, so we add ~80px
|
|
745
745
|
// for the queue list. Users can hide the queue list and shrink back to
|
|
746
746
|
// just the card if they want SE's exact footprint.
|
|
747
|
-
songrequest: { width: 480, height: 380 }
|
|
747
|
+
songrequest: { width: 480, height: 380 },
|
|
748
|
+
// Train: slim horizontal bar. SE train widgets vary in size but Lumia's
|
|
749
|
+
// layout is always a single-line ticker, so we fix the import footprint.
|
|
750
|
+
// (mapTrain also forces dimensions directly so this is a backstop only.)
|
|
751
|
+
train: { width: 540, height: 60 }
|
|
748
752
|
};
|
|
749
753
|
function translateVariationCondition(seType, seCondition, requirement, seEventType) {
|
|
750
754
|
if (seType === "gift") return { conditionType: "IS_GIFT", condition: 1 };
|
|
@@ -1475,6 +1479,8 @@ function mapGoal(widget, ctx) {
|
|
|
1475
1479
|
goalAnimationLoop: true,
|
|
1476
1480
|
unfilledColor: v.backgroundColor ?? "#400022",
|
|
1477
1481
|
filledColor: v.fillColor ?? "#ff0055",
|
|
1482
|
+
condensed: !!v.dense,
|
|
1483
|
+
showPercentComplete: !!v.percent,
|
|
1478
1484
|
alignItemsToEdges: false,
|
|
1479
1485
|
border: "solid 1px transparent",
|
|
1480
1486
|
borderRadius: "40px",
|
|
@@ -1610,10 +1616,7 @@ function mapCustom(widget, ctx) {
|
|
|
1610
1616
|
}
|
|
1611
1617
|
|
|
1612
1618
|
// src/se-import/mappers/misc.ts
|
|
1613
|
-
import {
|
|
1614
|
-
LumiaEventListTypes,
|
|
1615
|
-
LumiaMapAlertTypeToEventListType
|
|
1616
|
-
} from "@lumiastream/lumia-types";
|
|
1619
|
+
import { LumiaEventListTypes, LumiaMapAlertTypeToEventListType } from "@lumiastream/lumia-types";
|
|
1617
1620
|
|
|
1618
1621
|
// src/se-import/mappers/module-defaults.ts
|
|
1619
1622
|
var CHATBOX_DEFAULT_CONTENT_FIELDS = {
|
|
@@ -1674,13 +1677,24 @@ var CHATBOX_DEFAULT_MODULE = {
|
|
|
1674
1677
|
function mapChatboxTheme(seTheme) {
|
|
1675
1678
|
const t = (seTheme ?? "").toString().toLowerCase();
|
|
1676
1679
|
if (!t || t === "default") return "simple";
|
|
1677
|
-
if (t.includes("flipin") || t.includes("bubble") || t.includes("bubbly"))
|
|
1678
|
-
return "bubbly";
|
|
1680
|
+
if (t.includes("flipin") || t.includes("bubble") || t.includes("bubbly")) return "bubbly";
|
|
1679
1681
|
if (t.includes("glass") || t.includes("transparent")) return "glass";
|
|
1680
1682
|
if (t.includes("boxy") || t.includes("checker")) return "boxy";
|
|
1681
1683
|
if (t.includes("basic")) return "basic";
|
|
1682
1684
|
return "simple";
|
|
1683
1685
|
}
|
|
1686
|
+
function defaultChatboxBackgroundForSeTheme(seTheme) {
|
|
1687
|
+
const t = (seTheme ?? "").toString().toLowerCase();
|
|
1688
|
+
if (!t || t === "default") return "transparent";
|
|
1689
|
+
if (t === "custom") return "transparent";
|
|
1690
|
+
if (t.includes("glass") || t.includes("transparent") || t.includes("flipin") || t.includes("bubble") || t.includes("bubbly"))
|
|
1691
|
+
return "transparent";
|
|
1692
|
+
if (t.includes("white") || t.includes("light") || t.includes("clean") && !t.includes("dark"))
|
|
1693
|
+
return "transparent";
|
|
1694
|
+
if (t.includes("dark") || t.includes("boxy") || t.includes("checker") || t.includes("black"))
|
|
1695
|
+
return "#1e1e1e";
|
|
1696
|
+
return "#1e1e1e";
|
|
1697
|
+
}
|
|
1684
1698
|
var KAPPAGEN_EVENT_CATEGORIES = {
|
|
1685
1699
|
tip: [LumiaEventListTypes.DONATION],
|
|
1686
1700
|
cheer: [
|
|
@@ -1696,9 +1710,7 @@ var KAPPAGEN_EVENT_CATEGORIES = {
|
|
|
1696
1710
|
subscriber: [LumiaEventListTypes.SUBSCRIBERS],
|
|
1697
1711
|
purchase: [LumiaEventListTypes.PURCHASES]
|
|
1698
1712
|
};
|
|
1699
|
-
var alertKeysByEventListType = Object.entries(
|
|
1700
|
-
LumiaMapAlertTypeToEventListType
|
|
1701
|
-
).reduce(
|
|
1713
|
+
var alertKeysByEventListType = Object.entries(LumiaMapAlertTypeToEventListType).reduce(
|
|
1702
1714
|
(acc, [alertKey, eventListType]) => {
|
|
1703
1715
|
acc[eventListType] = acc[eventListType] ?? [];
|
|
1704
1716
|
acc[eventListType].push(alertKey);
|
|
@@ -1743,21 +1755,15 @@ function mapChatbox(widget, ctx) {
|
|
|
1743
1755
|
const messagePadding = paddingShorthand(messageCss);
|
|
1744
1756
|
const DEFAULT_CHATBOX_FONT_SIZE = 14;
|
|
1745
1757
|
const moduleCss = {};
|
|
1746
|
-
if (textCss["font-family"] != null)
|
|
1747
|
-
moduleCss.fontFamily = textCss["font-family"];
|
|
1758
|
+
if (textCss["font-family"] != null) moduleCss.fontFamily = textCss["font-family"];
|
|
1748
1759
|
moduleCss.fontSize = textCss["font-size"] != null ? textCss["font-size"] : DEFAULT_CHATBOX_FONT_SIZE;
|
|
1749
1760
|
if (textCss["color"] != null) moduleCss.color = textCss["color"];
|
|
1750
|
-
if (textCss["font-weight"] != null)
|
|
1751
|
-
|
|
1752
|
-
if (textCss["text-
|
|
1753
|
-
|
|
1754
|
-
if (textCss["text-align"] != null)
|
|
1755
|
-
moduleCss.textAlign = textCss["text-align"];
|
|
1756
|
-
if (textCss["line-height"] != null)
|
|
1757
|
-
moduleCss.lineHeight = textCss["line-height"];
|
|
1761
|
+
if (textCss["font-weight"] != null) moduleCss.fontWeight = textCss["font-weight"];
|
|
1762
|
+
if (textCss["text-shadow"] != null) moduleCss.textShadow = textCss["text-shadow"];
|
|
1763
|
+
if (textCss["text-align"] != null) moduleCss.textAlign = textCss["text-align"];
|
|
1764
|
+
if (textCss["line-height"] != null) moduleCss.lineHeight = textCss["line-height"];
|
|
1758
1765
|
if (messagePadding) moduleCss.padding = messagePadding;
|
|
1759
|
-
const
|
|
1760
|
-
const messageBackground = typeof messageCss["background"] === "string" && messageCss["background"].length > 0 ? messageCss["background"] : DEFAULT_CHATBOX_BG;
|
|
1766
|
+
const messageBackground = typeof messageCss["background"] === "string" && messageCss["background"].length > 0 ? messageCss["background"] : defaultChatboxBackgroundForSeTheme(v.theme);
|
|
1761
1767
|
moduleCss.background = messageBackground;
|
|
1762
1768
|
const messageFontFamily = typeof messageCss["font-family"] === "string" && messageCss["font-family"].length > 0 ? messageCss["font-family"] : void 0;
|
|
1763
1769
|
const highlightBackground = v.highlight && typeof v.highlight === "object" && typeof v.highlight["background"] === "string" ? v.highlight["background"] : void 0;
|
|
@@ -1867,9 +1873,7 @@ var SE_LISTENER_TO_LUMIA_CATEGORY = {
|
|
|
1867
1873
|
function computeAllowedEventsFromSEListeners(seListeners, explicitListener) {
|
|
1868
1874
|
const enabled = [];
|
|
1869
1875
|
if (seListeners && typeof seListeners === "object" && !Array.isArray(seListeners)) {
|
|
1870
|
-
for (const [k, v] of Object.entries(
|
|
1871
|
-
seListeners
|
|
1872
|
-
)) {
|
|
1876
|
+
for (const [k, v] of Object.entries(seListeners)) {
|
|
1873
1877
|
if (v) enabled.push(k);
|
|
1874
1878
|
}
|
|
1875
1879
|
} else if (Array.isArray(seListeners)) {
|
|
@@ -1887,6 +1891,7 @@ function computeAllowedEventsFromSEListeners(seListeners, explicitListener) {
|
|
|
1887
1891
|
if (allowedCategories.size === 0) return [];
|
|
1888
1892
|
const allowedAlerts = [];
|
|
1889
1893
|
Object.keys(LumiaMapAlertTypeToEventListType).forEach((alertKey) => {
|
|
1894
|
+
if (alertKey.includes("session")) return;
|
|
1890
1895
|
const mappedCategory = LumiaMapAlertTypeToEventListType[alertKey];
|
|
1891
1896
|
if (mappedCategory && allowedCategories.has(mappedCategory)) {
|
|
1892
1897
|
allowedAlerts.push(alertKey);
|
|
@@ -1904,10 +1909,7 @@ function seTemplateToMarqueeTemplate(seTemplate) {
|
|
|
1904
1909
|
}
|
|
1905
1910
|
function mapEventList(widget, ctx) {
|
|
1906
1911
|
const v = widget.variables ?? {};
|
|
1907
|
-
const allowedEvents = computeAllowedEventsFromSEListeners(
|
|
1908
|
-
widget.listeners,
|
|
1909
|
-
widget.listener
|
|
1910
|
-
);
|
|
1912
|
+
const allowedEvents = computeAllowedEventsFromSEListeners(widget.listeners, widget.listener);
|
|
1911
1913
|
const maxItems = v.visibleEvents ?? v.visibleItems ?? 5;
|
|
1912
1914
|
const seText = widget.text;
|
|
1913
1915
|
const scrolling = seText?.scrolling;
|
|
@@ -2194,10 +2196,7 @@ function mapSlideshow(widget, ctx) {
|
|
|
2194
2196
|
const url = typeof raw === "string" ? raw : raw.url ?? raw.src ?? "";
|
|
2195
2197
|
if (!url) return null;
|
|
2196
2198
|
return {
|
|
2197
|
-
type: inferSlideshowMediaType(
|
|
2198
|
-
typeof raw === "object" ? raw?.type : void 0,
|
|
2199
|
-
url
|
|
2200
|
-
),
|
|
2199
|
+
type: inferSlideshowMediaType(typeof raw === "object" ? raw?.type : void 0, url),
|
|
2201
2200
|
src: url,
|
|
2202
2201
|
name: nameFromUrl(url)
|
|
2203
2202
|
};
|
|
@@ -2242,6 +2241,46 @@ function mapSlideshow(widget, ctx) {
|
|
|
2242
2241
|
ctx
|
|
2243
2242
|
);
|
|
2244
2243
|
}
|
|
2244
|
+
function mapTrain(widget, ctx) {
|
|
2245
|
+
const v = widget.variables ?? {};
|
|
2246
|
+
const allowedEvents = computeAllowedEventsFromSEListeners(widget.listeners, widget.listener);
|
|
2247
|
+
const TRAIN_WIDTH = 540;
|
|
2248
|
+
const TRAIN_HEIGHT = v.vertical === true ? 200 : 60;
|
|
2249
|
+
const widgetWithSize = {
|
|
2250
|
+
...widget,
|
|
2251
|
+
css: { ...widget.css, width: TRAIN_WIDTH, height: TRAIN_HEIGHT }
|
|
2252
|
+
};
|
|
2253
|
+
return buildUnit(
|
|
2254
|
+
widgetWithSize,
|
|
2255
|
+
"train",
|
|
2256
|
+
{
|
|
2257
|
+
css: mapSeTextCssToModuleCss(widget, {
|
|
2258
|
+
fontSize: 24,
|
|
2259
|
+
fontFamily: "Nunito",
|
|
2260
|
+
fontWeight: "bold",
|
|
2261
|
+
color: "#ffffff",
|
|
2262
|
+
textShadow: "rgb(0, 0, 0) 1px 1px 1px",
|
|
2263
|
+
textAlign: "left",
|
|
2264
|
+
lineHeight: 1.3,
|
|
2265
|
+
background: "transparent"
|
|
2266
|
+
}),
|
|
2267
|
+
content: {
|
|
2268
|
+
version: 1,
|
|
2269
|
+
// SE stores train duration in minutes; Lumia stores it in seconds.
|
|
2270
|
+
duration: typeof v.duration === "number" && v.duration > 0 ? v.duration * 60 : 300,
|
|
2271
|
+
autoHide: false,
|
|
2272
|
+
showCount: v.showCount !== false,
|
|
2273
|
+
showTime: v.showTime !== false,
|
|
2274
|
+
showLatest: v.show_latest !== false,
|
|
2275
|
+
showIcons: v.icons !== false,
|
|
2276
|
+
vertical: v.vertical === true,
|
|
2277
|
+
...allowedEvents !== void 0 ? { allowedEvents } : { allowedEvents: [] }
|
|
2278
|
+
}
|
|
2279
|
+
},
|
|
2280
|
+
ctx,
|
|
2281
|
+
{ width: 540, height: 60 }
|
|
2282
|
+
);
|
|
2283
|
+
}
|
|
2245
2284
|
function mapTimer(widget, ctx) {
|
|
2246
2285
|
const v = widget.variables ?? {};
|
|
2247
2286
|
const textValue = typeof widget.text?.value === "string" ? widget.text.value : void 0;
|
|
@@ -2268,9 +2307,7 @@ function mapTimer(widget, ctx) {
|
|
|
2268
2307
|
resolved = true;
|
|
2269
2308
|
}
|
|
2270
2309
|
}
|
|
2271
|
-
if (!resolved && [v.days, v.hours, v.minutes, v.seconds].some(
|
|
2272
|
-
(part) => typeof part === "number"
|
|
2273
|
-
)) {
|
|
2310
|
+
if (!resolved && [v.days, v.hours, v.minutes, v.seconds].some((part) => typeof part === "number")) {
|
|
2274
2311
|
days = typeof v.days === "number" ? v.days : 0;
|
|
2275
2312
|
hours = typeof v.hours === "number" ? v.hours : 0;
|
|
2276
2313
|
minutes = typeof v.minutes === "number" ? v.minutes : 0;
|
|
@@ -2378,8 +2415,7 @@ function mapNowPlaying(widget, ctx) {
|
|
|
2378
2415
|
};
|
|
2379
2416
|
if (typeof seTextCss["text-transform"] === "string")
|
|
2380
2417
|
importedCss.textTransform = seTextCss["text-transform"];
|
|
2381
|
-
if (typeof seTextCss["font-style"] === "string")
|
|
2382
|
-
importedCss.fontStyle = seTextCss["font-style"];
|
|
2418
|
+
if (typeof seTextCss["font-style"] === "string") importedCss.fontStyle = seTextCss["font-style"];
|
|
2383
2419
|
if (typeof seTextCss["text-decoration"] === "string")
|
|
2384
2420
|
importedCss.textDecoration = seTextCss["text-decoration"];
|
|
2385
2421
|
if (typeof seTextCss["letter-spacing"] === "string" || typeof seTextCss["letter-spacing"] === "number") {
|
|
@@ -2604,10 +2640,11 @@ function mapViewerProfilesLeaderboard(widget, currency, ctx) {
|
|
|
2604
2640
|
// chosen font / size / color.
|
|
2605
2641
|
css: mapSeTextCssToModuleCss(widget, { fontSize: 18 }),
|
|
2606
2642
|
content: {
|
|
2643
|
+
theme: "list",
|
|
2607
2644
|
sortBy: TOP_LIST_SORT_BY[currency],
|
|
2608
2645
|
count,
|
|
2609
2646
|
title: TOP_LIST_TITLE[currency],
|
|
2610
|
-
showTitle:
|
|
2647
|
+
showTitle: false,
|
|
2611
2648
|
showAvatar: true,
|
|
2612
2649
|
showPlatform: true,
|
|
2613
2650
|
// Hide noisy columns that aren't relevant for a single-metric
|
|
@@ -3408,6 +3445,12 @@ function dispatch(widget, ctx) {
|
|
|
3408
3445
|
status: "direct",
|
|
3409
3446
|
lumiaType: "image"
|
|
3410
3447
|
};
|
|
3448
|
+
if (t === "se-widget-train")
|
|
3449
|
+
return {
|
|
3450
|
+
unit: mapTrain(widget, ctx),
|
|
3451
|
+
status: "direct",
|
|
3452
|
+
lumiaType: "train"
|
|
3453
|
+
};
|
|
3411
3454
|
return {
|
|
3412
3455
|
unit: mapUnsupportedAsText(widget, ctx),
|
|
3413
3456
|
status: "placeholder",
|
|
@@ -8447,7 +8490,6 @@ var REVIEW_REASONS = {
|
|
|
8447
8490
|
// `tipjar` module (see dispatcher.ts) and lands with `partial` status, so it
|
|
8448
8491
|
// never reaches the placeholder-reason fallback. If a future feature flag
|
|
8449
8492
|
// disables tipjar auto-import, add an entry to FLAG_OFF_REASONS instead.
|
|
8450
|
-
"se-widget-train": "No native Lumia equivalent \u2014 animated subscriber/event train.",
|
|
8451
8493
|
"se-widget-media-share": "No native Lumia equivalent \u2014 viewer-submitted media player.",
|
|
8452
8494
|
"se-widget-contest": "No native Lumia equivalent \u2014 SE-specific contest widget.",
|
|
8453
8495
|
"se-widget-giveaway": "No native Lumia equivalent \u2014 SE giveaway service.",
|
|
@@ -8478,9 +8520,7 @@ function extractSEOverlayId(input) {
|
|
|
8478
8520
|
}
|
|
8479
8521
|
function extractSEPreviewParts(input) {
|
|
8480
8522
|
const trimmed = input.trim();
|
|
8481
|
-
const m = trimmed.match(
|
|
8482
|
-
/streamelements\.com\/overlay\/([0-9a-f]{24})(?:\/([A-Za-z0-9_-]+))?/i
|
|
8483
|
-
);
|
|
8523
|
+
const m = trimmed.match(/streamelements\.com\/overlay\/([0-9a-f]{24})(?:\/([A-Za-z0-9_-]+))?/i);
|
|
8484
8524
|
if (!m) return null;
|
|
8485
8525
|
const overlayId = m[1];
|
|
8486
8526
|
const second = m[2];
|
|
@@ -8515,9 +8555,7 @@ async function fetchSEBootstrap({
|
|
|
8515
8555
|
}
|
|
8516
8556
|
const json = await res.json();
|
|
8517
8557
|
if (!isSEBootstrap(json)) {
|
|
8518
|
-
throw new Error(
|
|
8519
|
-
"Server returned a response that does not look like an SE bootstrap payload."
|
|
8520
|
-
);
|
|
8558
|
+
throw new Error("Server returned a response that does not look like an SE bootstrap payload.");
|
|
8521
8559
|
}
|
|
8522
8560
|
return json;
|
|
8523
8561
|
}
|
|
@@ -8560,11 +8598,7 @@ function importSEBootstrap(bootstrap) {
|
|
|
8560
8598
|
const lumiaGroupId = seUidToLumiaGroupId[uid];
|
|
8561
8599
|
const parentUid = typeof w.group === "string" ? w.group : null;
|
|
8562
8600
|
const parentLumiaGroupId = parentUid ? seUidToLumiaGroupId[parentUid] ?? null : null;
|
|
8563
|
-
const bounds = seCssToBounds(
|
|
8564
|
-
w.css,
|
|
8565
|
-
{ width: 200, height: 200 },
|
|
8566
|
-
importCanvas
|
|
8567
|
-
);
|
|
8601
|
+
const bounds = seCssToBounds(w.css, { width: 200, height: 200 }, importCanvas);
|
|
8568
8602
|
const layer = {
|
|
8569
8603
|
id: lumiaGroupId,
|
|
8570
8604
|
type: "group",
|
|
@@ -8697,9 +8731,7 @@ function applyReviewAction(result, moduleId, action, payload) {
|
|
|
8697
8731
|
if (action === "skip") {
|
|
8698
8732
|
delete modules[moduleId];
|
|
8699
8733
|
const nextLayers = layers.filter((l) => l.id !== moduleId);
|
|
8700
|
-
const reviewItems2 = result.reviewItems.filter(
|
|
8701
|
-
(r) => r.moduleId !== moduleId
|
|
8702
|
-
);
|
|
8734
|
+
const reviewItems2 = result.reviewItems.filter((r) => r.moduleId !== moduleId);
|
|
8703
8735
|
return {
|
|
8704
8736
|
...result,
|
|
8705
8737
|
overlay: {
|
|
@@ -8748,9 +8780,7 @@ function applyReviewAction(result, moduleId, action, payload) {
|
|
|
8748
8780
|
modules[extra.module.id] = extra.module;
|
|
8749
8781
|
}
|
|
8750
8782
|
modules[moduleId] = newModule;
|
|
8751
|
-
const reviewItems2 = result.reviewItems.filter(
|
|
8752
|
-
(r) => r.moduleId !== moduleId
|
|
8753
|
-
);
|
|
8783
|
+
const reviewItems2 = result.reviewItems.filter((r) => r.moduleId !== moduleId);
|
|
8754
8784
|
return {
|
|
8755
8785
|
...result,
|
|
8756
8786
|
overlay: {
|