Skip to content

Commit 6996fdb

Browse files
gettinToastygettinToastyblackxored
authored
Clean up platform logic dealing with lviedock features (#5401)
* Port LiveDock Component * Fix import errors and tabs * Add to ReactComponentList * Fix strict nulls * Fix import error * Fix reactivity issues * Fix positioning and styling * Begin 1 to 1 port * Define variables and functions * Add missing classNames * Fix non-modal redlines * Add modals to react * Import components * Fix rendering bugs * Add misssing classes * Change scope of windowWidth * Remove props from main window * Move to native react rendering * Revert to Vue wrapper component * Fix stale style blockers * Add css aliases * Begin livedock restructure * Fix rendering livedock * Use Realm * Fix compilation error * Fix Livedock breaking render * Use realm props binding * fix: pass theme to `Loader` * chore: uncoment main rendering * fix(main): restore wrappers, should fix resizing behavior * Restores main wrappers from the original Vue component, some of these are needed to preserve layout, while also in some cases separating the styles from the rendered component, e.g. footer, sidebar, where styles would be merged weirdly. * `overflow: auto` is apparently required and that's what it seems to fix the cutoff at the bottom, combined with the above. * Cleanup needed. * Re-add ChatTabs * Fix index typing for customization service * Fix typing in Studio.tsx * Fix resizing problem * Fix css on resize bar * Fix footer clipping at small sizes * Fix livedock collapse * Refactor resizebar into main window * Get resize working * Refactor to add collapse * Fix dock resizing * Add perf optimizations * Add animation * Fix non-editor size weirdness * Fix chat disappearing * Fix strict nulls issue * Fix strict nulls again * Fix strict nulls last time pls * Address CR * Clean up platform logic dealing with lviedock features * Fix tests --------- Co-authored-by: gettinToasty <sbeyer@logitech.com> Co-authored-by: Adrian Perez <adrian@adrianperez.org>
1 parent 50adc9d commit 6996fdb

11 files changed

Lines changed: 100 additions & 32 deletions

File tree

app/components-react/root/LiveDock.tsx

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import pick from 'lodash/pick';
66
import { initStore, useController } from 'components-react/hooks/zustand';
77
import { EStreamingState } from 'services/streaming';
88
import { EAppPageSlot, ILoadedApp } from 'services/platform-apps';
9-
import { getPlatformService, TPlatform } from 'services/platforms';
9+
import { getPlatformService, TLiveDockFeature, TPlatform } from 'services/platforms';
1010
import { $t } from 'services/i18n';
1111
import { Services } from '../service-provider';
1212
import Chat from './Chat';
@@ -22,11 +22,6 @@ const LiveDockCtx = React.createContext<LiveDockController | null>(null);
2222

2323
class LiveDockController {
2424
private streamingService = Services.StreamingService;
25-
private youtubeService = Services.YoutubeService;
26-
private facebookService = Services.FacebookService;
27-
private trovoService = Services.TrovoService;
28-
private kickService = Services.KickService;
29-
private tiktokService = Services.TikTokService;
3025
private userService = Services.UserService;
3126
private customizationService = Services.CustomizationService;
3227
private platformAppsService = Services.PlatformAppsService;
@@ -80,6 +75,11 @@ class LiveDockController {
8075
return this.userService.platform?.type;
8176
}
8277

78+
get platformService() {
79+
if (!this.platform) return;
80+
return getPlatformService(this.platform);
81+
}
82+
8383
get offlineImageSrc() {
8484
const mode = this.customizationService.isDarkTheme ? 'night' : 'day';
8585
return $i(`images/sleeping-kevin-${mode}.png`);
@@ -189,21 +189,14 @@ class LiveDockController {
189189
}
190190

191191
openPlatformStream() {
192-
let url = '';
193-
if (this.platform === 'youtube') url = this.youtubeService.streamPageUrl;
194-
if (this.platform === 'facebook') url = this.facebookService.streamPageUrl;
195-
if (this.platform === 'trovo') url = this.trovoService.streamPageUrl;
196-
if (this.platform === 'kick') url = this.kickService.streamPageUrl;
197-
if (this.platform === 'tiktok') url = this.tiktokService.streamPageUrl;
192+
const url = this.platformService?.streamPageUrl;
193+
if (!url) return;
198194
remote.shell.openExternal(url);
199195
}
200196

201197
openPlatformDash() {
202-
let url = '';
203-
if (this.platform === 'youtube') url = this.youtubeService.dashboardUrl;
204-
if (this.platform === 'facebook') url = this.facebookService.streamDashboardUrl;
205-
if (this.platform === 'tiktok') url = this.tiktokService.dashboardUrl;
206-
if (this.platform === 'kick') url = this.kickService.dashboardUrl;
198+
const url = this.platformService?.dashboardUrl;
199+
if (!url) return;
207200
remote.shell.openExternal(url);
208201
}
209202

@@ -239,6 +232,10 @@ class LiveDockController {
239232
showMultistreamChatInfo() {
240233
this.chatService.actions.showMultistreamChatWindow();
241234
}
235+
236+
hasLiveDockFeature(feature: TLiveDockFeature) {
237+
return this.platformService?.hasLiveDockFeature(feature);
238+
}
242239
}
243240

244241
export default function LiveDockWithContext() {
@@ -258,6 +255,7 @@ function LiveDock() {
258255

259256
const {
260257
isPlatform,
258+
hasLiveDockFeature,
261259
isStreaming,
262260
isRestreaming,
263261
hasChatTabs,
@@ -267,7 +265,6 @@ function LiveDock() {
267265
currentViewers,
268266
pageSlot,
269267
liveText,
270-
isPopOutAllowed,
271268
streamingStatus,
272269
} = useVuex(() =>
273270
pick(ctrl, [
@@ -281,7 +278,7 @@ function LiveDock() {
281278
'pageSlot',
282279
'currentViewers',
283280
'liveText',
284-
'isPopOutAllowed',
281+
'hasLiveDockFeature',
285282
'streamingStatus',
286283
]),
287284
);
@@ -384,7 +381,7 @@ function LiveDock() {
384381
<i onClick={() => ctrl.showEditStreamInfo()} className="icon-edit" />
385382
</Tooltip>
386383
)}
387-
{isPlatform(['youtube', 'facebook', 'trovo', 'tiktok', 'kick']) && isStreaming && (
384+
{hasLiveDockFeature('view-stream') && isStreaming && (
388385
<Tooltip
389386
title={$t('View your live stream in a web browser')}
390387
placement="right"
@@ -393,8 +390,7 @@ function LiveDock() {
393390
<i onClick={() => ctrl.openPlatformStream()} className="icon-studio" />
394391
</Tooltip>
395392
)}
396-
{isStreaming && <ShareStreamLink />}
397-
{isPlatform(['youtube', 'facebook', 'tiktok']) && isStreaming && (
393+
{hasLiveDockFeature('dashboard') && isStreaming && (
398394
<Tooltip
399395
title={$t('Go to Live Dashboard')}
400396
placement="right"
@@ -405,16 +401,16 @@ function LiveDock() {
405401
)}
406402
</div>
407403
<div className="flex">
408-
{(isPlatform(['twitch', 'trovo', 'facebook', 'kick']) ||
409-
(isPlatform(['youtube', 'twitter']) && isStreaming) ||
410-
(isPlatform(['tiktok']) && isRestreaming)) && (
404+
{(hasLiveDockFeature('refresh-chat') ||
405+
(hasLiveDockFeature('refresh-chat-streaming') && isStreaming) ||
406+
(hasLiveDockFeature('refresh-chat-restreaming') && isRestreaming)) && (
411407
<a onClick={() => ctrl.refreshChat()}>{$t('Refresh Chat')}</a>
412408
)}
413409
</div>
414410
</div>
415411
{!hideStyleBlockers &&
416-
(isPlatform(['twitch', 'trovo']) ||
417-
(isStreaming && isPlatform(['youtube', 'facebook', 'twitter', 'tiktok', 'kick']))) && (
412+
(hasLiveDockFeature('chat-offline') ||
413+
(isStreaming && hasLiveDockFeature('chat-streaming'))) && (
418414
<div className={styles.liveDockChat}>
419415
{hasChatTabs && <ChatTabs visibleChat={visibleChat} setChat={setChat} />}
420416
{!applicationLoading && !collapsed && chat}
@@ -429,8 +425,7 @@ function LiveDock() {
429425
</div>
430426
)}
431427
</div>
432-
{(!ctrl.platform ||
433-
(isPlatform(['youtube', 'facebook', 'twitter', 'tiktok', 'kick']) && !isStreaming)) && (
428+
{(!ctrl.platform || (hasLiveDockFeature('chat-streaming') && !isStreaming)) && (
434429
<div className={cx('flex flex--center flex--column', styles.liveDockChatOffline)}>
435430
<img className={styles.liveDockChatImgOffline} src={ctrl.offlineImageSrc} />
436431
{!hideStyleBlockers && <span>{$t('Your chat is currently offline')}</span>}

app/services/platforms/base-platform.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
TPlatformCapability,
77
TStartStreamOptions,
88
TPlatformCapabilityMap,
9+
TLiveDockFeature,
910
} from './index';
1011
import { StreamingService } from 'services/streaming';
1112
import { UserService } from 'services/user';
@@ -41,11 +42,18 @@ export abstract class BasePlatformService<T extends IPlatformState> extends Stat
4142

4243
abstract capabilities: Set<TPlatformCapability>;
4344

45+
abstract liveDockFeatures: Set<TLiveDockFeature>;
46+
4447
@ExecuteInCurrentWindow()
4548
hasCapability<T extends TPlatformCapability>(capability: T): this is TPlatformCapabilityMap[T] {
4649
return this.capabilities.has(capability);
4750
}
4851

52+
@ExecuteInCurrentWindow()
53+
hasLiveDockFeature(feature: TLiveDockFeature) {
54+
return this.liveDockFeatures.has(feature);
55+
}
56+
4957
get mergeUrl() {
5058
const host = this.hostsService.streamlabs;
5159
const token = this.userService.apiToken;

app/services/platforms/facebook.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@ import moment from 'moment';
22
import flatten from 'lodash/flatten';
33
import * as remote from '@electron/remote';
44
import { mutation, InheritMutations, ViewHandler } from '../core/stateful-service';
5-
import { IPlatformService, IGame, TPlatformCapability, IPlatformRequest, IPlatformState } from '.';
5+
import {
6+
IPlatformService,
7+
IGame,
8+
TPlatformCapability,
9+
IPlatformRequest,
10+
IPlatformState,
11+
TLiveDockFeature,
12+
} from '.';
613
import { HostsService } from 'services/hosts';
714
import { Inject } from 'services/core/injector';
815
import { authorizedHeaders } from 'util/requests';
@@ -169,6 +176,12 @@ export class FacebookService
169176
'themes',
170177
'viewerCount',
171178
]);
179+
readonly liveDockFeatures = new Set<TLiveDockFeature>([
180+
'chat-streaming',
181+
'refresh-chat',
182+
'dashboard',
183+
'view-stream',
184+
]);
172185

173186
authWindowOptions: Electron.BrowserWindowConstructorOptions = { width: 800, height: 800 };
174187

@@ -248,7 +261,7 @@ export class FacebookService
248261
return this.state.streamPageUrl;
249262
}
250263

251-
get streamDashboardUrl(): string {
264+
get dashboardUrl(): string {
252265
return this.state.streamDashboardUrl;
253266
}
254267

app/services/platforms/index.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ export interface IPlatformState {
174174
export interface IPlatformService {
175175
capabilities: Set<TPlatformCapability>;
176176
hasCapability<T extends TPlatformCapability>(capability: T): this is TPlatformCapabilityMap[T];
177+
hasLiveDockFeature(feature: TLiveDockFeature): boolean;
177178

178179
authWindowOptions: Electron.BrowserWindowConstructorOptions;
179180

@@ -222,6 +223,7 @@ export interface IPlatformService {
222223
readonly mergeUrl: string;
223224
readonly streamPageUrl: string;
224225
readonly chatUrl: string;
226+
readonly dashboardUrl?: string;
225227

226228
/**
227229
* the list of widgets supported by the platform
@@ -245,6 +247,15 @@ export interface IUserInfo {
245247
username?: string;
246248
}
247249

250+
export type TLiveDockFeature =
251+
| 'chat-offline'
252+
| 'chat-streaming'
253+
| 'dashboard'
254+
| 'view-stream'
255+
| 'refresh-chat'
256+
| 'refresh-chat-streaming'
257+
| 'refresh-chat-restreaming';
258+
248259
export enum EPlatform {
249260
Twitch = 'twitch',
250261
YouTube = 'youtube',

app/services/platforms/instagram.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
TPlatformCapability,
99
TStartStreamOptions,
1010
EPlatformCallResult,
11+
TLiveDockFeature,
1112
} from '.';
1213
import { BasePlatformService } from './base-platform';
1314
import { IGoLiveSettings } from 'services/streaming';
@@ -40,6 +41,7 @@ export class InstagramService
4041
readonly platform = 'instagram';
4142
readonly displayName = 'Instagram';
4243
readonly capabilities = new Set<TPlatformCapability>(['resolutionPreset', 'title']);
44+
readonly liveDockFeatures = new Set<TLiveDockFeature>();
4345

4446
static initialState: IInstagramServiceState = {
4547
...BasePlatformService.initialState,

app/services/platforms/kick.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
IPlatformState,
88
TPlatform,
99
TPlatformCapability,
10+
TLiveDockFeature,
1011
} from './index';
1112
import { authorizedHeaders, jfetch } from '../../util/requests';
1213
import { StreamError, throwStreamError } from '../streaming/stream-error';
@@ -123,6 +124,11 @@ export class KickService
123124
readonly platform = 'kick';
124125
readonly displayName = 'Kick';
125126
readonly capabilities = new Set<TPlatformCapability>(['title', 'chat', 'game', 'viewerCount']);
127+
readonly liveDockFeatures = new Set<TLiveDockFeature>([
128+
'view-stream',
129+
'refresh-chat',
130+
'chat-streaming',
131+
]);
126132

127133
authWindowOptions: Electron.BrowserWindowConstructorOptions = {
128134
width: 600,

app/services/platforms/tiktok.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
IPlatformService,
88
IPlatformState,
99
TPlatformCapability,
10+
TLiveDockFeature,
1011
} from './index';
1112
import { authorizedHeaders, jfetch } from '../../util/requests';
1213
import {
@@ -119,6 +120,12 @@ export class TikTokService
119120
readonly platform = 'tiktok';
120121
readonly displayName = 'TikTok';
121122
readonly capabilities = new Set<TPlatformCapability>(['title', 'viewerCount']);
123+
readonly liveDockFeatures = new Set<TLiveDockFeature>([
124+
'view-stream',
125+
'dashboard',
126+
'refresh-chat-restreaming',
127+
'chat-streaming',
128+
]);
122129

123130
authWindowOptions: Electron.BrowserWindowConstructorOptions = {
124131
width: 600,

app/services/platforms/trovo.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
IPlatformService,
77
IPlatformState,
88
TPlatformCapability,
9+
TLiveDockFeature,
910
} from './index';
1011
import { authorizedHeaders, jfetch } from '../../util/requests';
1112
import { throwStreamError } from '../streaming/stream-error';
@@ -62,6 +63,11 @@ export class TrovoService
6263
'streamlabels',
6364
'viewerCount',
6465
]);
66+
readonly liveDockFeatures = new Set<TLiveDockFeature>([
67+
'chat-offline',
68+
'refresh-chat',
69+
'view-stream',
70+
]);
6571
readonly apiBase = 'https://open-api.trovo.live/openplatform';
6672
readonly rtmpServer = 'rtmp://livepush.trovo.live/live/';
6773
readonly platform = 'trovo';

app/services/platforms/twitch.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
IPlatformRequest,
55
IPlatformService,
66
IPlatformState,
7+
TLiveDockFeature,
78
TPlatformCapability,
89
} from '.';
910
import { HostsService } from 'services/hosts';
@@ -120,6 +121,8 @@ export class TwitchService
120121
'viewerCount',
121122
]);
122123

124+
readonly liveDockFeatures = new Set<TLiveDockFeature>(['chat-offline', 'refresh-chat']);
125+
123126
authWindowOptions: Electron.BrowserWindowConstructorOptions = {
124127
width: 600,
125128
height: 800,

app/services/platforms/twitter.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import { InheritMutations, Inject, mutation, Service } from '../core';
22
import { BasePlatformService } from './base-platform';
3-
import { IPlatformRequest, IPlatformService, IPlatformState, TPlatformCapability } from './index';
3+
import {
4+
IPlatformRequest,
5+
IPlatformService,
6+
IPlatformState,
7+
TPlatformCapability,
8+
TLiveDockFeature,
9+
} from './index';
410
import { authorizedHeaders, jfetch } from '../../util/requests';
511
import { throwStreamError } from '../streaming/stream-error';
612
import { platformAuthorizedRequest } from './utils';
@@ -49,6 +55,10 @@ export class TwitterPlatformService
4955
};
5056

5157
readonly capabilities = new Set<TPlatformCapability>(['title', 'viewerCount']);
58+
readonly liveDockFeatures = new Set<TLiveDockFeature>([
59+
'refresh-chat-streaming',
60+
'chat-streaming',
61+
]);
5262
readonly apiBase = 'https://api.x.com/2';
5363
readonly domain = 'https://x.com';
5464
readonly platform = 'twitter';

0 commit comments

Comments
 (0)