Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
96 commits
Select commit Hold shift + click to select a range
589ec03
Update osn to v0.25.78 (#5706)
sandboxcoder Jan 14, 2026
7fdc9cc
Release version 1.20.5-preview.0
avacreeth Jan 14, 2026
48ea1dd
Fix dual output folder undo/redo. (#5688)
michelinewu Jan 15, 2026
0d66664
New Crowdin updates (#5647)
avacreeth Jan 15, 2026
127f369
(Mac) update electron-builder to properly bypass codesign (#5670)
sandboxcoder Jan 15, 2026
714b2b4
Update osn: restore "Rescale Output" option (#5708)
sandboxcoder Jan 15, 2026
07edba2
Release version 1.20.5-preview.1
avacreeth Jan 15, 2026
2f43be9
add progressCallback to – installOverlayAndWidgets (#5678)
cmm21 Jan 21, 2026
8171b0d
added 4 new games: dbd, arc raiders, dota2, rocket league (#5710)
ggolda Jan 23, 2026
829bea1
Merge branch 'master' into staging
avacreeth Jan 23, 2026
f9579f2
Merge branch 'master' into preview
avacreeth Jan 23, 2026
9d40401
Fix notifications icon hover color. (#5698)
michelinewu Jan 23, 2026
6674c04
Fix background color for unchecked checkboxes and beta tag. (#5699)
michelinewu Jan 23, 2026
5768830
Application Audio Capture plugin: Add field (#5709)
sandboxcoder Jan 23, 2026
8bf310f
Merge branch 'master' into staging
avacreeth Jan 23, 2026
5134fad
Merge branch 'master' into preview
avacreeth Jan 23, 2026
47f6eec
Stream Settings and Go Live Window UI updates. (#5703)
michelinewu Jan 26, 2026
a2550da
Merge branch 'master' into staging
gettinToasty Jan 26, 2026
eb7359e
Merge branch 'master' into preview
gettinToasty Jan 26, 2026
774aed6
Merge branch 'staging' into preview
avacreeth Jan 26, 2026
09967ef
Release version 1.20.5-preview.2
avacreeth Jan 26, 2026
be9ee3f
Redesign Onboarding (#5687)
gettinToasty Jan 27, 2026
23b7833
Merge branch 'master' into staging
avacreeth Jan 27, 2026
1f6b6e0
Merge branch 'master' into preview
avacreeth Jan 27, 2026
75cb588
Release version 1.20.5
avacreeth Jan 27, 2026
1e06a6e
Merge branch 'master-mac' into staging
avacreeth Jan 27, 2026
f154488
Fix onboarding bugs (#5717)
gettinToasty Jan 27, 2026
ccccf99
Merge branch 'master' into staging
avacreeth Jan 27, 2026
9099bc6
Merge branch 'master' into preview
avacreeth Jan 27, 2026
87aa109
Disable new onboarding on macos
gettinToasty Jan 27, 2026
baaac8c
Merge branch 'preview' into master-mac
avacreeth Jan 27, 2026
ac0b2c7
Release version 1.20.6
avacreeth Jan 27, 2026
1d650ad
Merge branch 'master-mac' into staging
avacreeth Jan 27, 2026
2a7dca6
Fix auth modal container (#5719)
gettinToasty Jan 28, 2026
7e7b700
Merge branch 'master' into staging
avacreeth Jan 28, 2026
4b5a100
Merge branch 'master' into preview
avacreeth Jan 28, 2026
59f2291
Fix chat collapse (#5723)
gettinToasty Jan 29, 2026
f5cddaf
Merge branch 'master' into staging
avacreeth Jan 29, 2026
8ed3e42
Merge branch 'master' into preview
avacreeth Jan 29, 2026
fe78f60
Update osn: update osn fix for multicam support (#5722)
summeroff Jan 29, 2026
8323e13
Merge branch 'staging' into preview
avacreeth Jan 29, 2026
2e27b74
Release version 1.20.7-preview.0
avacreeth Jan 29, 2026
b5491e7
fix(settings): remove keymap sections that are empty due to search st…
wesrupert Jan 29, 2026
91af44e
Update osn: Update osn: (#5724)
summeroff Jan 29, 2026
9849fcc
New Crowdin updates (#5716)
avacreeth Jan 29, 2026
954e99f
Release version 1.20.7-preview.1
avacreeth Jan 29, 2026
4c685d3
Fix device display not resizing correctly (#5721)
gettinToasty Jan 29, 2026
0a3b3ca
Merge branch 'master' into staging
avacreeth Jan 29, 2026
153e208
Merge branch 'master' into preview
avacreeth Jan 29, 2026
673d07e
Track dual stream and enhanced broadcasting. (#5714)
michelinewu Jan 30, 2026
7f31768
Membership test widget updates sponsors. (#5681)
michelinewu Jan 30, 2026
377c9e0
Prompt user to use H.264 codec if incompatible codec is used with res…
michelinewu Jan 30, 2026
6253a72
Merge branch 'master' into staging
gettinToasty Jan 30, 2026
9a58116
Merge branch 'master' into preview
gettinToasty Jan 30, 2026
587d8a7
Update osn: Update osn: (#5725)
summeroff Jan 30, 2026
eeed40f
New Crowdin updates (#5726)
avacreeth Jan 30, 2026
2cbb258
Merge branch 'staging' into preview
avacreeth Jan 30, 2026
ba449e3
Release version 1.20.7-preview.2
avacreeth Jan 30, 2026
53d3eb7
use ARCH env variable (#5728)
sandboxcoder Feb 2, 2026
d52af18
Fix last target not showing in Go Live Window. (#5732)
michelinewu Feb 2, 2026
9afbae3
Merge branch 'master' into staging
avacreeth Feb 2, 2026
6553760
Merge branch 'master' into preview
avacreeth Feb 2, 2026
1049e4f
New Crowdin updates (#5735)
avacreeth Feb 3, 2026
6811a16
apply fix for realm crash on repeted objects recreate (#5731)
summeroff Feb 3, 2026
8b77bb9
Merge branch 'staging' into preview
avacreeth Feb 3, 2026
882510c
Release version 1.20.7-preview.3
avacreeth Feb 3, 2026
87be86d
Release version 1.20.7
avacreeth Feb 4, 2026
28d2a0e
mac-release: validate binaries match ARCH (#5738)
sandboxcoder Feb 5, 2026
2f23a06
crash-handler: Add "Troubleshooting here" hyperlink (#5736)
sandboxcoder Feb 5, 2026
1c73b81
Release version 1.20.7-preview.4
avacreeth Feb 5, 2026
9b2eafd
Reorder platforms. (#5737)
michelinewu Feb 6, 2026
e384843
feat(widgets): add "Manage on Web" button (#5734)
wesrupert Feb 6, 2026
7ee944c
Make modal not closable (#5739)
gettinToasty Feb 6, 2026
394d7b0
Merge branch 'master' into staging
avacreeth Feb 6, 2026
f45d8e2
Merge branch 'master' into preview
avacreeth Feb 6, 2026
9ac1039
chore(widgets): fix web settings paths (#5743)
wesrupert Feb 6, 2026
d9c1d7f
Merge branch 'master' into staging
avacreeth Feb 6, 2026
118c51a
Merge branch 'master' into preview
avacreeth Feb 6, 2026
64b73e3
Update osn: Update OSN (#5744)
summeroff Feb 7, 2026
99c3b04
Merge branch 'staging' into preview
avacreeth Feb 7, 2026
e22c701
Release version 1.20.8-preview.0
avacreeth Feb 7, 2026
70c5bb5
Release version 1.20.8
avacreeth Feb 9, 2026
f490f9e
import crash-handler version 1.2.27 (#5749)
sandboxcoder Feb 10, 2026
d263342
add game pulse icon (#5753)
cmm21 Feb 17, 2026
1af34da
Release version 1.20.9-preview.0
avacreeth Feb 17, 2026
96a4492
Merge branch 'master' into staging
Feb 17, 2026
53c50e7
Release version 1.20.9-preview.1
avacreeth Feb 17, 2026
8eb89b7
Merge branch 'staging' into preview
avacreeth Feb 17, 2026
2ca1564
Release version 1.20.9-preview.2
avacreeth Feb 17, 2026
1c644c7
Release version 1.20.9
avacreeth Feb 17, 2026
626599b
feat(multistream): add ultra features page (#5741)
wesrupert Feb 18, 2026
47cb5ea
feat: add Game Pulse widget and GroupedListInput component (#5757)
cmm21 Feb 24, 2026
21bc76d
Merge branch 'master' into feat/reactive-data-editor
michelinewu Feb 25, 2026
10a2855
Fetch/set reactuve data when user logs out and in.
michelinewu Feb 25, 2026
46863bd
Handle new reactive data source.
michelinewu Feb 27, 2026
5c72b60
Fix normaliz url for both new and existing reactive sources.
michelinewu Mar 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 4 additions & 1 deletion app/app-services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export { SettingsManagerService } from 'services/settings-manager';
export { MarkersService } from 'services/markers';
export { RealmService } from 'services/realm';
export { StreamAvatarService } from 'services/stream-avatar/stream-avatar-service';
import { VirtualWebcamService } from 'services/virtual-webcam';
export { OnboardingV2Service } from 'services/onboarding/onboarding-v2';

// ONLINE SERVICES
export { UserService } from './services/user';
Expand Down Expand Up @@ -220,6 +220,8 @@ import { VisionService } from 'services/vision';
import { ReactiveDataService } from 'services/reactive-data';
import { SignalsService } from 'services/signals-manager';
import { TroubleshooterService } from 'services/troubleshooter';
import { OnboardingV2Service } from 'services/onboarding/onboarding-v2';
import { VirtualWebcamService } from 'services/virtual-webcam';

export const AppServices = {
AppService,
Expand Down Expand Up @@ -307,4 +309,5 @@ export const AppServices = {
VisionService,
ReactiveDataService,
TroubleshooterService,
OnboardingV2Service,
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useController } from 'components-react/hooks/zustand';

interface IDualOutputSourceSelector {
nodeId: string;
sourceName: string;
sceneId?: string;
}
export function DualOutputSourceSelector(p: IDualOutputSourceSelector) {
Expand Down Expand Up @@ -48,6 +49,7 @@ export function DualOutputSourceSelector(p: IDualOutputSourceSelector) {
visible={['icon-desktop', 'icon-desktop-hide'].includes(hoveredIcon)}
>
<i
data-name={`${p.sourceName}-horizontal`}
onClick={() => {
toggleVisibility(p.nodeId);
makeActive(p.nodeId);
Expand All @@ -69,6 +71,7 @@ export function DualOutputSourceSelector(p: IDualOutputSourceSelector) {
visible={['icon-phone-case', 'icon-phone-case-hide'].includes(hoveredIcon)}
>
<i
data-name={`${p.sourceName}-vertical`}
onClick={() => {
toggleVisibility(v.verticalNodeId);
makeActive(v.verticalNodeId);
Expand Down
1 change: 1 addition & 0 deletions app/components-react/editor/elements/SceneSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ function SceneSelector() {
title={$t('Scene Collections')}
dismissableKey={EDismissable.SceneCollectionsHelpTip}
position={{ top: '-8px', left: '102px' }}
style={{ position: 'absolute' }}
>
<div>
{$t(
Expand Down
10 changes: 8 additions & 2 deletions app/components-react/editor/elements/SourceSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,15 @@ class SourceSelectorController {
const parent = this.selectionService.views.globalSelection.getClosestParent();
if (parent) parentId = parent.id;
}

const sceneId =
this.scenesService.views.activeScene.id ??
this.selectionService.views.globalSelection.sceneId;

this.scenesService.actions.showNameFolder({
itemsToGroup,
parentId,
sceneId: this.scenesService.views.activeScene.id,
sceneId,
});
}
}
Expand Down Expand Up @@ -788,6 +793,7 @@ function StudioControls() {

<Tooltip title={ctrl.dualOutputTitle} placement="bottomRight">
<i
data-name="dual-output-toggle"
className={cx('icon-dual-output icon-button icon-button--lg', {
active: ctrl.isDualOutputActive,
})}
Expand Down Expand Up @@ -918,7 +924,7 @@ const TreeNode = React.forwardRef(
<>
{p.isGuestCamActive && <i className="fa fa-signal" />}
{p.isDualOutputActive && p.hasNodeMap && (
<DualOutputSourceSelector nodeId={p.id} sceneId={p?.sceneId} />
<DualOutputSourceSelector nodeId={p.id} sceneId={p?.sceneId} sourceName={p.title} />
)}
{p.selectiveRecordingEnabled && (
<Tooltip title={selectiveRecordingMetadata().tooltip} placement="left">
Expand Down
119 changes: 119 additions & 0 deletions app/components-react/modals/onboarding/Common.m.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
@import "../../../styles/index.less";

.modal-wrapper {
display: flex;
justify-content: center;
align-items: center;
height: 80% !important;
width: 80% !important;

:global(.ant-modal-content) {
z-index: 2000 !important; // show above everything
height: 100% !important;
}

:global(.ant-modal-footer) {
background-color: var(--background);
border-top: none;
}
}

.dark-box {
background-color: var(--section);
border-radius: 16px;
}

.centered {
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
text-align: center;
}

.kevin-box {
width: 56px;
height: 56px;
background: var(--teal);
border-radius: 16px;
position: relative;
margin-bottom: 32px;

svg {
.center();
}
}

.big-button {
border-radius: 32px !important;
width: 240px;
height: 64px !important;
font-weight: bold !important;
display: flex;
align-items: center;

i {
margin-right: 4px;
}
}

.big-button.white {
background: var(--white);
color: var(--section);

&:hover {
border: none;
background: var(--icon);
color: var(--section);
}
}

.platform-buttons {
display: flex;
flex-wrap: wrap;
justify-content: center;

button {
margin-right: 8px;
margin-top: 8px;
display: flex;
align-items: center;

i {
margin-right: 4px;
}
}
}

.platforms-container {
display: flex;
justify-content: space-evenly;
width: 800px;
flex-wrap: wrap;
}

.platform-card {
width: 240px;
height: 140px;
border-radius: 16px;
background: var(--section);
overflow: hidden;
margin-top: 16px;
padding-top: 16px;

&:hover {
cursor: pointer;
}

.platform-card-button {
background: var(--button);
width: 100%;
padding: 8px;
position: relative;
bottom: -12px;
}

:global(.ant-col-16) {
max-width: 100%;
}
}
71 changes: 71 additions & 0 deletions app/components-react/modals/onboarding/ConnectMore.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React from 'react';
import cx from 'classnames';
import { useVuex } from 'components-react/hooks';
import { Services } from 'components-react/service-provider';
import { $t } from 'services/i18n';
import styles from './Common.m.less';
import PlatformLogo from 'components-react/shared/PlatformLogo';
import { ListInput } from 'components-react/shared/inputs';
import { platformLabels, TPlatform } from 'services/platforms';
import { Header, IOnboardingStepProps, useAuth } from './Onboarding';
import Form from 'components-react/shared/inputs/Form';

export function ConnectMore(p: IOnboardingStepProps) {
const { UserService } = Services;

const { isPartialSLAuth } = useVuex(() => ({
isPartialSLAuth: UserService.views.isPartialSLAuth,
}));

const subtitle = isPartialSLAuth
? $t(
'Streamlabs Desktop requires that you have a connected platform account in order to use all of its features. By skipping this step, you will be logged out and some features may be unavailable.',
)
: $t('Connect your accounts for the best experience. You can always connect more later.');

const platformCards: TPlatform[] = ['twitch', 'youtube', 'tiktok', 'kick', 'facebook'];
const listedPlatforms: TPlatform[] = ['trovo', 'twitter', 'instagram'];

const { mergePlatform } = useAuth();

return (
<div className={styles.centered}>
<Header title={$t('Connect Platforms')} description={subtitle} />
<div className={styles.platformsContainer}>
{platformCards.map(platform => (
<PlatformCard platform={platform} />
))}
<div className={cx(styles.centered, styles.platformCard)}>
<i className="icon-platforms" style={{ fontSize: 32, padding: 8 }} />
<span>{$t('Select another platform')}</span>
<Form style={{ width: '100%', padding: '0 16px' }}>
<ListInput
options={listedPlatforms.map(platform => ({
label: platformLabels(platform),
value: platform,
}))}
onInput={mergePlatform}
nolabel
style={{ marginTop: 16 }}
/>
</Form>
</div>
</div>
</div>
);
}

function PlatformCard(p: { platform: TPlatform }) {
const { mergePlatform } = useAuth();

return (
<div
className={cx(styles.centered, styles.platformCard)}
onClick={() => mergePlatform(p.platform)}
>
<PlatformLogo platform={p.platform} size="medium" />
{platformLabels(p.platform)}
<div className={styles.platformCardButton}>{$t('Connect')}</div>
</div>
);
}
82 changes: 82 additions & 0 deletions app/components-react/modals/onboarding/Devices.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import React, { useEffect } from 'react';
import { DisplaySection } from 'components-react/pages/onboarding/HardwareSetup';
import styles from './Common.m.less';
import { Header, IOnboardingStepProps } from './Onboarding';
import { $t } from 'services/i18n';
import { ListInput } from 'components-react/shared/inputs';
import { useVuex } from 'components-react/hooks';
import { Services } from 'components-react/service-provider';
import Form from 'components-react/shared/inputs/Form';

export function Devices(p: IOnboardingStepProps) {
const { DefaultHardwareService, WindowsService } = Services;

const { videoDevices, audioDevices, selectedAudioDevice, selectedVideoDevice } = useVuex(() => ({
videoDevices: DefaultHardwareService.videoDevices.map(device => ({
label: device.description,
value: device.id,
})),
audioDevices: DefaultHardwareService.audioDevices.map(device => ({
label: device.description,
value: device.id,
})),
selectedVideoDevice: DefaultHardwareService.state.defaultVideoDevice,
selectedAudioDevice: DefaultHardwareService.state.defaultAudioDevice,
}));

// Set up temporary sources
useEffect(() => {
DefaultHardwareService.createTemporarySources();

if (!selectedVideoDevice && videoDevices.length) {
DefaultHardwareService.actions.setDefault('video', videoDevices[0].value);
}

return () => {
DefaultHardwareService.actions.clearTemporarySources();
};
}, []);

function setDevice(type: 'video' | 'audio') {
return (value: string) => {
DefaultHardwareService.actions.setDefault(type, value);
};
}

return (
<div className={styles.centered}>
<Header
title={$t('Set Up Your Mic & Webcam')}
description={$t('Connect your most essential devices now or later on')}
/>
<div
style={{
display: 'flex',
justifyContent: 'space-evenly',
alignItems: 'center',
width: '100%',
}}
>
<DisplaySection />
<div className={styles.darkBox} style={{ width: 360, height: 240, padding: 32 }}>
<Form layout="vertical">
<ListInput
label={$t('Webcam')}
options={videoDevices}
value={selectedVideoDevice}
onChange={setDevice('video')}
style={{ width: 200 }}
/>
<ListInput
label={$t('Microphone')}
options={audioDevices}
value={selectedAudioDevice}
onChange={setDevice('audio')}
style={{ width: 200 }}
/>
</Form>
</div>
</div>
</div>
);
}
Loading
Loading