Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(multistream): relax primary platform requirement #4855

Merged
merged 89 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
89 commits
Select commit Hold shift + click to select a range
afd2d76
fix(build): react-devtools build folder was ignored
blackxored Feb 27, 2024
d03e557
fix(build): only enable dev tools on dev mode
blackxored Feb 27, 2024
e0befa9
feat(multistream): allow disabling primary platform in UI
blackxored Jan 31, 2024
b3761a3
feat(multistream): don't force primary platform
blackxored Jan 31, 2024
8b29f7d
feat(streaming): disable Go Live button when no dest + views
blackxored Jan 31, 2024
ee6b28d
feat(streaming): avoid forcing primary platform chat
blackxored Feb 2, 2024
9cceda5
feat(streaming): use correct platform name when not streaming to primary
blackxored Feb 2, 2024
e656b20
feat(multistreaming): primary chat selector
blackxored Feb 5, 2024
458a87a
feat(multistreaming): setting primary chat sets primary platform
blackxored Feb 5, 2024
390b109
feat(multistreaming): sort platforms alphabetically, no more primary …
blackxored Feb 5, 2024
580c81b
fix(multistream): avoid showing primary chat switcher when unneeded
blackxored Feb 5, 2024
f0baf65
feat(multistream): only show primary switcher with multiple platforms
blackxored Feb 5, 2024
268bae5
fix(multistreaming): ensure one enabled platform persists for now
blackxored Feb 5, 2024
7b046d3
fix(streaming): initial attempt of fixing locked-out state
blackxored Feb 5, 2024
a1f6d22
refactor(streaming): remove unused imports
blackxored Feb 6, 2024
00be6ad
feat(multistreaming): set primary chat to last remaining active platf…
blackxored Feb 6, 2024
0a30140
fix(streaming): attempt to fix store watcher around `chatUrl`
blackxored Feb 8, 2024
dcefa70
fix(multistream): show primary chat switcher on advanced mode
blackxored Feb 8, 2024
820031f
fix(streaming): disable multistream check for enabling a primary plat…
blackxored Feb 8, 2024
1b1d8d1
fix(streaming): unlock dual output primary
blackxored Feb 8, 2024
55a74a0
feat(sidebar): new logged in status indicator featuring multiplatform
blackxored Feb 9, 2024
c1a977d
fix(style): logged in text margin
blackxored Feb 9, 2024
75f9a49
fix(style): custom destination icon hover
blackxored Feb 9, 2024
249e78d
fix(streaming): check to prevent going live w/o destinations
blackxored Feb 13, 2024
8200b76
fix(style): center platform indicator text
blackxored Feb 14, 2024
135ed72
fix(style): platform indicator
blackxored Feb 14, 2024
6af8553
refactor(streaming): fix strict nulls on platforms check
blackxored Feb 14, 2024
c3749a7
feat(i18n): translations for primary chat/login indicator
blackxored Feb 15, 2024
ecffc8c
refactor(streaming): remove no primary platform workarounds
blackxored Feb 15, 2024
32d208a
refactor(i18n): remove now unused translations
blackxored Feb 15, 2024
a3cad5a
chore: improve comment
blackxored Feb 15, 2024
8f4b511
chore: more comments
blackxored Feb 15, 2024
4f8bed1
feat(dual-output): primary chat switcher
blackxored Feb 15, 2024
a7bbb1a
fix(style): shrink Twitter logo on platform indicator
blackxored Feb 15, 2024
a951285
fix(style): spacing for multiple platform tools on dock
blackxored Feb 15, 2024
6c0291f
feat(multistream): switch primary chat while live
blackxored Feb 15, 2024
8b8245a
refactor(streaming): invert boolean for disable destination
blackxored Feb 16, 2024
b997b8d
refactor(streaming): remove now-unnecessary extra div on dest switchers
blackxored Feb 16, 2024
ca6a700
refactor(streaming): concise and clarify `isPrimary` check
blackxored Feb 16, 2024
8e7c93a
refactor(streaming): remove comments, custom dest and plat chat
blackxored Feb 16, 2024
4e179bc
refactor(streaming): remove unused import
blackxored Feb 16, 2024
afaa0a4
fix(streaming): set primary platform correctly when last selected
blackxored Feb 16, 2024
72a79ed
chore: remove comment after clarification
blackxored Feb 20, 2024
cd4a9f3
feat(onboarding): auto-select primary platform for Ultra users
blackxored Feb 20, 2024
5e72f70
fix(onboarding): attempt to fix stale state with dep
blackxored Feb 20, 2024
92cff46
fix(onboarding): use `isPrime` from Vuex
blackxored Feb 20, 2024
02051cb
fix(onboarding): typo
blackxored Feb 20, 2024
920cbf6
fix(onboarding): use `isPrime` from state
blackxored Feb 20, 2024
1fa4bd7
fix(onboarding): fetch prime status on starting SL auth
blackxored Feb 20, 2024
b4a6b47
fix(onboarding): add logging, await promise
blackxored Feb 20, 2024
8624f53
fix(style): better style for chat switcher on modal
blackxored Feb 21, 2024
f1f9555
Merge branch 'master' into feat/multistream-primary-platform-reqs
blackxored Apr 22, 2024
faa17ea
fix(multistreaming): filter out platforms that don't have chat
blackxored Apr 22, 2024
90e3759
Revert "fix(multistreaming): filter out platforms that don't have chat"
blackxored Apr 22, 2024
9f0b3ac
feat(multistream): allow switching of primary by toggles and more
blackxored Apr 22, 2024
3f63244
Merge branch 'master' into feat/multistream-primary-platform-reqs
blackxored Apr 25, 2024
fcb9048
fix(style): icon size for Twitter and TikTok
blackxored Apr 25, 2024
c56495f
refactor: enabling first platform w/ chat workaround might not be needed
blackxored Apr 25, 2024
ddbb786
feat: remove platform disabled state across
blackxored Apr 25, 2024
46252c8
feat(onboarding): auto-select primary platform
blackxored Apr 25, 2024
514ef6a
fix(streaming): Go Live settings were not properly resetting
blackxored Apr 26, 2024
2f1475e
fix: strict nulls
blackxored Apr 26, 2024
a62c3fb
Merge branch 'master' into feat/multistream-primary-platform-reqs
blackxored Apr 30, 2024
fd0f8fe
fix(chat): TikTok's fake chat refactor
blackxored Apr 30, 2024
ff1570d
Merge branch 'fix/go-live-settings' into feat/multistream-primary-pla…
blackxored May 1, 2024
69f88f2
chore: remove logging statement
blackxored May 1, 2024
bc336c4
Merge branch 'fix/go-live-settings' into feat/multistream-primary-pla…
blackxored May 1, 2024
74d15bb
fix(multistream): platform disabled style after failing to disable
blackxored May 7, 2024
07d166e
Merge branch 'fix/react-devtools-ignored' into feat/multistream-prima…
blackxored May 7, 2024
2a0622a
chore: comment
blackxored May 7, 2024
6dec668
fix(go-live): missing X icon on Dual Output free
blackxored May 7, 2024
a54c010
fix(main): custom destination icon padding
blackxored May 7, 2024
b6abba6
fix(chat): improve condition for Tiktok chat info
blackxored May 7, 2024
0e0042c
fix(go-live): custom destinations aren't really persisted
blackxored May 8, 2024
5bc56fd
Merge branch 'fix/custom-destinations-not-saved' into feat/multistrea…
blackxored May 8, 2024
8872c2c
feat: switch primary chat to new platform instead of TikTok
blackxored May 9, 2024
7a755ef
chore: typo and comment
blackxored May 9, 2024
a8007db
fix(style): size for Instagram icon on platform indicators
blackxored May 14, 2024
2107721
Merge branch 'master' into feat/multistream-primary-platform-reqs
blackxored May 14, 2024
dfdd379
fix(style): add margin to Instagram notice
blackxored May 14, 2024
92c238e
refactor(i18n): move Twitch strings to its own file
blackxored May 14, 2024
3e2bfe6
fix(auth): avoid showing username for Instagram or not logged in
blackxored May 14, 2024
0a7ca70
fix(instagram): use generic Logout on bottom left
blackxored May 14, 2024
bd19a40
fix(multistream): temp for multistream with TikTok as primary chat
blackxored May 14, 2024
d51d4f9
fix(i18n): generic logout str was not present in en_US anymore
blackxored May 14, 2024
76f5cde
fix: temp fix for dock if Instagram
blackxored May 14, 2024
6afc967
Merge branch 'master' into feat/multistream-primary-platform-reqs
blackxored May 29, 2024
ab6f749
Merge branch 'master' into feat/multistream-primary-platform-reqs
blackxored Jun 4, 2024
d612ea0
Merge branch 'master' into feat/multistream-primary-platform-reqs
blackxored Jun 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 11 additions & 5 deletions app/components-react/pages/onboarding/PrimaryPlatformSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ import { useVuex, useWatchVuex } from 'components-react/hooks';

export function PrimaryPlatformSelect() {
const { UserService, OnboardingService } = Services;
const { linkedPlatforms, isLogin } = useVuex(() => ({
const { linkedPlatforms, isLogin, isPrime } = useVuex(() => ({
linkedPlatforms: UserService.views.linkedPlatforms,
isLogin: OnboardingService.state.options.isLogin,
isPrime: UserService.state.isPrime,
}));
const { loading, authInProgress, authPlatform, finishSLAuth } = useModule(LoginModule);
const platforms = ['twitch', 'youtube', 'facebook', 'twitter', 'tiktok', 'trovo'];
Expand Down Expand Up @@ -62,17 +63,22 @@ export function PrimaryPlatformSelect() {

// There's probably a better way to do this
useEffect(() => {
// If user has exactly one streaming platform linked, we can proceed straight
// to a logged in state.
if (UserService.views.linkedPlatforms.length === 1) {
/*
* Per new requirements, we automatically select a platform for the user since they
* are now able to switch them off from the Go Live window. This makes this component
* obsolete except for the case where the user has no linked accounts at all.
*/
// TODO: we're still doing render side-effects here, which is not ideal
if (UserService.views.linkedPlatforms.length) {
selectPrimary(UserService.views.linkedPlatforms[0]);
return;
}

// TODO: This is probably dead code now
if (linkedPlatforms.length) {
setSelectedPlatform(linkedPlatforms[0]);
}
}, [linkedPlatforms.length]);
}, [linkedPlatforms.length, isPrime]);

// You may be confused why this component doesn't ever call `next()` to
// continue to the next step. The index-based step system makes this more
Expand Down
30 changes: 1 addition & 29 deletions app/components-react/root/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,6 @@ export default function Chat(props: {

let leaveFullScreenTrigger: Function;

const showTikTokInfo =
props.visibleChat === 'tiktok' ||
(props.visibleChat === 'default' &&
Services.UserService.state.auth?.primaryPlatform === 'tiktok');

const setTikTokChat =
Services.UserService.state.auth?.primaryPlatform === 'tiktok' &&
props.visibleChat === 'restream';

// Setup resize/fullscreen listeners
useEffect(() => {
resizeInterval = window.setInterval(() => {
Expand Down Expand Up @@ -66,9 +57,6 @@ export default function Chat(props: {
const cancelUnload = onUnload(() => service.actions.unmountChat(remote.getCurrentWindow().id));

return () => {
if (setTikTokChat) {
props.setChat('tiktok');
}
service.actions.unmountChat(remote.getCurrentWindow().id);
cancelUnload();
};
Expand Down Expand Up @@ -111,21 +99,5 @@ export default function Chat(props: {
);
}

return showTikTokInfo ? <TikTokChatInfo /> : <div className={styles.chat} ref={chatEl} />;
}

function TikTokChatInfo() {
function openPlatformDash() {
remote.shell.openExternal(Services.TikTokService.dashboardUrl);
}
return (
<div style={{ display: 'flex', flexDirection: 'column', marginTop: '30px' }}>
<div style={{ marginBottom: '5px' }}>
{$t('Access chat for TikTok in the TikTok Live Center.')}
</div>
<Button style={{ width: '200px', marginBottom: '10px' }} onClick={() => openPlatformDash()}>
{$t('Open TikTok Live Center')}
</Button>
</div>
);
return <div className={styles.chat} ref={chatEl} />;
}
5 changes: 1 addition & 4 deletions app/components-react/root/LiveDock.m.less
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,7 @@

.live-dock-platform-tools {
.flex();

i {
padding-right: 8px;
}
gap: 16px;
}

.live-dock-chat-apps__popout {
Expand Down
36 changes: 27 additions & 9 deletions app/components-react/root/LiveDock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import pick from 'lodash/pick';
import { initStore, useController } from 'components-react/hooks/zustand';
import { EStreamingState } from 'services/streaming';
import { EAppPageSlot, ILoadedApp } from 'services/platform-apps';
import { TPlatform, getPlatformService } from 'services/platforms';
import { getPlatformService, TPlatform } from 'services/platforms';
import { $t } from 'services/i18n';
import { Services } from '../service-provider';
import Chat from './Chat';
Expand All @@ -17,6 +17,7 @@ import PlatformAppPageView from 'components-react/shared/PlatformAppPageView';
import { useVuex } from 'components-react/hooks';
import { useRealmObject } from 'components-react/hooks/realm';
import { $i } from 'services/utils';
import { TikTokChatInfo } from './TiktokChatInfo';

const LiveDockCtx = React.createContext<LiveDockController | null>(null);

Expand Down Expand Up @@ -323,6 +324,30 @@ function LiveDock(p: { onLeft: boolean }) {
});
}

const chat = useMemo(() => {
const primaryChat = Services.UserService.state.auth!.primaryPlatform;
const showTiktokInfo = visibleChat === 'tiktok' || primaryChat === 'tiktok';

if (showTiktokInfo && !isRestreaming) {
return <TikTokChatInfo />;
}

const showInstagramInfo = primaryChat === 'instagram';
if (showInstagramInfo) {
// FIXME: empty tab
return <></>;
}

return (
<Chat
restream={isRestreaming && visibleChat === 'restream'}
key={visibleChat}
visibleChat={visibleChat}
setChat={setChat}
/>
);
}, [Services.UserService.state.auth!.primaryPlatform, visibleChat]);

return (
<div
className={cx(styles.liveDock, {
Expand Down Expand Up @@ -429,14 +454,7 @@ function LiveDock(p: { onLeft: boolean }) {
)}
</div>
)}
{!applicationLoading && !collapsed && (
<Chat
restream={isRestreaming && visibleChat === 'restream'}
key={visibleChat}
visibleChat={visibleChat}
setChat={setChat}
/>
)}
{!applicationLoading && !collapsed && chat}
{!['default', 'restream'].includes(visibleChat) && (
<PlatformAppPageView
className={styles.liveDockPlatformAppWebview}
Expand Down
34 changes: 34 additions & 0 deletions app/components-react/root/TiktokChatInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import * as remote from '@electron/remote';
import { Services } from '../service-provider';
import { $t } from '../../services/i18n';
import { Button } from 'antd';
import React from 'react';

export function TikTokChatInfo() {
function openPlatformDash() {
remote.shell.openExternal(Services.TikTokService.dashboardUrl);
}

return (
<div
style={{
display: 'flex',
flexDirection: 'column',
marginTop: '30px',
}}
>
<div style={{ marginBottom: '5px' }}>
{$t('Access chat for TikTok in the TikTok Live Center.')}
</div>
<Button
style={{
width: '200px',
marginBottom: '10px',
}}
onClick={() => openPlatformDash()}
>
{$t('Open TikTok Live Center')}
</Button>
</div>
);
}
1 change: 1 addition & 0 deletions app/components-react/shared/PlatformLogo.m.less
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
height: 40px;
background-size: contain;
background-repeat: no-repeat;
vertical-align: middle;

&.twitter--black {
background-image: url(https://slobs-cdn.streamlabs.com/media/twitter-logo-black.png);
Expand Down
34 changes: 15 additions & 19 deletions app/components-react/sidebar/NavTools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import PlatformLogo from 'components-react/shared/PlatformLogo';
import SubMenu from 'components-react/shared/SubMenu';
import MenuItem from 'components-react/shared/MenuItem';
import UltraIcon from 'components-react/shared/UltraIcon';
import PlatformIndicator from './PlatformIndicator';

export default function SideNav() {
const {
Expand Down Expand Up @@ -77,6 +78,12 @@ export default function SideNav() {

const throttledOpenDashboard = throttle(openDashboard, 2000, { trailing: false });

// Instagram doesn't provide a username, since we're not really linked, pass undefined for a generic logout msg w/o it
const username =
isLoggedIn && UserService.views.auth!.primaryPlatform !== 'instagram'
? UserService.username
: undefined;

function openHelp() {
UsageStatisticsService.actions.recordClick('SideNav2', 'help');
remote.shell.openExternal(
Expand Down Expand Up @@ -195,7 +202,7 @@ export default function SideNav() {
showModal={showModal}
handleAuth={handleAuth}
handleShowModal={handleShowModal}
username={UserService.username}
username={username}
/>
</>
);
Expand Down Expand Up @@ -258,6 +265,11 @@ function LogoutModal(p: {
handleShowModal: (status: boolean) => void;
username?: string;
}) {
const { username } = p;
const confirmMsg = username
? $t('Are you sure you want to log out %{username}?', { username })
: $t('Are you sure you want to log out?');

return (
<Modal
footer={null}
Expand All @@ -268,9 +280,7 @@ function LogoutModal(p: {
>
<Form className={styles.confirmLogout}>
<h2>{$t('Confirm')}</h2>
{$t('Are you sure you want to log out %{username}?', {
username: p.username,
})}
{confirmMsg}
<div className={styles.buttons}>
<Button onClick={() => p.handleAuth()}>{$t('Yes')}</Button>
<Button onClick={() => p.handleShowModal(false)}>{$t('No')}</Button>
Expand Down Expand Up @@ -307,21 +317,7 @@ function LoginMenuItem(p: {
{!isLoggedIn ? (
<span className={styles.loggedOut}>{menuTitles(menuItem.key)}</span>
) : (
isOpen && (
<>
{platform && (
<PlatformLogo
platform={platform?.type!}
className={cx(
styles.platformLogo,
styles[`platform-logo-${platform?.type ?? 'default'}`],
)}
/>
)}
<span className={styles.username}>{platform?.username || $t('Log Out')}</span>
<i className={cx('icon-logout', styles.loginArrow)} />
</>
)
isOpen && <PlatformIndicator platform={platform} />
)}
</MenuItem>
);
Expand Down
75 changes: 75 additions & 0 deletions app/components-react/sidebar/PlatformIndicator.m.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// TODO: these are duplicated from NavTools.m.less, consider refactoring out if not needed there
.platform-logo {
margin-right: 10px;

&-twitch {
color: var(--twitch) !important;
}
&-youtube {
color: var(--youtube) !important;
}
&-facebook {
color: var(--facebook) !important;
}
&-trovo, &-twitter, &-tiktok, &-instagram {
width: 15px;
height: 15px;
}
&-tiktok {
color: var(--tiktok) !important;
}
&-streamlabs {
color: var(--teal) !important;
}
&-default {
color: var(--logged-in) !important;
}
}

.username {
margin-bottom: 0px;
flex-grow: 1;
line-height: 20px;
margin: 2px 0 0 0;
}

.login-arrow {
justify-self: flex-end;
margin-left: 5px;
transform: scaleX(-1);
-moz-transform: scaleX(-1);
-webkit-transform: scaleX(-1);
-ms-transform: scaleX(-1);
transition: all 0.2s ease-in-out;
}

.platform-icons {
display: flex;
flex-direction: row;
gap: 1px;
align-items: center;
justify-content: center;

// Override the zooming effect applied to sidebar icons
i {
&,
&:hover {
transform: none !important;
transition: none !important;
}
}

// Custom destination icon
:global(.fa-globe) {
blackxored marked this conversation as resolved.
Show resolved Hide resolved
margin-right: 10px;
}

:global(.fa-globe) {
&,
&:hover,
&:focus,
&:active {
color: var(--icon) !important;
}
}
}