diff --git a/app/components-react/windows/go-live/CommonPlatformFields.tsx b/app/components-react/windows/go-live/CommonPlatformFields.tsx index 7de5efa6b98a..8107df733896 100644 --- a/app/components-react/windows/go-live/CommonPlatformFields.tsx +++ b/app/components-react/windows/go-live/CommonPlatformFields.tsx @@ -9,6 +9,9 @@ import { TLayoutMode } from './platforms/PlatformSettingsLayout'; import { Services } from '../../service-provider'; import AiHighlighterToggle from './AiHighlighterToggle'; import { EAvailableFeatures } from 'services/incremental-rollout'; +import * as remote from '@electron/remote'; +import InfoBanner from 'components-react/shared/InfoBanner'; +import { EDismissable } from 'services/dismissables'; interface ICommonPlatformSettings { title: string; @@ -68,8 +71,6 @@ export const CommonPlatformFields = InputComponent((rawProps: IProps) => { ? p.descriptionIsRequired : p.platform === 'facebook'; - const user = Services.UserService.views; - const hasDescription = p.platform ? view.supports('description', [p.platform as TPlatform]) : view.supports('description'); @@ -91,10 +92,6 @@ export const CommonPlatformFields = InputComponent((rawProps: IProps) => { } const titleTooltip = useMemo(() => { - if (enabledPlatforms.includes('tiktok')) { - return $t('Only 32 characters of your title will display on TikTok'); - } - if (enabledPlatforms.length === 1 && p?.platform === 'kick') { return $t('Edit your stream title on Kick after going live.'); } @@ -102,6 +99,8 @@ export const CommonPlatformFields = InputComponent((rawProps: IProps) => { return undefined; }, [enabledPlatforms]); + const shouldShowTikTokWarning = Services.TikTokService.shouldShowTikTokWarning; + return (
{/* USE CUSTOM CHECKBOX */} @@ -146,9 +145,28 @@ export const CommonPlatformFields = InputComponent((rawProps: IProps) => { !enabledPlatforms.includes('twitch') && ( )} + + {shouldShowTikTokWarning && }
)} ); }); + +function TikTokNoty() { + return ( + + ); +} + +function openConfirmation() { + remote.shell.openExternal(Services.TikTokService.notificationUrl); +} diff --git a/app/components-react/windows/go-live/DestinationSwitchers.tsx b/app/components-react/windows/go-live/DestinationSwitchers.tsx index 01d63d3bd094..e95b33fc2a68 100644 --- a/app/components-react/windows/go-live/DestinationSwitchers.tsx +++ b/app/components-react/windows/go-live/DestinationSwitchers.tsx @@ -2,7 +2,6 @@ import React, { useRef, MouseEvent } from 'react'; import { getPlatformService, TPlatform } from '../../../services/platforms'; import cx from 'classnames'; import { $t } from '../../../services/i18n'; -import * as remote from '@electron/remote'; import styles from './DestinationSwitchers.m.less'; import { ICustomStreamDestination } from '../../../services/settings/streaming'; import { Services } from '../../service-provider'; @@ -10,10 +9,6 @@ import { SwitchInput } from '../../shared/inputs'; import PlatformLogo from '../../shared/PlatformLogo'; import { useDebounce } from '../../hooks'; import { useGoLiveSettings } from './useGoLiveSettings'; -import { alertAsync } from '../../modals'; -import { ModalLayout } from 'components-react/shared/ModalLayout'; -import { Button, Form, Modal } from 'antd'; -import Translate from 'components-react/shared/Translate'; /** * Allows enabling/disabling platforms and custom destinations for the stream @@ -27,28 +22,23 @@ export function DestinationSwitchers(p: { showSelector?: boolean }) { switchPlatforms, switchCustomDestination, isPrimaryPlatform, - isPlatformLinked, isRestreamEnabled, } = useGoLiveSettings(); // use these references to apply debounce // for error handling and switch animation const enabledPlatformsRef = useRef(enabledPlatforms); enabledPlatformsRef.current = enabledPlatforms; + const enabledDestRef = useRef(enabledDestinations); enabledDestRef.current = enabledDestinations; - // special handling for TikTok for non-ultra users - // to disable/enable platforms and open ultra link - const promptConnectTikTok = !isPlatformLinked('tiktok'); - const shouldDisableCustomDestinationSwitchers = () => { // Multistream users can always add destinations if (isRestreamEnabled) { return false; } - // Otherwise, only a single platform and no custom destinations, - // TikTok should be handled by platform switching + // Otherwise, only a single platform and no custom destinations return enabledPlatforms.length > 0; }; @@ -66,48 +56,17 @@ export function DestinationSwitchers(p: { showSelector?: boolean }) { if (typeof target === 'number') { return enabledDestRef.current.includes(target); } else { - if (target === 'tiktok' && promptConnectTikTok) { - return false; - } - return enabledPlatformsRef.current.includes(target); } } function togglePlatform(platform: TPlatform, enabled: boolean) { - // On non multistream mode, switch the platform that was just selected while disabling all the others, - // allow TikTok to be added as an extra platform if (!isRestreamEnabled) { /* - * If TikTok is the platform being toggled: - * - Preserve the currently active platform so TikTok can be added to this list at the bottom of this function, - * we will have 2 active platforms and a Primary Chat switcher. - * - Remove TikTok from the list without removing the other active platform if we're disabling TikTok itself. + * Clearing this list ensures that when a new platform is selected, instead of enabling 2 platforms + * we switch to 1 enabled platforms that was just toggled. */ - if (platform === 'tiktok') { - if (enabled) { - /* - * If we had two platforms, none of which were tiktok, we still need to limit - * that to 1 platform without restreaming. - * This could happen when coming from having dual output enabled to off. - * TODO: this might not be needed after #5244, keeping here for a while for extra care - */ - enabledPlatformsRef.current = enabledPlatformsRef.current.slice(0, 1); - } else { - enabledPlatformsRef.current = enabledPlatformsRef.current.filter( - platform => platform !== 'tiktok', - ); - } - } else { - /* - * Clearing this list ensures that when a new platform is selected, instead of enabling 2 platforms - * we switch to 1 enabled platforms that was just toggled. - * We will also preserve TikTok as an active platform if it was before. - */ - enabledPlatformsRef.current = enabledPlatformsRef.current.includes('tiktok') - ? ['tiktok'] - : []; - } + enabledPlatformsRef.current = []; } else { enabledPlatformsRef.current = enabledPlatformsRef.current.filter(p => p !== platform); } @@ -124,18 +83,6 @@ export function DestinationSwitchers(p: { showSelector?: boolean }) { emitSwitch(); } - function toggleDest(ind: number, enabled: boolean) { - enabledDestRef.current = enabledDestRef.current.filter(index => index !== ind); - if (enabled) { - enabledDestRef.current.push(ind); - } - emitSwitch(ind, enabled); - } - - // TODO: find a cleaner way to do this - const isPrimary = (platform: TPlatform) => - isPrimaryPlatform(platform) || linkedPlatforms.length === 1; - return (
{linkedPlatforms.map(platform => ( @@ -144,21 +91,10 @@ export function DestinationSwitchers(p: { showSelector?: boolean }) { destination={platform} enabled={isEnabled(platform)} onChange={enabled => togglePlatform(platform, enabled)} - promptConnectTikTok={platform === 'tiktok' && promptConnectTikTok} isPrimary={isPrimaryPlatform(platform)} /> ))} - {!linkedPlatforms.includes('tiktok') && ( - togglePlatform('tiktok', enabled)} - isPrimary={isPrimaryPlatform('tiktok')} - promptConnectTikTok={promptConnectTikTok} - /> - )} - {customDestinations?.map((dest, ind) => ( unknown; isPrimary?: boolean; - promptConnectTikTok?: boolean; disabled?: boolean; } @@ -191,23 +126,8 @@ const DestinationSwitcher = React.forwardRef<{}, IDestinationSwitcherProps>((p, const switchInputRef = useRef(null); const containerRef = useRef(null); const platform = typeof p.destination === 'string' ? (p.destination as TPlatform) : null; - const { RestreamService, TikTokService, StreamingService } = Services; - const canEnableRestream = RestreamService.views.canEnableRestream; - const cannotDisableDestination = p.isPrimary && !canEnableRestream; - const showTikTokModal = - p.promptConnectTikTok || (platform === 'tiktok' && TikTokService.missingLiveAccess); - - // Preserving old TikTok functionality, so they can't enable the toggle if TikTok is not - // connected. - // TODO: this kind of logic should belong on caller, but ideally we would refactor all this - const tiktokDisabled = - platform === 'tiktok' && !StreamingService.views.isPlatformLinked('tiktok'); function onClickHandler(ev: MouseEvent) { - if (showTikTokModal) { - renderTikTokModal(p.promptConnectTikTok); - } - // If we're disabling the switch we shouldn't be emitting anything past below if (p.disabled) { return; @@ -218,43 +138,12 @@ const DestinationSwitcher = React.forwardRef<{}, IDestinationSwitcherProps>((p, // always proxy the click to the SwitchInput // so it can play a transition animation switchInputRef.current?.click(); - - /* - * TODO: - * this causes inconsistent state when disabling primary platform - * after is being re-enabled. Not sure which animation is referring to. - */ - // switch the container class without re-rendering to not stop the animation - /* - if (enable) { - containerRef.current?.classList.remove(styles.platformDisabled); - } else { - containerRef.current?.classList.add(styles.platformDisabled); - } - */ - } - - function addClass() { - containerRef.current?.classList.remove(styles.platformDisabled); - } - - function removeClass() { - if (p.isPrimary) { - alertAsync( - $t( - 'You cannot disable the platform you used to sign in to Streamlabs Desktop. Please sign in with a different platform to disable streaming to this destination.', - ), - ); - return; - } - p.onChange(false); - containerRef.current?.classList.add(styles.platformDisabled); } const { title, description, Switch, Logo } = (() => { if (platform) { // define slots for a platform switcher - const { UserService, StreamingService } = Services; + const { UserService } = Services; const service = getPlatformService(platform); const platformAuthData = UserService.state.auth?.platforms[platform]; const username = platformAuthData?.username ?? ''; @@ -266,13 +155,7 @@ const DestinationSwitcher = React.forwardRef<{}, IDestinationSwitcherProps>((p, ), Switch: () => ( - + ), }; } else { @@ -299,7 +182,7 @@ const DestinationSwitcher = React.forwardRef<{}, IDestinationSwitcherProps>((p,
@@ -320,54 +203,3 @@ const DestinationSwitcher = React.forwardRef<{}, IDestinationSwitcherProps>((p,
); }); - -export function renderTikTokModal(promptConnectTikTok?: boolean) { - const { TikTokService } = Services; - - const message = promptConnectTikTok - ? $t('Connect your TikTok account to stream to TikTok and one additional platform for free.') - : $t( - "Connect your TikTok account to stream to TikTok and one other platform for free. Haven't applied to stream on TikTok Live yet? Start the process here.", - { link: }, - ); - - function openApplicationInfoPage() { - remote.shell.openExternal(Services.TikTokService.applicationUrl); - } - - alertAsync({ - bodyStyle: { padding: '24px' }, - className: styles.tiktokModal, - type: 'confirm', - title: $t('Connect your TikTok Account'), - content: ( - - - - ), - icon: , - closable: true, - maskClosable: true, - cancelButtonProps: { style: { display: 'none' } }, - okButtonProps: { style: { display: 'none' } }, - modalRender: node => }>{node}, - width: 600, - }); -} - -function TikTokModalFooter() { - function connect() { - Modal.destroyAll(); - Services.NavigationService.actions.navigate('PlatformMerge', { platform: 'tiktok' }); - Services.WindowsService.actions.closeChildWindow(); - } - - return ( -
- - -
- ); -} diff --git a/app/components-react/windows/go-live/dual-output/NonUltraDestinationSwitchers.tsx b/app/components-react/windows/go-live/dual-output/NonUltraDestinationSwitchers.tsx index bdb31e60e23b..1841f4d7cb24 100644 --- a/app/components-react/windows/go-live/dual-output/NonUltraDestinationSwitchers.tsx +++ b/app/components-react/windows/go-live/dual-output/NonUltraDestinationSwitchers.tsx @@ -1,4 +1,4 @@ -import React, { useRef, useCallback, useMemo } from 'react'; +import React, { useRef, useCallback } from 'react'; import { getPlatformService, TPlatform } from 'services/platforms'; import cx from 'classnames'; import { $t } from 'services/i18n'; @@ -14,7 +14,6 @@ import Translate from 'components-react/shared/Translate'; import DualOutputPlatformSelector from './DualOutputPlatformSelector'; import { useDebounce } from 'components-react/hooks'; import DualOutputToggle from '../../../shared/DualOutputToggle'; -import { renderTikTokModal } from '../DestinationSwitchers'; interface INonUltraDestinationSwitchers { showSelector?: boolean; @@ -28,18 +27,11 @@ export function NonUltraDestinationSwitchers(p: INonUltraDestinationSwitchers) { switchPlatforms, switchCustomDestination, isPrimaryPlatform, - isPlatformLinked, isRestreamEnabled, } = useGoLiveSettings(); const enabledPlatformsRef = useRef(enabledPlatforms); enabledPlatformsRef.current = enabledPlatforms; const destinationSwitcherRef = useRef({ addClass: () => undefined }); - const promptConnectTikTok = !isPlatformLinked('tiktok'); - - const platforms = useMemo( - () => (promptConnectTikTok ? enabledPlatforms.concat('tiktok') : enabledPlatforms), - [enabledPlatforms, promptConnectTikTok], - ); const emitSwitch = useDebounce(500, () => { switchPlatforms(enabledPlatformsRef.current); @@ -53,10 +45,6 @@ export function NonUltraDestinationSwitchers(p: INonUltraDestinationSwitchers) { }, []); function isEnabled(target: TPlatform) { - if (target === 'tiktok' && promptConnectTikTok) { - return false; - } - return enabledPlatforms.includes(target); } @@ -75,14 +63,13 @@ export function NonUltraDestinationSwitchers(p: INonUltraDestinationSwitchers) { style={{ marginBottom: '15px' }} /> )} - {platforms.map((platform: TPlatform, index: number) => ( + {enabledPlatforms.map((platform: TPlatform, index: number) => ( togglePlatform(platform, enabled)} isPrimary={isPrimaryPlatform(platform)} - promptConnectTikTok={platform === 'tiktok' && promptConnectTikTok} canDisablePrimary={isRestreamEnabled} index={index} /> @@ -122,7 +109,6 @@ interface IDestinationSwitcherProps { enabled: boolean; onChange: (enabled: boolean) => unknown; isPrimary?: boolean; - promptConnectTikTok?: boolean; index: number; canDisablePrimary?: boolean; } @@ -144,10 +130,7 @@ const DestinationSwitcher = React.forwardRef<{ addClass: () => void }, IDestinat }; }); const containerRef = useRef(null); - const { TikTokService } = Services; const platform = typeof p.destination === 'string' ? (p.destination as TPlatform) : null; - const showTikTokModal = - p.promptConnectTikTok || (platform === 'tiktok' && TikTokService.missingLiveAccess); function addClass() { containerRef.current?.classList.remove(styles.platformDisabled); @@ -212,18 +195,10 @@ const DestinationSwitcher = React.forwardRef<{ addClass: () => void }, IDestinat
-
{ - if (showTikTokModal) { - renderTikTokModal(p.promptConnectTikTok); - } - }} - > +
{/* LOGO */} @@ -233,7 +208,7 @@ const DestinationSwitcher = React.forwardRef<{ addClass: () => void }, IDestinat {description}
{/* CLOSE */} - {(!p.isPrimary || !p.promptConnectTikTok) && } + {!p.isPrimary && }
diff --git a/app/components-react/windows/go-live/dual-output/UltraDestinationSwitchers.tsx b/app/components-react/windows/go-live/dual-output/UltraDestinationSwitchers.tsx index 58ef9e7aa1d1..01210fb2b0c1 100644 --- a/app/components-react/windows/go-live/dual-output/UltraDestinationSwitchers.tsx +++ b/app/components-react/windows/go-live/dual-output/UltraDestinationSwitchers.tsx @@ -1,4 +1,4 @@ -import React, { useRef, MouseEvent, useCallback, useMemo } from 'react'; +import React, { useRef, MouseEvent, useCallback } from 'react'; import { getPlatformService, TPlatform } from 'services/platforms'; import cx from 'classnames'; import { $t } from 'services/i18n'; @@ -14,7 +14,6 @@ import { alertAsync } from 'components-react/modals'; import Translate from 'components-react/shared/Translate'; import { useDebounce } from 'components-react/hooks'; import DualOutputToggle from '../../../shared/DualOutputToggle'; -import { renderTikTokModal } from '../DestinationSwitchers'; interface IUltraDestinationSwitchers { type?: 'default' | 'ultra'; @@ -30,28 +29,18 @@ export function UltraDestinationSwitchers(p: IUltraDestinationSwitchers) { customDestinations, isDualOutputMode, isPrimaryPlatform, - isPlatformLinked, switchPlatforms, switchCustomDestination, isRestreamEnabled, } = useGoLiveSettings(); const enabledPlatformsRef = useRef(enabledPlatforms); enabledPlatformsRef.current = enabledPlatforms; - const promptConnectTikTok = !isPlatformLinked('tiktok'); - - const platforms = useMemo( - () => (promptConnectTikTok ? linkedPlatforms.concat('tiktok') : linkedPlatforms), - [linkedPlatforms, promptConnectTikTok], - ); const emitSwitch = useDebounce(500, () => { switchPlatforms(enabledPlatformsRef.current); }); - const isEnabled = useCallback((target: TPlatform) => { - if (target === 'tiktok' && promptConnectTikTok) { - return false; - } + const isEnabled = useCallback((target: TPlatform) => { return enabledPlatformsRef.current.includes(target); }, []); @@ -83,14 +72,13 @@ export function UltraDestinationSwitchers(p: IUltraDestinationSwitchers) { style={{ marginBottom: '15px' }} /> )} - {platforms.map((platform: TPlatform, index: number) => ( + {linkedPlatforms.map((platform: TPlatform, index: number) => ( togglePlatform(platform, enabled)} isPrimary={isPrimaryPlatform(platform)} - promptConnectTikTok={platform === 'tiktok' && promptConnectTikTok} canDisablePrimary={isRestreamEnabled} index={index} /> @@ -113,7 +101,6 @@ interface IDestinationSwitcherProps { enabled: boolean; onChange: (enabled: boolean) => unknown; isPrimary?: boolean; - promptConnectTikTok?: boolean; canDisablePrimary?: boolean; index: number; } @@ -125,11 +112,9 @@ function DestinationSwitcher(p: IDestinationSwitcherProps) { const switchInputRef = useRef(null); const containerRef = useRef(null); const platform = typeof p.destination === 'string' ? (p.destination as TPlatform) : null; - const enable = !p.enabled ?? (p.promptConnectTikTok && p.promptConnectTikTok === true); - const { RestreamService, MagicLinkService, TikTokService } = Services; + const enable = !p.enabled; + const { RestreamService, MagicLinkService } = Services; const canDisablePrimary = p.canDisablePrimary; - const showTikTokModal = - p.promptConnectTikTok || (platform === 'tiktok' && TikTokService.missingLiveAccess); function onClickHandler(ev: MouseEvent) { // TODO: do we need this check if we're on an Ultra DestinationSwitcher @@ -142,7 +127,7 @@ function DestinationSwitcher(p: IDestinationSwitcherProps) { return; } - if (RestreamService.views.canEnableRestream && !p.promptConnectTikTok) { + if (RestreamService.views.canEnableRestream) { p.onChange(enable); // always proxy the click to the SwitchInput // so it can play a transition animation @@ -181,11 +166,7 @@ function DestinationSwitcher(p: IDestinationSwitcherProps) { inputRef={switchInputRef} value={p.enabled} name={platform} - disabled={ - canDisablePrimary - ? false - : p?.isPrimary || (p.promptConnectTikTok && platform === 'tiktok') - } + disabled={canDisablePrimary ? false : p?.isPrimary} uncontrolled className={styles.platformSwitch} checkedChildren={} @@ -218,13 +199,8 @@ function DestinationSwitcher(p: IDestinationSwitcherProps) { ref={containerRef} data-test="ultra-switcher" className={cx(styles.platformSwitcher, { - [styles.platformDisabled]: !p.enabled || p.promptConnectTikTok, + [styles.platformDisabled]: !p.enabled, })} - onClick={() => { - if (showTikTokModal) { - renderTikTokModal(p.promptConnectTikTok); - } - }} >
@@ -237,17 +213,7 @@ function DestinationSwitcher(p: IDestinationSwitcherProps) {
{/* SWITCH */} -
{ - if (showTikTokModal) { - renderTikTokModal(p.promptConnectTikTok); - e.stopPropagation(); - return; - } else { - onClickHandler(e); - } - }} - > +
diff --git a/app/components-react/windows/go-live/platforms/TiktokEditStreamInfo.tsx b/app/components-react/windows/go-live/platforms/TiktokEditStreamInfo.tsx index e58551d0551e..c9759b599a4f 100644 --- a/app/components-react/windows/go-live/platforms/TiktokEditStreamInfo.tsx +++ b/app/components-react/windows/go-live/platforms/TiktokEditStreamInfo.tsx @@ -22,6 +22,7 @@ export function TikTokEditStreamInfo(p: IPlatformComponentParams<'tiktok'>) { const approved = TikTokService.scope === 'approved'; const denied = TikTokService.scope === 'denied'; const controls = TikTokService.audienceControls; + const showNoty = TikTokService.locale === 'en-US'; function updateSettings(patch: Partial) { p.onChange({ ...ttSettings, ...patch }); diff --git a/app/i18n/en-US/tiktok.json b/app/i18n/en-US/tiktok.json index 2f2571e6d15c..6b758faa5055 100644 --- a/app/i18n/en-US/tiktok.json +++ b/app/i18n/en-US/tiktok.json @@ -26,5 +26,6 @@ "TikTok Stream Error": "TikTok Stream Error", "Couldn't confirm TikTok Live Access. Apply for Live Permissions below": "Couldn't confirm TikTok Live Access. Apply for Live Permissions below", "Connect your TikTok account": "Connect your TikTok account", - "Connect your TikTok account to stream to TikTok and one other platform for free. Haven't applied to stream on TikTok Live yet? Start the process here.": "Connect your TikTok account to stream to TikTok and one other platform for free. Haven't applied to stream on TikTok Live yet? Start the process here." + "Connect your TikTok account to stream to TikTok and one other platform for free. Haven't applied to stream on TikTok Live yet? Start the process here.": "Connect your TikTok account to stream to TikTok and one other platform for free. Haven't applied to stream on TikTok Live yet? Start the process here.", + "Streaming to TikTok may not work due to ban in effect. Learn more here.": "Streaming to TikTok may not work due to ban in effect. Learn more here." } diff --git a/app/services/dismissables.ts b/app/services/dismissables.ts index b232d49e679c..f75796ede85e 100644 --- a/app/services/dismissables.ts +++ b/app/services/dismissables.ts @@ -17,6 +17,7 @@ export enum EDismissable { LoginPrompt = 'login_prompt', TikTokRejected = 'tiktok_rejected', TikTokEligible = 'tiktok_eligible', + TikTokBanned = 'tiktok_banned', } interface IDismissablesServiceState { diff --git a/app/services/platforms/tiktok.ts b/app/services/platforms/tiktok.ts index 48394a751b13..61cfa730e8b9 100644 --- a/app/services/platforms/tiktok.ts +++ b/app/services/platforms/tiktok.ts @@ -213,7 +213,7 @@ export class TikTokService // if the stream did not start successfully, prevent going live if (!streamInfo?.id) { await this.handleOpenLiveManager(); - throwStreamError('TIKTOK_GENERATE_CREDENTIALS_FAILED'); + throwStreamError('TIKTOK_GENERATE_CREDENTIALS_FAILED', {}, `User locale is ${this.locale}`); } ttSettings.serverUrl = streamInfo.rtmp; @@ -273,7 +273,7 @@ export class TikTokService return this.userService.updatePlatformToken('tiktok', response.access_token); }) .catch(e => { - console.error('Error fetching new token.'); + console.error('Error fetching new token. User locale is ', this.locale); return Promise.reject(e); }); } @@ -334,8 +334,10 @@ export class TikTokService ); const details = (e as any).result?.error - ? `${(e as any).result.error.type} ${(e as any).result.error.message}` - : 'Connection failed'; + ? `${(e as any).result.error.type} ${(e as any).result.error.message} User locale is ${ + this.locale + }` + : `Connection failed. User locale is ${this.locale}`; if (notApproved) { this.SET_LIVE_SCOPE('relog'); @@ -377,11 +379,15 @@ export class TikTokService return jfetch(request).catch((e: unknown) => { if (e instanceof StreamError) { - throwStreamError('TIKTOK_GENERATE_CREDENTIALS_FAILED', e as any); + throwStreamError( + 'TIKTOK_GENERATE_CREDENTIALS_FAILED', + e as any, + `User locale is ${this.locale}`, + ); } const error = this.handleStartStreamError((e as ITikTokError)?.status); - throwStreamError(error.type, { status: error.status }); + throwStreamError(error.type, { status: error.status }, `User locale is ${this.locale}`); }); } @@ -537,9 +543,9 @@ export class TikTokService games.push(this.defaultGame); return games; }) - .catch(e => { + .catch((e: unknown) => { console.error('Error fetching TikTok categories: ', e); - return []; + return [] as IGame[]; }); } @@ -557,7 +563,7 @@ export class TikTokService console.debug('TikTok stream status: ', status); if (status === EPlatformCallResult.TikTokScopeOutdated) { - throwStreamError('TIKTOK_SCOPE_OUTDATED'); + throwStreamError('TIKTOK_SCOPE_OUTDATED', {}, `User locale is ${this.locale}`); } this.SET_PREPOPULATED(true); @@ -654,6 +660,10 @@ export class TikTokService return 'https://livecenter.tiktok.com/replay'; } + get notificationUrl(): string { + return 'https://streamlabs.com/content-hub/post/is-tiktok-banned'; + } + get locale(): string { return I18nService.instance.state.locale; } @@ -704,6 +714,10 @@ export class TikTokService return false; } + get shouldShowTikTokWarning() { + return this.streamingService.views.isPlatformLinked('tiktok'); + } + convertScope(scope: number, applicationStatus?: string): TTikTokLiveScopeTypes { if (applicationStatus === 'never_applied' && scope !== ETikTokLiveScopeReason.APPROVED_OBS) { return 'never-applied';