From 094a1441cdad9a9f2fe081e0bc9c666365680213 Mon Sep 17 00:00:00 2001 From: Sean Beyer Date: Fri, 30 Jan 2026 13:58:29 -0800 Subject: [PATCH 1/5] Add EventList component --- app/components-react/widgets/EventList.tsx | 227 +++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 app/components-react/widgets/EventList.tsx diff --git a/app/components-react/widgets/EventList.tsx b/app/components-react/widgets/EventList.tsx new file mode 100644 index 000000000000..eab54bdceb67 --- /dev/null +++ b/app/components-react/widgets/EventList.tsx @@ -0,0 +1,227 @@ +import React from 'react'; +import { Menu } from 'antd'; +import { IWidgetCommonState, useWidget, WidgetModule } from './common/useWidget'; +import { WidgetLayout } from './common/WidgetLayout'; +import { $t } from '../../services/i18n'; +import { metadata } from '../shared/inputs/metadata'; +import FormFactory from 'components-react/shared/inputs/FormFactory'; +import { UserService } from 'app-services'; +import { Services } from 'components-react/service-provider'; +import { TPlatform } from 'services/platforms'; +import Form from 'components-react/shared/inputs/Form'; + +interface IEventListState extends IWidgetCommonState { + data: { + themes: Dictionary<{ label: string }>; + settings: { + animation_speed: number; + background_color: string; + bits_minimum: number; + brightness: number; + fade_time: number; + flip_x: boolean; + flip_y: boolean; + font_family: string; + hide_animation: string; + hue: number; + keep_history: boolean; + max_events: number; + raid_raider_minimum: number; + saturation: number; + show_animation: string; + show_bits: boolean; + show_donations: boolean; + show_eldonations: boolean; + show_follows: boolean; + show_gamewispresubscriptions: boolean; + show_gamewispsubscriptions: boolean; + show_justgivingdonations: boolean; + show_merch: boolean; + show_pledges: boolean; + show_raids: boolean; + show_redemptions: boolean; + show_resubs: boolean; + show_smfredemptions: boolean; + show_sub_tiers: boolean; + show_subscriptions: boolean; + show_subscribers: boolean; + show_tiltifydonations: boolean; + show_treats: boolean; + text_color: string; + text_size: number; + theme: string; + theme_color: string; + }; + }; +} + +export function EventList() { + const { + isLoading, + settings, + eventMeta, + fontMeta, + visualMeta, + updateSetting, + setSelectedTab, + selectedTab, + } = useEventList(); + + // use 1 column layout + return ( + + setSelectedTab(e.key)} selectedKeys={[selectedTab]}> + {$t('Manage List')} + {$t('Font Settings')} + {$t('Visual Settings')} + +
+ {!isLoading && selectedTab === 'event' && ( + + )} + {!isLoading && selectedTab === 'font' && ( + + )} + {!isLoading && selectedTab === 'visual' && ( + + )} + +
+ ); +} + +export class EventListModule extends WidgetModule { + get UserService() { + return Services.UserService; + } + + get eventsByPlatform() { + const platform = this.UserService.views.platform?.type; + const baseEvents = { + show_donations: metadata.bool({ label: $t('Donations') }), + show_merch: metadata.bool({ label: $t('Merch') }), + }; + const platformEvents: PartialRec = { + twitch: { + show_follows: metadata.bool({ label: $t('Follows') }), + show_subscriptions: metadata.bool({ label: $t('Subscriptions') }), + show_resubs: metadata.bool({ label: $t('Show Resubs') }), + show_sub_tiers: metadata.bool({ label: $t('Show Sub Tiers') }), + show_bits: metadata.bool({ label: $t('Bits') }), + show_raids: metadata.bool({ label: $t('Raids') }), + }, + facebook: { + show_follows: metadata.bool({ label: $t('Follows') }), + show_stars: metadata.bool({ label: $t('Stars') }), + show_supports: metadata.bool({ label: $t('Supporters') }), + show_likes: metadata.bool({ label: $t('Likes') }), + show_shares: metadata.bool({ label: $t('Shares') }), + }, + youtube: { + show_subscribers: metadata.bool({ label: $t('Subscriptions') }), + show_sponsors: metadata.bool({ label: $t('Members') }), + show_fanfundings: metadata.bool({ label: $t('Super Chats') }), + }, + trovo: { + show_follows: metadata.bool({ label: $t('Follows') }), + show_raids: metadata.bool({ label: $t('Raids') }), + show_subscriptions: metadata.bool({ label: $t('Subscriptions') }), + show_resubs: metadata.bool({ label: $t('Show Resubs') }), + show_sub_gifts: metadata.bool({ label: $t('Show Gift Subs') }), + show_sub_tiers: metadata.bool({ label: $t('Show Sub Tiers') }), + }, + }; + if (!platform) return baseEvents; + return { ...platformEvents[platform], ...baseEvents }; + } + + get eventMeta() { + return { + enabled: { + type: 'checkboxGroup', + label: $t('Enable Events'), + children: this.eventsByPlatform, + }, + max_events: metadata.slider({ + label: $t('Max Events'), + max: 10, + step: 1, + children: { + bits_minimum: metadata.number({ + displayed: this.UserService.views.platform?.type === 'twitch', + label: $t('Min. Bits'), + tooltip: $t( + 'The smallest amount of bits a cheer must have for an event to be shown. Setting this to 0 will make every cheer trigger an event.', + ), + }), + }, + }), + }; + } + + get fontMeta() { + return { + text_color: metadata.color({ + label: $t('Text Color'), + tooltip: $t('A hex code for the base text color.'), + }), + font_family: { label: $t('Font') }, + text_size: metadata.fontSize({ + label: $t('Font Size'), + min: 10, + max: 80, + tooltip: $t( + 'The font size in pixels. Reasonable size typically ranges between 24px and 48px.', + ), + }), + }; + } + + get visualMeta() { + return { + theme: metadata.list({ + label: $t('Theme'), + options: Object.entries(this.widgetData.themes).map(([theme, val]) => ({ + label: val.label, + value: theme, + })), + }), + background_color: metadata.color({ + label: $t('Background Color'), + tooltip: $t( + 'A hex code for the widget background. This is for preview purposes only. It will not be shown in your stream.', + ), + }), + show_animation: { + type: 'animation', + label: $t('Show Animation'), + filter: 'eventIn', + }, + hide_animation: { + type: 'animation', + label: $t('Hide Animation'), + filter: 'eventOut', + }, + animation_speed: metadata.slider({ + label: $t('Animation Speed'), + min: 250, + max: 4000, + step: 250, + }), + fade_time: metadata.slider({ label: $t('Fade Time'), max: 60, step: 1 }), + other: { + type: 'checkboxGroup', + label: $t('Other Options'), + children: { + flip_x: metadata.bool({ label: $t('Flip X') }), + flip_y: metadata.bool({ label: $t('Flip Y') }), + keep_history: metadata.bool({ label: $t('Keep Events History') }), + }, + }, + }; + } +} + +function useEventList() { + return useWidget(); +} From c0657897981285adcca5cfbaaca36c5e2077b5c7 Mon Sep 17 00:00:00 2001 From: Sean Beyer Date: Fri, 30 Jan 2026 14:13:07 -0800 Subject: [PATCH 2/5] Add animation and fontFamily metadata --- app/components-react/shared/inputs/FormFactory.tsx | 1 + app/components-react/shared/inputs/inputs.ts | 3 ++- app/components-react/shared/inputs/metadata.ts | 6 ++++++ app/components-react/widgets/EventList.tsx | 14 +++----------- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/components-react/shared/inputs/FormFactory.tsx b/app/components-react/shared/inputs/FormFactory.tsx index fbbf932a8a41..3f52ff70863e 100644 --- a/app/components-react/shared/inputs/FormFactory.tsx +++ b/app/components-react/shared/inputs/FormFactory.tsx @@ -32,6 +32,7 @@ const componentTable: { time: inputs.TimeInput, animation: inputs.AnimationInput, duration: inputs.DurationInput, + fontFamily: inputs.FontFamilyInput, }; interface IFormMetadata { diff --git a/app/components-react/shared/inputs/inputs.ts b/app/components-react/shared/inputs/inputs.ts index 68f47748ade5..4073eed1fedb 100644 --- a/app/components-react/shared/inputs/inputs.ts +++ b/app/components-react/shared/inputs/inputs.ts @@ -37,7 +37,8 @@ export type TInputType = | 'radio' | 'imagepicker' | 'animation' - | 'duration'; + | 'duration' + | 'fontFamily'; export type TInputLayout = 'horizontal' | 'vertical' | 'inline'; diff --git a/app/components-react/shared/inputs/metadata.ts b/app/components-react/shared/inputs/metadata.ts index 7c01b6b031c3..ff9caaac424b 100644 --- a/app/components-react/shared/inputs/metadata.ts +++ b/app/components-react/shared/inputs/metadata.ts @@ -23,6 +23,7 @@ export const metadata = { ...options, type: 'slider', }), + fontFamily: (options: IListMetadata) => ({ ...options, type: 'fontFamily' }), autocomplete: (options: IListMetadata) => ({ ...options, type: 'autocomplete', @@ -42,6 +43,7 @@ export const metadata = { ...options, type: 'radio', }), + animation: (options: IAnimationMetadata) => ({ ...options, type: 'animation' }), }; export type TInputMetadata = @@ -117,6 +119,10 @@ interface IFileMetadata extends IBaseMetadata { buttonContent?: React.ReactNode; } +interface IAnimationMetadata extends IListMetadata { + filter?: 'in' | 'out' | 'text' | 'eventIn' | 'eventOut'; +} + export interface IListMetadata extends IBaseMetadata { value?: T; options?: IListOption[]; diff --git a/app/components-react/widgets/EventList.tsx b/app/components-react/widgets/EventList.tsx index eab54bdceb67..fe9821801062 100644 --- a/app/components-react/widgets/EventList.tsx +++ b/app/components-react/widgets/EventList.tsx @@ -165,7 +165,7 @@ export class EventListModule extends WidgetModule { label: $t('Text Color'), tooltip: $t('A hex code for the base text color.'), }), - font_family: { label: $t('Font') }, + font_family: metadata.fontFamily({ label: $t('Font') }), text_size: metadata.fontSize({ label: $t('Font Size'), min: 10, @@ -192,16 +192,8 @@ export class EventListModule extends WidgetModule { 'A hex code for the widget background. This is for preview purposes only. It will not be shown in your stream.', ), }), - show_animation: { - type: 'animation', - label: $t('Show Animation'), - filter: 'eventIn', - }, - hide_animation: { - type: 'animation', - label: $t('Hide Animation'), - filter: 'eventOut', - }, + show_animation: metadata.animation({ label: $t('Show Animation'), filter: 'eventIn' }), + hide_animation: metadata.animation({ label: $t('Hide Animation'), filter: 'eventOut' }), animation_speed: metadata.slider({ label: $t('Animation Speed'), min: 250, From 222d8dca1dc87568af20d3d98465051e70252853 Mon Sep 17 00:00:00 2001 From: Sean Beyer Date: Fri, 30 Jan 2026 14:27:04 -0800 Subject: [PATCH 3/5] Add infra --- .../widgets/common/WidgetWindow.tsx | 4 +- app/components/widgets/EventList.vue | 91 ------------------- app/components/widgets/EventList.vue.ts | 75 --------------- app/services/sources/sources.ts | 2 +- app/services/widgets/widgets-config.ts | 31 ++++++- app/services/windows.ts | 2 - 6 files changed, 30 insertions(+), 175 deletions(-) delete mode 100644 app/components/widgets/EventList.vue delete mode 100644 app/components/widgets/EventList.vue.ts diff --git a/app/components-react/widgets/common/WidgetWindow.tsx b/app/components-react/widgets/common/WidgetWindow.tsx index e2d9237dd84f..5997eca12072 100644 --- a/app/components-react/widgets/common/WidgetWindow.tsx +++ b/app/components-react/widgets/common/WidgetWindow.tsx @@ -18,7 +18,7 @@ import { ChatBox, ChatBoxModule } from '../ChatBox'; // Credits import { DonationTicker, DonationTickerModule } from '../DonationTicker'; import { EmoteWall, EmoteWallModule } from '../EmoteWall'; -// EventList +import { EventList, EventListModule } from '../EventList'; // MediaShare // Poll // SpinWheel @@ -46,7 +46,7 @@ export const components = { // Credits DonationTicker: [DonationTicker, DonationTickerModule], EmoteWall: [EmoteWall, EmoteWallModule], - // EventList + EventList: [EventList, EventListModule], // MediaShare // Poll // SpinWheel diff --git a/app/components/widgets/EventList.vue b/app/components/widgets/EventList.vue deleted file mode 100644 index 18eca951e648..000000000000 --- a/app/components/widgets/EventList.vue +++ /dev/null @@ -1,91 +0,0 @@ - - - diff --git a/app/components/widgets/EventList.vue.ts b/app/components/widgets/EventList.vue.ts deleted file mode 100644 index 27da0820a3e0..000000000000 --- a/app/components/widgets/EventList.vue.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { Component } from 'vue-property-decorator'; -import { EventListService, IEventListData } from 'services/widgets/settings/event-list'; - -import WidgetEditor from 'components/windows/WidgetEditor.vue'; -import WidgetSettings from './WidgetSettings.vue'; -import { inputComponents } from 'components/shared/inputs'; -import { AnimationInput } from './inputs'; -import VFormGroup from 'components/shared/inputs/VFormGroup.vue'; -import { $t } from 'services/i18n'; -import ValidatedForm from 'components/shared/inputs/ValidatedForm'; -import { Inject } from 'services/core/injector'; -import { UserService } from 'services/user'; - -@Component({ - components: { - WidgetEditor, - VFormGroup, - AnimationInput, - ValidatedForm, - ...inputComponents, - }, -}) -export default class EventList extends WidgetSettings { - @Inject() userService: UserService; - - get themeMetadata() { - return Object.keys(this.wData.themes).map(theme => ({ - title: this.wData.themes[theme].label, - value: theme, - })); - } - - get eventsForPlatform() { - const baseEvents = [ - { key: 'show_donations', title: $t('Donations') }, - { key: 'show_merch', title: $t('Merch') }, - ]; - return this.service.eventsByPlatform().concat(baseEvents); - } - - get minsForPlatform() { - return this.service.minsByPlatform(); - } - - valueForEvent(event: { key: string; title: string }) { - // TODO: index - // @ts-ignore - return this.wData.settings[event.key]; - } - - setEvent(event: { key: string; title: string }, value: boolean) { - // TODO: index - // @ts-ignore - this.wData.settings[event.key] = value; - } - - textColorTooltip = $t('A hex code for the base text color.'); - - backgroundColorTooltip = $t( - 'A hex code for the widget background. This is for preview purposes only. It will not be shown in your stream.', - ); - - fontSizeTooltip = $t( - 'The font size in pixels. Reasonable size typically ranges between 24px and 48px.', - ); - - get navItems() { - return [ - { value: 'manage-list', label: $t('Manage List') }, - { value: 'font', label: $t('Font Settings') }, - { value: 'visual', label: $t('Visual Settings') }, - { value: 'source', label: $t('Source') }, - ]; - } -} diff --git a/app/services/sources/sources.ts b/app/services/sources/sources.ts index a59cf88feea1..68c2c002bb7a 100644 --- a/app/services/sources/sources.ts +++ b/app/services/sources/sources.ts @@ -819,7 +819,7 @@ export class SourcesService extends StatefulService { // Credits 'DonationTicker', 'EmoteWall', - // EventList + 'EventList', // MediaShare // Poll // SpinWheel diff --git a/app/services/widgets/widgets-config.ts b/app/services/widgets/widgets-config.ts index 5afb5eede5e8..e963fbf3ccce 100644 --- a/app/services/widgets/widgets-config.ts +++ b/app/services/widgets/widgets-config.ts @@ -10,7 +10,8 @@ export type TWidgetType = | WidgetType.DonationTicker | WidgetType.CustomWidget | WidgetType.ChatBox - | WidgetType.SponsorBanner; + | WidgetType.SponsorBanner + | WidgetType.EventList; export interface IWidgetConfig { type: TWidgetType; @@ -252,9 +253,31 @@ export function getWidgetsConfig( customFieldsAllowed: true, }, - // EventList: { - // - // }, + [WidgetType.EventList]: { + type: WidgetType.EventList, + + defaultTransform: { + width: 600, + height: 600, + x: 1, + y: 0, + anchor: AnchorPoint.NorthEast, + }, + + settingsWindowSize: { + width: 600, + height: 900, + }, + + url: `https://${host}/widgets/event-list/v1/${token}`, + previewUrl: `https://${host}/widgets/event-list/v1/${token}?simulate=1`, + dataFetchUrl: `https://${host}/api/v5/slobs/widget/eventlist`, + settingsSaveUrl: `https://${host}/api/v5/slobs/widget/eventlist`, + settingsUpdateEvent: 'eventListSettingsUpdate', + customCodeAllowed: true, + customFieldsAllowed: true, + testers: ['follow', 'sub', 'donation', 'bits'], + }, // MediaShare: { // diff --git a/app/services/windows.ts b/app/services/windows.ts index fe0f89ac0829..1d327f3ec30c 100644 --- a/app/services/windows.ts +++ b/app/services/windows.ts @@ -63,7 +63,6 @@ import FollowerGoal from 'components/widgets/goal/FollowerGoal'; import CharityGoal from 'components/widgets/goal/CharityGoal'; import StreamBoss from 'components/widgets/StreamBoss.vue'; import Credits from 'components/widgets/Credits.vue'; -import EventList from 'components/widgets/EventList.vue'; import TipJar from 'components/widgets/TipJar.vue'; import MediaShare from 'components/widgets/MediaShare'; import AlertBox from 'components/widgets/AlertBox.vue'; @@ -123,7 +122,6 @@ export function getComponents() { MultistreamChatInfo, CharityGoal, Credits, - EventList, TipJar, StreamBoss, SubGoal, From d4378a1e3cdb738f9957de1439677cb2dd6e88ce Mon Sep 17 00:00:00 2001 From: Sean Beyer Date: Fri, 30 Jan 2026 14:36:36 -0800 Subject: [PATCH 4/5] Fix rendering error --- app/components-react/widgets/EventList.tsx | 2 +- app/services/widgets/widgets-config.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/components-react/widgets/EventList.tsx b/app/components-react/widgets/EventList.tsx index fe9821801062..375e3ace204f 100644 --- a/app/components-react/widgets/EventList.tsx +++ b/app/components-react/widgets/EventList.tsx @@ -181,7 +181,7 @@ export class EventListModule extends WidgetModule { return { theme: metadata.list({ label: $t('Theme'), - options: Object.entries(this.widgetData.themes).map(([theme, val]) => ({ + options: Object.entries(this.widgetData?.themes || []).map(([theme, val]) => ({ label: val.label, value: theme, })), diff --git a/app/services/widgets/widgets-config.ts b/app/services/widgets/widgets-config.ts index e963fbf3ccce..275f6c4a3cab 100644 --- a/app/services/widgets/widgets-config.ts +++ b/app/services/widgets/widgets-config.ts @@ -265,8 +265,8 @@ export function getWidgetsConfig( }, settingsWindowSize: { - width: 600, - height: 900, + width: 850, + height: 700, }, url: `https://${host}/widgets/event-list/v1/${token}`, From 62fa1843ad55b294d1af4204ac6eaa3a4f7ee093 Mon Sep 17 00:00:00 2001 From: Sean Beyer Date: Mon, 2 Feb 2026 14:27:47 -0800 Subject: [PATCH 5/5] Remove deprecated services --- app/app-services.ts | 3 - .../widgets/settings/donation-ticker.ts | 54 ------- app/services/widgets/settings/emote-wall.ts | 69 -------- app/services/widgets/settings/event-list.ts | 152 ------------------ 4 files changed, 278 deletions(-) delete mode 100644 app/services/widgets/settings/donation-ticker.ts delete mode 100644 app/services/widgets/settings/emote-wall.ts delete mode 100644 app/services/widgets/settings/event-list.ts diff --git a/app/app-services.ts b/app/app-services.ts index b5e2728fa492..ab3df84e2bf6 100644 --- a/app/app-services.ts +++ b/app/app-services.ts @@ -121,16 +121,13 @@ export { SupporterGoalService } from 'services/widgets/settings/supporter-goal'; export { SubscriberGoalService } from 'services/widgets/settings/subscriber-goal'; export { CharityGoalService } from 'services/widgets/settings/charity-goal'; export { StreamBossService } from 'services/widgets/settings/stream-boss'; -export { DonationTickerService } from 'services/widgets/settings/donation-ticker'; export { CreditsService } from 'services/widgets/settings/credits'; -export { EventListService } from 'services/widgets/settings/event-list'; export { TipJarService } from 'services/widgets/settings/tip-jar'; export { SubGoalService } from 'services/widgets/settings/sub-goal'; export { MediaShareService } from 'services/widgets/settings/media-share'; export { AlertBoxService } from 'services/widgets/settings/alert-box'; export { SpinWheelService } from 'services/widgets/settings/spin-wheel'; export { PollService } from 'services/widgets/settings/poll'; -export { EmoteWallService } from 'services/widgets/settings/emote-wall'; export { ChatHighlightService } from 'services/widgets/settings/chat-highlight'; export { SuperchatGoalService } from 'services/widgets/settings/superchat-goal'; diff --git a/app/services/widgets/settings/donation-ticker.ts b/app/services/widgets/settings/donation-ticker.ts deleted file mode 100644 index bea18455d28a..000000000000 --- a/app/services/widgets/settings/donation-ticker.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { - IWidgetData, - IWidgetSettings, - WidgetDefinitions, - WidgetSettingsService, - WidgetType, -} from 'services/widgets'; -import { WIDGET_INITIAL_STATE } from './widget-settings'; -import { InheritMutations } from 'services/core/stateful-service'; - -export interface IDonationTickerSettings extends IWidgetSettings { - background_color: string; - font: string; - font_color: string; - font_color2: string; - font_color3: string; - font_size: number; - font_weight: number; - max_donation_age: number; - max_donations: number; - message_format: string; - min_donation_amount: number; - scroll_speed: number; -} - -export interface IDonationTickerData extends IWidgetData { - settings: IDonationTickerSettings; -} - -@InheritMutations() -export class DonationTickerService extends WidgetSettingsService { - static initialState = WIDGET_INITIAL_STATE; - - getApiSettings() { - return { - type: WidgetType.DonationTicker, - url: WidgetDefinitions[WidgetType.DonationTicker].url(this.getHost(), this.getWidgetToken()), - previewUrl: `https://${this.getHost()}/widgets/donation-ticker?token=${this.getWidgetToken()}&simulate=1`, - dataFetchUrl: `https://${this.getHost()}/api/v5/slobs/widget/ticker`, - settingsSaveUrl: `https://${this.getHost()}/api/v5/slobs/widget/ticker`, - settingsUpdateEvent: 'donationTickerSettingsUpdate', - customCodeAllowed: true, - customFieldsAllowed: true, - hasTestButtons: true, - }; - } - - protected patchAfterFetch(data: any): IDonationTickerData { - // backend accepts and returns some numerical values as strings - data.settings.font_size = parseInt(data.settings.font_size, 10); - data.settings.font_weight = parseInt(data.settings.font_weight, 10); - return data; - } -} diff --git a/app/services/widgets/settings/emote-wall.ts b/app/services/widgets/settings/emote-wall.ts deleted file mode 100644 index 8a03b70709a1..000000000000 --- a/app/services/widgets/settings/emote-wall.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { - IWidgetData, - IWidgetSettings, - WidgetDefinitions, - WidgetSettingsService, - WidgetType, -} from 'services/widgets'; -import { WIDGET_INITIAL_STATE } from './widget-settings'; -import { InheritMutations } from 'services/core/stateful-service'; -import { formMetadata, metadata } from 'components/shared/inputs'; -import { $t } from 'services/i18n'; - -export interface IEmoteWallSettings extends IWidgetSettings { - combo_count: number; - combo_required: boolean; - combo_timeframe: number; // milliseconds - emote_animation_duration: number; // milliseconds - emote_scale: number; - enabled: boolean; - ignore_duplicates: boolean; -} - -export interface IEmoteWallData extends IWidgetData { - settings: IEmoteWallSettings; -} - -@InheritMutations() -export class EmoteWallService extends WidgetSettingsService { - static initialState = WIDGET_INITIAL_STATE; - - getApiSettings() { - return { - type: WidgetType.EmoteWall, - url: WidgetDefinitions[WidgetType.EmoteWall].url(this.getHost(), this.getWidgetToken()), - previewUrl: `https://${this.getHost()}/widgets/emote-wall?token=${this.getWidgetToken()}&simulate=1`, - dataFetchUrl: `https://${this.getHost()}/api/v5/slobs/widget/emote-wall`, - settingsSaveUrl: `https://${this.getHost()}/api/v5/slobs/widget/emote-wall`, - settingsUpdateEvent: 'emoteWallSettingsUpdate', - customCodeAllowed: false, - customFieldsAllowed: false, - hasTestButtons: true, - }; - } - - getMetadata() { - return formMetadata({ - enabled: metadata.toggle({ title: $t('Enabled') }), - duration: metadata.slider({ title: $t('Duration'), min: 1, max: 60 }), - scale: metadata.slider({ title: $t('Emote Scale'), min: 1, max: 10 }), - comboRequired: metadata.toggle({ title: $t('Combo Required') }), - comboCount: metadata.slider({ title: $t('Combo Count'), min: 2, max: 100 }), - comboTimeframe: metadata.slider({ title: $t('Combo Timeframe'), min: 1, max: 60 }), - ignoreDuplicates: metadata.toggle({ title: $t('Ignore Duplicates') }), - }); - } - - patchAfterFetch(data: IEmoteWallData) { - data.settings.combo_timeframe = data.settings.combo_timeframe / 1000; - data.settings.emote_animation_duration = data.settings.emote_animation_duration / 1000; - - return data; - } - - patchBeforeSend(settings: IEmoteWallSettings) { - settings.combo_timeframe = settings.combo_timeframe * 1000; - settings.emote_animation_duration = settings.emote_animation_duration * 1000; - return settings; - } -} diff --git a/app/services/widgets/settings/event-list.ts b/app/services/widgets/settings/event-list.ts deleted file mode 100644 index df7d5666525f..000000000000 --- a/app/services/widgets/settings/event-list.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { - IWidgetData, - IWidgetSettings, - WidgetDefinitions, - WidgetSettingsService, - WidgetType, -} from 'services/widgets'; -import { metadata } from 'components/widgets/inputs/index'; -import { WIDGET_INITIAL_STATE } from './widget-settings'; -import { InheritMutations } from 'services/core/stateful-service'; -import { $t } from 'services/i18n'; -import { TPlatform } from '../../platforms'; - -export interface IEventListSettings extends IWidgetSettings { - animation_speed: number; - background_color: string; - bits_minimum: number; - brightness: number; - fade_time: number; - flip_x: boolean; - flip_y: boolean; - font_family: string; - hide_animation: string; - hue: number; - keep_history: boolean; - max_events: number; - raid_raider_minimum: number; - saturation: number; - show_animation: string; - show_bits: boolean; - show_donations: boolean; - show_eldonations: boolean; - show_follows: boolean; - show_gamewispresubscriptions: boolean; - show_gamewispsubscriptions: boolean; - show_justgivingdonations: boolean; - show_merch: boolean; - show_pledges: boolean; - show_raids: boolean; - show_redemptions: boolean; - show_resubs: boolean; - show_smfredemptions: boolean; - show_sub_tiers: boolean; - show_subscriptions: boolean; - show_subscribers: boolean; - show_tiltifydonations: boolean; - show_treats: boolean; - text_color: string; - text_size: number; - theme: string; - theme_color: string; -} - -export interface IEventListData extends IWidgetData { - themes: any; - settings: IEventListSettings; -} - -@InheritMutations() -export class EventListService extends WidgetSettingsService { - static initialState = WIDGET_INITIAL_STATE; - - getApiSettings() { - return { - type: WidgetType.EventList, - url: WidgetDefinitions[WidgetType.EventList].url(this.getHost(), this.getWidgetToken()), - previewUrl: `https://${this.getHost()}/widgets/event-list/v1/${this.getWidgetToken()}?simulate=1`, - dataFetchUrl: `https://${this.getHost()}/api/v5/slobs/widget/eventlist`, - settingsSaveUrl: `https://${this.getHost()}/api/v5/slobs/widget/eventlist`, - settingsUpdateEvent: 'eventListSettingsUpdate', - customCodeAllowed: true, - customFieldsAllowed: true, - testers: ['Follow', 'Subscription', 'Donation', 'Bits'], - }; - } - - getMetadata() { - return { - theme: metadata.list({ - options: [ - { title: 'Clean', value: 'standard' }, - { title: 'Boxed', value: 'boxed' }, - { title: 'Twitch', value: 'twitch' }, - { title: 'Old School', value: 'oldschool' }, - { title: 'Chunky', value: 'chunky' }, - ], - }), - message_hide_delay: metadata.slider({ - min: 0, - max: 200, - }), - }; - } - - eventsByPlatform(): { key: string; title: string }[] { - const platform = this.userService.platform.type as Exclude< - TPlatform, - 'tiktok' | 'twitter' | 'instagram' | 'kick' - >; - return { - twitch: [ - { key: 'show_follows', title: $t('Follows') }, - { key: 'show_subscriptions', title: $t('Subscriptions') }, - { key: 'show_resubs', title: $t('Show Resubs') }, - { key: 'show_sub_tiers', title: $t('Show Sub Tiers') }, - { key: 'show_bits', title: $t('Bits') }, - { key: 'show_raids', title: $t('Raids') }, - ], - facebook: [ - { key: 'show_follows', title: $t('Follows') }, - { key: 'show_stars', title: $t('Stars') }, - { key: 'show_supports', title: $t('Supporters') }, - { key: 'show_likes', title: $t('Likes') }, - { key: 'show_shares', title: $t('Shares') }, - ], - youtube: [ - { key: 'show_subscribers', title: $t('Subscriptions') }, - { key: 'show_sponsors', title: $t('Members') }, - { key: 'show_fanfundings', title: $t('Super Chats') }, - ], - trovo: [ - { key: 'show_follows', title: $t('Follows') }, - { key: 'show_raids', title: $t('Raids') }, - { key: 'show_subscriptions', title: $t('Subscriptions') }, - { key: 'show_resubs', title: $t('Show Resubs') }, - { key: 'show_sub_gifts', title: $t('Show Gift Subs') }, - { key: 'show_sub_tiers', title: $t('Show Sub Tiers') }, - ], - }[platform]; - } - - minsByPlatform(): { key: string; title: string; tooltip?: string }[] { - const platform = this.userService.platform.type; - return { - twitch: [ - { - key: 'bits_minimum', - title: $t('Min. Bits'), - - tooltip: $t( - 'The smallest amount of bits a cheer must have for an event to be shown.' + - ' Setting this to 0 will make every cheer trigger an event.', - ), - }, - ], - }[platform as 'twitch']; - } - - protected patchBeforeSend(data: IEventListSettings): any { - return { ...data }; - } -}