Go Live Window Refactor.#5958
Open
michelinewu wants to merge 71 commits into
Open
Conversation
BundleMonFiles updated (2)
Unchanged files (2)
Total files change +2.5MB +19.69% Final result: ✅ View report in BundleMon website ➡️ |
… on an unmounted component.
Comment on lines
+1638
to
+1640
| // The horizontal stream has started but the vertical stream status is still Starting. Update the status here, instead of | ||
| // when the vertical stream actually starts, to prevent a race condition where the UI might show all streams as Live when | ||
| // they are still starting. |
Comment on lines
+126
to
+131
| emitIsLiveForTest(isLive: boolean): void { | ||
| if (!Utils.isTestMode()) return; | ||
| this.streamSettingsService.setGoLiveSettings({ streamShift: true }); | ||
| this.SET_STREAM_SWITCHER_STATUS('pending'); | ||
| this.isLive.next(isLive); | ||
| } |
Comment on lines
+80
to
+94
| const onChange = useCallback( | ||
| (val: string) => { | ||
| const updatedDisplay = val as TDisplayOutput; | ||
| if (p.platform) { | ||
| updatePlatformDisplayAndSaveSettings(p.platform, updatedDisplay); | ||
| } else { | ||
| if (updatedDisplay === 'both') { | ||
| // There's no UI that would allow for this, but just in case | ||
| throw new Error('Attempted to update custom display for dual stream, this is impossible'); | ||
| } | ||
| updateCustomDestinationDisplayAndSaveSettings(p.index, updatedDisplay as TDisplayType); | ||
| } | ||
| updateCustomDestinationDisplayAndSaveSettings(p.index, val as TDisplayType); | ||
| } | ||
| }; | ||
| }, | ||
| [p.platform, p.index], | ||
| ); |
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 108 out of 108 changed files in this pull request and generated 4 comments.
Comments suppressed due to low confidence (1)
app/components-react/windows/go-live/useGoLiveSettings.ts:291
- The non-Ultra prepopulate pruning only considers
enabledPlatforms.length > 2, but it does not consider enabled custom destinations. If a user previously saved settings with custom destinations enabled (or >2 total targets) and later loses Ultra, the Go Live window can start with more than 2 targets enabled, bypassing the non-Ultra limit. Consider pruning/disable extra enabled custom destinations here as well so the initial state always satisfies the 2-target limit.
| await waitForSettingsWindowLoaded(); | ||
| await clickButton('Close'); | ||
|
|
||
| await addDummyAccount('kick'); |
Comment on lines
283
to
287
| /** | ||
| * A shortcut for useForm().assertFormContains() | ||
| * The second argument can be an assertion message (a string containing spaces) | ||
| * or the indexKey for field lookup. | ||
| */ |
Comment on lines
+254
to
266
| const handleGoLive = useCallback(async () => { | ||
| if (!isPrime) { | ||
| // Check to see if the user has a valid display assignment | ||
| if (!hasValidDisplayAssignment) { | ||
| alertInfo({ | ||
| name: 'dual-output-info-alert', | ||
| text: $t( | ||
| 'To use Dual Output you must stream to at least one horizontal and one vertical platform.', | ||
| ), | ||
| }); | ||
|
|
||
| return; | ||
| } |
Contributor
Author
There was a problem hiding this comment.
This behavior is intentional. Dual output as a mode will be removed after this new go live window UI is merged
Comment on lines
+38
to
+42
| async function installHighlighter() { | ||
| await showPage('Highlighter'); | ||
| await clickIfDisplayed('[name="installHighlighter"]'); | ||
| await waitForDisplayed('h3=Installing...', { timeout: 60000 }); | ||
| } |
Comment on lines
+111
to
+118
| export async function isTooltipDisplayed( | ||
| hoverSelector: string, | ||
| tooltipSelector: string, | ||
| duration?: number, | ||
| ): Promise<boolean> { | ||
| await hoverElement(hoverSelector, duration); | ||
| return isDisplayed(tooltipSelector); | ||
| } |
Comment on lines
47
to
52
| if (scope === 'relog') { | ||
| skipCheckingErrorsInLog(); | ||
|
|
||
| t.true( | ||
| await isDisplayed('div=Failed to update TikTok account', { timeout: 3000 }), | ||
| 'TikTok remerge error shown', | ||
| ); | ||
| await isDisplayed('span=Failed to update TikTok account', { | ||
| timeout: 3000, | ||
| timeoutMsg: 'TikTok remerge error not shown for relog scope', | ||
| }); | ||
| return; |
Comment on lines
61
to
63
| await waitForDisplayed('div[data-name="tiktok-settings"]'); | ||
| await isTabActive('Streamlabs Access', 'tiktokLiveAccess'); | ||
|
|
Comment on lines
+72
to
+76
| await clickTab('Stream with TikTok Stream Key', 'tiktokStreamKey'); | ||
| await isDisplayed('[data-name="tiktokStreamForm"]', { | ||
| timeout: 3000, | ||
| timeoutMsg: 'TikTok stream key form not shown for approved scope', | ||
| }); |
Comment on lines
+353
to
+354
| // Default tooltip | ||
| await isTooltipDisplayed('i.icon-information', '[data-name="explanation"]', 1000); |
Comment on lines
+356
to
+358
| // Default tooltip stays the same when multiple platforms are enabled | ||
| await fillForm({ youtube: true }); | ||
| await isTooltipDisplayed('i.icon-information', '[data-name="explanation"]', 1000); |
Comment on lines
+360
to
+362
| // Dual output tooltip | ||
| await fillForm({ youtubeDisplay: 'vertical' }); | ||
| await isTooltipDisplayed('i.icon-information', '[data-name="dual-output"]', 1000); |
Comment on lines
+391
to
+393
| await fillForm({ patreon: true }); | ||
| await isTooltipDisplayed('i.icon-information', '[data-name="patreon"]', 1000); | ||
| await assertFormContains({ streamShift: false }); |
Comment on lines
+396
to
+398
| await fillForm({ patreon: false }); | ||
| await isTooltipDisplayed('i.icon-information', '[data-name="explanation"]', 1000); | ||
| await assertFormContains({ streamShift: true }); |
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 110 out of 110 changed files in this pull request and generated 4 comments.
Comments suppressed due to low confidence (1)
test/regular/streaming/youtube.ts:51
logInYouTubeEnabledAccountis used as a boolean flag (retried) but can returnvoidwhenretries === 0, forcing callers intoboolean | voidand making the result ambiguous. Return a boolean in all paths (or throw) so call sites can rely on the type/value.
Comment on lines
+119
to
123
| function DefaultAddDestinationButton(p: IAddDestinationButtonProps) { | ||
| return ( | ||
| <Button | ||
| data-name="default-add-destination" | ||
| name="default-add-destination" | ||
| className={cx(styles.addDestinationBtn, styles.defaultOutputBtn, p.className)} |
Comment on lines
+133
to
+137
| function SmallAddDestinationButton(p: IAddDestinationButtonProps) { | ||
| return ( | ||
| <Button | ||
| data-name="default-add-destination" | ||
| className={cx(styles.addDestinationBtn, styles.smallBtn, p.className)} | ||
| name="default-add-destination" | ||
| className={cx(styles.smallBtn, p.className)} |
Comment on lines
+147
to
+148
| [settings, updatePlatform], | ||
| ); |
Comment on lines
+842
to
+849
| async forceStreamShiftGoLive() { | ||
| this.streamSettingsService.setGoLiveSettings({ streamShift: false }); | ||
| await this.deleteTargets(); | ||
| this.SET_STREAM_SWITCHER_STATUS('inactive'); | ||
| this.SET_STREAM_SWITCHER_STREAM_ID(); | ||
| this.SET_STREAM_SWITCHER_TARGETS([]); | ||
| this.SET_STREAM_SWITCHER_FORCE_GO_LIVE(true); | ||
| } |
Contributor
Author
There was a problem hiding this comment.
This is intended
Comment on lines
+29
to
+33
| // Ultra banner should be visible for non-prime users | ||
| await isDisplayed('[name="banner-add-destination"]'); | ||
|
|
||
| // Add destination button should be below the platform card if there is only one target | ||
| await isDisplayed('[name="bottom-add-destination"]'); |
Comment on lines
+35
to
+36
| // Stream shift should be disabled and tooltip should be visible | ||
| await isDisplayed('[data-name="shift-ultra-icon"]'); |
Comment on lines
+57
to
+58
| // Add destination button should be above the platform card if there are multiple targets | ||
| await isDisplayed('[name="top-add-destination"]'); |
Comment on lines
+49
to
+68
| // Memoize the values of `hasDescription` to avoid unnecessary re-renders of the component | ||
| // but it never needs to be updated after the first render because supported fields for platforms | ||
| // can't change without updating the service | ||
| const hasDescription = useMemo( | ||
| () => | ||
| p.platform | ||
| ? Services.StreamingService.views.supports('description', [p.platform]) | ||
| : Services.StreamingService.views.supports('description'), | ||
| [], | ||
| ); | ||
|
|
||
| // Same as above for `title` | ||
| const title = useMemo( | ||
| () => (hasDescription ? $t('Use different title and description') : $t('Use different title')), | ||
| [], | ||
| ); | ||
|
|
||
| const showCheckbox = useMemo(() => { | ||
| return p.enabledPlatformsCount && p.enabledPlatformsCount > 1; | ||
| }, [p.enabledPlatformsCount]); |
Comment on lines
40
to
+43
| async function logInYouTubeEnabledAccount( | ||
| t: TExecutionContext, | ||
| retries: number = 3, | ||
| ): Promise<void> { | ||
| ): Promise<boolean | void> { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Go Live Window Refactor
Summary
A broad refactor of the Go Live window: rebuilt UI components, a new theming system, consolidated feature-availability logic, and a batch of correctness fixes around Stream Shift, dual output, and per-platform settings. The goal is a cleaner, more consistent Go Live experience with a single, predictable source of truth for what is enabled/disabled/hidden across the many user states (Ultra vs. non-Ultra, dual output, Stream Shift, mid-stream, Patreon, etc.). The new theming system should allow for faster UI updates since the Go Live Window themes are now independent.
What changed
UI components
GoLiveWindow,GoLiveSettings,DestinationSwitchers,PlatformSettings,PrimaryChatSwitcher,EditStreamWindow.SwitcherCard,CustomFieldsCheckbox, sharedAnimatedWrapper, and refactored sharedTabs,RadioInput,InfoBadge,Tooltip, andButtonHighlighted.AdvancedSettingsSwitch.Theming & styling
golive-day-theme,golive-night-theme,golive-prime-dark,golive-prime-light(lazy-loaded), plus updates tothemes.g.less,colors.less, and a new top-levelgo-live.less.*.m.lessmodules and fixed a range of styling issues: platform logo colors, Ultra button/banner styling, primary button hover colors, recording tooltip, Stream Shift toggle alignment (non-Ultra) TikTok form, Edit Stream margins, and non-Ultra settings height.Stream Shift
Platform & dual-output fixes
Recording / AI Highlighter
Services
streaming,streaming-view,restream,customization,user, platform services (patreon,kick,youtube), and settings services to support the above.Tests
Notes for reviewers
.lessfiles) and the four new theme stylesheets; the substantive logic changes are concentrated in the Go Live components,useGoLiveSettings, and the streaming/platform services.