@lumiastream/ui 0.2.9 → 0.3.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.js +259 -112
- package/dist/se-import.d.ts +1 -1
- package/dist/se-import.js +259 -112
- package/package.json +5 -3
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" },
|
|
@@ -3739,35 +3745,38 @@ function mapReadout(widget, fallbackVar, ctx) {
|
|
|
3739
3745
|
);
|
|
3740
3746
|
}
|
|
3741
3747
|
|
|
3748
|
+
// src/se-import/mappers/alert.ts
|
|
3749
|
+
import { LumiaAlertConfigs } from "@lumiastream/lumia-types";
|
|
3750
|
+
|
|
3742
3751
|
// src/se-import/mappers/provider-alerts.ts
|
|
3743
3752
|
var ALERT_BOX_KEYS = {
|
|
3744
3753
|
twitch: {
|
|
3745
|
-
follower: "twitch-follower",
|
|
3746
|
-
subscriber: "twitch-subscriber",
|
|
3747
|
-
tip: "streamelements-donation",
|
|
3748
|
-
cheer: "twitch-bits",
|
|
3749
|
-
raid: "twitch-raid",
|
|
3750
|
-
merch: "fourthwall-shopOrder",
|
|
3751
|
-
purchase: "fourthwall-shopOrder",
|
|
3752
|
-
charityCampaignDonation: "twitch-charityDonation"
|
|
3754
|
+
follower: ["twitch-follower"],
|
|
3755
|
+
subscriber: ["twitch-subscriber"],
|
|
3756
|
+
tip: ["lumiastream-donation", "streamelements-donation"],
|
|
3757
|
+
cheer: ["twitch-bits"],
|
|
3758
|
+
raid: ["twitch-raid"],
|
|
3759
|
+
merch: ["fourthwall-shopOrder"],
|
|
3760
|
+
purchase: ["fourthwall-shopOrder"],
|
|
3761
|
+
charityCampaignDonation: ["twitch-charityDonation"]
|
|
3753
3762
|
},
|
|
3754
3763
|
kick: {
|
|
3755
|
-
follower: "kick-follower",
|
|
3756
|
-
subscriber: "kick-subscriber",
|
|
3757
|
-
tip: "streamelements-donation",
|
|
3758
|
-
cheer: "kick-kicks",
|
|
3759
|
-
raid: "kick-host",
|
|
3760
|
-
host: "kick-host",
|
|
3761
|
-
merch: "fourthwall-shopOrder",
|
|
3762
|
-
purchase: "fourthwall-shopOrder"
|
|
3764
|
+
follower: ["kick-follower"],
|
|
3765
|
+
subscriber: ["kick-subscriber"],
|
|
3766
|
+
tip: ["lumiastream-donation", "streamelements-donation"],
|
|
3767
|
+
cheer: ["kick-kicks"],
|
|
3768
|
+
raid: ["kick-host"],
|
|
3769
|
+
host: ["kick-host"],
|
|
3770
|
+
merch: ["fourthwall-shopOrder"],
|
|
3771
|
+
purchase: ["fourthwall-shopOrder"]
|
|
3763
3772
|
},
|
|
3764
3773
|
youtube: {
|
|
3765
|
-
follower: "youtube-subscriber",
|
|
3766
|
-
subscriber: "youtube-member",
|
|
3767
|
-
tip: "streamelements-donation",
|
|
3768
|
-
cheer: "youtube-superchat",
|
|
3769
|
-
merch: "fourthwall-shopOrder",
|
|
3770
|
-
purchase: "fourthwall-shopOrder"
|
|
3774
|
+
follower: ["youtube-subscriber"],
|
|
3775
|
+
subscriber: ["youtube-member"],
|
|
3776
|
+
tip: ["lumiastream-donation", "streamelements-donation"],
|
|
3777
|
+
cheer: ["youtube-superchat"],
|
|
3778
|
+
merch: ["fourthwall-shopOrder"],
|
|
3779
|
+
purchase: ["fourthwall-shopOrder"]
|
|
3771
3780
|
}
|
|
3772
3781
|
};
|
|
3773
3782
|
var KAPPAGEN_KEYS = {
|
|
@@ -3776,52 +3785,93 @@ var KAPPAGEN_KEYS = {
|
|
|
3776
3785
|
subscriber: "twitch-subscriber",
|
|
3777
3786
|
cheer: "twitch-bits",
|
|
3778
3787
|
raid: "twitch-raid",
|
|
3779
|
-
tip: "
|
|
3788
|
+
tip: "lumiastream-donation"
|
|
3780
3789
|
},
|
|
3781
3790
|
kick: {
|
|
3782
3791
|
follower: "kick-follower",
|
|
3783
3792
|
subscriber: "kick-subscriber",
|
|
3784
3793
|
cheer: "kick-kicks",
|
|
3785
3794
|
raid: "kick-host",
|
|
3786
|
-
tip: "
|
|
3795
|
+
tip: "lumiastream-donation"
|
|
3787
3796
|
},
|
|
3788
3797
|
youtube: {
|
|
3789
3798
|
follower: "youtube-subscriber",
|
|
3790
3799
|
subscriber: "youtube-member",
|
|
3791
3800
|
cheer: "youtube-superchat",
|
|
3792
|
-
tip: "
|
|
3801
|
+
tip: "lumiastream-donation"
|
|
3793
3802
|
}
|
|
3794
3803
|
};
|
|
3795
3804
|
var STREAMBOSS_LISTENER_KEYS = {
|
|
3796
3805
|
twitch: {
|
|
3797
|
-
"follower-latest": "twitch-follower",
|
|
3798
|
-
"subscriber-latest": "twitch-subscriber",
|
|
3799
|
-
"tip-latest": "lumiastream-donation",
|
|
3800
|
-
"cheer-latest": "twitch-bits",
|
|
3801
|
-
"raid-latest": "twitch-raid"
|
|
3806
|
+
"follower-latest": ["twitch-follower"],
|
|
3807
|
+
"subscriber-latest": ["twitch-subscriber"],
|
|
3808
|
+
"tip-latest": ["lumiastream-donation", "streamelements-donation"],
|
|
3809
|
+
"cheer-latest": ["twitch-bits"],
|
|
3810
|
+
"raid-latest": ["twitch-raid"]
|
|
3802
3811
|
},
|
|
3803
3812
|
kick: {
|
|
3804
|
-
"follower-latest": "kick-follower",
|
|
3805
|
-
"subscriber-latest": "kick-subscriber",
|
|
3806
|
-
"tip-latest": "lumiastream-donation",
|
|
3807
|
-
"cheer-latest": "kick-kicks",
|
|
3808
|
-
"raid-latest": "kick-host"
|
|
3813
|
+
"follower-latest": ["kick-follower"],
|
|
3814
|
+
"subscriber-latest": ["kick-subscriber"],
|
|
3815
|
+
"tip-latest": ["lumiastream-donation", "streamelements-donation"],
|
|
3816
|
+
"cheer-latest": ["kick-kicks"],
|
|
3817
|
+
"raid-latest": ["kick-host"]
|
|
3809
3818
|
},
|
|
3810
3819
|
youtube: {
|
|
3811
|
-
"follower-latest": "youtube-subscriber",
|
|
3812
|
-
"subscriber-latest": "youtube-member",
|
|
3813
|
-
"tip-latest": "lumiastream-donation",
|
|
3814
|
-
"cheer-latest": "youtube-superchat"
|
|
3820
|
+
"follower-latest": ["youtube-subscriber"],
|
|
3821
|
+
"subscriber-latest": ["youtube-member"],
|
|
3822
|
+
"tip-latest": ["lumiastream-donation", "streamelements-donation"],
|
|
3823
|
+
"cheer-latest": ["youtube-superchat"]
|
|
3815
3824
|
}
|
|
3816
3825
|
};
|
|
3817
|
-
|
|
3818
|
-
|
|
3826
|
+
var CURATED_ALERTS = {
|
|
3827
|
+
twitch: [
|
|
3828
|
+
"twitch-follower",
|
|
3829
|
+
"twitch-subscriber",
|
|
3830
|
+
"twitch-giftSubscription",
|
|
3831
|
+
"twitch-bits",
|
|
3832
|
+
"twitch-bitsCombo",
|
|
3833
|
+
"twitch-raid",
|
|
3834
|
+
"twitch-points",
|
|
3835
|
+
"twitch-redemption",
|
|
3836
|
+
"twitch-charityDonation",
|
|
3837
|
+
"twitch-hypetrainStarted",
|
|
3838
|
+
"twitch-clip",
|
|
3839
|
+
"twitch-shoutoutReceive",
|
|
3840
|
+
"twitch-watchStreak",
|
|
3841
|
+
"twitch-firstChatter",
|
|
3842
|
+
"twitch-extension"
|
|
3843
|
+
],
|
|
3844
|
+
kick: [
|
|
3845
|
+
"kick-follower",
|
|
3846
|
+
"kick-subscriber",
|
|
3847
|
+
"kick-subscriptionGift",
|
|
3848
|
+
"kick-kicks",
|
|
3849
|
+
"kick-host",
|
|
3850
|
+
"kick-points",
|
|
3851
|
+
"kick-firstChatter"
|
|
3852
|
+
],
|
|
3853
|
+
youtube: [
|
|
3854
|
+
"youtube-subscriber",
|
|
3855
|
+
"youtube-member",
|
|
3856
|
+
"youtube-giftMembers",
|
|
3857
|
+
"youtube-superchat",
|
|
3858
|
+
"youtube-supersticker",
|
|
3859
|
+
"youtube-gifts",
|
|
3860
|
+
"youtube-like",
|
|
3861
|
+
"youtube-firstChatter"
|
|
3862
|
+
]
|
|
3863
|
+
};
|
|
3864
|
+
function curatedAlertsFor(provider = "twitch") {
|
|
3865
|
+
return CURATED_ALERTS[provider] ?? [];
|
|
3866
|
+
}
|
|
3867
|
+
function alertBoxKeysFor(seEvent, provider = "twitch") {
|
|
3868
|
+
return ALERT_BOX_KEYS[provider]?.[seEvent] ?? [];
|
|
3819
3869
|
}
|
|
3820
3870
|
function kappagenKeyFor(seEvent, provider = "twitch") {
|
|
3821
3871
|
return KAPPAGEN_KEYS[provider]?.[seEvent];
|
|
3822
3872
|
}
|
|
3823
|
-
function
|
|
3824
|
-
return STREAMBOSS_LISTENER_KEYS[provider]?.[seListener];
|
|
3873
|
+
function streamBossListenerKeysFor(seListener, provider = "twitch") {
|
|
3874
|
+
return STREAMBOSS_LISTENER_KEYS[provider]?.[seListener] ?? [];
|
|
3825
3875
|
}
|
|
3826
3876
|
function readBootstrapProvider(bootstrap) {
|
|
3827
3877
|
const ch = bootstrap.channel;
|
|
@@ -4011,6 +4061,16 @@ function pickBaseAlertFields(event) {
|
|
|
4011
4061
|
const { on: _on, variations: _variations, matchEmptyCondition: _mec, ...base } = event;
|
|
4012
4062
|
return base;
|
|
4013
4063
|
}
|
|
4064
|
+
function cloneEventForKey(template, lumiaKey) {
|
|
4065
|
+
const defaultMessage = LumiaAlertConfigs[lumiaKey]?.message ?? "{{username}}";
|
|
4066
|
+
const cloned = structuredClone(template);
|
|
4067
|
+
const c = cloned;
|
|
4068
|
+
if (c.themeSettings) c.themeSettings.firstMessageTemplate = defaultMessage;
|
|
4069
|
+
if (c.text?.content) c.text.content.value = defaultMessage;
|
|
4070
|
+
c.variations = [];
|
|
4071
|
+
c.on = true;
|
|
4072
|
+
return cloned;
|
|
4073
|
+
}
|
|
4014
4074
|
function mapAlertBox(widget, opts = {}, ctx) {
|
|
4015
4075
|
const v = widget.variables ?? {};
|
|
4016
4076
|
const events = {};
|
|
@@ -4019,12 +4079,20 @@ function mapAlertBox(widget, opts = {}, ctx) {
|
|
|
4019
4079
|
for (const seKey of eventKeys) {
|
|
4020
4080
|
const ev = v[seKey];
|
|
4021
4081
|
if (!ev || typeof ev !== "object") continue;
|
|
4022
|
-
const
|
|
4023
|
-
if (
|
|
4082
|
+
const lumiaKeys = alertBoxKeysFor(seKey, ctx?.provider);
|
|
4083
|
+
if (lumiaKeys.length === 0) continue;
|
|
4024
4084
|
const built = buildAlertEvent(ev, seKey);
|
|
4025
|
-
|
|
4085
|
+
for (const lumiaKey of lumiaKeys) {
|
|
4086
|
+
events[lumiaKey] = built;
|
|
4087
|
+
}
|
|
4026
4088
|
if (firstEvent == null) firstEvent = built;
|
|
4027
4089
|
}
|
|
4090
|
+
if (!opts.onlyEvents && firstEvent && ctx?.provider) {
|
|
4091
|
+
for (const lumiaKey of curatedAlertsFor(ctx.provider)) {
|
|
4092
|
+
if (events[lumiaKey]) continue;
|
|
4093
|
+
events[lumiaKey] = cloneEventForKey(firstEvent, lumiaKey);
|
|
4094
|
+
}
|
|
4095
|
+
}
|
|
4028
4096
|
const baseAlert = firstEvent ? pickBaseAlertFields(firstEvent) : {};
|
|
4029
4097
|
return buildUnit(widget, "alert", { alert: { ...baseAlert, events } }, ctx);
|
|
4030
4098
|
}
|
|
@@ -4252,6 +4320,63 @@ import {
|
|
|
4252
4320
|
LumiaEventListTypes,
|
|
4253
4321
|
LumiaMapAlertTypeToEventListType
|
|
4254
4322
|
} from "@lumiastream/lumia-types";
|
|
4323
|
+
|
|
4324
|
+
// src/se-import/mappers/module-defaults.ts
|
|
4325
|
+
var CHATBOX_DEFAULT_CONTENT_FIELDS = {
|
|
4326
|
+
type: "lumia",
|
|
4327
|
+
src: "",
|
|
4328
|
+
userLevels: [1, 2, 3, 4, 5, 6, 7, 8, 9],
|
|
4329
|
+
permanent: true,
|
|
4330
|
+
maxItemsToShow: 20,
|
|
4331
|
+
removeAfter: 3e4,
|
|
4332
|
+
animations: {
|
|
4333
|
+
enterAnimation: "fadeIn",
|
|
4334
|
+
exitAnimation: "fadeOut",
|
|
4335
|
+
enterAnimationDuration: 1e3,
|
|
4336
|
+
exitAnimationDuration: 1e3,
|
|
4337
|
+
enterAnimationDelay: 0,
|
|
4338
|
+
exitAnimationDelay: 0
|
|
4339
|
+
},
|
|
4340
|
+
ignoredList: [],
|
|
4341
|
+
background: "transparent",
|
|
4342
|
+
theme: "simple",
|
|
4343
|
+
chatboxStreamingSite: {
|
|
4344
|
+
twitch: { message: "", icon: "", themeConfig: { primaryColor: "#915dff", showUsernameColors: true } },
|
|
4345
|
+
youtube: { message: "", icon: "", themeConfig: { primaryColor: "#ff0000", usePlatformColor: false } },
|
|
4346
|
+
facebook: { message: "", icon: "", themeConfig: { primaryColor: "#4267B2", usePlatformColor: false } },
|
|
4347
|
+
tiktok: { message: "", icon: "", themeConfig: { primaryColor: "#ff0050", usePlatformColor: false } },
|
|
4348
|
+
kick: { message: "", icon: "", themeConfig: { primaryColor: "#3AD305", usePlatformColor: false } },
|
|
4349
|
+
discord: { message: "", icon: "", themeConfig: { primaryColor: "#7289da", usePlatformColor: false } }
|
|
4350
|
+
},
|
|
4351
|
+
borderRadius: "10px",
|
|
4352
|
+
bgOpacity: 0.4,
|
|
4353
|
+
ignoredStreamingSites: [],
|
|
4354
|
+
horizontal: false,
|
|
4355
|
+
reverseFlow: false,
|
|
4356
|
+
showBadges: true,
|
|
4357
|
+
showSiteIcon: false,
|
|
4358
|
+
showEmotes: true,
|
|
4359
|
+
showAvatar: false,
|
|
4360
|
+
showTimestamp: false,
|
|
4361
|
+
hideAlerts: false,
|
|
4362
|
+
hyperClickableLinks: true,
|
|
4363
|
+
clickableChatterProfiles: false,
|
|
4364
|
+
previewMediaInChat: true,
|
|
4365
|
+
previewMediaUserLevels: ["streamer", "moderators", "vips", "tier3", "tier2", "subscribers", "regular", "follower", "anyone"],
|
|
4366
|
+
breakLine: true,
|
|
4367
|
+
fadeOutAfterDelay: false,
|
|
4368
|
+
fadeOutDelayTime: 5,
|
|
4369
|
+
useAnimatedEmotes: true,
|
|
4370
|
+
sites: ["twitch", "kick", "youtube", "facebook", "discord", "ffz", "seventv", "bttv"],
|
|
4371
|
+
border: "solid 1px transparent",
|
|
4372
|
+
itemGap: 8
|
|
4373
|
+
};
|
|
4374
|
+
var CHATBOX_DEFAULT_MODULE = {
|
|
4375
|
+
version: 7,
|
|
4376
|
+
content: CHATBOX_DEFAULT_CONTENT_FIELDS
|
|
4377
|
+
};
|
|
4378
|
+
|
|
4379
|
+
// src/se-import/mappers/misc.ts
|
|
4255
4380
|
function mapChatboxTheme(seTheme) {
|
|
4256
4381
|
const t = (seTheme ?? "").toString().toLowerCase();
|
|
4257
4382
|
if (!t || t === "default") return "simple";
|
|
@@ -4311,6 +4436,8 @@ function paddingShorthand(message) {
|
|
|
4311
4436
|
return `${px(t)} ${px(r)} ${px(b)} ${px(l)}`;
|
|
4312
4437
|
}
|
|
4313
4438
|
function mapChatbox(widget, ctx) {
|
|
4439
|
+
const chatboxDefaults = CHATBOX_DEFAULT_MODULE.content;
|
|
4440
|
+
const chatboxVersion = CHATBOX_DEFAULT_MODULE.version;
|
|
4314
4441
|
const v = widget.variables ?? {};
|
|
4315
4442
|
const textCss = widget.text?.css ?? {};
|
|
4316
4443
|
const messageCss = textCss.message ?? {};
|
|
@@ -4345,59 +4472,58 @@ function mapChatbox(widget, ctx) {
|
|
|
4345
4472
|
widget,
|
|
4346
4473
|
"chatbox",
|
|
4347
4474
|
{
|
|
4475
|
+
// Stamp the module version from the authoritative defaults so
|
|
4476
|
+
// Overlay-UI's per-module Settings.tsx migration check
|
|
4477
|
+
// (`module?.version !== currentVersion`) treats this import as
|
|
4478
|
+
// already-current. Without this, every freshly-imported chatbox
|
|
4479
|
+
// would trip the migration toast on first open even though the
|
|
4480
|
+
// content is already complete.
|
|
4481
|
+
version: chatboxVersion,
|
|
4348
4482
|
// Visual styling (font / color / padding etc) lives on module.css, not
|
|
4349
4483
|
// content. Lumia's TextStyle settings panel + the chatbox renderer both
|
|
4350
4484
|
// read from here.
|
|
4351
4485
|
css: moduleCss,
|
|
4352
4486
|
content: {
|
|
4487
|
+
// `chatboxDefaults` resolves host-injected first (preferred), then
|
|
4488
|
+
// the local snapshot — see the top of this function. Spreading it
|
|
4489
|
+
// here guarantees every field the chatbox renderer expects is
|
|
4490
|
+
// present (`type`, `sites`, `useAnimatedEmotes`, etc.); the
|
|
4491
|
+
// SE-specific override block below wins for the opinions that
|
|
4492
|
+
// differ from a fresh-add.
|
|
4493
|
+
...chatboxDefaults,
|
|
4494
|
+
// ─── SE-specific overrides ────────────────────────────────────────
|
|
4495
|
+
// The fresh-Lumia defaults assume the streamer is creating a new
|
|
4496
|
+
// chatbox; SE-imported ones have opinions that differ. Override
|
|
4497
|
+
// only those.
|
|
4353
4498
|
theme: mapChatboxTheme(v.theme),
|
|
4354
4499
|
fadeOutAfterDelay: fadeOutSeconds > 0,
|
|
4355
4500
|
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
4501
|
ignoredList: Array.isArray(v.ignored) ? v.ignored : [],
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
reverseFlow: false,
|
|
4365
|
-
hideAlerts: false,
|
|
4366
|
-
hideAlertMessage: false,
|
|
4502
|
+
// SE chat widgets default to showing avatars + site icons + tight
|
|
4503
|
+
// line wrapping; Lumia's fresh default is the opposite.
|
|
4367
4504
|
showAvatar: true,
|
|
4368
|
-
showBadges: true,
|
|
4369
|
-
showEmotes: true,
|
|
4370
4505
|
showSiteIcon: true,
|
|
4371
|
-
showTimestamp: false,
|
|
4372
4506
|
breakLine: false,
|
|
4373
|
-
hyperClickableLinks: true,
|
|
4374
4507
|
clickableChatterProfiles: true,
|
|
4375
|
-
|
|
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
|
-
},
|
|
4508
|
+
hideAlertMessage: false,
|
|
4389
4509
|
// Carry the SE message-level font override and the streamer's
|
|
4390
4510
|
// accent color across so the imported chatbox looks right at
|
|
4391
4511
|
// first paint. Background lives on `module.css.background`
|
|
4392
4512
|
// above — `content.background` was a dead write the renderer
|
|
4393
4513
|
// never read.
|
|
4394
4514
|
...messageFontFamily ? { messageFontFamily } : {},
|
|
4515
|
+
// Twitch primary color override — deep-merge into the full
|
|
4516
|
+
// chatboxStreamingSite map from the default (otherwise we'd
|
|
4517
|
+
// clobber the youtube/kick/facebook/tiktok/discord entries the
|
|
4518
|
+
// chatbox renderer reads for per-platform theming).
|
|
4395
4519
|
...accentColor ? {
|
|
4396
4520
|
chatboxStreamingSite: {
|
|
4521
|
+
...chatboxDefaults.chatboxStreamingSite,
|
|
4397
4522
|
twitch: {
|
|
4523
|
+
...chatboxDefaults.chatboxStreamingSite.twitch,
|
|
4398
4524
|
themeConfig: {
|
|
4399
|
-
|
|
4400
|
-
|
|
4525
|
+
...chatboxDefaults.chatboxStreamingSite.twitch.themeConfig,
|
|
4526
|
+
primaryColor: accentColor
|
|
4401
4527
|
}
|
|
4402
4528
|
}
|
|
4403
4529
|
}
|
|
@@ -4420,20 +4546,28 @@ function mapChatbox(widget, ctx) {
|
|
|
4420
4546
|
}
|
|
4421
4547
|
var SE_LISTENER_TO_LUMIA_CATEGORY = {
|
|
4422
4548
|
"follower-latest": "follower",
|
|
4549
|
+
"follower-recent": "follower",
|
|
4423
4550
|
"subscriber-latest": "subscribers",
|
|
4424
4551
|
"subscriber-new-latest": "subscribers",
|
|
4425
4552
|
"subscriber-resub-latest": "subscribers",
|
|
4553
|
+
"subscriber-recent": "subscribers",
|
|
4426
4554
|
"subscriber-gifted-latest": "gifts",
|
|
4427
4555
|
"community-gift-latest": "gifts",
|
|
4428
4556
|
"cheer-latest": "bits",
|
|
4557
|
+
"cheer-recent": "bits",
|
|
4429
4558
|
"cheerPurchase-latest": "bits",
|
|
4430
4559
|
"tip-latest": "donation",
|
|
4560
|
+
"tip-recent": "donation",
|
|
4431
4561
|
"raid-latest": "raids",
|
|
4562
|
+
"raid-recent": "raids",
|
|
4432
4563
|
"host-latest": "hosts",
|
|
4564
|
+
"host-recent": "hosts",
|
|
4433
4565
|
"redemption-latest": "redemption",
|
|
4434
4566
|
"merch-latest": "purchases",
|
|
4567
|
+
"merch-recent": "purchases",
|
|
4435
4568
|
"purchase-latest": "purchases",
|
|
4436
4569
|
"superchat-latest": "superchats",
|
|
4570
|
+
"superchat-recent": "superchats",
|
|
4437
4571
|
"hypetrain-latest": "hypetrain"
|
|
4438
4572
|
};
|
|
4439
4573
|
var ALL_LUMIA_EVENTLIST_CATEGORIES = [
|
|
@@ -4458,8 +4592,7 @@ var ALL_LUMIA_EVENTLIST_CATEGORIES = [
|
|
|
4458
4592
|
"stars",
|
|
4459
4593
|
"fans",
|
|
4460
4594
|
"shares",
|
|
4461
|
-
"raffles"
|
|
4462
|
-
"others"
|
|
4595
|
+
"raffles"
|
|
4463
4596
|
];
|
|
4464
4597
|
function computeListenerFilters(seListeners, explicitListener) {
|
|
4465
4598
|
const enabled = [];
|
|
@@ -4484,10 +4617,27 @@ function computeListenerFilters(seListeners, explicitListener) {
|
|
|
4484
4617
|
if (allowed.size === 0) return [];
|
|
4485
4618
|
return ALL_LUMIA_EVENTLIST_CATEGORIES.filter((c) => !allowed.has(c));
|
|
4486
4619
|
}
|
|
4620
|
+
function seScrollSpeedToMarqueeDurationSec(seSpeed) {
|
|
4621
|
+
const n = typeof seSpeed === "number" && Number.isFinite(seSpeed) ? seSpeed : 6;
|
|
4622
|
+
const clamped = Math.min(20, Math.max(1, n));
|
|
4623
|
+
const duration = 60 / clamped;
|
|
4624
|
+
return Math.min(120, Math.max(5, Math.round(duration * 10) / 10));
|
|
4625
|
+
}
|
|
4626
|
+
function seTemplateToMarqueeTemplate(seTemplate) {
|
|
4627
|
+
if (typeof seTemplate !== "string" || !seTemplate.trim()) return void 0;
|
|
4628
|
+
return seTemplate.split("{name}").join("{username}").split("{username}").join("{username}");
|
|
4629
|
+
}
|
|
4487
4630
|
function mapEventList(widget, ctx) {
|
|
4488
4631
|
const v = widget.variables ?? {};
|
|
4489
4632
|
const filters = computeListenerFilters(widget.listeners, widget.listener);
|
|
4490
4633
|
const maxItems = v.visibleEvents ?? v.visibleItems ?? 5;
|
|
4634
|
+
const seText = widget.text;
|
|
4635
|
+
const scrolling = seText?.scrolling;
|
|
4636
|
+
const isMarquee = !!(scrolling && scrolling.enabled === true);
|
|
4637
|
+
const itemTemplate = isMarquee ? seTemplateToMarqueeTemplate(seText?.value) : void 0;
|
|
4638
|
+
const marqueeSpeed = isMarquee ? seScrollSpeedToMarqueeDurationSec(scrolling?.speed) : void 0;
|
|
4639
|
+
const marqueeDirection = isMarquee ? scrolling?.direction === "right" ? "right" : "left" : void 0;
|
|
4640
|
+
const theme = isMarquee ? "marquee" : v.theme ?? "simple";
|
|
4491
4641
|
return buildUnit(
|
|
4492
4642
|
widget,
|
|
4493
4643
|
"eventlist",
|
|
@@ -4496,7 +4646,7 @@ function mapEventList(widget, ctx) {
|
|
|
4496
4646
|
// Lumia eventlist reads font/size/color from module.css.
|
|
4497
4647
|
css: mapSeTextCssToModuleCss(widget, { fontSize: 18 }),
|
|
4498
4648
|
content: {
|
|
4499
|
-
theme
|
|
4649
|
+
theme,
|
|
4500
4650
|
direction: v.direction ?? "top",
|
|
4501
4651
|
maxItemsToShow: maxItems,
|
|
4502
4652
|
visibleEvents: maxItems,
|
|
@@ -4508,14 +4658,26 @@ function mapEventList(widget, ctx) {
|
|
|
4508
4658
|
// `sites` is a platform blacklist (same shape). Default to "no platforms hidden".
|
|
4509
4659
|
sites: [],
|
|
4510
4660
|
// Eventlist Manager assumes these objects exist; provide an empty stub so
|
|
4511
|
-
// imported overlays render without throwing.
|
|
4512
|
-
themeConfig
|
|
4661
|
+
// imported overlays render without throwing. The marquee theme reads
|
|
4662
|
+
// `itemTemplate` off either currentThemeConfig or themeConfig — stash
|
|
4663
|
+
// SE's per-item template here so the imported widget reproduces the
|
|
4664
|
+
// original (e.g. "{name} " → "{username} ").
|
|
4665
|
+
themeConfig: isMarquee && itemTemplate ? { itemTemplate } : {},
|
|
4513
4666
|
eventListType: {},
|
|
4514
4667
|
condensedText: false,
|
|
4515
|
-
horizontal
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4668
|
+
// `horizontal` keeps non-marquee widgets that had scrolling enabled in
|
|
4669
|
+
// SE laid out on a single row (eventlist already supports this); for
|
|
4670
|
+
// marquee, the CSS animation drives the scroll so this is informational.
|
|
4671
|
+
horizontal: isMarquee,
|
|
4672
|
+
...isMarquee && marqueeSpeed !== void 0 ? { marqueeSpeed } : {},
|
|
4673
|
+
...isMarquee && marqueeDirection ? { marqueeDirection } : {},
|
|
4674
|
+
// Inter-item spacing for the ticker. SE has no equivalent (their items
|
|
4675
|
+
// butt against each other) but a 24px gap matches the visual rhythm of
|
|
4676
|
+
// their default font sizes and keeps usernames from colliding.
|
|
4677
|
+
...isMarquee ? { marqueeItemGap: 24 } : {},
|
|
4678
|
+
showAlertIcon: !isMarquee,
|
|
4679
|
+
showSiteIcon: !isMarquee,
|
|
4680
|
+
showUserAvatar: !isMarquee,
|
|
4519
4681
|
showDetailedText: false,
|
|
4520
4682
|
hideAlertMessage: false
|
|
4521
4683
|
}
|
|
@@ -5565,13 +5727,15 @@ function mapStreamBoss(widget, ctx) {
|
|
|
5565
5727
|
const selectedEvents = [];
|
|
5566
5728
|
for (const seListener of SE_LISTENERS) {
|
|
5567
5729
|
if (!listenerIsOn(widget.listeners, seListener)) continue;
|
|
5568
|
-
const
|
|
5569
|
-
if (
|
|
5730
|
+
const alertKeys = streamBossListenerKeysFor(seListener, ctx?.provider);
|
|
5731
|
+
if (alertKeys.length === 0) continue;
|
|
5570
5732
|
const raw = seDamage[seListener];
|
|
5571
5733
|
const value = typeof raw === "number" && Number.isFinite(raw) && raw > 0 ? raw : null;
|
|
5572
5734
|
if (value === null) continue;
|
|
5573
|
-
|
|
5574
|
-
|
|
5735
|
+
for (const alertKey of alertKeys) {
|
|
5736
|
+
damageMap[alertKey] = { value, mode: SE_LISTENER_MODE[seListener] };
|
|
5737
|
+
selectedEvents.push(alertKey);
|
|
5738
|
+
}
|
|
5575
5739
|
}
|
|
5576
5740
|
const barColor = typeof v.colors?.frame === "string" && v.colors.frame ? v.colors.frame : "#2bff00";
|
|
5577
5741
|
const theme = v.showImage === false ? "bar-only" : "card";
|
|
@@ -5708,23 +5872,6 @@ var GOAL_TYPES = /* @__PURE__ */ new Set([
|
|
|
5708
5872
|
"se-widget-merch-goal"
|
|
5709
5873
|
]);
|
|
5710
5874
|
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"]);
|
|
5711
|
-
var SCROLLING_RECENT_TYPES = /* @__PURE__ */ new Set([
|
|
5712
|
-
"se-widget-follower-recent",
|
|
5713
|
-
"se-widget-subscriber-recent",
|
|
5714
|
-
"se-widget-cheer-recent",
|
|
5715
|
-
"se-widget-tip-recent"
|
|
5716
|
-
]);
|
|
5717
|
-
var RECENT_TO_LATEST_FALLBACK_VAR = {
|
|
5718
|
-
"se-widget-follower-recent": "twitch_last_follower",
|
|
5719
|
-
"se-widget-subscriber-recent": "twitch_last_subscriber",
|
|
5720
|
-
"se-widget-cheer-recent": "twitch_last_bit",
|
|
5721
|
-
"se-widget-tip-recent": "latest_donator"
|
|
5722
|
-
};
|
|
5723
|
-
function isScrollingRecentWidget(widget) {
|
|
5724
|
-
if (!SCROLLING_RECENT_TYPES.has(widget.type)) return false;
|
|
5725
|
-
const scrolling = widget.text?.scrolling;
|
|
5726
|
-
return !!(scrolling && typeof scrolling === "object" && scrolling.enabled === true);
|
|
5727
|
-
}
|
|
5728
5875
|
function dispatch(widget, ctx) {
|
|
5729
5876
|
const t = widget.type;
|
|
5730
5877
|
console.log("[SE-IMPORT] dispatch widget", {
|
|
@@ -5753,10 +5900,6 @@ function dispatch(widget, ctx) {
|
|
|
5753
5900
|
if (t === "se-widget-donor-drive-alert") return { unit: mapSingleAlert(widget, "donordrive-donation", ctx), status: "direct", lumiaType: "alert" };
|
|
5754
5901
|
if (t === "se-widget-extralife-alert") return { unit: mapSingleAlert(widget, "extralife-donation", ctx), status: "direct", lumiaType: "alert" };
|
|
5755
5902
|
if (t === "se-widget-tiltify-alert") return { unit: mapSingleAlert(widget, "tiltify-campaignDonation", ctx), status: "direct", lumiaType: "alert" };
|
|
5756
|
-
if (isScrollingRecentWidget(widget)) {
|
|
5757
|
-
const fallbackVar = RECENT_TO_LATEST_FALLBACK_VAR[t] ?? "username";
|
|
5758
|
-
return { unit: mapReadout(widget, fallbackVar, ctx), status: "direct", lumiaType: "text" };
|
|
5759
|
-
}
|
|
5760
5903
|
if (EVENTLIST_TYPES.has(t)) return { unit: mapEventList(widget, ctx), status: "direct", lumiaType: "eventlist" };
|
|
5761
5904
|
if (t === "se-widget-top-tippers-list") return { unit: mapViewerProfilesLeaderboard(widget, "tips", ctx), status: "direct", lumiaType: "viewerprofiles" };
|
|
5762
5905
|
if (t === "se-widget-top-cheerers-list") return { unit: mapViewerProfilesLeaderboard(widget, "cheers", ctx), status: "direct", lumiaType: "viewerprofiles" };
|
|
@@ -8472,7 +8615,11 @@ function SEImportWizard({
|
|
|
8472
8615
|
);
|
|
8473
8616
|
mirrorAbortRef.current?.abort();
|
|
8474
8617
|
onClose();
|
|
8475
|
-
if (
|
|
8618
|
+
if (importsToSave.length === 1 && lastUuid) {
|
|
8619
|
+
onComplete({ overlayId: lastUuid });
|
|
8620
|
+
} else if (importsToSave.length > 1) {
|
|
8621
|
+
onComplete({});
|
|
8622
|
+
}
|
|
8476
8623
|
} catch (error) {
|
|
8477
8624
|
notify.error(`Import failed: ${extractErrorMessage(error)}`);
|
|
8478
8625
|
} finally {
|
package/dist/se-import.d.ts
CHANGED
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" },
|
|
@@ -624,35 +630,38 @@ function mapReadout(widget, fallbackVar, ctx) {
|
|
|
624
630
|
);
|
|
625
631
|
}
|
|
626
632
|
|
|
633
|
+
// src/se-import/mappers/alert.ts
|
|
634
|
+
import { LumiaAlertConfigs } from "@lumiastream/lumia-types";
|
|
635
|
+
|
|
627
636
|
// src/se-import/mappers/provider-alerts.ts
|
|
628
637
|
var ALERT_BOX_KEYS = {
|
|
629
638
|
twitch: {
|
|
630
|
-
follower: "twitch-follower",
|
|
631
|
-
subscriber: "twitch-subscriber",
|
|
632
|
-
tip: "streamelements-donation",
|
|
633
|
-
cheer: "twitch-bits",
|
|
634
|
-
raid: "twitch-raid",
|
|
635
|
-
merch: "fourthwall-shopOrder",
|
|
636
|
-
purchase: "fourthwall-shopOrder",
|
|
637
|
-
charityCampaignDonation: "twitch-charityDonation"
|
|
639
|
+
follower: ["twitch-follower"],
|
|
640
|
+
subscriber: ["twitch-subscriber"],
|
|
641
|
+
tip: ["lumiastream-donation", "streamelements-donation"],
|
|
642
|
+
cheer: ["twitch-bits"],
|
|
643
|
+
raid: ["twitch-raid"],
|
|
644
|
+
merch: ["fourthwall-shopOrder"],
|
|
645
|
+
purchase: ["fourthwall-shopOrder"],
|
|
646
|
+
charityCampaignDonation: ["twitch-charityDonation"]
|
|
638
647
|
},
|
|
639
648
|
kick: {
|
|
640
|
-
follower: "kick-follower",
|
|
641
|
-
subscriber: "kick-subscriber",
|
|
642
|
-
tip: "streamelements-donation",
|
|
643
|
-
cheer: "kick-kicks",
|
|
644
|
-
raid: "kick-host",
|
|
645
|
-
host: "kick-host",
|
|
646
|
-
merch: "fourthwall-shopOrder",
|
|
647
|
-
purchase: "fourthwall-shopOrder"
|
|
649
|
+
follower: ["kick-follower"],
|
|
650
|
+
subscriber: ["kick-subscriber"],
|
|
651
|
+
tip: ["lumiastream-donation", "streamelements-donation"],
|
|
652
|
+
cheer: ["kick-kicks"],
|
|
653
|
+
raid: ["kick-host"],
|
|
654
|
+
host: ["kick-host"],
|
|
655
|
+
merch: ["fourthwall-shopOrder"],
|
|
656
|
+
purchase: ["fourthwall-shopOrder"]
|
|
648
657
|
},
|
|
649
658
|
youtube: {
|
|
650
|
-
follower: "youtube-subscriber",
|
|
651
|
-
subscriber: "youtube-member",
|
|
652
|
-
tip: "streamelements-donation",
|
|
653
|
-
cheer: "youtube-superchat",
|
|
654
|
-
merch: "fourthwall-shopOrder",
|
|
655
|
-
purchase: "fourthwall-shopOrder"
|
|
659
|
+
follower: ["youtube-subscriber"],
|
|
660
|
+
subscriber: ["youtube-member"],
|
|
661
|
+
tip: ["lumiastream-donation", "streamelements-donation"],
|
|
662
|
+
cheer: ["youtube-superchat"],
|
|
663
|
+
merch: ["fourthwall-shopOrder"],
|
|
664
|
+
purchase: ["fourthwall-shopOrder"]
|
|
656
665
|
}
|
|
657
666
|
};
|
|
658
667
|
var KAPPAGEN_KEYS = {
|
|
@@ -661,52 +670,93 @@ var KAPPAGEN_KEYS = {
|
|
|
661
670
|
subscriber: "twitch-subscriber",
|
|
662
671
|
cheer: "twitch-bits",
|
|
663
672
|
raid: "twitch-raid",
|
|
664
|
-
tip: "
|
|
673
|
+
tip: "lumiastream-donation"
|
|
665
674
|
},
|
|
666
675
|
kick: {
|
|
667
676
|
follower: "kick-follower",
|
|
668
677
|
subscriber: "kick-subscriber",
|
|
669
678
|
cheer: "kick-kicks",
|
|
670
679
|
raid: "kick-host",
|
|
671
|
-
tip: "
|
|
680
|
+
tip: "lumiastream-donation"
|
|
672
681
|
},
|
|
673
682
|
youtube: {
|
|
674
683
|
follower: "youtube-subscriber",
|
|
675
684
|
subscriber: "youtube-member",
|
|
676
685
|
cheer: "youtube-superchat",
|
|
677
|
-
tip: "
|
|
686
|
+
tip: "lumiastream-donation"
|
|
678
687
|
}
|
|
679
688
|
};
|
|
680
689
|
var STREAMBOSS_LISTENER_KEYS = {
|
|
681
690
|
twitch: {
|
|
682
|
-
"follower-latest": "twitch-follower",
|
|
683
|
-
"subscriber-latest": "twitch-subscriber",
|
|
684
|
-
"tip-latest": "lumiastream-donation",
|
|
685
|
-
"cheer-latest": "twitch-bits",
|
|
686
|
-
"raid-latest": "twitch-raid"
|
|
691
|
+
"follower-latest": ["twitch-follower"],
|
|
692
|
+
"subscriber-latest": ["twitch-subscriber"],
|
|
693
|
+
"tip-latest": ["lumiastream-donation", "streamelements-donation"],
|
|
694
|
+
"cheer-latest": ["twitch-bits"],
|
|
695
|
+
"raid-latest": ["twitch-raid"]
|
|
687
696
|
},
|
|
688
697
|
kick: {
|
|
689
|
-
"follower-latest": "kick-follower",
|
|
690
|
-
"subscriber-latest": "kick-subscriber",
|
|
691
|
-
"tip-latest": "lumiastream-donation",
|
|
692
|
-
"cheer-latest": "kick-kicks",
|
|
693
|
-
"raid-latest": "kick-host"
|
|
698
|
+
"follower-latest": ["kick-follower"],
|
|
699
|
+
"subscriber-latest": ["kick-subscriber"],
|
|
700
|
+
"tip-latest": ["lumiastream-donation", "streamelements-donation"],
|
|
701
|
+
"cheer-latest": ["kick-kicks"],
|
|
702
|
+
"raid-latest": ["kick-host"]
|
|
694
703
|
},
|
|
695
704
|
youtube: {
|
|
696
|
-
"follower-latest": "youtube-subscriber",
|
|
697
|
-
"subscriber-latest": "youtube-member",
|
|
698
|
-
"tip-latest": "lumiastream-donation",
|
|
699
|
-
"cheer-latest": "youtube-superchat"
|
|
705
|
+
"follower-latest": ["youtube-subscriber"],
|
|
706
|
+
"subscriber-latest": ["youtube-member"],
|
|
707
|
+
"tip-latest": ["lumiastream-donation", "streamelements-donation"],
|
|
708
|
+
"cheer-latest": ["youtube-superchat"]
|
|
700
709
|
}
|
|
701
710
|
};
|
|
702
|
-
|
|
703
|
-
|
|
711
|
+
var CURATED_ALERTS = {
|
|
712
|
+
twitch: [
|
|
713
|
+
"twitch-follower",
|
|
714
|
+
"twitch-subscriber",
|
|
715
|
+
"twitch-giftSubscription",
|
|
716
|
+
"twitch-bits",
|
|
717
|
+
"twitch-bitsCombo",
|
|
718
|
+
"twitch-raid",
|
|
719
|
+
"twitch-points",
|
|
720
|
+
"twitch-redemption",
|
|
721
|
+
"twitch-charityDonation",
|
|
722
|
+
"twitch-hypetrainStarted",
|
|
723
|
+
"twitch-clip",
|
|
724
|
+
"twitch-shoutoutReceive",
|
|
725
|
+
"twitch-watchStreak",
|
|
726
|
+
"twitch-firstChatter",
|
|
727
|
+
"twitch-extension"
|
|
728
|
+
],
|
|
729
|
+
kick: [
|
|
730
|
+
"kick-follower",
|
|
731
|
+
"kick-subscriber",
|
|
732
|
+
"kick-subscriptionGift",
|
|
733
|
+
"kick-kicks",
|
|
734
|
+
"kick-host",
|
|
735
|
+
"kick-points",
|
|
736
|
+
"kick-firstChatter"
|
|
737
|
+
],
|
|
738
|
+
youtube: [
|
|
739
|
+
"youtube-subscriber",
|
|
740
|
+
"youtube-member",
|
|
741
|
+
"youtube-giftMembers",
|
|
742
|
+
"youtube-superchat",
|
|
743
|
+
"youtube-supersticker",
|
|
744
|
+
"youtube-gifts",
|
|
745
|
+
"youtube-like",
|
|
746
|
+
"youtube-firstChatter"
|
|
747
|
+
]
|
|
748
|
+
};
|
|
749
|
+
function curatedAlertsFor(provider = "twitch") {
|
|
750
|
+
return CURATED_ALERTS[provider] ?? [];
|
|
751
|
+
}
|
|
752
|
+
function alertBoxKeysFor(seEvent, provider = "twitch") {
|
|
753
|
+
return ALERT_BOX_KEYS[provider]?.[seEvent] ?? [];
|
|
704
754
|
}
|
|
705
755
|
function kappagenKeyFor(seEvent, provider = "twitch") {
|
|
706
756
|
return KAPPAGEN_KEYS[provider]?.[seEvent];
|
|
707
757
|
}
|
|
708
|
-
function
|
|
709
|
-
return STREAMBOSS_LISTENER_KEYS[provider]?.[seListener];
|
|
758
|
+
function streamBossListenerKeysFor(seListener, provider = "twitch") {
|
|
759
|
+
return STREAMBOSS_LISTENER_KEYS[provider]?.[seListener] ?? [];
|
|
710
760
|
}
|
|
711
761
|
function readBootstrapProvider(bootstrap) {
|
|
712
762
|
const ch = bootstrap.channel;
|
|
@@ -896,6 +946,16 @@ function pickBaseAlertFields(event) {
|
|
|
896
946
|
const { on: _on, variations: _variations, matchEmptyCondition: _mec, ...base } = event;
|
|
897
947
|
return base;
|
|
898
948
|
}
|
|
949
|
+
function cloneEventForKey(template, lumiaKey) {
|
|
950
|
+
const defaultMessage = LumiaAlertConfigs[lumiaKey]?.message ?? "{{username}}";
|
|
951
|
+
const cloned = structuredClone(template);
|
|
952
|
+
const c = cloned;
|
|
953
|
+
if (c.themeSettings) c.themeSettings.firstMessageTemplate = defaultMessage;
|
|
954
|
+
if (c.text?.content) c.text.content.value = defaultMessage;
|
|
955
|
+
c.variations = [];
|
|
956
|
+
c.on = true;
|
|
957
|
+
return cloned;
|
|
958
|
+
}
|
|
899
959
|
function mapAlertBox(widget, opts = {}, ctx) {
|
|
900
960
|
const v = widget.variables ?? {};
|
|
901
961
|
const events = {};
|
|
@@ -904,12 +964,20 @@ function mapAlertBox(widget, opts = {}, ctx) {
|
|
|
904
964
|
for (const seKey of eventKeys) {
|
|
905
965
|
const ev = v[seKey];
|
|
906
966
|
if (!ev || typeof ev !== "object") continue;
|
|
907
|
-
const
|
|
908
|
-
if (
|
|
967
|
+
const lumiaKeys = alertBoxKeysFor(seKey, ctx?.provider);
|
|
968
|
+
if (lumiaKeys.length === 0) continue;
|
|
909
969
|
const built = buildAlertEvent(ev, seKey);
|
|
910
|
-
|
|
970
|
+
for (const lumiaKey of lumiaKeys) {
|
|
971
|
+
events[lumiaKey] = built;
|
|
972
|
+
}
|
|
911
973
|
if (firstEvent == null) firstEvent = built;
|
|
912
974
|
}
|
|
975
|
+
if (!opts.onlyEvents && firstEvent && ctx?.provider) {
|
|
976
|
+
for (const lumiaKey of curatedAlertsFor(ctx.provider)) {
|
|
977
|
+
if (events[lumiaKey]) continue;
|
|
978
|
+
events[lumiaKey] = cloneEventForKey(firstEvent, lumiaKey);
|
|
979
|
+
}
|
|
980
|
+
}
|
|
913
981
|
const baseAlert = firstEvent ? pickBaseAlertFields(firstEvent) : {};
|
|
914
982
|
return buildUnit(widget, "alert", { alert: { ...baseAlert, events } }, ctx);
|
|
915
983
|
}
|
|
@@ -1137,6 +1205,63 @@ import {
|
|
|
1137
1205
|
LumiaEventListTypes,
|
|
1138
1206
|
LumiaMapAlertTypeToEventListType
|
|
1139
1207
|
} from "@lumiastream/lumia-types";
|
|
1208
|
+
|
|
1209
|
+
// src/se-import/mappers/module-defaults.ts
|
|
1210
|
+
var CHATBOX_DEFAULT_CONTENT_FIELDS = {
|
|
1211
|
+
type: "lumia",
|
|
1212
|
+
src: "",
|
|
1213
|
+
userLevels: [1, 2, 3, 4, 5, 6, 7, 8, 9],
|
|
1214
|
+
permanent: true,
|
|
1215
|
+
maxItemsToShow: 20,
|
|
1216
|
+
removeAfter: 3e4,
|
|
1217
|
+
animations: {
|
|
1218
|
+
enterAnimation: "fadeIn",
|
|
1219
|
+
exitAnimation: "fadeOut",
|
|
1220
|
+
enterAnimationDuration: 1e3,
|
|
1221
|
+
exitAnimationDuration: 1e3,
|
|
1222
|
+
enterAnimationDelay: 0,
|
|
1223
|
+
exitAnimationDelay: 0
|
|
1224
|
+
},
|
|
1225
|
+
ignoredList: [],
|
|
1226
|
+
background: "transparent",
|
|
1227
|
+
theme: "simple",
|
|
1228
|
+
chatboxStreamingSite: {
|
|
1229
|
+
twitch: { message: "", icon: "", themeConfig: { primaryColor: "#915dff", showUsernameColors: true } },
|
|
1230
|
+
youtube: { message: "", icon: "", themeConfig: { primaryColor: "#ff0000", usePlatformColor: false } },
|
|
1231
|
+
facebook: { message: "", icon: "", themeConfig: { primaryColor: "#4267B2", usePlatformColor: false } },
|
|
1232
|
+
tiktok: { message: "", icon: "", themeConfig: { primaryColor: "#ff0050", usePlatformColor: false } },
|
|
1233
|
+
kick: { message: "", icon: "", themeConfig: { primaryColor: "#3AD305", usePlatformColor: false } },
|
|
1234
|
+
discord: { message: "", icon: "", themeConfig: { primaryColor: "#7289da", usePlatformColor: false } }
|
|
1235
|
+
},
|
|
1236
|
+
borderRadius: "10px",
|
|
1237
|
+
bgOpacity: 0.4,
|
|
1238
|
+
ignoredStreamingSites: [],
|
|
1239
|
+
horizontal: false,
|
|
1240
|
+
reverseFlow: false,
|
|
1241
|
+
showBadges: true,
|
|
1242
|
+
showSiteIcon: false,
|
|
1243
|
+
showEmotes: true,
|
|
1244
|
+
showAvatar: false,
|
|
1245
|
+
showTimestamp: false,
|
|
1246
|
+
hideAlerts: false,
|
|
1247
|
+
hyperClickableLinks: true,
|
|
1248
|
+
clickableChatterProfiles: false,
|
|
1249
|
+
previewMediaInChat: true,
|
|
1250
|
+
previewMediaUserLevels: ["streamer", "moderators", "vips", "tier3", "tier2", "subscribers", "regular", "follower", "anyone"],
|
|
1251
|
+
breakLine: true,
|
|
1252
|
+
fadeOutAfterDelay: false,
|
|
1253
|
+
fadeOutDelayTime: 5,
|
|
1254
|
+
useAnimatedEmotes: true,
|
|
1255
|
+
sites: ["twitch", "kick", "youtube", "facebook", "discord", "ffz", "seventv", "bttv"],
|
|
1256
|
+
border: "solid 1px transparent",
|
|
1257
|
+
itemGap: 8
|
|
1258
|
+
};
|
|
1259
|
+
var CHATBOX_DEFAULT_MODULE = {
|
|
1260
|
+
version: 7,
|
|
1261
|
+
content: CHATBOX_DEFAULT_CONTENT_FIELDS
|
|
1262
|
+
};
|
|
1263
|
+
|
|
1264
|
+
// src/se-import/mappers/misc.ts
|
|
1140
1265
|
function mapChatboxTheme(seTheme) {
|
|
1141
1266
|
const t = (seTheme ?? "").toString().toLowerCase();
|
|
1142
1267
|
if (!t || t === "default") return "simple";
|
|
@@ -1196,6 +1321,8 @@ function paddingShorthand(message) {
|
|
|
1196
1321
|
return `${px(t)} ${px(r)} ${px(b)} ${px(l)}`;
|
|
1197
1322
|
}
|
|
1198
1323
|
function mapChatbox(widget, ctx) {
|
|
1324
|
+
const chatboxDefaults = CHATBOX_DEFAULT_MODULE.content;
|
|
1325
|
+
const chatboxVersion = CHATBOX_DEFAULT_MODULE.version;
|
|
1199
1326
|
const v = widget.variables ?? {};
|
|
1200
1327
|
const textCss = widget.text?.css ?? {};
|
|
1201
1328
|
const messageCss = textCss.message ?? {};
|
|
@@ -1230,59 +1357,58 @@ function mapChatbox(widget, ctx) {
|
|
|
1230
1357
|
widget,
|
|
1231
1358
|
"chatbox",
|
|
1232
1359
|
{
|
|
1360
|
+
// Stamp the module version from the authoritative defaults so
|
|
1361
|
+
// Overlay-UI's per-module Settings.tsx migration check
|
|
1362
|
+
// (`module?.version !== currentVersion`) treats this import as
|
|
1363
|
+
// already-current. Without this, every freshly-imported chatbox
|
|
1364
|
+
// would trip the migration toast on first open even though the
|
|
1365
|
+
// content is already complete.
|
|
1366
|
+
version: chatboxVersion,
|
|
1233
1367
|
// Visual styling (font / color / padding etc) lives on module.css, not
|
|
1234
1368
|
// content. Lumia's TextStyle settings panel + the chatbox renderer both
|
|
1235
1369
|
// read from here.
|
|
1236
1370
|
css: moduleCss,
|
|
1237
1371
|
content: {
|
|
1372
|
+
// `chatboxDefaults` resolves host-injected first (preferred), then
|
|
1373
|
+
// the local snapshot — see the top of this function. Spreading it
|
|
1374
|
+
// here guarantees every field the chatbox renderer expects is
|
|
1375
|
+
// present (`type`, `sites`, `useAnimatedEmotes`, etc.); the
|
|
1376
|
+
// SE-specific override block below wins for the opinions that
|
|
1377
|
+
// differ from a fresh-add.
|
|
1378
|
+
...chatboxDefaults,
|
|
1379
|
+
// ─── SE-specific overrides ────────────────────────────────────────
|
|
1380
|
+
// The fresh-Lumia defaults assume the streamer is creating a new
|
|
1381
|
+
// chatbox; SE-imported ones have opinions that differ. Override
|
|
1382
|
+
// only those.
|
|
1238
1383
|
theme: mapChatboxTheme(v.theme),
|
|
1239
1384
|
fadeOutAfterDelay: fadeOutSeconds > 0,
|
|
1240
1385
|
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
1386
|
ignoredList: Array.isArray(v.ignored) ? v.ignored : [],
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
reverseFlow: false,
|
|
1250
|
-
hideAlerts: false,
|
|
1251
|
-
hideAlertMessage: false,
|
|
1387
|
+
// SE chat widgets default to showing avatars + site icons + tight
|
|
1388
|
+
// line wrapping; Lumia's fresh default is the opposite.
|
|
1252
1389
|
showAvatar: true,
|
|
1253
|
-
showBadges: true,
|
|
1254
|
-
showEmotes: true,
|
|
1255
1390
|
showSiteIcon: true,
|
|
1256
|
-
showTimestamp: false,
|
|
1257
1391
|
breakLine: false,
|
|
1258
|
-
hyperClickableLinks: true,
|
|
1259
1392
|
clickableChatterProfiles: true,
|
|
1260
|
-
|
|
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
|
-
},
|
|
1393
|
+
hideAlertMessage: false,
|
|
1274
1394
|
// Carry the SE message-level font override and the streamer's
|
|
1275
1395
|
// accent color across so the imported chatbox looks right at
|
|
1276
1396
|
// first paint. Background lives on `module.css.background`
|
|
1277
1397
|
// above — `content.background` was a dead write the renderer
|
|
1278
1398
|
// never read.
|
|
1279
1399
|
...messageFontFamily ? { messageFontFamily } : {},
|
|
1400
|
+
// Twitch primary color override — deep-merge into the full
|
|
1401
|
+
// chatboxStreamingSite map from the default (otherwise we'd
|
|
1402
|
+
// clobber the youtube/kick/facebook/tiktok/discord entries the
|
|
1403
|
+
// chatbox renderer reads for per-platform theming).
|
|
1280
1404
|
...accentColor ? {
|
|
1281
1405
|
chatboxStreamingSite: {
|
|
1406
|
+
...chatboxDefaults.chatboxStreamingSite,
|
|
1282
1407
|
twitch: {
|
|
1408
|
+
...chatboxDefaults.chatboxStreamingSite.twitch,
|
|
1283
1409
|
themeConfig: {
|
|
1284
|
-
|
|
1285
|
-
|
|
1410
|
+
...chatboxDefaults.chatboxStreamingSite.twitch.themeConfig,
|
|
1411
|
+
primaryColor: accentColor
|
|
1286
1412
|
}
|
|
1287
1413
|
}
|
|
1288
1414
|
}
|
|
@@ -1305,20 +1431,28 @@ function mapChatbox(widget, ctx) {
|
|
|
1305
1431
|
}
|
|
1306
1432
|
var SE_LISTENER_TO_LUMIA_CATEGORY = {
|
|
1307
1433
|
"follower-latest": "follower",
|
|
1434
|
+
"follower-recent": "follower",
|
|
1308
1435
|
"subscriber-latest": "subscribers",
|
|
1309
1436
|
"subscriber-new-latest": "subscribers",
|
|
1310
1437
|
"subscriber-resub-latest": "subscribers",
|
|
1438
|
+
"subscriber-recent": "subscribers",
|
|
1311
1439
|
"subscriber-gifted-latest": "gifts",
|
|
1312
1440
|
"community-gift-latest": "gifts",
|
|
1313
1441
|
"cheer-latest": "bits",
|
|
1442
|
+
"cheer-recent": "bits",
|
|
1314
1443
|
"cheerPurchase-latest": "bits",
|
|
1315
1444
|
"tip-latest": "donation",
|
|
1445
|
+
"tip-recent": "donation",
|
|
1316
1446
|
"raid-latest": "raids",
|
|
1447
|
+
"raid-recent": "raids",
|
|
1317
1448
|
"host-latest": "hosts",
|
|
1449
|
+
"host-recent": "hosts",
|
|
1318
1450
|
"redemption-latest": "redemption",
|
|
1319
1451
|
"merch-latest": "purchases",
|
|
1452
|
+
"merch-recent": "purchases",
|
|
1320
1453
|
"purchase-latest": "purchases",
|
|
1321
1454
|
"superchat-latest": "superchats",
|
|
1455
|
+
"superchat-recent": "superchats",
|
|
1322
1456
|
"hypetrain-latest": "hypetrain"
|
|
1323
1457
|
};
|
|
1324
1458
|
var ALL_LUMIA_EVENTLIST_CATEGORIES = [
|
|
@@ -1343,8 +1477,7 @@ var ALL_LUMIA_EVENTLIST_CATEGORIES = [
|
|
|
1343
1477
|
"stars",
|
|
1344
1478
|
"fans",
|
|
1345
1479
|
"shares",
|
|
1346
|
-
"raffles"
|
|
1347
|
-
"others"
|
|
1480
|
+
"raffles"
|
|
1348
1481
|
];
|
|
1349
1482
|
function computeListenerFilters(seListeners, explicitListener) {
|
|
1350
1483
|
const enabled = [];
|
|
@@ -1369,10 +1502,27 @@ function computeListenerFilters(seListeners, explicitListener) {
|
|
|
1369
1502
|
if (allowed.size === 0) return [];
|
|
1370
1503
|
return ALL_LUMIA_EVENTLIST_CATEGORIES.filter((c) => !allowed.has(c));
|
|
1371
1504
|
}
|
|
1505
|
+
function seScrollSpeedToMarqueeDurationSec(seSpeed) {
|
|
1506
|
+
const n = typeof seSpeed === "number" && Number.isFinite(seSpeed) ? seSpeed : 6;
|
|
1507
|
+
const clamped = Math.min(20, Math.max(1, n));
|
|
1508
|
+
const duration = 60 / clamped;
|
|
1509
|
+
return Math.min(120, Math.max(5, Math.round(duration * 10) / 10));
|
|
1510
|
+
}
|
|
1511
|
+
function seTemplateToMarqueeTemplate(seTemplate) {
|
|
1512
|
+
if (typeof seTemplate !== "string" || !seTemplate.trim()) return void 0;
|
|
1513
|
+
return seTemplate.split("{name}").join("{username}").split("{username}").join("{username}");
|
|
1514
|
+
}
|
|
1372
1515
|
function mapEventList(widget, ctx) {
|
|
1373
1516
|
const v = widget.variables ?? {};
|
|
1374
1517
|
const filters = computeListenerFilters(widget.listeners, widget.listener);
|
|
1375
1518
|
const maxItems = v.visibleEvents ?? v.visibleItems ?? 5;
|
|
1519
|
+
const seText = widget.text;
|
|
1520
|
+
const scrolling = seText?.scrolling;
|
|
1521
|
+
const isMarquee = !!(scrolling && scrolling.enabled === true);
|
|
1522
|
+
const itemTemplate = isMarquee ? seTemplateToMarqueeTemplate(seText?.value) : void 0;
|
|
1523
|
+
const marqueeSpeed = isMarquee ? seScrollSpeedToMarqueeDurationSec(scrolling?.speed) : void 0;
|
|
1524
|
+
const marqueeDirection = isMarquee ? scrolling?.direction === "right" ? "right" : "left" : void 0;
|
|
1525
|
+
const theme = isMarquee ? "marquee" : v.theme ?? "simple";
|
|
1376
1526
|
return buildUnit(
|
|
1377
1527
|
widget,
|
|
1378
1528
|
"eventlist",
|
|
@@ -1381,7 +1531,7 @@ function mapEventList(widget, ctx) {
|
|
|
1381
1531
|
// Lumia eventlist reads font/size/color from module.css.
|
|
1382
1532
|
css: mapSeTextCssToModuleCss(widget, { fontSize: 18 }),
|
|
1383
1533
|
content: {
|
|
1384
|
-
theme
|
|
1534
|
+
theme,
|
|
1385
1535
|
direction: v.direction ?? "top",
|
|
1386
1536
|
maxItemsToShow: maxItems,
|
|
1387
1537
|
visibleEvents: maxItems,
|
|
@@ -1393,14 +1543,26 @@ function mapEventList(widget, ctx) {
|
|
|
1393
1543
|
// `sites` is a platform blacklist (same shape). Default to "no platforms hidden".
|
|
1394
1544
|
sites: [],
|
|
1395
1545
|
// Eventlist Manager assumes these objects exist; provide an empty stub so
|
|
1396
|
-
// imported overlays render without throwing.
|
|
1397
|
-
themeConfig
|
|
1546
|
+
// imported overlays render without throwing. The marquee theme reads
|
|
1547
|
+
// `itemTemplate` off either currentThemeConfig or themeConfig — stash
|
|
1548
|
+
// SE's per-item template here so the imported widget reproduces the
|
|
1549
|
+
// original (e.g. "{name} " → "{username} ").
|
|
1550
|
+
themeConfig: isMarquee && itemTemplate ? { itemTemplate } : {},
|
|
1398
1551
|
eventListType: {},
|
|
1399
1552
|
condensedText: false,
|
|
1400
|
-
horizontal
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1553
|
+
// `horizontal` keeps non-marquee widgets that had scrolling enabled in
|
|
1554
|
+
// SE laid out on a single row (eventlist already supports this); for
|
|
1555
|
+
// marquee, the CSS animation drives the scroll so this is informational.
|
|
1556
|
+
horizontal: isMarquee,
|
|
1557
|
+
...isMarquee && marqueeSpeed !== void 0 ? { marqueeSpeed } : {},
|
|
1558
|
+
...isMarquee && marqueeDirection ? { marqueeDirection } : {},
|
|
1559
|
+
// Inter-item spacing for the ticker. SE has no equivalent (their items
|
|
1560
|
+
// butt against each other) but a 24px gap matches the visual rhythm of
|
|
1561
|
+
// their default font sizes and keeps usernames from colliding.
|
|
1562
|
+
...isMarquee ? { marqueeItemGap: 24 } : {},
|
|
1563
|
+
showAlertIcon: !isMarquee,
|
|
1564
|
+
showSiteIcon: !isMarquee,
|
|
1565
|
+
showUserAvatar: !isMarquee,
|
|
1404
1566
|
showDetailedText: false,
|
|
1405
1567
|
hideAlertMessage: false
|
|
1406
1568
|
}
|
|
@@ -2450,13 +2612,15 @@ function mapStreamBoss(widget, ctx) {
|
|
|
2450
2612
|
const selectedEvents = [];
|
|
2451
2613
|
for (const seListener of SE_LISTENERS) {
|
|
2452
2614
|
if (!listenerIsOn(widget.listeners, seListener)) continue;
|
|
2453
|
-
const
|
|
2454
|
-
if (
|
|
2615
|
+
const alertKeys = streamBossListenerKeysFor(seListener, ctx?.provider);
|
|
2616
|
+
if (alertKeys.length === 0) continue;
|
|
2455
2617
|
const raw = seDamage[seListener];
|
|
2456
2618
|
const value = typeof raw === "number" && Number.isFinite(raw) && raw > 0 ? raw : null;
|
|
2457
2619
|
if (value === null) continue;
|
|
2458
|
-
|
|
2459
|
-
|
|
2620
|
+
for (const alertKey of alertKeys) {
|
|
2621
|
+
damageMap[alertKey] = { value, mode: SE_LISTENER_MODE[seListener] };
|
|
2622
|
+
selectedEvents.push(alertKey);
|
|
2623
|
+
}
|
|
2460
2624
|
}
|
|
2461
2625
|
const barColor = typeof v.colors?.frame === "string" && v.colors.frame ? v.colors.frame : "#2bff00";
|
|
2462
2626
|
const theme = v.showImage === false ? "bar-only" : "card";
|
|
@@ -2593,23 +2757,6 @@ var GOAL_TYPES = /* @__PURE__ */ new Set([
|
|
|
2593
2757
|
"se-widget-merch-goal"
|
|
2594
2758
|
]);
|
|
2595
2759
|
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"]);
|
|
2596
|
-
var SCROLLING_RECENT_TYPES = /* @__PURE__ */ new Set([
|
|
2597
|
-
"se-widget-follower-recent",
|
|
2598
|
-
"se-widget-subscriber-recent",
|
|
2599
|
-
"se-widget-cheer-recent",
|
|
2600
|
-
"se-widget-tip-recent"
|
|
2601
|
-
]);
|
|
2602
|
-
var RECENT_TO_LATEST_FALLBACK_VAR = {
|
|
2603
|
-
"se-widget-follower-recent": "twitch_last_follower",
|
|
2604
|
-
"se-widget-subscriber-recent": "twitch_last_subscriber",
|
|
2605
|
-
"se-widget-cheer-recent": "twitch_last_bit",
|
|
2606
|
-
"se-widget-tip-recent": "latest_donator"
|
|
2607
|
-
};
|
|
2608
|
-
function isScrollingRecentWidget(widget) {
|
|
2609
|
-
if (!SCROLLING_RECENT_TYPES.has(widget.type)) return false;
|
|
2610
|
-
const scrolling = widget.text?.scrolling;
|
|
2611
|
-
return !!(scrolling && typeof scrolling === "object" && scrolling.enabled === true);
|
|
2612
|
-
}
|
|
2613
2760
|
function dispatch(widget, ctx) {
|
|
2614
2761
|
const t = widget.type;
|
|
2615
2762
|
console.log("[SE-IMPORT] dispatch widget", {
|
|
@@ -2638,10 +2785,6 @@ function dispatch(widget, ctx) {
|
|
|
2638
2785
|
if (t === "se-widget-donor-drive-alert") return { unit: mapSingleAlert(widget, "donordrive-donation", ctx), status: "direct", lumiaType: "alert" };
|
|
2639
2786
|
if (t === "se-widget-extralife-alert") return { unit: mapSingleAlert(widget, "extralife-donation", ctx), status: "direct", lumiaType: "alert" };
|
|
2640
2787
|
if (t === "se-widget-tiltify-alert") return { unit: mapSingleAlert(widget, "tiltify-campaignDonation", ctx), status: "direct", lumiaType: "alert" };
|
|
2641
|
-
if (isScrollingRecentWidget(widget)) {
|
|
2642
|
-
const fallbackVar = RECENT_TO_LATEST_FALLBACK_VAR[t] ?? "username";
|
|
2643
|
-
return { unit: mapReadout(widget, fallbackVar, ctx), status: "direct", lumiaType: "text" };
|
|
2644
|
-
}
|
|
2645
2788
|
if (EVENTLIST_TYPES.has(t)) return { unit: mapEventList(widget, ctx), status: "direct", lumiaType: "eventlist" };
|
|
2646
2789
|
if (t === "se-widget-top-tippers-list") return { unit: mapViewerProfilesLeaderboard(widget, "tips", ctx), status: "direct", lumiaType: "viewerprofiles" };
|
|
2647
2790
|
if (t === "se-widget-top-cheerers-list") return { unit: mapViewerProfilesLeaderboard(widget, "cheers", ctx), status: "direct", lumiaType: "viewerprofiles" };
|
|
@@ -7342,7 +7485,11 @@ function SEImportWizard({
|
|
|
7342
7485
|
);
|
|
7343
7486
|
mirrorAbortRef.current?.abort();
|
|
7344
7487
|
onClose();
|
|
7345
|
-
if (
|
|
7488
|
+
if (importsToSave.length === 1 && lastUuid) {
|
|
7489
|
+
onComplete({ overlayId: lastUuid });
|
|
7490
|
+
} else if (importsToSave.length > 1) {
|
|
7491
|
+
onComplete({});
|
|
7492
|
+
}
|
|
7346
7493
|
} catch (error) {
|
|
7347
7494
|
notify.error(`Import failed: ${extractErrorMessage(error)}`);
|
|
7348
7495
|
} finally {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lumiastream/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
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.
|
|
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",
|