@3dsource/angular-unreal-module 0.0.46 → 0.0.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +0 -0
- package/README.md +10 -11
- package/fesm2022/3dsource-angular-unreal-module.mjs +555 -364
- package/fesm2022/3dsource-angular-unreal-module.mjs.map +1 -1
- package/index.d.ts +209 -96
- package/package.json +7 -7
- package/index.d.ts.map +0 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { InjectionToken, inject, Injectable, ChangeDetectionStrategy, Component, Pipe, DestroyRef, signal, ElementRef, input, HostListener, Input, ViewChild, computed, output } from '@angular/core';
|
|
3
|
-
import { filter, withLatestFrom, distinctUntilChanged, switchMap, first, catchError, map as map$1, tap,
|
|
3
|
+
import { filter, withLatestFrom, distinctUntilChanged, switchMap, first, catchError, timeout, map as map$1, tap, takeUntil, exhaustMap, debounceTime, takeWhile, skip as skip$1, delay } from 'rxjs/operators';
|
|
4
4
|
import { createAction, props, Store, provideState, createReducer, on, createFeature, createSelector } from '@ngrx/store';
|
|
5
|
-
import {
|
|
6
|
-
import { skip, share, merge, Subject, interval, of, map, from, take, fromEvent, timer,
|
|
7
|
-
import { Falsy, Truthy, Logger, calculateMedian, clampf, Signal, tapLog, generateUuid, COLOR_CODES, where, KeyboardNumericCode, InvertedKeyMap, Semaphore,
|
|
5
|
+
import { Actions, ofType, provideEffects, createEffect } from '@ngrx/effects';
|
|
6
|
+
import { skip, share, merge, Subject, interval, of, map, from, take, fromEvent, timer, throwError, defer, Observable, switchMap as switchMap$1, retry, timeout as timeout$1, tap as tap$1, startWith, combineLatestWith, takeUntil as takeUntil$1, auditTime, debounceTime as debounceTime$1, EMPTY, mergeMap, scan, concatMap, animationFrameScheduler, BehaviorSubject, combineLatest, first as first$1, distinctUntilChanged as distinctUntilChanged$1, concat } from 'rxjs';
|
|
7
|
+
import { Falsy, Truthy, Logger, calculateMedian, clampf, Signal, tapLog, generateUuid, COLOR_CODES, where, KeyboardNumericCode, InvertedKeyMap, Semaphore, lerp, getCanvasCached, getSnapshot, whereNot, HEXtoRGB, RGBtoHSV, inverseLerp, HSVtoRGB, RGBtoHEX, fpIsASameAsB, fitIntoRectangle } from '@3dsource/utils';
|
|
8
8
|
import { HttpClient } from '@angular/common/http';
|
|
9
9
|
import { toSignal, takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
|
|
10
10
|
import { DialogRef, DIALOG_DATA, Dialog } from '@angular/cdk/dialog';
|
|
@@ -19,21 +19,30 @@ import { FormsModule } from '@angular/forms';
|
|
|
19
19
|
const WSCloseCode_NORMAL_CLOSURE = 3000;
|
|
20
20
|
const WSCloseCode_NORMAL_AFK_TIMEOUT = 3001;
|
|
21
21
|
const WSCloseCode_NORMAL_MANUAL_DISCONNECT = 3002;
|
|
22
|
-
const
|
|
22
|
+
const WSCloseCode_FORCE_CIRRUS_CLOSE = 3003;
|
|
23
|
+
const WSCloseCode_CIRRUS_PLAYER_DISCONNECTED = 1001;
|
|
24
|
+
const WSCloseCode_CIRRUS_ABNORMAL_CLOSURE = 1006;
|
|
25
|
+
const WSCloseCode_CIRRUS_MAX_PLAYERS_ERROR = 1013;
|
|
26
|
+
const WSCloseCode_CIRRUS_STREAMER_KIKED_PLAYER = 1011;
|
|
23
27
|
const WSCloseCodes = [
|
|
24
28
|
WSCloseCode_NORMAL_CLOSURE,
|
|
25
29
|
WSCloseCode_NORMAL_AFK_TIMEOUT,
|
|
26
30
|
WSCloseCode_NORMAL_MANUAL_DISCONNECT,
|
|
27
|
-
|
|
31
|
+
WSCloseCode_FORCE_CIRRUS_CLOSE,
|
|
32
|
+
WSCloseCode_CIRRUS_MAX_PLAYERS_ERROR,
|
|
33
|
+
WSCloseCode_CIRRUS_ABNORMAL_CLOSURE,
|
|
28
34
|
];
|
|
29
35
|
|
|
30
36
|
const DisconnectReason = {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
Afk: 'Afk',
|
|
38
|
+
None: 'None',
|
|
39
|
+
Destroy: 'Destroy',
|
|
40
|
+
DataChannelClosed: 'DataChannelClosed',
|
|
41
|
+
DataChannelTimeout: 'DataChannelTimeout',
|
|
42
|
+
WebRTCError: 'WebRTCError',
|
|
43
|
+
WebSocketError: 'WebSocketError',
|
|
44
|
+
WebSocketClose: 'WebSocketClose',
|
|
45
|
+
DropConnection: 'DropConnection',
|
|
37
46
|
};
|
|
38
47
|
|
|
39
48
|
/*
|
|
@@ -90,7 +99,7 @@ const trackMixpanelEvent = createAction(scoped `track mixpanel event`, props());
|
|
|
90
99
|
const changeLowBandwidth = createAction(scoped `change low bandwidth`, props());
|
|
91
100
|
const setMaxFps = createAction(scoped `change fps`, props());
|
|
92
101
|
const destroyRemoteConnections = createAction(scoped `destroyRemoteConnections`, props());
|
|
93
|
-
const
|
|
102
|
+
const destroyUnrealScene = createAction(scoped `destroyUnrealScene`);
|
|
94
103
|
const setCirrusConnected = createAction(scoped `cirrusConnected`);
|
|
95
104
|
const setCirrusDisconnected = createAction(scoped `cirrusDisconnected`);
|
|
96
105
|
const changeStatusMainVideoOnScene = createAction(scoped `change status main video on scene`, props());
|
|
@@ -109,9 +118,10 @@ const setFreezeFrameFromVideo = createAction(scoped `set freeze frame from video
|
|
|
109
118
|
const setEstablishingConnection = createAction(scoped `set establishing connection`, props());
|
|
110
119
|
const setDataChannelConnected = createAction(scoped `set data channel connected`, props());
|
|
111
120
|
const setConfig = createAction(scoped `set config`, props());
|
|
112
|
-
const
|
|
113
|
-
const
|
|
114
|
-
const setViewportReady = createAction(scoped `set viewport ready
|
|
121
|
+
const disconnectStream = createAction(scoped `disconnectStream`, props());
|
|
122
|
+
const dropConnection = createAction(scoped `dropConnection`);
|
|
123
|
+
const setViewportReady = createAction(scoped `set viewport ready`);
|
|
124
|
+
const setViewportNotReady = createAction(scoped `set viewport not ready`);
|
|
115
125
|
const changeStreamResolutionAction = createAction(scoped `change stream resolution`, props());
|
|
116
126
|
const changeStreamResolutionSuccessAction = createAction(scoped `change stream resolution success action`, props());
|
|
117
127
|
const setSignalingName = createAction(scoped `set aws instanceName`, props());
|
|
@@ -120,13 +130,16 @@ const commandStarted = createAction(scoped `command started`, props());
|
|
|
120
130
|
const commandCompleted = createAction(scoped `command completed`, props());
|
|
121
131
|
const setLoopBackCommandIsCompleted = createAction(scoped `set loopBack command is completed`);
|
|
122
132
|
const showUnrealErrorMessage = createAction(scoped `show unreal error message`, props());
|
|
123
|
-
const initSignalling = createAction(scoped `init signalling
|
|
124
|
-
|
|
133
|
+
const initSignalling = createAction(scoped `init signalling`, (data = {
|
|
134
|
+
resetDisconnectionReason: true,
|
|
135
|
+
}) => ({
|
|
136
|
+
resetDisconnectionReason: data.resetDisconnectionReason,
|
|
137
|
+
}));
|
|
138
|
+
const startStream = createAction(scoped `startStream`, props());
|
|
125
139
|
const resetConfig = createAction(scoped `reset config`);
|
|
126
140
|
const resetAfkAction = createAction(scoped `reset afk action`);
|
|
127
141
|
const resetWarnTimeout = createAction(scoped `reset config warn timeout`);
|
|
128
|
-
const
|
|
129
|
-
const resetUnrealState = createAction(scoped `reset unreal state`);
|
|
142
|
+
const abortEstablishingConnection = createAction(scoped `abortEstablishingConnection`);
|
|
130
143
|
|
|
131
144
|
const SpecialKeyCodes = {
|
|
132
145
|
BackSpace: 8,
|
|
@@ -237,6 +250,7 @@ const CONSOLE_COMMAND_PIXEL_QUALITY = 'PixelStreaming.FreezeFrameQuality 95';
|
|
|
237
250
|
const FULL_HD_WIDTH = 1920;
|
|
238
251
|
const FULL_HD_HEIGHT = 1080;
|
|
239
252
|
const WS_TIMEOUT = 2000;
|
|
253
|
+
const POLLING_TIME = 4000;
|
|
240
254
|
const WS_OPEN_STATE = 1;
|
|
241
255
|
const DEFAULT_AFK_TIMEOUT_PERIOD = 15;
|
|
242
256
|
const DEFAULT_AFK_TIMEOUT = 120;
|
|
@@ -344,8 +358,10 @@ class AFKService extends SubService {
|
|
|
344
358
|
if (this.countdown === 0) {
|
|
345
359
|
// The user failed to click so disconnect them
|
|
346
360
|
this.hideOverlay();
|
|
347
|
-
|
|
348
|
-
|
|
361
|
+
this.store.dispatch(disconnectStream({
|
|
362
|
+
reason: DisconnectReason.Afk,
|
|
363
|
+
message: `AFK timeout:${this.selectWarnTimeout()} seconds, popup timeout:${this.closeTimeout} seconds`,
|
|
364
|
+
}));
|
|
349
365
|
clearInterval(this.countdownTimer);
|
|
350
366
|
}
|
|
351
367
|
else {
|
|
@@ -353,10 +369,10 @@ class AFKService extends SubService {
|
|
|
353
369
|
}
|
|
354
370
|
}, 1000);
|
|
355
371
|
}
|
|
356
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
357
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.
|
|
372
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: AFKService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
373
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: AFKService }); }
|
|
358
374
|
}
|
|
359
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
375
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: AFKService, decorators: [{
|
|
360
376
|
type: Injectable
|
|
361
377
|
}], ctorParameters: () => [] });
|
|
362
378
|
|
|
@@ -431,10 +447,10 @@ class FreezeFrameService extends SubService {
|
|
|
431
447
|
progress: 1,
|
|
432
448
|
}));
|
|
433
449
|
}
|
|
434
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
435
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.
|
|
450
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: FreezeFrameService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
451
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: FreezeFrameService }); }
|
|
436
452
|
}
|
|
437
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
453
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: FreezeFrameService, decorators: [{
|
|
438
454
|
type: Injectable
|
|
439
455
|
}] });
|
|
440
456
|
|
|
@@ -738,10 +754,10 @@ class VideoService extends SubService {
|
|
|
738
754
|
error: () => ({}),
|
|
739
755
|
});
|
|
740
756
|
}
|
|
741
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
742
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.
|
|
757
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: VideoService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
758
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: VideoService }); }
|
|
743
759
|
}
|
|
744
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
760
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: VideoService, decorators: [{
|
|
745
761
|
type: Injectable
|
|
746
762
|
}], ctorParameters: () => [] });
|
|
747
763
|
|
|
@@ -955,10 +971,10 @@ class CommandTelemetryService {
|
|
|
955
971
|
this.trackTime(out);
|
|
956
972
|
funcToDecorate(out);
|
|
957
973
|
}
|
|
958
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
959
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.
|
|
974
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: CommandTelemetryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
975
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: CommandTelemetryService }); }
|
|
960
976
|
}
|
|
961
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
977
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: CommandTelemetryService, decorators: [{
|
|
962
978
|
type: Injectable
|
|
963
979
|
}], ctorParameters: () => [] });
|
|
964
980
|
function TelemetryStart(externalId) {
|
|
@@ -982,99 +998,221 @@ function OfferHandler(msg) {
|
|
|
982
998
|
this.onOffer$.next(msg);
|
|
983
999
|
}
|
|
984
1000
|
|
|
1001
|
+
function httpUrlToWs(url) {
|
|
1002
|
+
return url.replace('http://', 'ws://').replace('https://', 'wss://');
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
function createWebSocket(wsUrl) {
|
|
1006
|
+
if (typeof window === 'undefined' || !('WebSocket' in window)) {
|
|
1007
|
+
return throwError(() => new Error("Your browser doesn't support WebSocket"));
|
|
1008
|
+
}
|
|
1009
|
+
Logger.info('Creating socket', wsUrl);
|
|
1010
|
+
return defer(() => new Observable((observer) => {
|
|
1011
|
+
const ws = new WebSocket(wsUrl);
|
|
1012
|
+
const onOpen = () => {
|
|
1013
|
+
observer.next(ws); // connection established
|
|
1014
|
+
};
|
|
1015
|
+
const onError = (ev) => {
|
|
1016
|
+
const anyEv = ev;
|
|
1017
|
+
const err = anyEv?.error instanceof Error
|
|
1018
|
+
? anyEv.error
|
|
1019
|
+
: new Error('WebSocket failed to connect');
|
|
1020
|
+
observer.error(err);
|
|
1021
|
+
};
|
|
1022
|
+
const onClose = (ev) => {
|
|
1023
|
+
if (ws.readyState !== WebSocket.OPEN) {
|
|
1024
|
+
observer.error(new Error(`WebSocket closed before open (code ${ev.code})`));
|
|
1025
|
+
}
|
|
1026
|
+
};
|
|
1027
|
+
ws.addEventListener('open', onOpen);
|
|
1028
|
+
ws.addEventListener('error', onError);
|
|
1029
|
+
ws.addEventListener('close', onClose);
|
|
1030
|
+
return () => {
|
|
1031
|
+
ws.removeEventListener('open', onOpen);
|
|
1032
|
+
ws.removeEventListener('error', onError);
|
|
1033
|
+
ws.removeEventListener('close', onClose);
|
|
1034
|
+
};
|
|
1035
|
+
})).pipe(timeout({
|
|
1036
|
+
first: WS_TIMEOUT, // fail if no 'open' event in this window
|
|
1037
|
+
with: () => throwError(() => new Error(`WebSocket connection timed out after ${WS_TIMEOUT}ms`)),
|
|
1038
|
+
}));
|
|
1039
|
+
}
|
|
1040
|
+
|
|
985
1041
|
class SignallingService extends SubService {
|
|
986
1042
|
constructor() {
|
|
987
1043
|
super();
|
|
1044
|
+
this.action$ = inject(Actions);
|
|
988
1045
|
this.httpClient = inject(HttpClient);
|
|
989
1046
|
this.regionsPingService = inject(RegionsPingService);
|
|
990
1047
|
this.onOffer$ = new Subject();
|
|
991
1048
|
this.onConfig$ = new Subject();
|
|
992
1049
|
this.onWebRtcIce$ = new Subject();
|
|
993
1050
|
this.onWebRtcAnswer$ = new Subject();
|
|
1051
|
+
this.abort$ = this.action$.pipe(ofType(abortEstablishingConnection));
|
|
994
1052
|
this.wsMsgHandlers = {};
|
|
995
|
-
this.establishingConnection = toSignal(this.store.select(unrealFeature.selectEstablishingConnection));
|
|
996
|
-
this.isCirrusConnected = toSignal(this.store.select(unrealFeature.selectCirrusConnected));
|
|
997
|
-
this.establishingConnectionDrop$ = this.store
|
|
998
|
-
.select(unrealFeature.selectEstablishingConnection)
|
|
999
|
-
.pipe(skip(1), filter(Falsy), tapLog('selectEstablishingConnection'), share());
|
|
1000
1053
|
this.setHandlersFromStream();
|
|
1001
1054
|
this.store
|
|
1002
1055
|
.select(unrealFeature.selectDataChannelConnected)
|
|
1003
1056
|
.pipe(filter(Truthy))
|
|
1004
1057
|
.subscribe(() => {
|
|
1005
|
-
this.send(
|
|
1058
|
+
this.send({
|
|
1006
1059
|
type: 'p2pEstablished',
|
|
1007
1060
|
source: 'front',
|
|
1008
1061
|
sessionId: generateUuid(),
|
|
1009
|
-
})
|
|
1010
|
-
});
|
|
1011
|
-
combineLatest([
|
|
1012
|
-
this.store
|
|
1013
|
-
.select(selectMatchMakerUrls)
|
|
1014
|
-
.pipe(tapLog('MatchMakerUrls changed:')),
|
|
1015
|
-
this.store.select(selectIsAutostart).pipe(tapLog('Autostart is:')),
|
|
1016
|
-
])
|
|
1017
|
-
.pipe(filter(([, autoStart]) => autoStart), map$1(([matchMakerUrls]) => [...matchMakerUrls].filter(Truthy)), filter((urls) => urls.length > 0))
|
|
1018
|
-
.subscribe((urls) => this.connectToSignaling(urls));
|
|
1019
|
-
this.store
|
|
1020
|
-
.select(selectWsUrl)
|
|
1021
|
-
.pipe(filter(Truthy))
|
|
1022
|
-
.subscribe((url) => {
|
|
1023
|
-
this.initWebSocket(url);
|
|
1062
|
+
});
|
|
1024
1063
|
});
|
|
1025
1064
|
}
|
|
1026
|
-
initEstablishingConnection() {
|
|
1027
|
-
this.showStatusMessage(UnrealStatusMessage.STARTING_YOUR_SESSION);
|
|
1028
|
-
this.store.dispatch(setEstablishingConnection({ value: true }));
|
|
1029
|
-
}
|
|
1030
|
-
stopEstablishingConnection() {
|
|
1031
|
-
this.store.dispatch(setEstablishingConnection({ value: false }));
|
|
1032
|
-
}
|
|
1033
1065
|
connectToSignaling(urlList) {
|
|
1066
|
+
Logger.log('CONNECT TO SIGNALLING');
|
|
1034
1067
|
// Preparation for WebSocket Orchestration
|
|
1035
1068
|
this.correlationId = generateUuid();
|
|
1036
1069
|
this.environmentId = '7e356e8d-8fa5-4cf7-83d0-394903e7b0d6';
|
|
1037
1070
|
ResetTelemetry();
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1071
|
+
this.startEstablishingConnection();
|
|
1072
|
+
return defer(() => this.getRegion().pipe(map$1((region) => this.adaptUrlsToRegion(urlList, region)), switchMap$1((urls) => this.getAwsInstance(urls).pipe(first())), tap((awsInstance) => this.store.dispatch(setAwsInstance(awsInstance))), switchMap$1(({ wsUrl }) => this.connectToCirrus(wsUrl)), filter(Truthy), first(), tap((ws) => (this.ws = ws)), takeUntil(this.abort$))).pipe(
|
|
1073
|
+
// Retry the whole attempt on error, advancing to the next URL each time.
|
|
1074
|
+
retry({
|
|
1075
|
+
delay: (err, attempt) => {
|
|
1076
|
+
Logger.info(`Retrying Signalling Connection in ${POLLING_TIME}ms. Attempt# ${attempt}.`, err?.message);
|
|
1077
|
+
return timer(POLLING_TIME);
|
|
1078
|
+
},
|
|
1079
|
+
// count: 10, // Optional: cap the number of attempts.
|
|
1080
|
+
}));
|
|
1081
|
+
}
|
|
1082
|
+
startEstablishingConnection() {
|
|
1083
|
+
this.showStatusMessage(UnrealStatusMessage.STARTING_YOUR_SESSION);
|
|
1084
|
+
this.store.dispatch(setEstablishingConnection({ value: true }));
|
|
1085
|
+
}
|
|
1086
|
+
adaptUrlsToRegion(urlList, region) {
|
|
1087
|
+
return urlList.map((url) => {
|
|
1088
|
+
if (region && !url.includes(':region')) {
|
|
1089
|
+
return url.replace(/signallingserver/gi, `signallingserver/region:${region}`);
|
|
1090
|
+
}
|
|
1091
|
+
return url;
|
|
1054
1092
|
});
|
|
1055
1093
|
}
|
|
1056
|
-
|
|
1057
|
-
|
|
1094
|
+
/**
|
|
1095
|
+
* Resolves an active AWS *signaling* instance and returns a WebSocket endpoint.
|
|
1096
|
+
*
|
|
1097
|
+
* The observable produced by this method is **cold** and executes inside a `defer`,
|
|
1098
|
+
* so each subscription (including those triggered by `retry`) pulls the **next**
|
|
1099
|
+
* URL candidate from a generator created by `getActiveUrl(urlsPool)`.
|
|
1100
|
+
*
|
|
1101
|
+
* ### Execution flow
|
|
1102
|
+
*
|
|
1103
|
+
* 1. **Telemetry** — Starts a `getSignaling` span for end-to-end timing.
|
|
1104
|
+
* 2. **Candidate URL selection** — A stateful generator (`urlGen`) is created
|
|
1105
|
+
* from `urlsPool`. Each resubscription (e.g. via `retry`) advances to the next URL.
|
|
1106
|
+
* 3. **Short-circuit for WS URLs** — If the picked candidate already matches
|
|
1107
|
+
* `ws://` or `wss://`, emit `{ wsUrl, pollingUrl: null, instanceName: null }`
|
|
1108
|
+
* immediately and complete (no HTTP request).
|
|
1109
|
+
* 4. **Await client/view identifiers** — `this.store.select(selectClientAndViewIds)`
|
|
1110
|
+
* is tapped for logging (missing IDs) and then filtered to require both `clientId`
|
|
1111
|
+
* and `viewId` to be truthy.
|
|
1112
|
+
* 5. **Single in-flight HTTP orchestration call** — Uses `exhaustMap` to issue
|
|
1113
|
+
* `GET {signalingUrl}{clientId}/{viewId}`. New `{clientId, viewId}` emissions
|
|
1114
|
+
* while the request is in flight are **ignored** until completion, preventing overlap.
|
|
1115
|
+
* 6. **Per-attempt timeout** — `timeout(WS_TIMEOUT)` caps how long we wait for a response.
|
|
1116
|
+
* On timeout, the attempt errors and the outer `retry` schedules the next URL.
|
|
1117
|
+
* 7. **Response validation & progress reporting** — A `filter`:
|
|
1118
|
+
* - Calls `TelemetryStop('getSignaling', { ...data, multi: true })` on receipt.
|
|
1119
|
+
* - If `data.signallingServer === ''` or `data.error`:
|
|
1120
|
+
* shows a status message, optionally dispatches `setStatusPercentSignallingServer`
|
|
1121
|
+
* with `data.info.percent`, and **throws** to fail the attempt (triggers `retry`).
|
|
1122
|
+
* 8. **Mapping to `AwsInstance`** — Converts the validated orchestration payload into:
|
|
1123
|
+
* - `wsUrl`: via `httpUrlToWs(\`\${location.protocol}//\${data.signallingServer}\`)`
|
|
1124
|
+
* - `pollingUrl`: the base `signalingUrl` that succeeded
|
|
1125
|
+
* - `instanceName`: the (validated) `data.signallingServer`
|
|
1126
|
+
* 9. **Retry policy** — On *any* upstream error (timeout, HTTP error, invalid payload),
|
|
1127
|
+
* `retry({ delay })`:
|
|
1128
|
+
* - Shows a “connecting” status,
|
|
1129
|
+
* - Logs the attempt number,
|
|
1130
|
+
* - Waits `WS_TIMEOUT` ms (via `timer`) and **resubscribes**, advancing `urlGen`.
|
|
1131
|
+
*
|
|
1132
|
+
* ### Concurrency semantics
|
|
1133
|
+
*
|
|
1134
|
+
* - `exhaustMap` guarantees a **single** HTTP request per attempt; subsequent
|
|
1135
|
+
* `{clientId, viewId}` emissions are ignored until the current request completes.
|
|
1136
|
+
*
|
|
1137
|
+
* ### Telemetry semantics
|
|
1138
|
+
*
|
|
1139
|
+
* - `TelemetryStart('getSignaling')` begins before work.
|
|
1140
|
+
* - `TelemetryStop('getSignaling', {...})` runs on receipt of an orchestration response.
|
|
1141
|
+
* If an attempt fails (e.g., timeout), stopping the span is the responsibility of
|
|
1142
|
+
* your telemetry layer or a `finalize` elsewhere if desired.
|
|
1143
|
+
*
|
|
1144
|
+
* ### Error & retry semantics
|
|
1145
|
+
*
|
|
1146
|
+
* - Missing/never-emitted IDs → timeout → retry with next URL.
|
|
1147
|
+
* - HTTP/network error → retry with next URL.
|
|
1148
|
+
* - Invalid orchestration payload (`error` set or empty `signallingServer`) → throw in
|
|
1149
|
+
* validation filter → retry with next URL.
|
|
1150
|
+
* - Short-circuit WS path **does not** retry (emits once, completes).
|
|
1151
|
+
*
|
|
1152
|
+
* @param urlsPool - Ordered list of base URLs to probe. Retries advance through this list
|
|
1153
|
+
* until a working signaling server is found. A candidate may also be a direct `ws://`/`wss://`
|
|
1154
|
+
* URL to short-circuit HTTP orchestration.
|
|
1155
|
+
*
|
|
1156
|
+
* @returns Observable that emits exactly one {@link AwsInstance} on success and then completes.
|
|
1157
|
+
* On failure, the stream errors; the built-in `retry` operator re-subscribes after `WS_TIMEOUT`
|
|
1158
|
+
* and advances to the next URL candidate.
|
|
1159
|
+
*
|
|
1160
|
+
* @throws Emits an error within the observable chain (not a thrown synchronous exception) when:
|
|
1161
|
+
* - The HTTP request fails or times out.
|
|
1162
|
+
* - The orchestration response indicates an error or an empty `signallingServer`.
|
|
1163
|
+
* - Any other operator in the chain surfaces an error.
|
|
1164
|
+
*
|
|
1165
|
+
* @remarks
|
|
1166
|
+
* - The URL generator (`urlGen`) is created **outside** `defer`, so resubscriptions
|
|
1167
|
+
* advance the pool. Creating it inside `defer` would restart from the first URL each retry.
|
|
1168
|
+
* - `location.protocol` is used to derive `ws` vs `wss`. If this may run in non-browser
|
|
1169
|
+
* contexts (e.g., SSR), guard or abstract this logic.
|
|
1170
|
+
* - Consider capping retries with `count` in `retry({ count, delay })` when appropriate.
|
|
1171
|
+
*
|
|
1172
|
+
* @example
|
|
1173
|
+
* ```ts
|
|
1174
|
+
* getAwsInstance(['https://signaling.example.com/', 'wss://direct.example.com'])
|
|
1175
|
+
* .subscribe({
|
|
1176
|
+
* next: ({ wsUrl }) => connect(wsUrl),
|
|
1177
|
+
* error: (e) => console.error('Unable to establish signaling:', e),
|
|
1178
|
+
* });
|
|
1179
|
+
* ```
|
|
1180
|
+
*
|
|
1181
|
+
* @see httpUrlToWs
|
|
1182
|
+
* @see selectClientAndViewIds
|
|
1183
|
+
* @see setStatusPercentSignallingServer
|
|
1184
|
+
*/
|
|
1185
|
+
getAwsInstance(urlsPool) {
|
|
1058
1186
|
TelemetryStart('getSignaling');
|
|
1059
|
-
|
|
1187
|
+
// Stateful iterator over candidate URLs; retries advance this sequence.
|
|
1188
|
+
const urlGen = getActiveUrl(urlsPool);
|
|
1189
|
+
return defer(() => {
|
|
1060
1190
|
const signalingUrl = `${urlGen.next().value}`;
|
|
1191
|
+
// Short-circuit if the candidate is already a WS endpoint.
|
|
1061
1192
|
if (signalingUrl.match(/^ws(s?):\/\//i)) {
|
|
1062
|
-
|
|
1193
|
+
return of({
|
|
1063
1194
|
wsUrl: signalingUrl,
|
|
1064
1195
|
pollingUrl: null,
|
|
1065
1196
|
instanceName: null,
|
|
1066
|
-
})
|
|
1067
|
-
return;
|
|
1197
|
+
});
|
|
1068
1198
|
}
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
])
|
|
1073
|
-
.pipe(tap(([clientId, viewId]) => {
|
|
1199
|
+
return this.store.select(selectClientAndViewIds).pipe(
|
|
1200
|
+
// Log missing IDs without altering the stream.
|
|
1201
|
+
tap(({ clientId, viewId }) => {
|
|
1074
1202
|
if (!clientId || !viewId) {
|
|
1075
1203
|
console.error('Client ID or View ID is not set');
|
|
1076
1204
|
}
|
|
1077
|
-
}),
|
|
1205
|
+
}),
|
|
1206
|
+
// Only proceed when both identifiers are available.
|
|
1207
|
+
filter(({ clientId, viewId }) => !!clientId && !!viewId),
|
|
1208
|
+
// Take first value
|
|
1209
|
+
first(),
|
|
1210
|
+
// Ensure a single in-flight HTTP request per attempt.
|
|
1211
|
+
exhaustMap(({ clientId, viewId }) => this.httpClient.get(`${signalingUrl}${clientId}/${viewId}`)),
|
|
1212
|
+
// Bound the time spent waiting for the orchestration response.
|
|
1213
|
+
timeout$1(POLLING_TIME),
|
|
1214
|
+
// Validate response; report progress; fail fast on invalid payloads.
|
|
1215
|
+
filter((data) => {
|
|
1078
1216
|
TelemetryStop('getSignaling', { ...data, multi: true });
|
|
1079
1217
|
if (data.signallingServer === '' || data.error) {
|
|
1080
1218
|
this.showStatusMessage(data?.mm_message || 'Server not found');
|
|
@@ -1083,27 +1221,44 @@ class SignallingService extends SubService {
|
|
|
1083
1221
|
percent: data.info.percent,
|
|
1084
1222
|
}));
|
|
1085
1223
|
}
|
|
1086
|
-
|
|
1224
|
+
// Throwing here fails the attempt and activates the retry strategy.
|
|
1225
|
+
throw new Error(`Orchestration message => ${data?.mm_message || 'Polling retry'}`);
|
|
1087
1226
|
}
|
|
1088
|
-
this.store.dispatch(setStatusPercentSignallingServer({ percent: 100 }));
|
|
1089
1227
|
return true;
|
|
1090
|
-
}),
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
.subscribe((data) => {
|
|
1096
|
-
subscription.unsubscribe();
|
|
1097
|
-
const wsProtocol = location.protocol.match(/https/i) ? 'wss' : 'ws';
|
|
1098
|
-
const wsUrl = `${wsProtocol}://${data.signallingServer}`;
|
|
1099
|
-
this.store.dispatch(setAwsInstance({
|
|
1228
|
+
}),
|
|
1229
|
+
// Map a valid orchestration payload into the final AwsInstance.
|
|
1230
|
+
map$1((data) => {
|
|
1231
|
+
const wsUrl = httpUrlToWs(`${location.protocol}//${data.signallingServer}`);
|
|
1232
|
+
return {
|
|
1100
1233
|
wsUrl,
|
|
1101
1234
|
pollingUrl: signalingUrl,
|
|
1102
1235
|
instanceName: data.signallingServer,
|
|
1103
|
-
}
|
|
1104
|
-
});
|
|
1105
|
-
}
|
|
1106
|
-
|
|
1236
|
+
};
|
|
1237
|
+
}));
|
|
1238
|
+
}).pipe(
|
|
1239
|
+
// Retry the whole attempt on error, advancing to the next URL each time.
|
|
1240
|
+
retry({
|
|
1241
|
+
delay: (err, attempt) => {
|
|
1242
|
+
this.showStatusMessage(UnrealStatusMessage.CONNECTING_TO_SESSION);
|
|
1243
|
+
Logger.log(`Retrying with new URL in ${POLLING_TIME}ms. Attempt# ${attempt}`, err?.message);
|
|
1244
|
+
return timer(POLLING_TIME);
|
|
1245
|
+
},
|
|
1246
|
+
// count: 10, // Optional: cap the number of attempts.
|
|
1247
|
+
}));
|
|
1248
|
+
}
|
|
1249
|
+
connectToCirrus(wsUrl) {
|
|
1250
|
+
this.clearWs();
|
|
1251
|
+
return createWebSocket(wsUrl).pipe(tapLog('WS CREATED'), tap((ws) => {
|
|
1252
|
+
TelemetryStart('iceCandidate');
|
|
1253
|
+
this.addWsHandlers(ws);
|
|
1254
|
+
}));
|
|
1255
|
+
}
|
|
1256
|
+
addWsHandlers(ws) {
|
|
1257
|
+
ws.onmessage = OnMessageHandler.bind(this);
|
|
1258
|
+
ws.onclose = OnCloseHandler.bind(this);
|
|
1259
|
+
ws.onerror = OnErrorHandler.bind(this);
|
|
1260
|
+
Logger.log('WS HANDLERS ADDED');
|
|
1261
|
+
OnOpenHandler.call(this);
|
|
1107
1262
|
}
|
|
1108
1263
|
showStatusMessage(message) {
|
|
1109
1264
|
this.store.dispatch(setStatusMessage({ message }));
|
|
@@ -1113,10 +1268,7 @@ class SignallingService extends SubService {
|
|
|
1113
1268
|
* @param data
|
|
1114
1269
|
*/
|
|
1115
1270
|
close(data) {
|
|
1116
|
-
const { code, reason } = data
|
|
1117
|
-
code: WSCloseCode_NORMAL_CLOSURE,
|
|
1118
|
-
reason: 'NoReason',
|
|
1119
|
-
};
|
|
1271
|
+
const { code, reason } = data;
|
|
1120
1272
|
if (this.ws)
|
|
1121
1273
|
Logger.warn('Closing existing WebSocket connection');
|
|
1122
1274
|
this.ws?.close(code, reason);
|
|
@@ -1142,47 +1294,6 @@ class SignallingService extends SubService {
|
|
|
1142
1294
|
}
|
|
1143
1295
|
}
|
|
1144
1296
|
}
|
|
1145
|
-
watchTimeoutOrErrorAndReconnectLater() {
|
|
1146
|
-
this.stopRetryTimer();
|
|
1147
|
-
this.wsTimeoutHandler = setTimeout(() => {
|
|
1148
|
-
Logger.warn('No WS Response, retrying new signaling');
|
|
1149
|
-
this.showStatusMessage(UnrealStatusMessage.CONNECTING_TO_SESSION);
|
|
1150
|
-
this.stopEstablishingConnection();
|
|
1151
|
-
this.store.dispatch(initSignalling());
|
|
1152
|
-
}, WS_TIMEOUT);
|
|
1153
|
-
}
|
|
1154
|
-
stopRetryTimer() {
|
|
1155
|
-
clearTimeout(this.wsTimeoutHandler);
|
|
1156
|
-
}
|
|
1157
|
-
initWebSocket(url) {
|
|
1158
|
-
if (!window?.['WebSocket']) {
|
|
1159
|
-
alert("Your browser doesn't support WebSocket");
|
|
1160
|
-
return;
|
|
1161
|
-
}
|
|
1162
|
-
this.clearWs();
|
|
1163
|
-
const wsUrl = this.httpUrlToWs(url);
|
|
1164
|
-
Logger.info('Creating socket', wsUrl);
|
|
1165
|
-
try {
|
|
1166
|
-
this.ws = new WebSocket(wsUrl);
|
|
1167
|
-
}
|
|
1168
|
-
catch (error) {
|
|
1169
|
-
this.ws = {};
|
|
1170
|
-
this.store.dispatch(setErrorMessage({
|
|
1171
|
-
errorType: 'WebSocketError',
|
|
1172
|
-
message: 'WebSocket Error',
|
|
1173
|
-
}));
|
|
1174
|
-
Logger.error('Error creating WebSocket', error);
|
|
1175
|
-
}
|
|
1176
|
-
this.ws.onmessage = OnMessageHandler.bind(this);
|
|
1177
|
-
this.ws.onerror = OnErrorHandler.bind(this);
|
|
1178
|
-
this.ws.onclose = OnCloseHandler.bind(this);
|
|
1179
|
-
this.ws.onopen = OnOpenHandler.bind(this);
|
|
1180
|
-
this.watchTimeoutOrErrorAndReconnectLater();
|
|
1181
|
-
TelemetryStart('iceCandidate');
|
|
1182
|
-
}
|
|
1183
|
-
httpUrlToWs(url) {
|
|
1184
|
-
return url.replace('http://', 'ws://').replace('https://', 'wss://');
|
|
1185
|
-
}
|
|
1186
1297
|
clearWs() {
|
|
1187
1298
|
this.onWebRtcAnswer$.next(null);
|
|
1188
1299
|
if (this.ws) {
|
|
@@ -1214,10 +1325,14 @@ class SignallingService extends SubService {
|
|
|
1214
1325
|
this.wsMsgHandlers.instanceReserved = InstanceReservedHandler.bind(this);
|
|
1215
1326
|
this.wsMsgHandlers.offer = OfferHandler.bind(this);
|
|
1216
1327
|
}
|
|
1217
|
-
|
|
1218
|
-
|
|
1328
|
+
getRegion() {
|
|
1329
|
+
Logger.log('Start Getting Region');
|
|
1330
|
+
return this.regionsPingService.getFastest().pipe(first());
|
|
1331
|
+
}
|
|
1332
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: SignallingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1333
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: SignallingService }); }
|
|
1219
1334
|
}
|
|
1220
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
1335
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: SignallingService, decorators: [{
|
|
1221
1336
|
type: Injectable
|
|
1222
1337
|
}], ctorParameters: () => [] });
|
|
1223
1338
|
|
|
@@ -1270,17 +1385,13 @@ class WebRtcPlayerService extends SubService {
|
|
|
1270
1385
|
Logger.info('Creating offer');
|
|
1271
1386
|
let offer;
|
|
1272
1387
|
try {
|
|
1273
|
-
clearTimeout(this.webRtcErrorTimeout);
|
|
1274
1388
|
offer = await this.createPeerConnection(this.cfg);
|
|
1275
|
-
this.webRtcErrorTimeout = setTimeout(() => {
|
|
1276
|
-
if (this.pcClient?.connectionState?.match(/connecting|failed/gi)) {
|
|
1277
|
-
this.dispatchWebRtcError('WebRTCError: Timeout');
|
|
1278
|
-
}
|
|
1279
|
-
}, 10000);
|
|
1280
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1281
1389
|
}
|
|
1282
|
-
catch
|
|
1283
|
-
this.
|
|
1390
|
+
catch {
|
|
1391
|
+
this.store.dispatch(disconnectStream({
|
|
1392
|
+
reason: DisconnectReason.WebRTCError,
|
|
1393
|
+
message: 'WebRTCError: Offer Error',
|
|
1394
|
+
}));
|
|
1284
1395
|
}
|
|
1285
1396
|
return offer;
|
|
1286
1397
|
}
|
|
@@ -1338,6 +1449,8 @@ class WebRtcPlayerService extends SubService {
|
|
|
1338
1449
|
Logger.warn('Closing existing PeerConnection');
|
|
1339
1450
|
this.pcClient?.close();
|
|
1340
1451
|
this.pcClient = null;
|
|
1452
|
+
if (this.dcClient)
|
|
1453
|
+
Logger.warn('Closing existing DataChannel');
|
|
1341
1454
|
this.dcClient?.close();
|
|
1342
1455
|
this.dcClient = null;
|
|
1343
1456
|
}
|
|
@@ -1380,13 +1493,6 @@ class WebRtcPlayerService extends SubService {
|
|
|
1380
1493
|
Logger.error("For testing you can enable HTTP microphone access Chrome by visiting chrome://flags/ and enabling 'unsafely-treat-insecure-origin-as-secure'");
|
|
1381
1494
|
}
|
|
1382
1495
|
}
|
|
1383
|
-
dispatchWebRtcError(message) {
|
|
1384
|
-
Logger.error(message);
|
|
1385
|
-
this.store.dispatch(setErrorMessage({
|
|
1386
|
-
errorType: 'WebRTCError',
|
|
1387
|
-
message,
|
|
1388
|
-
}));
|
|
1389
|
-
}
|
|
1390
1496
|
async createPeerConnection(config) {
|
|
1391
1497
|
this.closePC();
|
|
1392
1498
|
this.pcClient = new RTCPeerConnection(config);
|
|
@@ -1515,8 +1621,9 @@ class WebRtcPlayerService extends SubService {
|
|
|
1515
1621
|
.pipe(first())
|
|
1516
1622
|
.subscribe((e) => {
|
|
1517
1623
|
Logger.warn(`[DATACHANNEL] Data channel disconnected: ${datachannel.label}(${datachannel.id})`, e);
|
|
1518
|
-
this.store.dispatch(
|
|
1519
|
-
|
|
1624
|
+
this.store.dispatch(disconnectStream({
|
|
1625
|
+
reason: DisconnectReason.DataChannelClosed,
|
|
1626
|
+
message: 'DataChannelClosed',
|
|
1520
1627
|
}));
|
|
1521
1628
|
});
|
|
1522
1629
|
fromEvent(datachannel, 'error')
|
|
@@ -1549,8 +1656,7 @@ class WebRtcPlayerService extends SubService {
|
|
|
1549
1656
|
text +=
|
|
1550
1657
|
'\n If you are experiencing connection problems please try Google Chrome';
|
|
1551
1658
|
}
|
|
1552
|
-
this.store.dispatch(
|
|
1553
|
-
this.store.dispatch(setDataChannelConnected({ value: true }));
|
|
1659
|
+
this.store.dispatch(setDataChannelConnected({ message: text }));
|
|
1554
1660
|
}
|
|
1555
1661
|
async createOffer(pcClient) {
|
|
1556
1662
|
try {
|
|
@@ -1566,10 +1672,10 @@ class WebRtcPlayerService extends SubService {
|
|
|
1566
1672
|
Logger.error("Couldn't create offer");
|
|
1567
1673
|
}
|
|
1568
1674
|
}
|
|
1569
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
1570
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.
|
|
1675
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: WebRtcPlayerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1676
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: WebRtcPlayerService }); }
|
|
1571
1677
|
}
|
|
1572
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
1678
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: WebRtcPlayerService, decorators: [{
|
|
1573
1679
|
type: Injectable
|
|
1574
1680
|
}], ctorParameters: () => [] });
|
|
1575
1681
|
|
|
@@ -1684,7 +1790,7 @@ class AggregatorService extends SubService {
|
|
|
1684
1790
|
?.remove();
|
|
1685
1791
|
}
|
|
1686
1792
|
startListenCallbacks() {
|
|
1687
|
-
Logger.info('Start Listen Callbacks');
|
|
1793
|
+
Logger.info('Start Listen Unreal Callbacks');
|
|
1688
1794
|
let previousJson = null;
|
|
1689
1795
|
this.addResponseEventListener('unrealEvents', (data) => {
|
|
1690
1796
|
try {
|
|
@@ -1788,10 +1894,10 @@ class AggregatorService extends SubService {
|
|
|
1788
1894
|
Logger.warn(`unrecognized data received, packet ID ${view[0]}`);
|
|
1789
1895
|
}
|
|
1790
1896
|
}
|
|
1791
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
1792
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.
|
|
1897
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: AggregatorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1898
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: AggregatorService }); }
|
|
1793
1899
|
}
|
|
1794
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
1900
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: AggregatorService, decorators: [{
|
|
1795
1901
|
type: Injectable
|
|
1796
1902
|
}], ctorParameters: () => [] });
|
|
1797
1903
|
|
|
@@ -1806,7 +1912,10 @@ class ConsoleExtensionsService extends SubService {
|
|
|
1806
1912
|
return;
|
|
1807
1913
|
}
|
|
1808
1914
|
window.dropConnection = () => {
|
|
1809
|
-
this.store.dispatch(
|
|
1915
|
+
this.store.dispatch(disconnectStream({
|
|
1916
|
+
reason: DisconnectReason.DropConnection,
|
|
1917
|
+
message: 'Manual Console Drop',
|
|
1918
|
+
}));
|
|
1810
1919
|
return true;
|
|
1811
1920
|
};
|
|
1812
1921
|
window.toggleBandwidth = () => {
|
|
@@ -1840,10 +1949,10 @@ class ConsoleExtensionsService extends SubService {
|
|
|
1840
1949
|
Logger.info('setWarnTime() => set time to appear the AFK window.');
|
|
1841
1950
|
Logger.info('emitCommand(command) => send command to Unreal Engine.');
|
|
1842
1951
|
}
|
|
1843
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
1844
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.
|
|
1952
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: ConsoleExtensionsService, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1953
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: ConsoleExtensionsService }); }
|
|
1845
1954
|
}
|
|
1846
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
1955
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: ConsoleExtensionsService, decorators: [{
|
|
1847
1956
|
type: Injectable
|
|
1848
1957
|
}] });
|
|
1849
1958
|
|
|
@@ -1854,10 +1963,10 @@ class DevModeService {
|
|
|
1854
1963
|
setDevMode(value) {
|
|
1855
1964
|
return localStorage.setItem('devMode', value.toString());
|
|
1856
1965
|
}
|
|
1857
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
1858
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.
|
|
1966
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: DevModeService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1967
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: DevModeService, providedIn: 'root' }); }
|
|
1859
1968
|
}
|
|
1860
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
1969
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: DevModeService, decorators: [{
|
|
1861
1970
|
type: Injectable,
|
|
1862
1971
|
args: [{
|
|
1863
1972
|
providedIn: 'root',
|
|
@@ -2132,10 +2241,10 @@ class UnrealCommunicatorService {
|
|
|
2132
2241
|
callback,
|
|
2133
2242
|
});
|
|
2134
2243
|
}
|
|
2135
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
2136
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.
|
|
2244
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: UnrealCommunicatorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2245
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: UnrealCommunicatorService }); }
|
|
2137
2246
|
}
|
|
2138
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
2247
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: UnrealCommunicatorService, decorators: [{
|
|
2139
2248
|
type: Injectable
|
|
2140
2249
|
}], ctorParameters: () => [] });
|
|
2141
2250
|
|
|
@@ -2634,7 +2743,7 @@ class RegionsPingService {
|
|
|
2634
2743
|
}
|
|
2635
2744
|
}
|
|
2636
2745
|
getFastest(regionListUrl = this.unrealInitialConfig?.regionsPingUrl || '') {
|
|
2637
|
-
return this.getProviders(regionListUrl).pipe(switchMap$1((providers) => this.getPingResult(providers)), catchError(() => of(null)), map$1((data) => data?.region_code));
|
|
2746
|
+
return this.getProviders(regionListUrl).pipe(switchMap$1((providers) => this.getPingResult(providers)), catchError(() => of(null)), tapLog('PingResult'), map$1((data) => data?.region_code));
|
|
2638
2747
|
}
|
|
2639
2748
|
getPingResult(providers) {
|
|
2640
2749
|
const regions = providers.regions;
|
|
@@ -2691,6 +2800,9 @@ class RegionsPingService {
|
|
|
2691
2800
|
credentials: 'omit', // Optional: prevents sending or receiving cookies, which can affect caching.
|
|
2692
2801
|
}, timeout);
|
|
2693
2802
|
}
|
|
2803
|
+
catch {
|
|
2804
|
+
//Do not remove this block, else finally will not work!
|
|
2805
|
+
}
|
|
2694
2806
|
finally {
|
|
2695
2807
|
const latency = Math.round(performance.now() - startTime);
|
|
2696
2808
|
pingResults.push(latency);
|
|
@@ -2712,10 +2824,10 @@ class RegionsPingService {
|
|
|
2712
2824
|
throw error;
|
|
2713
2825
|
}
|
|
2714
2826
|
}
|
|
2715
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
2716
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.
|
|
2827
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: RegionsPingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2828
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: RegionsPingService }); }
|
|
2717
2829
|
}
|
|
2718
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
2830
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: RegionsPingService, decorators: [{
|
|
2719
2831
|
type: Injectable
|
|
2720
2832
|
}], ctorParameters: () => [] });
|
|
2721
2833
|
|
|
@@ -2755,10 +2867,10 @@ class StreamStatusTelemetryService {
|
|
|
2755
2867
|
init() {
|
|
2756
2868
|
// do nothing, just to not forget to initialize Service
|
|
2757
2869
|
}
|
|
2758
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
2759
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.
|
|
2870
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: StreamStatusTelemetryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2871
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: StreamStatusTelemetryService }); }
|
|
2760
2872
|
}
|
|
2761
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
2873
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: StreamStatusTelemetryService, decorators: [{
|
|
2762
2874
|
type: Injectable
|
|
2763
2875
|
}], ctorParameters: () => [] });
|
|
2764
2876
|
|
|
@@ -2792,7 +2904,6 @@ const initialState = {
|
|
|
2792
2904
|
viewportReady: false,
|
|
2793
2905
|
dataChannelConnected: false,
|
|
2794
2906
|
isVideoPlaying: false,
|
|
2795
|
-
isFreezeLoaderPercents: false,
|
|
2796
2907
|
statusPercentSignallingServer: null,
|
|
2797
2908
|
statusMessage: null,
|
|
2798
2909
|
errorMessage: null,
|
|
@@ -2801,7 +2912,7 @@ const initialState = {
|
|
|
2801
2912
|
streamResolution: { width: null, height: null },
|
|
2802
2913
|
freezeFrameFromVideo: { dataUrl: null, progress: null },
|
|
2803
2914
|
freezeFrame: { dataUrl: null, progress: null },
|
|
2804
|
-
disconnectReason: DisconnectReason.
|
|
2915
|
+
disconnectReason: DisconnectReason.None,
|
|
2805
2916
|
awsInstance: {
|
|
2806
2917
|
wsUrl: null,
|
|
2807
2918
|
instanceName: null,
|
|
@@ -2811,7 +2922,6 @@ const initialState = {
|
|
|
2811
2922
|
autoStart: true,
|
|
2812
2923
|
warnTimeout: DEFAULT_AFK_TIMEOUT,
|
|
2813
2924
|
},
|
|
2814
|
-
matchMakerUrls: [],
|
|
2815
2925
|
loaderCommands: {
|
|
2816
2926
|
commandsInProgress: [],
|
|
2817
2927
|
totalCommandsStarted: 0,
|
|
@@ -2844,12 +2954,17 @@ const unrealReducer = createReducer(initialState, on(changeLowBandwidth, (state,
|
|
|
2844
2954
|
pollingUrl,
|
|
2845
2955
|
},
|
|
2846
2956
|
};
|
|
2847
|
-
}), on(setViewportReady, (state
|
|
2957
|
+
}), on(setViewportReady, (state) => {
|
|
2848
2958
|
return {
|
|
2849
2959
|
...state,
|
|
2850
|
-
viewportReady:
|
|
2851
|
-
statusMessage:
|
|
2852
|
-
errorMessage:
|
|
2960
|
+
viewportReady: true,
|
|
2961
|
+
statusMessage: null,
|
|
2962
|
+
errorMessage: null,
|
|
2963
|
+
};
|
|
2964
|
+
}), on(setViewportNotReady, (state) => {
|
|
2965
|
+
return {
|
|
2966
|
+
...state,
|
|
2967
|
+
viewportReady: false,
|
|
2853
2968
|
};
|
|
2854
2969
|
}), on(updateCirrusInfo, (state, { ssInfo, ssData }) => {
|
|
2855
2970
|
return {
|
|
@@ -2877,14 +2992,15 @@ const unrealReducer = createReducer(initialState, on(changeLowBandwidth, (state,
|
|
|
2877
2992
|
progress: freezeFrame.progress || null,
|
|
2878
2993
|
},
|
|
2879
2994
|
};
|
|
2880
|
-
}), on(
|
|
2995
|
+
}), on(disconnectStream, (state, errorMessage) => {
|
|
2881
2996
|
if (state.dataChannelConnected) {
|
|
2882
2997
|
return state;
|
|
2883
2998
|
}
|
|
2884
2999
|
return {
|
|
2885
3000
|
...state,
|
|
2886
|
-
errorMessage
|
|
3001
|
+
errorMessage,
|
|
2887
3002
|
statusMessage: null,
|
|
3003
|
+
wasInitialized: true,
|
|
2888
3004
|
};
|
|
2889
3005
|
}), on(setFreezeFrameFromVideo, (state, freezeFrameFromVideo) => {
|
|
2890
3006
|
return {
|
|
@@ -2894,7 +3010,7 @@ const unrealReducer = createReducer(initialState, on(changeLowBandwidth, (state,
|
|
|
2894
3010
|
progress: freezeFrameFromVideo.progress || null,
|
|
2895
3011
|
},
|
|
2896
3012
|
};
|
|
2897
|
-
}), on(setStatusMessage, (state, { message }) => {
|
|
3013
|
+
}), on(setStatusMessage, setDataChannelConnected, (state, { message }) => {
|
|
2898
3014
|
return {
|
|
2899
3015
|
...state,
|
|
2900
3016
|
statusMessage: message,
|
|
@@ -2904,32 +3020,23 @@ const unrealReducer = createReducer(initialState, on(changeLowBandwidth, (state,
|
|
|
2904
3020
|
...state,
|
|
2905
3021
|
establishingConnection: value,
|
|
2906
3022
|
};
|
|
2907
|
-
}), on(setIsFreezeLoaderPercents, (state) => {
|
|
2908
|
-
return {
|
|
2909
|
-
...state,
|
|
2910
|
-
isFreezeLoaderPercents: true,
|
|
2911
|
-
};
|
|
2912
3023
|
}), on(setStatusPercentSignallingServer, (state, { percent }) => {
|
|
2913
3024
|
return {
|
|
2914
3025
|
...state,
|
|
2915
3026
|
statusPercentSignallingServer: percent,
|
|
2916
3027
|
};
|
|
2917
|
-
}), on(setDataChannelConnected, (state
|
|
3028
|
+
}), on(setDataChannelConnected, (state) => {
|
|
2918
3029
|
return {
|
|
2919
3030
|
...state,
|
|
2920
|
-
dataChannelConnected:
|
|
2921
|
-
|
|
3031
|
+
dataChannelConnected: true,
|
|
3032
|
+
establishingConnection: false,
|
|
3033
|
+
wasInitialized: true,
|
|
2922
3034
|
};
|
|
2923
|
-
}), on(setConfig, (state, { config }) => {
|
|
3035
|
+
}), on(setConfig, startStream, (state, { config }) => {
|
|
2924
3036
|
return {
|
|
2925
3037
|
...state,
|
|
2926
3038
|
streamConfig: { ...state.streamConfig, ...config },
|
|
2927
3039
|
};
|
|
2928
|
-
}), on(setMatchMakerUrls, (state, { matchMakerUrls }) => {
|
|
2929
|
-
return {
|
|
2930
|
-
...state,
|
|
2931
|
-
matchMakerUrls,
|
|
2932
|
-
};
|
|
2933
3040
|
}), on(resetConfig, (state) => {
|
|
2934
3041
|
return {
|
|
2935
3042
|
...state,
|
|
@@ -2943,20 +3050,17 @@ const unrealReducer = createReducer(initialState, on(changeLowBandwidth, (state,
|
|
|
2943
3050
|
warnTimeout: DEFAULT_AFK_TIMEOUT,
|
|
2944
3051
|
},
|
|
2945
3052
|
};
|
|
2946
|
-
}), on(
|
|
3053
|
+
}), on(initSignalling, (state, { resetDisconnectionReason = true }) => {
|
|
2947
3054
|
return {
|
|
2948
3055
|
...state,
|
|
2949
|
-
|
|
3056
|
+
disconnectReason: resetDisconnectionReason
|
|
3057
|
+
? DisconnectReason.None
|
|
3058
|
+
: state.disconnectReason,
|
|
2950
3059
|
};
|
|
2951
|
-
}), on(
|
|
3060
|
+
}), on(destroyRemoteConnections, (state, { reason }) => {
|
|
2952
3061
|
return {
|
|
2953
3062
|
...state,
|
|
2954
|
-
|
|
2955
|
-
};
|
|
2956
|
-
}), on(initSignalling, (state) => {
|
|
2957
|
-
return {
|
|
2958
|
-
...state,
|
|
2959
|
-
disconnectReason: DisconnectReason.none,
|
|
3063
|
+
disconnectReason: reason,
|
|
2960
3064
|
};
|
|
2961
3065
|
}), on(setSignalingName, (state, { instanceName }) => {
|
|
2962
3066
|
return {
|
|
@@ -3021,9 +3125,16 @@ const unrealReducer = createReducer(initialState, on(changeLowBandwidth, (state,
|
|
|
3021
3125
|
...state,
|
|
3022
3126
|
loaderCommands: removeExileCommands(state.loaderCommands, id),
|
|
3023
3127
|
};
|
|
3024
|
-
}), on(
|
|
3128
|
+
}), on(setCirrusConnected, (state) => {
|
|
3129
|
+
return {
|
|
3130
|
+
...state,
|
|
3131
|
+
cirrusConnected: true,
|
|
3132
|
+
};
|
|
3133
|
+
}), on(setCirrusDisconnected, (state) => {
|
|
3025
3134
|
return {
|
|
3026
3135
|
...initialState,
|
|
3136
|
+
establishingConnection: state.establishingConnection,
|
|
3137
|
+
disconnectReason: state.disconnectReason,
|
|
3027
3138
|
wasInitialized: state.wasInitialized,
|
|
3028
3139
|
isFirstSuccessLoad: state.isFirstSuccessLoad,
|
|
3029
3140
|
matchUrls: state.matchUrls,
|
|
@@ -3033,7 +3144,12 @@ const unrealReducer = createReducer(initialState, on(changeLowBandwidth, (state,
|
|
|
3033
3144
|
videoIntroSrc: state.videoIntroSrc,
|
|
3034
3145
|
imageLoadingSrc: state.imageLoadingSrc,
|
|
3035
3146
|
};
|
|
3036
|
-
}), on(
|
|
3147
|
+
}), on(dropConnection, (state) => {
|
|
3148
|
+
return {
|
|
3149
|
+
...state,
|
|
3150
|
+
establishingConnection: false,
|
|
3151
|
+
};
|
|
3152
|
+
}), on(destroyUnrealScene, () => {
|
|
3037
3153
|
return initialState;
|
|
3038
3154
|
}));
|
|
3039
3155
|
|
|
@@ -3050,10 +3166,10 @@ class UnrealErrorModalComponent {
|
|
|
3050
3166
|
close() {
|
|
3051
3167
|
this.dialogRef.close();
|
|
3052
3168
|
}
|
|
3053
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
3054
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.
|
|
3169
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: UnrealErrorModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3170
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.2", type: UnrealErrorModalComponent, isStandalone: true, selector: "app-unreal-error-modal", ngImport: i0, template: "<div class=\"src-modal src-modal--small\">\n <div class=\"src-modal__header\">\n <div\n class=\"src-modal__title\"\n [attr.data-testid]=\"'unreal-error-header-title'\"\n >\n Warning\n </div>\n </div>\n <div class=\"src-modal__body\">\n <div>{{ dialogData.content }}</div>\n </div>\n <div class=\"src-modal__footer\">\n <src-button [colorScheme]=\"'secondary'\" (onClick)=\"close()\">\n Ok\n </src-button>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: SourceButtonComponent, selector: "src-button", inputs: ["type", "appearance", "colorScheme", "size", "state", "customClass", "hasDisclosure", "isFullWidth", "isPressed", "isDisabled", "isLoading", "iconButton", "srcButtonConfig", "formID", "data-testid"], outputs: ["onClick", "onSubmit"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3055
3171
|
}
|
|
3056
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
3172
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: UnrealErrorModalComponent, decorators: [{
|
|
3057
3173
|
type: Component,
|
|
3058
3174
|
args: [{ selector: 'app-unreal-error-modal', changeDetection: ChangeDetectionStrategy.OnPush, imports: [SourceButtonComponent], template: "<div class=\"src-modal src-modal--small\">\n <div class=\"src-modal__header\">\n <div\n class=\"src-modal__title\"\n [attr.data-testid]=\"'unreal-error-header-title'\"\n >\n Warning\n </div>\n </div>\n <div class=\"src-modal__body\">\n <div>{{ dialogData.content }}</div>\n </div>\n <div class=\"src-modal__footer\">\n <src-button [colorScheme]=\"'secondary'\" (onClick)=\"close()\">\n Ok\n </src-button>\n </div>\n</div>\n" }]
|
|
3059
3175
|
}] });
|
|
@@ -3073,23 +3189,38 @@ class UnrealEffects {
|
|
|
3073
3189
|
this.videoService = inject(VideoService);
|
|
3074
3190
|
this.dataChannelConnectionTimeout = this.unrealInitialConfig?.dataChannelConnectionTimeout ??
|
|
3075
3191
|
DATA_CHANNEL_CONNECTION_TIMEOUT;
|
|
3076
|
-
this.
|
|
3077
|
-
|
|
3192
|
+
this.disconnectReasonHandling$ = createEffect(() => {
|
|
3193
|
+
const destroyReasons = [
|
|
3194
|
+
DisconnectReason.Afk,
|
|
3195
|
+
DisconnectReason.DataChannelClosed,
|
|
3196
|
+
DisconnectReason.DataChannelTimeout,
|
|
3197
|
+
DisconnectReason.WebSocketError,
|
|
3198
|
+
DisconnectReason.WebSocketClose,
|
|
3199
|
+
DisconnectReason.WebRTCError,
|
|
3200
|
+
DisconnectReason.DropConnection,
|
|
3201
|
+
];
|
|
3202
|
+
return this.actions$.pipe(ofType(disconnectStream), filter(({ reason }) => destroyReasons.some((r) => r === reason)), tap(({ reason, message }) => {
|
|
3203
|
+
Logger.log(`Disconnect Call=> reason:'${reason}', message:'${message}'`);
|
|
3204
|
+
}), map(({ reason }) => destroyRemoteConnections({ reason })));
|
|
3078
3205
|
});
|
|
3079
3206
|
this.destroyConnections$ = createEffect(() => {
|
|
3080
|
-
return this.actions$.pipe(ofType(
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
return this.actions$.pipe(ofType(destroyConnectionsAndResetState), map(() => resetUnrealState()));
|
|
3207
|
+
return this.actions$.pipe(ofType(destroyUnrealScene), map(() => destroyRemoteConnections({
|
|
3208
|
+
reason: DisconnectReason.Destroy,
|
|
3209
|
+
})));
|
|
3084
3210
|
});
|
|
3085
3211
|
this.destroyRemoteConnections$ = createEffect(() => {
|
|
3086
|
-
return this.actions$.pipe(ofType(destroyRemoteConnections), tap(({
|
|
3212
|
+
return this.actions$.pipe(ofType(destroyRemoteConnections), tap(({ reason }) => {
|
|
3087
3213
|
this.signallingService.close({
|
|
3088
|
-
code:
|
|
3089
|
-
reason
|
|
3214
|
+
code: WSCloseCode_FORCE_CIRRUS_CLOSE,
|
|
3215
|
+
reason,
|
|
3090
3216
|
});
|
|
3091
3217
|
this.player.closePC();
|
|
3092
|
-
}));
|
|
3218
|
+
}), filter(({ reason }) => reason === DisconnectReason.DropConnection), map(() => dropConnection()));
|
|
3219
|
+
});
|
|
3220
|
+
this.webrtcErrorModalComponent$ = createEffect(() => {
|
|
3221
|
+
return this.actions$.pipe(ofType(disconnectStream), filter(({ reason }) => reason === DisconnectReason.WebRTCError), debounceTime$1(400), switchMap$1(() => this.store
|
|
3222
|
+
.select(unrealFeature.selectDataChannelConnected)
|
|
3223
|
+
.pipe(take(1), filter(Falsy))), tap(() => this.dialog.open(WebrtcErrorModalComponent)));
|
|
3093
3224
|
}, { dispatch: false });
|
|
3094
3225
|
this.changeStreamResolution$ = createEffect(() => {
|
|
3095
3226
|
return this.actions$.pipe(ofType(changeStreamResolutionAction), filter((size) => !!(size?.width && size?.height)), withLatestFrom(this.store.select(unrealFeature.selectStreamResolution)), filter(([newSizes, savedSizes]) => !(newSizes.width === savedSizes.width &&
|
|
@@ -3122,45 +3253,67 @@ class UnrealEffects {
|
|
|
3122
3253
|
this.resetAfk$ = createEffect(() => {
|
|
3123
3254
|
return this.actions$.pipe(ofType(setConfig, resetWarnTimeout, resetConfig), map(() => resetAfkAction()));
|
|
3124
3255
|
});
|
|
3125
|
-
this.
|
|
3126
|
-
|
|
3256
|
+
this.abortEstablishingConnection$ = createEffect(() => {
|
|
3257
|
+
const viewportReady$ = this.store
|
|
3258
|
+
.select(unrealFeature.selectViewportReady)
|
|
3259
|
+
.pipe(filter(Truthy), map(() => abortEstablishingConnection()));
|
|
3260
|
+
const disconnectEvents$ = this.actions$.pipe(ofType(setCirrusDisconnected, destroyUnrealScene, dropConnection), map(() => abortEstablishingConnection()));
|
|
3261
|
+
return merge(viewportReady$, disconnectEvents$).pipe(tapLog('ABORT'));
|
|
3127
3262
|
});
|
|
3128
3263
|
this.setMaxFps$ = createEffect(() => {
|
|
3129
3264
|
return this.actions$.pipe(ofType(setMaxFps), tap(({ maxFps }) => {
|
|
3130
3265
|
this.commandsSender.sendCommandToUnreal(getSetFpsCommand(maxFps));
|
|
3131
3266
|
}));
|
|
3132
3267
|
}, { dispatch: false });
|
|
3133
|
-
this.webrtcErrorModalComponent$ = createEffect(() => {
|
|
3134
|
-
return this.actions$.pipe(ofType(setErrorMessage), debounceTime$1(400), combineLatestWith(this.store.select(unrealFeature.selectDataChannelConnected)), filter(([error, isConnected]) => {
|
|
3135
|
-
return !isConnected && error?.errorType === 'WebRTCError';
|
|
3136
|
-
}), tap(() => this.dialog.open(WebrtcErrorModalComponent)));
|
|
3137
|
-
}, { dispatch: false });
|
|
3138
3268
|
this.resetAfkAction$ = createEffect(() => {
|
|
3139
3269
|
return this.actions$.pipe(ofType(resetAfkAction), tap(() => resetAfk()));
|
|
3140
3270
|
}, { dispatch: false });
|
|
3141
|
-
this.
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3271
|
+
this.setSignalingTo100$ = createEffect(() => this.actions$.pipe(ofType(setAwsInstance), map(() => setStatusPercentSignallingServer({ percent: 100 }))));
|
|
3272
|
+
this.setDataChannelTimeoutCheck$ = createEffect(() => this.actions$.pipe(ofType(setAwsInstance),
|
|
3273
|
+
// require wsUrl present on the action payload
|
|
3274
|
+
filter((action) => !!action.wsUrl),
|
|
3275
|
+
// for each awsInstance action capture one ssData snapshot, then wait for dataChannelConnected
|
|
3276
|
+
switchMap$1((awsInstance) => {
|
|
3277
|
+
return this.store.select(unrealFeature.selectSsData).pipe(filter(Truthy), take(1), tap(() => Logger.log(`DataChannel timeout check started with next timeout: ${this.dataChannelConnectionTimeout}ms`)), switchMap$1((ssData) => {
|
|
3278
|
+
const abort$ = this.actions$.pipe(ofType(setCirrusDisconnected), take(1));
|
|
3279
|
+
return this.store
|
|
3280
|
+
.select(unrealFeature.selectDataChannelConnected)
|
|
3281
|
+
.pipe(
|
|
3282
|
+
// wait until data channel reports connected (truthy)
|
|
3283
|
+
filter(Truthy), take(1),
|
|
3284
|
+
// 🚫 If Cirrus (or anything else) disconnects first, abort BEFORE timeout fires.
|
|
3285
|
+
takeUntil(abort$),
|
|
3286
|
+
// if it becomes true within timeout -> complete without dispatching any action
|
|
3287
|
+
timeout$1(this.dataChannelConnectionTimeout),
|
|
3288
|
+
// successful connect → no action
|
|
3289
|
+
mergeMap(() => EMPTY),
|
|
3290
|
+
// ⏱️ Only actual timeout (or real upstream error) ends up here.
|
|
3291
|
+
catchError(() => {
|
|
3292
|
+
const error = `⏱️ DataChannel connection timeout ${this.dataChannelConnectionTimeout}ms, requesting new signaling.`;
|
|
3293
|
+
Logger.error(error);
|
|
3294
|
+
const body = {
|
|
3295
|
+
awsInstance,
|
|
3296
|
+
connectionId: ssData?.connectionId,
|
|
3297
|
+
href: location.href,
|
|
3298
|
+
userAgent: navigator.userAgent,
|
|
3299
|
+
error,
|
|
3300
|
+
};
|
|
3301
|
+
return this.http
|
|
3302
|
+
.post(awsInstance.pollingUrl || '', body)
|
|
3303
|
+
.pipe(catchError((postError) => {
|
|
3304
|
+
Logger.error('Error sending timeout info:', postError);
|
|
3305
|
+
return of(null);
|
|
3306
|
+
}),
|
|
3307
|
+
// map response to the destroy action which ngrx will dispatch
|
|
3308
|
+
map(() => disconnectStream({
|
|
3309
|
+
reason: DisconnectReason.DataChannelTimeout,
|
|
3310
|
+
message: 'Data Channel Timeout',
|
|
3311
|
+
})));
|
|
3157
3312
|
}));
|
|
3158
|
-
})
|
|
3159
|
-
|
|
3160
|
-
})));
|
|
3161
|
-
});
|
|
3313
|
+
}));
|
|
3314
|
+
})));
|
|
3162
3315
|
this.destroyConnectionAndRestart$ = createEffect(() => {
|
|
3163
|
-
return this.actions$.pipe(ofType(destroyRemoteConnections), filter(({
|
|
3316
|
+
return this.actions$.pipe(ofType(destroyRemoteConnections), filter(({ reason }) => reason === DisconnectReason.DataChannelTimeout), switchMap$1(() => this.actions$.pipe(ofType(setCirrusDisconnected), first())), map(() => initSignalling()));
|
|
3164
3317
|
});
|
|
3165
3318
|
this.showUnrealError$ = createEffect(() => {
|
|
3166
3319
|
return this.actions$.pipe(ofType(showUnrealErrorMessage), map(({ code }) => getRtcErrorMessage(code)), distinctUntilChanged(), filter(Truthy), switchMap$1((content) => this.dialog.open(UnrealErrorModalComponent, {
|
|
@@ -3198,27 +3351,48 @@ class UnrealEffects {
|
|
|
3198
3351
|
(videoStats.aggregatedStats.framesDecoded || 0) > 15), first(), map(() => setLoopBackCommandIsCompleted()))));
|
|
3199
3352
|
});
|
|
3200
3353
|
this.setViewportReadyBySetLoopBackCommandIsCompleted$ = createEffect(() => {
|
|
3201
|
-
return this.actions$.pipe(ofType(setLoopBackCommandIsCompleted), tap(() => TelemetryStop('SetViewportReady', { ready: true })), map(() => setViewportReady(
|
|
3354
|
+
return this.actions$.pipe(ofType(setLoopBackCommandIsCompleted), tap(() => TelemetryStop('SetViewportReady', { ready: true })), map(() => setViewportReady()));
|
|
3355
|
+
});
|
|
3356
|
+
this.startStream$ = createEffect(() => {
|
|
3357
|
+
return this.actions$.pipe(ofType(startStream), tapLog('Start Stream Pressed'), map(() => initSignalling()));
|
|
3202
3358
|
});
|
|
3203
3359
|
this.listenUnrealCallbackByInitSignalling$ = createEffect(() => {
|
|
3204
3360
|
return this.actions$.pipe(ofType(initSignalling), switchMap$1(() => fromSignal(UnrealInternalSignalEvents.UnrealCallback).pipe(map(({ json }) => json?.commandCallback
|
|
3205
3361
|
?.correlationId), filter(Truthy), map((id) => commandCompleted({ id })))));
|
|
3206
3362
|
});
|
|
3207
|
-
this.
|
|
3208
|
-
return this.actions$.pipe(ofType(initSignalling), withLatestFrom(this.store.select(unrealFeature.selectMatchUrls)),
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
if (isEmpty(matchMakerUrls)) {
|
|
3212
|
-
throw Error('Signalling URL(s) is empty');
|
|
3363
|
+
this.connectToSignaling$ = createEffect(() => {
|
|
3364
|
+
return this.actions$.pipe(ofType(initSignalling), withLatestFrom(this.store.select(unrealFeature.selectMatchUrls), this.store.select(selectIsAutostart), this.store.select(unrealFeature.selectCirrusConnected)), filter(([, , autoStart, cirrusConnected]) => {
|
|
3365
|
+
if (cirrusConnected) {
|
|
3366
|
+
Logger.warn(`SIGNALING REQUEST can't be called when cirrus connection is already established.`);
|
|
3213
3367
|
}
|
|
3214
|
-
return
|
|
3215
|
-
}))
|
|
3368
|
+
return autoStart && !cirrusConnected;
|
|
3369
|
+
}), map(([, matchMakerUrls]) => [...matchMakerUrls].filter(Truthy)), filter((urls) => urls.length > 0),
|
|
3370
|
+
// Ensure a single in-flight request per attempt.
|
|
3371
|
+
exhaustMap((urls) => this.signallingService.connectToSignaling(urls)));
|
|
3372
|
+
}, { dispatch: false });
|
|
3373
|
+
/**
|
|
3374
|
+
* Effect: `forceViewportNotReady$`
|
|
3375
|
+
*
|
|
3376
|
+
* Ensures the viewport is explicitly marked as *not ready* to prevent
|
|
3377
|
+
* a temporary black screen flash when disconnecting.
|
|
3378
|
+
*
|
|
3379
|
+
* ### Why
|
|
3380
|
+
* - The video stream is disconnected immediately.
|
|
3381
|
+
* - The DataChannel closes slightly later.
|
|
3382
|
+
* - Closing the DataChannel resets the Unreal scene,
|
|
3383
|
+
* which also sets `viewPortReady` to `false`.
|
|
3384
|
+
*
|
|
3385
|
+
* Without this effect, the order of these events may cause
|
|
3386
|
+
* a visible flicker (video flashing to black).
|
|
3387
|
+
*/
|
|
3388
|
+
this.forceViewportNotReady$ = createEffect(() => {
|
|
3389
|
+
return this.actions$.pipe(ofType(destroyRemoteConnections), map(() => setViewportNotReady()));
|
|
3216
3390
|
});
|
|
3217
3391
|
}
|
|
3218
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
3219
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.
|
|
3392
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: UnrealEffects, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
3393
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: UnrealEffects }); }
|
|
3220
3394
|
}
|
|
3221
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
3395
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: UnrealEffects, decorators: [{
|
|
3222
3396
|
type: Injectable
|
|
3223
3397
|
}] });
|
|
3224
3398
|
|
|
@@ -3231,11 +3405,10 @@ const selectIsFreezeFrameLoading = createSelector(unrealFeature.selectFreezeFram
|
|
|
3231
3405
|
const selectFreezeFrameCombinedDataUrl = createSelector(selectFreezeFrameDataUrlFromVideo, selectFreezeFrameDataUrl, (dataUrlFromVideo, remoteDataUrl) => dataUrlFromVideo || remoteDataUrl || null);
|
|
3232
3406
|
const selectStreamConfig = createSelector(unrealFeature.selectStreamConfig, (config) => config);
|
|
3233
3407
|
const selectWarnTimeout = createSelector(selectStreamConfig, (config) => config?.warnTimeout || DEFAULT_AFK_TIMEOUT);
|
|
3234
|
-
const selectMatchMakerUrls = createSelector(unrealFeature.selectMatchMakerUrls, (urls) => (urls || []).filter(Truthy));
|
|
3235
3408
|
const selectIsAutostart = createSelector(selectStreamConfig, (config) => config?.autoStart);
|
|
3236
|
-
const
|
|
3237
|
-
const selectShowReconnectPopup = createSelector(unrealFeature.
|
|
3238
|
-
const selectShowLoader = createSelector(
|
|
3409
|
+
const showPopupWithoutAutoStart = createSelector(selectStreamConfig, unrealFeature.selectWasInitialized, (config, wasInitialized) => !config.autoStart && !wasInitialized);
|
|
3410
|
+
const selectShowReconnectPopup = createSelector(unrealFeature.selectCirrusConnected, unrealFeature.selectEstablishingConnection, (connected, establishing) => !connected && !establishing);
|
|
3411
|
+
const selectShowLoader = createSelector(selectShowReconnectPopup, unrealFeature.selectViewportReady, (showPopup, viewPortReady) => !showPopup && !viewPortReady);
|
|
3239
3412
|
const selectIsVideoPlayingAndDataChannelConnected = createSelector(unrealFeature.selectIsVideoPlaying, unrealFeature.selectDataChannelConnected, (isVideoPlaying, isDataChannelConnected) => isVideoPlaying && isDataChannelConnected);
|
|
3240
3413
|
const selectSignalingParameters = createSelector(unrealFeature.selectSsData, unrealFeature.selectAwsInstance, unrealFeature.selectSsInfo, (data, instance, ssInfo) => {
|
|
3241
3414
|
const info = [];
|
|
@@ -3279,6 +3452,8 @@ const selectTotalProgress = createSelector(unrealFeature.selectStatusPercentSign
|
|
|
3279
3452
|
const percentRest = lerp(0, 1 - splitPoint, commandProgress);
|
|
3280
3453
|
return clampf(0, 1, percentSignaling + percentRest);
|
|
3281
3454
|
});
|
|
3455
|
+
const selectClientAndViewIds = createSelector(unrealFeature.selectStreamClientCompanyId, unrealFeature.selectStreamViewId, (clientId, viewId) => ({ clientId, viewId }));
|
|
3456
|
+
const isLoaderScreenVisible = createSelector(unrealFeature.selectViewportReady, unrealFeature.selectDataChannelConnected, unrealFeature.selectCirrusConnected, (viewReady, cirrusConnected, dataChannelConnected) => !viewReady || !cirrusConnected || !dataChannelConnected);
|
|
3282
3457
|
|
|
3283
3458
|
function InstanceReservedHandler(msg) {
|
|
3284
3459
|
this.store.dispatch(setSignalingName({
|
|
@@ -3302,26 +3477,30 @@ function SSInfoHandler(msg) {
|
|
|
3302
3477
|
return null;
|
|
3303
3478
|
}
|
|
3304
3479
|
|
|
3480
|
+
const dropCodes = [
|
|
3481
|
+
WSCloseCode_CIRRUS_PLAYER_DISCONNECTED,
|
|
3482
|
+
WSCloseCode_CIRRUS_ABNORMAL_CLOSURE,
|
|
3483
|
+
WSCloseCode_CIRRUS_STREAMER_KIKED_PLAYER,
|
|
3484
|
+
WSCloseCode_CIRRUS_MAX_PLAYERS_ERROR,
|
|
3485
|
+
];
|
|
3305
3486
|
function OnCloseHandler(e) {
|
|
3306
|
-
|
|
3307
|
-
Logger.warn(
|
|
3487
|
+
const message = `WebSocket closed: ${JSON.stringify(e.code)} - ${e.reason}`;
|
|
3488
|
+
Logger.warn(message);
|
|
3308
3489
|
this.store.dispatch(setCirrusDisconnected());
|
|
3490
|
+
if (dropCodes.includes(e.code)) {
|
|
3491
|
+
this.store.dispatch(dropConnection());
|
|
3492
|
+
}
|
|
3309
3493
|
}
|
|
3310
3494
|
|
|
3311
3495
|
function OnErrorHandler(e) {
|
|
3312
|
-
clearTimeout(this.wsTimeoutHandler);
|
|
3313
3496
|
Logger.warn(`WS error: ${JSON.stringify(e)}`);
|
|
3314
|
-
this.store.dispatch(
|
|
3315
|
-
|
|
3497
|
+
this.store.dispatch(disconnectStream({
|
|
3498
|
+
reason: DisconnectReason.WebSocketError,
|
|
3316
3499
|
message: 'WebSocket Error',
|
|
3317
3500
|
}));
|
|
3318
|
-
this.store.dispatch(destroyRemoteConnections({ disconnectReason: DisconnectReason.wsOnError }));
|
|
3319
|
-
this.initEstablishingConnection();
|
|
3320
|
-
this.watchTimeoutOrErrorAndReconnectLater();
|
|
3321
3501
|
}
|
|
3322
3502
|
|
|
3323
3503
|
function OnMessageHandler(e) {
|
|
3324
|
-
clearTimeout(this.wsTimeoutHandler);
|
|
3325
3504
|
const handleData = (data) => {
|
|
3326
3505
|
//Logger.colored(...COLOR_CODES.FROM_SIGNALING, data);
|
|
3327
3506
|
const msg = JSON.parse(data);
|
|
@@ -3336,7 +3515,6 @@ function OnMessageHandler(e) {
|
|
|
3336
3515
|
}
|
|
3337
3516
|
|
|
3338
3517
|
function OnOpenHandler() {
|
|
3339
|
-
this.stopRetryTimer();
|
|
3340
3518
|
this.store.dispatch(setCirrusConnected());
|
|
3341
3519
|
this.send({
|
|
3342
3520
|
type: OrchestrationMessageTypes.requestReservation,
|
|
@@ -3351,8 +3529,12 @@ function OnOpenHandler() {
|
|
|
3351
3529
|
});
|
|
3352
3530
|
}
|
|
3353
3531
|
|
|
3354
|
-
|
|
3355
|
-
|
|
3532
|
+
/**
|
|
3533
|
+
* Keeps the max of numbers seen so far; resets to 0 whenever `reset$` emits.
|
|
3534
|
+
* Emits `0` immediately on reset.
|
|
3535
|
+
*/
|
|
3536
|
+
const clampAndKeepMaxPercents = (reset$) => {
|
|
3537
|
+
return (source$) => merge(source$.pipe(map((value) => ({ type: 'value', value }))), reset$.pipe(map(() => ({ type: 'reset' })))).pipe(scan((max, evt) => (evt.type === 'reset' ? 0 : Math.max(max, evt.value)), 0));
|
|
3356
3538
|
};
|
|
3357
3539
|
|
|
3358
3540
|
function observeCommandResponse(data, sender, timeOut = 60000, dispatchOnTimeout = true) {
|
|
@@ -3367,7 +3549,7 @@ function observeCommandResponse(data, sender, timeOut = 60000, dispatchOnTimeout
|
|
|
3367
3549
|
: { json: { commandCallback: json } };
|
|
3368
3550
|
}), filter(({ json }) => {
|
|
3369
3551
|
return json.commandCallback.correlationId === correlationId;
|
|
3370
|
-
}), timeout(timeOut), catchError(() => dispatchOnTimeout
|
|
3552
|
+
}), timeout$1(timeOut), catchError(() => dispatchOnTimeout
|
|
3371
3553
|
? of({ json: { commandCallback: { correlationId: 'timeout' } } })
|
|
3372
3554
|
: of(null)), first(), tapLog('Command Response Observer'), filter(Truthy));
|
|
3373
3555
|
setTimeout(() => sender(out), 0);
|
|
@@ -3872,10 +4054,10 @@ class ClickableOverlayComponent {
|
|
|
3872
4054
|
constructor() {
|
|
3873
4055
|
this.state = toSignal(fromSignal(UnrealInternalSignalEvents.ClickableOverlay).pipe(map$1((data) => (typeof data === 'object' ? data : null))));
|
|
3874
4056
|
}
|
|
3875
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
3876
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.
|
|
4057
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: ClickableOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4058
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.2", type: ClickableOverlayComponent, isStandalone: true, selector: "app-clickable-overlay", ngImport: i0, template: "@if (state()) {\n <div\n (click)=\"state()?.onOverlayClick()\"\n [ngClass]=\"state()?.className\"\n id=\"videoPlayOverlay\"\n >\n @if (state()?.isActivityDetected) {\n <div class=\"resume-box\">\n <div aria-hidden=\"true\" class=\"resume-box__pic\" role=\"presentation\">\n <div [innerHTML]=\"state()?.message\" class=\"text-number\"></div>\n </div>\n <div class=\"resume-box__text\">\n <h3 class=\"resume-box__heading\">Session will time out soon</h3>\n <p>\n No activity detected. Press 'Continue' if you wish to keep your\n session active\n </p>\n </div>\n <src-button\n [colorScheme]=\"'primary'\"\n [isFullWidth]=\"true\"\n [size]=\"'large'\"\n [data-testid]=\"'continue-session'\"\n >\n Continue\n </src-button>\n </div>\n }\n </div>\n}\n", styles: ["#videoPlayOverlay{position:absolute;z-index:30;top:0;width:100%;height:100%;font-size:1.8em;font-family:var(--src-font-family-body);background-color:#646464b3}.clickableState{display:flex;justify-content:center;align-items:center;cursor:pointer}.textDisplayState{display:flex}.hiddenState{display:none}.resume-box{width:340px;padding:32px 20px 20px;flex-direction:column;align-items:center;border-radius:var(--src-border-rounded-parent, 8px);background:var(--src-color-bg-default, #fff);box-shadow:0 26px 80px #0003,0 0 1px #0003}.resume-box .resume-box__pic{width:72px;height:72px;margin:0 auto 22px;border-radius:48px;background:#ecf0f2;padding:12px;display:flex;align-items:center;justify-content:center}.resume-box .resume-box__pic .text-number{color:var(--src-colors-text-default, #1f2937);text-align:center;font-family:var(--src-font-family-body);font-size:30px;font-style:normal;font-weight:400;line-height:24px}.resume-box__text{margin-bottom:18px}.resume-box__text p{text-align:center;font-family:var(--src-font-family-body);font-size:var(--src-font-size-sm, 14px);font-style:normal;font-weight:400;line-height:24px;color:var(--src-color-text-default-subdued, #6b7280)}.resume-box__text .resume-box__heading{color:var(--src-color-bg-default, #1f2937);text-align:center;font-family:var(--src-font-family-body);font-size:18px;font-style:normal;font-weight:500;line-height:26px;margin-bottom:8px}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: SourceButtonComponent, selector: "src-button", inputs: ["type", "appearance", "colorScheme", "size", "state", "customClass", "hasDisclosure", "isFullWidth", "isPressed", "isDisabled", "isLoading", "iconButton", "srcButtonConfig", "formID", "data-testid"], outputs: ["onClick", "onSubmit"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3877
4059
|
}
|
|
3878
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
4060
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: ClickableOverlayComponent, decorators: [{
|
|
3879
4061
|
type: Component,
|
|
3880
4062
|
args: [{ selector: 'app-clickable-overlay', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgClass, SourceButtonComponent], template: "@if (state()) {\n <div\n (click)=\"state()?.onOverlayClick()\"\n [ngClass]=\"state()?.className\"\n id=\"videoPlayOverlay\"\n >\n @if (state()?.isActivityDetected) {\n <div class=\"resume-box\">\n <div aria-hidden=\"true\" class=\"resume-box__pic\" role=\"presentation\">\n <div [innerHTML]=\"state()?.message\" class=\"text-number\"></div>\n </div>\n <div class=\"resume-box__text\">\n <h3 class=\"resume-box__heading\">Session will time out soon</h3>\n <p>\n No activity detected. Press 'Continue' if you wish to keep your\n session active\n </p>\n </div>\n <src-button\n [colorScheme]=\"'primary'\"\n [isFullWidth]=\"true\"\n [size]=\"'large'\"\n [data-testid]=\"'continue-session'\"\n >\n Continue\n </src-button>\n </div>\n }\n </div>\n}\n", styles: ["#videoPlayOverlay{position:absolute;z-index:30;top:0;width:100%;height:100%;font-size:1.8em;font-family:var(--src-font-family-body);background-color:#646464b3}.clickableState{display:flex;justify-content:center;align-items:center;cursor:pointer}.textDisplayState{display:flex}.hiddenState{display:none}.resume-box{width:340px;padding:32px 20px 20px;flex-direction:column;align-items:center;border-radius:var(--src-border-rounded-parent, 8px);background:var(--src-color-bg-default, #fff);box-shadow:0 26px 80px #0003,0 0 1px #0003}.resume-box .resume-box__pic{width:72px;height:72px;margin:0 auto 22px;border-radius:48px;background:#ecf0f2;padding:12px;display:flex;align-items:center;justify-content:center}.resume-box .resume-box__pic .text-number{color:var(--src-colors-text-default, #1f2937);text-align:center;font-family:var(--src-font-family-body);font-size:30px;font-style:normal;font-weight:400;line-height:24px}.resume-box__text{margin-bottom:18px}.resume-box__text p{text-align:center;font-family:var(--src-font-family-body);font-size:var(--src-font-size-sm, 14px);font-style:normal;font-weight:400;line-height:24px;color:var(--src-color-text-default-subdued, #6b7280)}.resume-box__text .resume-box__heading{color:var(--src-color-bg-default, #1f2937);text-align:center;font-family:var(--src-font-family-body);font-size:18px;font-style:normal;font-weight:500;line-height:26px;margin-bottom:8px}\n"] }]
|
|
3881
4063
|
}] });
|
|
@@ -3886,10 +4068,10 @@ class FreezeFrameComponent {
|
|
|
3886
4068
|
this.freezeFrameProgressMessageFromVideo = toSignal(this.store.select(selectFreezeFrameProgressMessageFromVideo));
|
|
3887
4069
|
this.combinedFreeze = toSignal(this.store.select(selectFreezeFrameCombinedDataUrl));
|
|
3888
4070
|
}
|
|
3889
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
3890
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.
|
|
4071
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: FreezeFrameComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4072
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.2", type: FreezeFrameComponent, isStandalone: true, selector: "app-freeze-frame", ngImport: i0, template: "<div class=\"freeze-images\">\n @if (combinedFreeze()) {\n <img\n [src]=\"combinedFreeze()\"\n class=\"videoStillImage\"\n alt=\"freezeFrameImage\"\n />\n }\n\n @if (freezeFrameProgressMessageFromVideo()) {\n <div class=\"progress-status\">\n {{ freezeFrameProgressMessageFromVideo() }}\n </div>\n }\n</div>\n", styles: [".freeze-images{pointer-events:none;position:absolute;left:0;top:0;width:100%;height:100%;z-index:1}.freeze-images .freezeFrameOverlay{top:0;left:0;width:100%;height:100%;position:absolute;object-fit:cover;object-position:center}.freeze-images .videoStillImage{position:absolute;z-index:1;top:0;left:0;width:100%;height:100%;object-fit:cover}.freeze-images .progress-status{position:absolute;top:50%;left:50%;z-index:1;display:flex;flex-direction:column;justify-content:center;align-items:center;width:auto;height:auto;margin:0;padding:10px;background-color:#ffffffb3;border:1px solid grey;transform:translate(-50%,-50%)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3891
4073
|
}
|
|
3892
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
4074
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: FreezeFrameComponent, decorators: [{
|
|
3893
4075
|
type: Component,
|
|
3894
4076
|
args: [{ selector: 'app-freeze-frame', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"freeze-images\">\n @if (combinedFreeze()) {\n <img\n [src]=\"combinedFreeze()\"\n class=\"videoStillImage\"\n alt=\"freezeFrameImage\"\n />\n }\n\n @if (freezeFrameProgressMessageFromVideo()) {\n <div class=\"progress-status\">\n {{ freezeFrameProgressMessageFromVideo() }}\n </div>\n }\n</div>\n", styles: [".freeze-images{pointer-events:none;position:absolute;left:0;top:0;width:100%;height:100%;z-index:1}.freeze-images .freezeFrameOverlay{top:0;left:0;width:100%;height:100%;position:absolute;object-fit:cover;object-position:center}.freeze-images .videoStillImage{position:absolute;z-index:1;top:0;left:0;width:100%;height:100%;object-fit:cover}.freeze-images .progress-status{position:absolute;top:50%;left:50%;z-index:1;display:flex;flex-direction:column;justify-content:center;align-items:center;width:auto;height:auto;margin:0;padding:10px;background-color:#ffffffb3;border:1px solid grey;transform:translate(-50%,-50%)}\n"] }]
|
|
3895
4077
|
}] });
|
|
@@ -3917,10 +4099,10 @@ class SafePipe {
|
|
|
3917
4099
|
throw new Error(`Invalid safe type specified: ${type}`);
|
|
3918
4100
|
}
|
|
3919
4101
|
}
|
|
3920
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
3921
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.2.
|
|
4102
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: SafePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
4103
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.2.2", ngImport: i0, type: SafePipe, isStandalone: true, name: "safe" }); }
|
|
3922
4104
|
}
|
|
3923
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
4105
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: SafePipe, decorators: [{
|
|
3924
4106
|
type: Pipe,
|
|
3925
4107
|
args: [{
|
|
3926
4108
|
name: 'safe',
|
|
@@ -3934,10 +4116,10 @@ class LowBandwidthModalComponent {
|
|
|
3934
4116
|
close(value) {
|
|
3935
4117
|
this.dialogRef.close(value || false);
|
|
3936
4118
|
}
|
|
3937
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
3938
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.
|
|
4119
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: LowBandwidthModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4120
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.2", type: LowBandwidthModalComponent, isStandalone: true, selector: "app-low-bandwidth-modal", ngImport: i0, template: "<div [attr.data-testid]=\"'low-bandwidth'\" class=\"src-modal src-modal--lbm\">\n <header class=\"src-modal__header\">\n <h6 [attr.data-testid]=\"'title'\" class=\"src-modal__title\">\n Unstable Connection\n </h6>\n </header>\n <section class=\"src-modal__body\">\n <div\n [innerHtml]=\"\n 'Fluid Interactivity Modes were disabled due to an unstable connection. Showcase Gallery Mode is enabled. To regain full functionality, switch to Interactive Mode.'\n | safe: 'html'\n \"\n class=\"src-modal__scroll-box\"\n ></div>\n </section>\n <footer class=\"src-modal__footer\">\n <div class=\"src-modal__buttons\">\n <src-button\n (onClick)=\"close(true)\"\n [data-testid]=\"'switch-to-interactive-mode'\"\n >\n Switch\n </src-button>\n\n <src-button\n (onClick)=\"close()\"\n [data-testid]=\"'close-lbm-modal'\"\n colorScheme=\"primary\"\n >\n Ok\n </src-button>\n </div>\n </footer>\n</div>\n", styles: [".src-modal--lbm{width:360px}.src-modal--lbm .src-modal__body{font-size:14px;line-height:24px}.src-modal--lbm .src-modal__buttons{display:flex;gap:8px}\n"], dependencies: [{ kind: "component", type: SourceButtonComponent, selector: "src-button", inputs: ["type", "appearance", "colorScheme", "size", "state", "customClass", "hasDisclosure", "isFullWidth", "isPressed", "isDisabled", "isLoading", "iconButton", "srcButtonConfig", "formID", "data-testid"], outputs: ["onClick", "onSubmit"] }, { kind: "pipe", type: SafePipe, name: "safe" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3939
4121
|
}
|
|
3940
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
4122
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: LowBandwidthModalComponent, decorators: [{
|
|
3941
4123
|
type: Component,
|
|
3942
4124
|
args: [{ selector: 'app-low-bandwidth-modal', changeDetection: ChangeDetectionStrategy.OnPush, imports: [SourceIconButtonComponent, SafePipe, SourceButtonComponent], template: "<div [attr.data-testid]=\"'low-bandwidth'\" class=\"src-modal src-modal--lbm\">\n <header class=\"src-modal__header\">\n <h6 [attr.data-testid]=\"'title'\" class=\"src-modal__title\">\n Unstable Connection\n </h6>\n </header>\n <section class=\"src-modal__body\">\n <div\n [innerHtml]=\"\n 'Fluid Interactivity Modes were disabled due to an unstable connection. Showcase Gallery Mode is enabled. To regain full functionality, switch to Interactive Mode.'\n | safe: 'html'\n \"\n class=\"src-modal__scroll-box\"\n ></div>\n </section>\n <footer class=\"src-modal__footer\">\n <div class=\"src-modal__buttons\">\n <src-button\n (onClick)=\"close(true)\"\n [data-testid]=\"'switch-to-interactive-mode'\"\n >\n Switch\n </src-button>\n\n <src-button\n (onClick)=\"close()\"\n [data-testid]=\"'close-lbm-modal'\"\n colorScheme=\"primary\"\n >\n Ok\n </src-button>\n </div>\n </footer>\n</div>\n", styles: [".src-modal--lbm{width:360px}.src-modal--lbm .src-modal__body{font-size:14px;line-height:24px}.src-modal--lbm .src-modal__buttons{display:flex;gap:8px}\n"] }]
|
|
3943
4125
|
}] });
|
|
@@ -3947,10 +4129,10 @@ class AfkRestartScreenLockerComponent {
|
|
|
3947
4129
|
this.store = inject(Store);
|
|
3948
4130
|
this.videoService = inject(VideoService);
|
|
3949
4131
|
this.destroyRef = inject(DestroyRef);
|
|
3950
|
-
this.showReconnectPopup =
|
|
3951
|
-
this.
|
|
3952
|
-
this.imageLoadingSrc =
|
|
3953
|
-
this.streamConfig =
|
|
4132
|
+
this.showReconnectPopup = this.store.selectSignal(selectShowReconnectPopup);
|
|
4133
|
+
this.isLoaderScreenVisible = this.store.selectSignal(isLoaderScreenVisible);
|
|
4134
|
+
this.imageLoadingSrc = this.store.selectSignal(unrealFeature.selectImageLoadingSrc);
|
|
4135
|
+
this.streamConfig = this.store.selectSignal(selectStreamConfig);
|
|
3954
4136
|
this.isSecondStart = signal(!!(this.streamConfig()?.autoStart && location.href.match(/^https/gi)), ...(ngDevMode ? [{ debugName: "isSecondStart" }] : []));
|
|
3955
4137
|
this.playCallBack = null;
|
|
3956
4138
|
}
|
|
@@ -3972,18 +4154,18 @@ class AfkRestartScreenLockerComponent {
|
|
|
3972
4154
|
});
|
|
3973
4155
|
}
|
|
3974
4156
|
connect() {
|
|
3975
|
-
this.store.dispatch(
|
|
4157
|
+
this.store.dispatch(startStream({ config: { autoStart: true } }));
|
|
3976
4158
|
}
|
|
3977
4159
|
onDisconnect() {
|
|
3978
4160
|
this.isSecondStart.set(true);
|
|
3979
4161
|
this.playCallBack = null;
|
|
3980
4162
|
}
|
|
3981
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
3982
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.
|
|
4163
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: AfkRestartScreenLockerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4164
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.2", type: AfkRestartScreenLockerComponent, isStandalone: true, selector: "app-afk-restart-screen-locker", ngImport: i0, template: "@if (isLoaderScreenVisible()) {\n <div class=\"preload\">\n <div class=\"back\">\n @if (imageLoadingSrc()) {\n <img\n [ngSrc]=\"imageLoadingSrc()!\"\n fill\n loading=\"lazy\"\n alt=\"image loading src\"\n />\n }\n </div>\n\n @if (showReconnectPopup()) {\n <div class=\"stream-message-wrapper\">\n <div class=\"resume-box\">\n @if (isSecondStart()) {\n <div class=\"resume-box__text\">\n Your stream has been paused due to inactivity\n </div>\n }\n\n <src-button\n (onClick)=\"connect()\"\n [isFullWidth]=\"true\"\n [size]=\"'large'\"\n [colorScheme]=\"'primary'\"\n [data-testid]=\"'connect-button'\"\n class=\"connect-button\"\n >\n {{ isSecondStart() ? 'Resume' : 'Start' }}\n </src-button>\n </div>\n </div>\n }\n </div>\n}\n", styles: [".preload{position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}.preload .back{position:absolute;top:0;left:0;display:flex;justify-content:center;align-items:center;width:100%;height:100%;background-color:#fff}.preload .back img{width:100%;height:100%;object-fit:cover}.preload .stream-message-wrapper{position:absolute;top:0;left:0;width:100%;height:100%;background-color:transparent;z-index:3;display:flex;align-items:center;justify-content:center}.resume-box{padding:16px;position:absolute;bottom:0;left:50%;gap:12px;display:flex;transform:translate(-50%,-50%);flex-direction:column;align-items:center;border-radius:var(--src-border-rounded-parent, 8px);background:var(--src-color-bg-default, #fff);box-shadow:0 26px 80px #0003,0 0 1px #0003}.resume-box .connect-button{width:100%}.resume-box__text{color:var(--src-color-gray-500, #6b7280);text-align:center;font-family:var(--src-font-family-body);font-size:14px;font-style:normal;font-weight:400;line-height:24px}.preload .message-loader{position:absolute;bottom:20px;left:50%;display:block;margin:auto;transform:translate(-50%)}.preload .message-loader>p{margin:0;line-height:1;transition:all ease .35s}.preload .message-loader>p span{font-size:10px;transition:all ease .35s}@media (min-width: 1900px){.preload .message-loader{bottom:40px}}\n"], dependencies: [{ kind: "directive", type: NgOptimizedImage, selector: "img[ngSrc]", inputs: ["ngSrc", "ngSrcset", "sizes", "width", "height", "decoding", "loading", "priority", "loaderParams", "disableOptimizedSrcset", "fill", "placeholder", "placeholderConfig", "src", "srcset"] }, { kind: "component", type: SourceButtonComponent, selector: "src-button", inputs: ["type", "appearance", "colorScheme", "size", "state", "customClass", "hasDisclosure", "isFullWidth", "isPressed", "isDisabled", "isLoading", "iconButton", "srcButtonConfig", "formID", "data-testid"], outputs: ["onClick", "onSubmit"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3983
4165
|
}
|
|
3984
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
4166
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: AfkRestartScreenLockerComponent, decorators: [{
|
|
3985
4167
|
type: Component,
|
|
3986
|
-
args: [{ selector: 'app-afk-restart-screen-locker', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgOptimizedImage, SourceButtonComponent, SourceButtonComponent], template: "@if (
|
|
4168
|
+
args: [{ selector: 'app-afk-restart-screen-locker', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgOptimizedImage, SourceButtonComponent, SourceButtonComponent], template: "@if (isLoaderScreenVisible()) {\n <div class=\"preload\">\n <div class=\"back\">\n @if (imageLoadingSrc()) {\n <img\n [ngSrc]=\"imageLoadingSrc()!\"\n fill\n loading=\"lazy\"\n alt=\"image loading src\"\n />\n }\n </div>\n\n @if (showReconnectPopup()) {\n <div class=\"stream-message-wrapper\">\n <div class=\"resume-box\">\n @if (isSecondStart()) {\n <div class=\"resume-box__text\">\n Your stream has been paused due to inactivity\n </div>\n }\n\n <src-button\n (onClick)=\"connect()\"\n [isFullWidth]=\"true\"\n [size]=\"'large'\"\n [colorScheme]=\"'primary'\"\n [data-testid]=\"'connect-button'\"\n class=\"connect-button\"\n >\n {{ isSecondStart() ? 'Resume' : 'Start' }}\n </src-button>\n </div>\n </div>\n }\n </div>\n}\n", styles: [".preload{position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}.preload .back{position:absolute;top:0;left:0;display:flex;justify-content:center;align-items:center;width:100%;height:100%;background-color:#fff}.preload .back img{width:100%;height:100%;object-fit:cover}.preload .stream-message-wrapper{position:absolute;top:0;left:0;width:100%;height:100%;background-color:transparent;z-index:3;display:flex;align-items:center;justify-content:center}.resume-box{padding:16px;position:absolute;bottom:0;left:50%;gap:12px;display:flex;transform:translate(-50%,-50%);flex-direction:column;align-items:center;border-radius:var(--src-border-rounded-parent, 8px);background:var(--src-color-bg-default, #fff);box-shadow:0 26px 80px #0003,0 0 1px #0003}.resume-box .connect-button{width:100%}.resume-box__text{color:var(--src-color-gray-500, #6b7280);text-align:center;font-family:var(--src-font-family-body);font-size:14px;font-style:normal;font-weight:400;line-height:24px}.preload .message-loader{position:absolute;bottom:20px;left:50%;display:block;margin:auto;transform:translate(-50%)}.preload .message-loader>p{margin:0;line-height:1;transition:all ease .35s}.preload .message-loader>p span{font-size:10px;transition:all ease .35s}@media (min-width: 1900px){.preload .message-loader{bottom:40px}}\n"] }]
|
|
3987
4169
|
}] });
|
|
3988
4170
|
|
|
3989
4171
|
class StatGraphComponent {
|
|
@@ -4048,10 +4230,10 @@ class StatGraphComponent {
|
|
|
4048
4230
|
}
|
|
4049
4231
|
this.draw();
|
|
4050
4232
|
}
|
|
4051
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
4052
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.
|
|
4233
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: StatGraphComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4234
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.2", type: StatGraphComponent, isStandalone: true, selector: "app-stat-graph", inputs: { color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, tickStep: { classPropertyName: "tickStep", publicName: "tickStep", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, dataTick: { classPropertyName: "dataTick", publicName: "dataTick", isSignal: false, isRequired: false, transformFunction: null } }, host: { listeners: { "window:resize": "resize($event)" } }, viewQueries: [{ propertyName: "graph", first: true, predicate: ["graph"], descendants: true }], ngImport: i0, template: "<div class=\"content\">\n <p>{{ label() }}: {{ current }} | Min:{{ min }} | Max:{{ max }}</p>\n <canvas #graph class=\"graph\"></canvas>\n</div>\n", styles: [".content{width:100%;height:100%}.content p{color:#fff;margin:5px 0 0;height:25px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4053
4235
|
}
|
|
4054
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
4236
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: StatGraphComponent, decorators: [{
|
|
4055
4237
|
type: Component,
|
|
4056
4238
|
args: [{ selector: 'app-stat-graph', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"content\">\n <p>{{ label() }}: {{ current }} | Min:{{ min }} | Max:{{ max }}</p>\n <canvas #graph class=\"graph\"></canvas>\n</div>\n", styles: [".content{width:100%;height:100%}.content p{color:#fff;margin:5px 0 0;height:25px}\n"] }]
|
|
4057
4239
|
}], propDecorators: { graph: [{
|
|
@@ -4176,29 +4358,28 @@ class VideoStatsComponent {
|
|
|
4176
4358
|
elements: this.elementsToShow,
|
|
4177
4359
|
}));
|
|
4178
4360
|
}
|
|
4179
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
4180
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.
|
|
4361
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: VideoStatsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4362
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.2", type: VideoStatsComponent, isStandalone: true, selector: "app-video-stats", ngImport: i0, template: "@if (videoStatus()) {\n @if (viewportReady()) {\n <div class=\"settings-container\">\n <button (click)=\"toggle()\" class=\"gear-button\">Stats</button>\n <div (click)=\"toggle()\" [class.min]=\"collapsed\" id=\"aggregatedStats\">\n <div class=\"forNerds\">\n <div (click)=\"$event.stopPropagation()\" class=\"static\">\n <li>\n <app-stat-graph\n [dataTick]=\"fpsTick()\"\n label=\"FPS (higher is better)\"\n />\n </li>\n <li>\n <app-stat-graph\n [dataTick]=\"videoQP()\"\n label=\"QP (lower is better)\"\n color=\"#D5ff07\"\n />\n </li>\n <li>\n <app-stat-graph\n [dataTick]=\"bitrateTick()\"\n label=\"Bitrate\"\n color=\"#D57F07\"\n />\n </li>\n </div>\n <div>\n @for (graph of graphList$ | async; track graph) {\n <li (click)=\"toggleGraph($event, graph.key, 0)\" class=\"graph\">\n <app-stat-graph\n [label]=\"graph.key\"\n [dataTick]=\"graph.stat | async\"\n [color]=\"graph.color\"\n />\n </li>\n }\n </div>\n </div>\n\n @for (el of videoStatus(); track el.key + $index) {\n <div (click)=\"toggleGraph($event, el.key, el.value)\" class=\"stat\">\n <span>{{ el.key }}: </span>{{ el.value | json }}\n </div>\n }\n </div>\n </div>\n @if (!collapsed) {\n <div [innerHTML]=\"ssInfo() | safe: 'html'\" class=\"ssInfo\"></div>\n }\n }\n}\n", styles: [".settings-container{position:absolute;top:65px;left:10px;z-index:1000;bottom:10px}.gear-button{left:0;width:50px;position:absolute;background:none;cursor:pointer;font-size:10px;font-weight:500;border:1px solid;border-radius:9px;background:#0162cc;color:#fff;padding:4px}.gear-button>*{color:#fff;filter:drop-shadow(1px 1px 1px rgb(0,0,0))}#aggregatedStats{max-height:calc(100% - 25px);overflow-y:auto;margin-top:25px;left:20px;z-index:31;max-width:400px;padding:10px;background-color:#fff3;border:1px solid grey}#aggregatedStats>*{color:#fff;text-shadow:-1px -1px 0 #000,1px -1px 0 #000,-1px 1px 0 #000,1px 1px 0 #000}#aggregatedStats:empty{display:none}#aggregatedStats button{position:absolute;right:5px;top:5px}#aggregatedStats.min{display:none}#aggregatedStats .forNerds{width:100%}#aggregatedStats .forNerds li{list-style-type:none;height:60px}#aggregatedStats .forNerds li app-stat-graph{display:block;width:100%;height:100%}#aggregatedStats .stat{cursor:pointer}#aggregatedStats .stat span{font-weight:700}#aggregatedStats .graph{cursor:pointer}#aggregatedStats .static{pointer-events:all}.ssInfo{position:absolute;top:0;left:50%;transform:translate(-50%);color:#fff;text-shadow:-1px -1px 0 #000,1px -1px 0 #000,-1px 1px 0 #000,1px 1px 0 #000;text-align:center;width:80%;pointer-events:none}\n"], dependencies: [{ kind: "component", type: StatGraphComponent, selector: "app-stat-graph", inputs: ["color", "tickStep", "label", "dataTick"] }, { kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "pipe", type: SafePipe, name: "safe" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4181
4363
|
}
|
|
4182
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
4364
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: VideoStatsComponent, decorators: [{
|
|
4183
4365
|
type: Component,
|
|
4184
4366
|
args: [{ selector: 'app-video-stats', changeDetection: ChangeDetectionStrategy.OnPush, imports: [StatGraphComponent, AsyncPipe, JsonPipe, SafePipe], template: "@if (videoStatus()) {\n @if (viewportReady()) {\n <div class=\"settings-container\">\n <button (click)=\"toggle()\" class=\"gear-button\">Stats</button>\n <div (click)=\"toggle()\" [class.min]=\"collapsed\" id=\"aggregatedStats\">\n <div class=\"forNerds\">\n <div (click)=\"$event.stopPropagation()\" class=\"static\">\n <li>\n <app-stat-graph\n [dataTick]=\"fpsTick()\"\n label=\"FPS (higher is better)\"\n />\n </li>\n <li>\n <app-stat-graph\n [dataTick]=\"videoQP()\"\n label=\"QP (lower is better)\"\n color=\"#D5ff07\"\n />\n </li>\n <li>\n <app-stat-graph\n [dataTick]=\"bitrateTick()\"\n label=\"Bitrate\"\n color=\"#D57F07\"\n />\n </li>\n </div>\n <div>\n @for (graph of graphList$ | async; track graph) {\n <li (click)=\"toggleGraph($event, graph.key, 0)\" class=\"graph\">\n <app-stat-graph\n [label]=\"graph.key\"\n [dataTick]=\"graph.stat | async\"\n [color]=\"graph.color\"\n />\n </li>\n }\n </div>\n </div>\n\n @for (el of videoStatus(); track el.key + $index) {\n <div (click)=\"toggleGraph($event, el.key, el.value)\" class=\"stat\">\n <span>{{ el.key }}: </span>{{ el.value | json }}\n </div>\n }\n </div>\n </div>\n @if (!collapsed) {\n <div [innerHTML]=\"ssInfo() | safe: 'html'\" class=\"ssInfo\"></div>\n }\n }\n}\n", styles: [".settings-container{position:absolute;top:65px;left:10px;z-index:1000;bottom:10px}.gear-button{left:0;width:50px;position:absolute;background:none;cursor:pointer;font-size:10px;font-weight:500;border:1px solid;border-radius:9px;background:#0162cc;color:#fff;padding:4px}.gear-button>*{color:#fff;filter:drop-shadow(1px 1px 1px rgb(0,0,0))}#aggregatedStats{max-height:calc(100% - 25px);overflow-y:auto;margin-top:25px;left:20px;z-index:31;max-width:400px;padding:10px;background-color:#fff3;border:1px solid grey}#aggregatedStats>*{color:#fff;text-shadow:-1px -1px 0 #000,1px -1px 0 #000,-1px 1px 0 #000,1px 1px 0 #000}#aggregatedStats:empty{display:none}#aggregatedStats button{position:absolute;right:5px;top:5px}#aggregatedStats.min{display:none}#aggregatedStats .forNerds{width:100%}#aggregatedStats .forNerds li{list-style-type:none;height:60px}#aggregatedStats .forNerds li app-stat-graph{display:block;width:100%;height:100%}#aggregatedStats .stat{cursor:pointer}#aggregatedStats .stat span{font-weight:700}#aggregatedStats .graph{cursor:pointer}#aggregatedStats .static{pointer-events:all}.ssInfo{position:absolute;top:0;left:50%;transform:translate(-50%);color:#fff;text-shadow:-1px -1px 0 #000,1px -1px 0 #000,-1px 1px 0 #000,1px 1px 0 #000;text-align:center;width:80%;pointer-events:none}\n"] }]
|
|
4185
4367
|
}], ctorParameters: () => [] });
|
|
4186
4368
|
|
|
4187
4369
|
class UnrealStatusComponent {
|
|
4188
4370
|
constructor() {
|
|
4189
|
-
this.store = inject(Store);
|
|
4190
|
-
this.unrealInitialConfig = inject(UNREAL_CONFIG, {
|
|
4191
|
-
optional: true,
|
|
4192
|
-
});
|
|
4193
|
-
this.resetLoaderTrigger$ = this.store
|
|
4194
|
-
.select(unrealFeature.selectCirrusConnected)
|
|
4195
|
-
.pipe(filter(Falsy));
|
|
4196
4371
|
this.isDevMode = inject(DevModeService).isDevMode;
|
|
4372
|
+
this.unrealInitialConfig = inject(UNREAL_CONFIG);
|
|
4197
4373
|
this.destroyRef = inject(DestroyRef);
|
|
4374
|
+
this.store = inject(Store);
|
|
4375
|
+
this.resetPercentageSignal$ = this.store
|
|
4376
|
+
.select(selectShowLoader)
|
|
4377
|
+
.pipe(filter(Falsy));
|
|
4378
|
+
this.showLoader = this.store.selectSignal(selectShowLoader);
|
|
4198
4379
|
/**
|
|
4199
4380
|
* An observable that emits smoothed percentage values from 0 to 100.
|
|
4200
4381
|
*/
|
|
4201
|
-
this.messagePercents
|
|
4382
|
+
this.messagePercents = toSignal(this.store.select(selectTotalProgress).pipe(clampAndKeepMaxPercents(this.resetPercentageSignal$), floatToSmoothPercents(), distinctUntilChanged(), map$1((progress) => progress || 0)));
|
|
4202
4383
|
}
|
|
4203
4384
|
ngOnInit() {
|
|
4204
4385
|
/**
|
|
@@ -4236,7 +4417,7 @@ class UnrealStatusComponent {
|
|
|
4236
4417
|
* A subscription that merges various status observables and emits debounced status via postMessage.
|
|
4237
4418
|
*/
|
|
4238
4419
|
merge(nullifyObs$, cirrusConnected$, signalingStatus$, streamToggle$)
|
|
4239
|
-
.pipe(debounceTime(0), tapLog('STATUS'), takeUntilDestroyed(this.destroyRef))
|
|
4420
|
+
.pipe(debounceTime(0), tapLog('STATUS=>'), takeUntilDestroyed(this.destroyRef))
|
|
4240
4421
|
.subscribe((status) => this.sendMessageToIndex(status));
|
|
4241
4422
|
}
|
|
4242
4423
|
/**
|
|
@@ -4258,12 +4439,12 @@ class UnrealStatusComponent {
|
|
|
4258
4439
|
// Fails silently if the iframe's content window cannot be accessed
|
|
4259
4440
|
}
|
|
4260
4441
|
}
|
|
4261
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
4262
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.
|
|
4442
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: UnrealStatusComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4443
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.2", type: UnrealStatusComponent, isStandalone: true, selector: "app-unreal-status", ngImport: i0, template: "@if (showLoader()) {\n <div class=\"status-box\">\n <div class=\"status-box__message\">\n <src-loading\n [size]=\"30\"\n [backgroundStrokeColor]=\"'#E5E7EB'\"\n [progressStrokeColor]=\"'#1F2937'\"\n />\n {{ messagePercents() }}%\n </div>\n </div>\n}\n\n@if (isDevMode) {\n <app-video-stats />\n}\n", styles: ["app-stat-graph{height:30px;width:100%}.status-box{position:absolute;top:80%;left:50%;transform:translate(-50%,-50%);z-index:101;display:flex;justify-content:center;align-items:center;width:auto;max-width:500px;margin:0;background:var(--src-color-bg-default);border:none;border-radius:var(--src-border-rounded-full, 9999px);box-shadow:0 8px 20px #1718181f,0 3px 6px #17181814;pointer-events:none}.status-box__message{display:flex;align-items:center;padding:12px 20px 12px 16px;color:var(--src-color-text-default, #1f2937);font-size:16px;font-weight:400;line-height:24px}.status-box__message .status-box__message_text{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}.status-box__message src-loading{margin-right:12px}\n"], dependencies: [{ kind: "component", type: VideoStatsComponent, selector: "app-video-stats" }, { kind: "component", type: SourceLoadingComponent, selector: "src-loading", inputs: ["size", "progress", "lineCap", "backgroundStrokeColor", "progressStrokeColor", "strokeWidth", "data-testid"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4263
4444
|
}
|
|
4264
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
4445
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: UnrealStatusComponent, decorators: [{
|
|
4265
4446
|
type: Component,
|
|
4266
|
-
args: [{ selector: 'app-unreal-status', changeDetection: ChangeDetectionStrategy.OnPush, imports: [VideoStatsComponent, SourceLoadingComponent], template: "@if (
|
|
4447
|
+
args: [{ selector: 'app-unreal-status', changeDetection: ChangeDetectionStrategy.OnPush, imports: [VideoStatsComponent, SourceLoadingComponent], template: "@if (showLoader()) {\n <div class=\"status-box\">\n <div class=\"status-box__message\">\n <src-loading\n [size]=\"30\"\n [backgroundStrokeColor]=\"'#E5E7EB'\"\n [progressStrokeColor]=\"'#1F2937'\"\n />\n {{ messagePercents() }}%\n </div>\n </div>\n}\n\n@if (isDevMode) {\n <app-video-stats />\n}\n", styles: ["app-stat-graph{height:30px;width:100%}.status-box{position:absolute;top:80%;left:50%;transform:translate(-50%,-50%);z-index:101;display:flex;justify-content:center;align-items:center;width:auto;max-width:500px;margin:0;background:var(--src-color-bg-default);border:none;border-radius:var(--src-border-rounded-full, 9999px);box-shadow:0 8px 20px #1718181f,0 3px 6px #17181814;pointer-events:none}.status-box__message{display:flex;align-items:center;padding:12px 20px 12px 16px;color:var(--src-color-text-default, #1f2937);font-size:16px;font-weight:400;line-height:24px}.status-box__message .status-box__message_text{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}.status-box__message src-loading{margin-right:12px}\n"] }]
|
|
4267
4448
|
}] });
|
|
4268
4449
|
|
|
4269
4450
|
class UnrealSceneComponent {
|
|
@@ -4351,8 +4532,7 @@ class UnrealSceneComponent {
|
|
|
4351
4532
|
}
|
|
4352
4533
|
ngOnDestroy() {
|
|
4353
4534
|
this.commandsSender.destroy();
|
|
4354
|
-
this.store.dispatch(
|
|
4355
|
-
this.store.dispatch(resetUnrealStateAction());
|
|
4535
|
+
this.store.dispatch(destroyUnrealScene());
|
|
4356
4536
|
}
|
|
4357
4537
|
adaptVideo(size) {
|
|
4358
4538
|
const video = this.videoService.video;
|
|
@@ -4447,10 +4627,10 @@ class UnrealSceneComponent {
|
|
|
4447
4627
|
makeEven(value) {
|
|
4448
4628
|
return Math.floor((value + 1) / 2) * 2;
|
|
4449
4629
|
}
|
|
4450
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
4451
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.1", type: UnrealSceneComponent, isStandalone: true, selector: "app-unreal-scene", inputs: { isStudio: { classPropertyName: "isStudio", publicName: "isStudio", isSignal: true, isRequired: false, transformFunction: null }, useContainerAsSizeProvider: { classPropertyName: "useContainerAsSizeProvider", publicName: "useContainerAsSizeProvider", isSignal: true, isRequired: false, transformFunction: null }, studioResolutionSize: { classPropertyName: "studioResolutionSize", publicName: "studioResolutionSize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { changeMouseOverScene: "changeMouseOverScene" }, host: { listeners: { "mouseover": "onMouseOver()", "mouseout": "onMouseOut()" } }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], ngImport: i0, template: "<div class=\"frame unreal-container\">\n <div #container [class.lightModeCursor]=\"lightMode()\" id=\"player\"></div>\n\n <app-unreal-status />\n <app-freeze-frame />\n <app-clickable-overlay />\n <app-afk-restart-screen-locker />\n\n <ng-content select=\"app-video-locker\"></ng-content>\n <ng-content select=\"app-pdf\"></ng-content>\n <ng-content select=\"app-show-case\"></ng-content>\n <ng-content select=\"app-low-bandwidth-detector\"></ng-content>\n</div>\n", styles: ["#player{position:absolute;width:100%;height:100%;display:flex;justify-content:center;align-items:center;overflow:hidden}.unreal-container{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#fff}.unreal-container.select{cursor:url('data:image/svg+xml,<svg width=\"24\" height=\"24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M15.15 21.375a1.423 1.423 0 0 1-1.15.063 1.487 1.487 0 0 1-.85-.788l-3-6.45-2.325 3.25c-.283.4-.658.525-1.125.375-.467-.15-.7-.466-.7-.95V4.05c0-.417.188-.717.563-.9.375-.183.729-.142 1.062.125l10.1 7.95c.383.284.496.65.337 1.1-.158.45-.479.675-.962.675h-4.2l2.975 6.375c.183.384.204.767.063 1.15a1.487 1.487 0 0 1-.788.85Z\" fill=\"%23000\"/><path d=\"m12.697 20.861.002.005c.237.495.617.852 1.128 1.04.515.191 1.039.16 1.539-.08a1.987 1.987 0 0 0 1.04-1.128 1.922 1.922 0 0 0-.079-1.536v-.003L13.684 13.5H17.1c.32 0 .628-.075.89-.26.263-.184.438-.447.544-.749.106-.3.135-.617.04-.925a1.458 1.458 0 0 0-.545-.738L7.936 2.883a1.51 1.51 0 0 0-.768-.336 1.471 1.471 0 0 0-.825.154 1.495 1.495 0 0 0-.626.547 1.492 1.492 0 0 0-.217.802v12.825c0 .324.08.634.272.897.193.261.467.43.775.53.31.099.632.12.942.016.31-.103.555-.313.743-.578h.001l1.825-2.552 2.639 5.673Z\" stroke=\"%23fff\" stroke-opacity=\".7\"/></svg>') 6 2,auto}.unreal-container.orbit{cursor:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\"><path fill=\"%23000\" d=\"M11.998 21.6c-1.966 0-3.737-.53-5.312-1.588-1.575-1.058-2.738-2.437-3.488-4.137a.852.852 0 0 1 .013-.713.867.867 0 0 1 .512-.487.86.86 0 0 1 .688.037c.225.109.387.28.487.513.617 1.35 1.559 2.45 2.825 3.3 1.267.85 2.692 1.275 4.275 1.275 1.384 0 2.646-.33 3.788-.988a7.985 7.985 0 0 0 2.762-2.612h-.85a.873.873 0 0 1-.64-.257.863.863 0 0 1-.26-.638.88.88 0 0 1 .26-.643.864.864 0 0 1 .64-.262h3c.255 0 .47.086.642.259a.87.87 0 0 1 .258.64v3a.874.874 0 0 1-.257.642.863.863 0 0 1-.637.259.88.88 0 0 1-.643-.259.865.865 0 0 1-.263-.641v-.725a9.95 9.95 0 0 1-3.35 2.925c-1.35.733-2.833 1.1-4.45 1.1Zm0-17.4c-1.383 0-2.645.33-3.787.987A7.985 7.985 0 0 0 5.448 7.8h.85c.255 0 .47.086.642.257a.863.863 0 0 1 .258.638.88.88 0 0 1-.258.642.864.864 0 0 1-.642.263h-3a.87.87 0 0 1-.64-.259.87.87 0 0 1-.26-.641v-3c0-.255.086-.469.258-.641a.863.863 0 0 1 .637-.26.88.88 0 0 1 .643.26.864.864 0 0 1 .262.64v.726A9.95 9.95 0 0 1 7.548 3.5c1.35-.733 2.834-1.1 4.45-1.1 2 0 3.788.542 5.363 1.625 1.575 1.083 2.736 2.49 3.482 4.22a.724.724 0 0 1-.045.646.926.926 0 0 1-.525.437.87.87 0 0 1-.687-.04.977.977 0 0 1-.488-.513c-.616-1.35-1.558-2.45-2.825-3.3-1.266-.85-2.691-1.275-4.275-1.275Zm0 10.8a2.893 2.893 0 0 1-2.125-.875A2.893 2.893 0 0 1 8.998 12c0-.833.292-1.542.875-2.125A2.893 2.893 0 0 1 11.998 9c.834 0 1.542.292 2.125.875.584.583.875 1.292.875 2.125s-.291 1.542-.875 2.125a2.893 2.893 0 0 1-2.125.875Z\"/><path stroke=\"%23fff\" stroke-opacity=\".7\" d=\"m2.739 16.072.002.005c.789 1.788 2.014 3.24 3.666 4.35 1.66 1.116 3.53 1.673 5.591 1.673 1.696 0 3.262-.386 4.69-1.16a10.54 10.54 0 0 0 2.714-2.097c.069.167.171.32.308.454.272.268.613.403.994.403.38 0 .722-.135.992-.406s.402-.614.402-.994v-3c0-.381-.134-.724-.405-.995a1.37 1.37 0 0 0-.995-.405h-3c-.383 0-.727.137-.997.411a1.38 1.38 0 0 0-.403.994c0 .38.135.723.407.992.238.237.532.369.858.397a7.552 7.552 0 0 1-2.027 1.685c-1.062.613-2.237.92-3.538.92-1.488 0-2.815-.397-3.996-1.19-1.19-.798-2.07-1.826-2.647-3.087-.147-.34-.393-.6-.727-.76a1.36 1.36 0 0 0-1.073-.058c-.37.133-.64.397-.8.754a1.351 1.351 0 0 0-.016 1.114Zm4.553-8.37a1.36 1.36 0 0 0-.858-.396A7.552 7.552 0 0 1 8.46 5.62c1.062-.613 2.237-.921 3.537-.921 1.489 0 2.816.398 3.997 1.19 1.19.8 2.07 1.827 2.646 3.088.148.34.394.6.728.76a1.37 1.37 0 0 0 1.068.063c.347-.12.62-.346.799-.668.187-.338.215-.71.072-1.072l-.003-.007-.003-.007c-.784-1.818-2.006-3.298-3.658-4.434C15.982 2.47 14.094 1.9 11.998 1.9c-1.695 0-3.261.385-4.688 1.16a10.536 10.536 0 0 0-2.715 2.096 1.364 1.364 0 0 0-.308-.453 1.38 1.38 0 0 0-.994-.403c-.38 0-.722.135-.992.406s-.403.614-.403.994v3c0 .38.135.724.406.995.27.27.614.405.994.405h3c.384 0 .727-.137.998-.412a1.38 1.38 0 0 0 .402-.993c0-.38-.135-.723-.406-.992ZM9.52 14.48a3.393 3.393 0 0 0 2.478 1.02c.965 0 1.8-.342 2.479-1.02a3.392 3.392 0 0 0 1.021-2.48c0-.963-.343-1.8-1.021-2.478A3.392 3.392 0 0 0 11.998 8.5c-.964 0-1.8.343-2.478 1.021A3.392 3.392 0 0 0 8.498 12c0 .964.344 1.8 1.022 2.479Z\"/></svg>') 12 12,auto}.unreal-container.pan{cursor:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\"><path fill=\"%23000\" d=\"M11.997 10.075a1.01 1.01 0 0 1-.738-.313 1.008 1.008 0 0 1-.312-.737V6.15l-.95.95a.998.998 0 0 1-.763.312 1.09 1.09 0 0 1-.763-.337 1.06 1.06 0 0 1-.324-.775c0-.3.108-.558.324-.775l2.776-2.775c.117-.116.237-.2.362-.25a1.04 1.04 0 0 1 .775 0c.125.05.246.134.363.25l2.8 2.8c.216.217.32.47.313.762a1.096 1.096 0 0 1-.338.763 1.058 1.058 0 0 1-.775.325c-.3 0-.558-.108-.775-.325l-.925-.925v2.875c0 .283-.104.53-.312.737a1.01 1.01 0 0 1-.738.313Zm0 11.5a1.04 1.04 0 0 1-.388-.075 1.103 1.103 0 0 1-.362-.25l-2.8-2.8a1.002 1.002 0 0 1-.313-.762c.009-.292.121-.546.337-.763.217-.217.475-.325.775-.325.3 0 .559.108.775.325l.926.925v-2.875c0-.283.104-.529.312-.737a1.01 1.01 0 0 1 .738-.313c.283 0 .529.104.738.313.208.208.312.454.312.737v2.875l.95-.95a.998.998 0 0 1 .762-.312c.292.008.546.12.763.337.216.217.324.475.324.775 0 .3-.108.559-.324.775l-2.775 2.775c-.117.116-.238.2-.363.25a1.04 1.04 0 0 1-.387.075Zm4.925-6.05a1.058 1.058 0 0 1-.326-.774c0-.3.109-.559.326-.776l.925-.925H14.97c-.283 0-.528-.104-.736-.312a1.01 1.01 0 0 1-.313-.738c0-.283.104-.53.313-.738.208-.208.453-.312.737-.312h2.875l-.95-.95a.998.998 0 0 1-.313-.762 1.09 1.09 0 0 1 .338-.764 1.06 1.06 0 0 1 .775-.324c.3 0 .558.108.775.324l2.774 2.776c.117.117.2.238.251.363a1.04 1.04 0 0 1 0 .775c-.05.124-.134.245-.25.362l-2.8 2.8c-.217.216-.471.32-.762.313a1.096 1.096 0 0 1-.763-.337Zm-11.4 0L2.746 12.75a1.103 1.103 0 0 1-.25-.362 1.04 1.04 0 0 1 0-.775c.05-.125.133-.246.25-.363l2.8-2.8c.216-.216.47-.32.762-.313.292.01.546.121.763.337.217.217.325.476.325.776 0 .3-.108.558-.325.775l-.925.925h2.875c.283 0 .529.104.737.312.208.209.313.455.313.738s-.105.53-.313.738a1.008 1.008 0 0 1-.737.312H6.147l.95.95c.217.217.32.471.312.762a1.09 1.09 0 0 1-.337.764 1.06 1.06 0 0 1-.775.324c-.3 0-.559-.108-.776-.324Z\"/><path stroke=\"%23fff\" stroke-opacity=\".7\" d=\"M9.22 7.912c.436.013.821-.15 1.13-.458l.097-.097v1.668c0 .422.16.793.458 1.09.298.299.67.46 1.092.46.422 0 .793-.161 1.091-.46.298-.297.459-.668.459-1.09V7.357l.071.072c.309.308.693.471 1.13.471.435 0 .82-.163 1.128-.471.301-.303.47-.676.483-1.102v-.001a1.501 1.501 0 0 0-.46-1.13l-2.799-2.8a1.6 1.6 0 0 0-.528-.36l-.003-.001a1.54 1.54 0 0 0-1.145 0l-.002.001a1.6 1.6 0 0 0-.529.36L8.118 5.172l-.001.001a1.56 1.56 0 0 0-.47 1.128c0 .435.163.82.47 1.128.303.303.676.472 1.103.484Zm0 0 .014-.5-.015.5Zm-1.311 6.865a1.497 1.497 0 0 0-.458-1.13l-.097-.097h1.668c.421 0 .793-.16 1.09-.458.298-.299.46-.67.46-1.092a1.51 1.51 0 0 0-.46-1.091 1.507 1.507 0 0 0-1.09-.459H7.354l.071-.072c.309-.308.472-.692.472-1.128 0-.436-.163-.82-.472-1.13a1.596 1.596 0 0 0-1.101-.482h-.002a1.501 1.501 0 0 0-1.129.459l-2.8 2.8a1.6 1.6 0 0 0-.36.528l-.001.003a1.54 1.54 0 0 0 0 1.144v.003c.081.2.208.375.362.529l2.774 2.775c.309.308.693.47 1.129.47.435 0 .82-.162 1.128-.47.303-.302.472-.676.484-1.102Zm0 0-.5-.014.5.015v-.001Zm3.038-8.627-.5.5.5.207V6.15Zm.475 15.814.002.001a1.54 1.54 0 0 0 1.145 0h.002c.2-.081.375-.208.53-.362l2.775-2.774a1.56 1.56 0 0 0 .47-1.129c0-.435-.162-.82-.47-1.128a1.589 1.589 0 0 0-1.103-.484 1.497 1.497 0 0 0-1.13.458l-.096.097v-1.668c0-.421-.161-.793-.459-1.09a1.509 1.509 0 0 0-1.091-.46c-.422 0-.794.161-1.092.46a1.507 1.507 0 0 0-.458 1.09v1.668l-.072-.072a1.558 1.558 0 0 0-1.129-.471c-.436 0-.82.163-1.128.471l-.001.001c-.301.302-.47.675-.483 1.101v.001c-.012.437.151.821.46 1.13l2.8 2.8c.153.153.328.28.528.36Zm5.146-6.085c.303.302.676.47 1.102.484a1.5 1.5 0 0 0 1.13-.46l2.8-2.8a1.6 1.6 0 0 0 .36-.528l.002-.003a1.54 1.54 0 0 0 0-1.144l-.001-.003a1.6 1.6 0 0 0-.361-.529l-2.774-2.775h-.001a1.56 1.56 0 0 0-1.128-.47c-.436 0-.82.162-1.128.47h-.001a1.59 1.59 0 0 0-.484 1.102c-.012.437.15.822.459 1.13l.097.097h-1.668c-.422 0-.793.16-1.09.459-.299.298-.46.67-.46 1.091 0 .422.161.793.46 1.092.297.297.668.458 1.09.458h1.668l-.072.072a1.558 1.558 0 0 0-.472 1.129c0 .435.164.82.472 1.128ZM6.147 13.05l.5.5.207-.5h-.707Z\"/></svg>') 12 12,auto}.unreal-container.dolly{cursor:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\"><mask id=\"a\" width=\"24\" height=\"24\" x=\"0\" y=\"0\" maskUnits=\"userSpaceOnUse\" style=\"mask-type:alpha\"><path fill=\"%23127392\" d=\"M0 0h24v24H0z\"/></mask><g mask=\"url(%23a)\"><path fill=\"%23000\" d=\"M12.002 20.575a1.026 1.026 0 0 1-.75-.325l-2.55-2.55a.933.933 0 0 1-.287-.713c.008-.275.113-.513.313-.713.2-.2.441-.3.725-.3.283 0 .524.1.724.3l.776.776V6.95l-.8.8c-.2.2-.438.296-.712.288a1.018 1.018 0 0 1-.713-.312c-.2-.2-.3-.442-.3-.726s.1-.525.3-.725l2.524-2.525a1.026 1.026 0 0 1 1.5 0l2.55 2.55c.2.2.296.438.289.713a1.023 1.023 0 0 1-.314.713c-.2.2-.441.3-.724.3a.988.988 0 0 1-.725-.3l-.775-.776v10.1l.8-.8c.2-.2.437-.296.712-.288.275.008.512.112.712.312.2.2.3.442.3.726s-.1.525-.3.725l-2.524 2.525a1.026 1.026 0 0 1-.75.325Z\"/><path stroke=\"%23fff\" stroke-opacity=\".7\" d=\"M13.553 8.153c.28.245.62.373 1 .373.415 0 .784-.153 1.078-.447.287-.287.446-.644.46-1.05v-.002a1.432 1.432 0 0 0-.435-1.08l-2.55-2.55-.354.353.354-.354a1.526 1.526 0 0 0-2.207 0L8.374 5.921A1.487 1.487 0 0 0 7.928 7c0 .416.152.785.446 1.08.288.287.645.446 1.052.457l4.127-.384Zm0 0v7.693m0-7.693a1.667 1.667 0 0 1-.079-.074l-3.021.075v7.693a1.482 1.482 0 0 0-1-.373c-.416 0-.785.153-1.079.447a1.522 1.522 0 0 0-.46 1.05v.002c-.011.417.14.786.435 1.08l2.55 2.55a1.527 1.527 0 0 0 2.207 0l2.525-2.524c.294-.294.446-.663.446-1.079 0-.416-.152-.785-.446-1.08a1.518 1.518 0 0 0-1.052-.457m0 0-.014.5.014-.5Zm0 0a1.424 1.424 0 0 0-1.027.383m0 0a1.583 1.583 0 0 0-.053.05l.354.354m-.3-.404v.104l.3.3m0 0-.3-.3v.6l.3-.3Z\"/></g></svg>') 12 12,auto}.unreal-container.disabled:before{content:\"\";position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}#playerUI{position:absolute;z-index:10;width:100%}#statsContainer{display:none;text-align:left;background-color:#000c}#stats{padding:6px;font-weight:700;font-size:14px;color:#0f0}canvas{position:absolute;image-rendering:crisp-edges}#overlay{position:absolute;top:0;right:2%;z-index:100;padding:4px;border-top-width:0;-webkit-border-bottom-right-radius:5px;-moz-border-radius-bottomright:5px;border-bottom-right-radius:5px;-webkit-border-bottom-left-radius:5px;-moz-border-radius-bottomleft:5px;border-bottom-left-radius:5px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-touch-callout:none}.overlay{font-weight:lighter;font-family:var(--src-font-family-body)}#overlayButton:hover{cursor:pointer}#overlayButton{font-size:40px;text-align:right}#overlaySettings{display:none;width:300px;padding:4px}#videoMessageOverlay{position:absolute;z-index:20;width:100%;margin:auto;font-size:1.8em;font-family:var(--src-font-family-body)}#playButton{display:inline-block;height:auto}img#playButton{width:10%;max-width:241px}#UIInteraction{position:fixed}#UIInteractionButtonBoundary{padding:2px}#UIInteractionButton{cursor:pointer}#hiddenInput{position:absolute;left:-10%;width:0;opacity:0}#editTextButton{position:absolute;width:40px;height:40px}\n"], dependencies: [{ kind: "component", type: AfkRestartScreenLockerComponent, selector: "app-afk-restart-screen-locker" }, { kind: "component", type: ClickableOverlayComponent, selector: "app-clickable-overlay" }, { kind: "component", type: UnrealStatusComponent, selector: "app-unreal-status" }, { kind: "component", type: FreezeFrameComponent, selector: "app-freeze-frame" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4630
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: UnrealSceneComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4631
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.2.2", type: UnrealSceneComponent, isStandalone: true, selector: "app-unreal-scene", inputs: { isStudio: { classPropertyName: "isStudio", publicName: "isStudio", isSignal: true, isRequired: false, transformFunction: null }, useContainerAsSizeProvider: { classPropertyName: "useContainerAsSizeProvider", publicName: "useContainerAsSizeProvider", isSignal: true, isRequired: false, transformFunction: null }, studioResolutionSize: { classPropertyName: "studioResolutionSize", publicName: "studioResolutionSize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { changeMouseOverScene: "changeMouseOverScene" }, host: { listeners: { "mouseover": "onMouseOver()", "mouseout": "onMouseOut()" } }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], ngImport: i0, template: "<div class=\"frame unreal-container\">\n <div #container [class.lightModeCursor]=\"lightMode()\" id=\"player\"></div>\n\n <app-unreal-status />\n <app-freeze-frame />\n <app-clickable-overlay />\n <app-afk-restart-screen-locker />\n\n <ng-content select=\"app-video-locker\"></ng-content>\n <ng-content select=\"app-pdf\"></ng-content>\n <ng-content select=\"app-show-case\"></ng-content>\n <ng-content select=\"app-low-bandwidth-detector\"></ng-content>\n</div>\n", styles: ["#player{position:absolute;width:100%;height:100%;display:flex;justify-content:center;align-items:center;overflow:hidden}.unreal-container{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#fff}.unreal-container.select{cursor:url('data:image/svg+xml,<svg width=\"24\" height=\"24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M15.15 21.375a1.423 1.423 0 0 1-1.15.063 1.487 1.487 0 0 1-.85-.788l-3-6.45-2.325 3.25c-.283.4-.658.525-1.125.375-.467-.15-.7-.466-.7-.95V4.05c0-.417.188-.717.563-.9.375-.183.729-.142 1.062.125l10.1 7.95c.383.284.496.65.337 1.1-.158.45-.479.675-.962.675h-4.2l2.975 6.375c.183.384.204.767.063 1.15a1.487 1.487 0 0 1-.788.85Z\" fill=\"%23000\"/><path d=\"m12.697 20.861.002.005c.237.495.617.852 1.128 1.04.515.191 1.039.16 1.539-.08a1.987 1.987 0 0 0 1.04-1.128 1.922 1.922 0 0 0-.079-1.536v-.003L13.684 13.5H17.1c.32 0 .628-.075.89-.26.263-.184.438-.447.544-.749.106-.3.135-.617.04-.925a1.458 1.458 0 0 0-.545-.738L7.936 2.883a1.51 1.51 0 0 0-.768-.336 1.471 1.471 0 0 0-.825.154 1.495 1.495 0 0 0-.626.547 1.492 1.492 0 0 0-.217.802v12.825c0 .324.08.634.272.897.193.261.467.43.775.53.31.099.632.12.942.016.31-.103.555-.313.743-.578h.001l1.825-2.552 2.639 5.673Z\" stroke=\"%23fff\" stroke-opacity=\".7\"/></svg>') 6 2,auto}.unreal-container.orbit{cursor:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\"><path fill=\"%23000\" d=\"M11.998 21.6c-1.966 0-3.737-.53-5.312-1.588-1.575-1.058-2.738-2.437-3.488-4.137a.852.852 0 0 1 .013-.713.867.867 0 0 1 .512-.487.86.86 0 0 1 .688.037c.225.109.387.28.487.513.617 1.35 1.559 2.45 2.825 3.3 1.267.85 2.692 1.275 4.275 1.275 1.384 0 2.646-.33 3.788-.988a7.985 7.985 0 0 0 2.762-2.612h-.85a.873.873 0 0 1-.64-.257.863.863 0 0 1-.26-.638.88.88 0 0 1 .26-.643.864.864 0 0 1 .64-.262h3c.255 0 .47.086.642.259a.87.87 0 0 1 .258.64v3a.874.874 0 0 1-.257.642.863.863 0 0 1-.637.259.88.88 0 0 1-.643-.259.865.865 0 0 1-.263-.641v-.725a9.95 9.95 0 0 1-3.35 2.925c-1.35.733-2.833 1.1-4.45 1.1Zm0-17.4c-1.383 0-2.645.33-3.787.987A7.985 7.985 0 0 0 5.448 7.8h.85c.255 0 .47.086.642.257a.863.863 0 0 1 .258.638.88.88 0 0 1-.258.642.864.864 0 0 1-.642.263h-3a.87.87 0 0 1-.64-.259.87.87 0 0 1-.26-.641v-3c0-.255.086-.469.258-.641a.863.863 0 0 1 .637-.26.88.88 0 0 1 .643.26.864.864 0 0 1 .262.64v.726A9.95 9.95 0 0 1 7.548 3.5c1.35-.733 2.834-1.1 4.45-1.1 2 0 3.788.542 5.363 1.625 1.575 1.083 2.736 2.49 3.482 4.22a.724.724 0 0 1-.045.646.926.926 0 0 1-.525.437.87.87 0 0 1-.687-.04.977.977 0 0 1-.488-.513c-.616-1.35-1.558-2.45-2.825-3.3-1.266-.85-2.691-1.275-4.275-1.275Zm0 10.8a2.893 2.893 0 0 1-2.125-.875A2.893 2.893 0 0 1 8.998 12c0-.833.292-1.542.875-2.125A2.893 2.893 0 0 1 11.998 9c.834 0 1.542.292 2.125.875.584.583.875 1.292.875 2.125s-.291 1.542-.875 2.125a2.893 2.893 0 0 1-2.125.875Z\"/><path stroke=\"%23fff\" stroke-opacity=\".7\" d=\"m2.739 16.072.002.005c.789 1.788 2.014 3.24 3.666 4.35 1.66 1.116 3.53 1.673 5.591 1.673 1.696 0 3.262-.386 4.69-1.16a10.54 10.54 0 0 0 2.714-2.097c.069.167.171.32.308.454.272.268.613.403.994.403.38 0 .722-.135.992-.406s.402-.614.402-.994v-3c0-.381-.134-.724-.405-.995a1.37 1.37 0 0 0-.995-.405h-3c-.383 0-.727.137-.997.411a1.38 1.38 0 0 0-.403.994c0 .38.135.723.407.992.238.237.532.369.858.397a7.552 7.552 0 0 1-2.027 1.685c-1.062.613-2.237.92-3.538.92-1.488 0-2.815-.397-3.996-1.19-1.19-.798-2.07-1.826-2.647-3.087-.147-.34-.393-.6-.727-.76a1.36 1.36 0 0 0-1.073-.058c-.37.133-.64.397-.8.754a1.351 1.351 0 0 0-.016 1.114Zm4.553-8.37a1.36 1.36 0 0 0-.858-.396A7.552 7.552 0 0 1 8.46 5.62c1.062-.613 2.237-.921 3.537-.921 1.489 0 2.816.398 3.997 1.19 1.19.8 2.07 1.827 2.646 3.088.148.34.394.6.728.76a1.37 1.37 0 0 0 1.068.063c.347-.12.62-.346.799-.668.187-.338.215-.71.072-1.072l-.003-.007-.003-.007c-.784-1.818-2.006-3.298-3.658-4.434C15.982 2.47 14.094 1.9 11.998 1.9c-1.695 0-3.261.385-4.688 1.16a10.536 10.536 0 0 0-2.715 2.096 1.364 1.364 0 0 0-.308-.453 1.38 1.38 0 0 0-.994-.403c-.38 0-.722.135-.992.406s-.403.614-.403.994v3c0 .38.135.724.406.995.27.27.614.405.994.405h3c.384 0 .727-.137.998-.412a1.38 1.38 0 0 0 .402-.993c0-.38-.135-.723-.406-.992ZM9.52 14.48a3.393 3.393 0 0 0 2.478 1.02c.965 0 1.8-.342 2.479-1.02a3.392 3.392 0 0 0 1.021-2.48c0-.963-.343-1.8-1.021-2.478A3.392 3.392 0 0 0 11.998 8.5c-.964 0-1.8.343-2.478 1.021A3.392 3.392 0 0 0 8.498 12c0 .964.344 1.8 1.022 2.479Z\"/></svg>') 12 12,auto}.unreal-container.pan{cursor:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\"><path fill=\"%23000\" d=\"M11.997 10.075a1.01 1.01 0 0 1-.738-.313 1.008 1.008 0 0 1-.312-.737V6.15l-.95.95a.998.998 0 0 1-.763.312 1.09 1.09 0 0 1-.763-.337 1.06 1.06 0 0 1-.324-.775c0-.3.108-.558.324-.775l2.776-2.775c.117-.116.237-.2.362-.25a1.04 1.04 0 0 1 .775 0c.125.05.246.134.363.25l2.8 2.8c.216.217.32.47.313.762a1.096 1.096 0 0 1-.338.763 1.058 1.058 0 0 1-.775.325c-.3 0-.558-.108-.775-.325l-.925-.925v2.875c0 .283-.104.53-.312.737a1.01 1.01 0 0 1-.738.313Zm0 11.5a1.04 1.04 0 0 1-.388-.075 1.103 1.103 0 0 1-.362-.25l-2.8-2.8a1.002 1.002 0 0 1-.313-.762c.009-.292.121-.546.337-.763.217-.217.475-.325.775-.325.3 0 .559.108.775.325l.926.925v-2.875c0-.283.104-.529.312-.737a1.01 1.01 0 0 1 .738-.313c.283 0 .529.104.738.313.208.208.312.454.312.737v2.875l.95-.95a.998.998 0 0 1 .762-.312c.292.008.546.12.763.337.216.217.324.475.324.775 0 .3-.108.559-.324.775l-2.775 2.775c-.117.116-.238.2-.363.25a1.04 1.04 0 0 1-.387.075Zm4.925-6.05a1.058 1.058 0 0 1-.326-.774c0-.3.109-.559.326-.776l.925-.925H14.97c-.283 0-.528-.104-.736-.312a1.01 1.01 0 0 1-.313-.738c0-.283.104-.53.313-.738.208-.208.453-.312.737-.312h2.875l-.95-.95a.998.998 0 0 1-.313-.762 1.09 1.09 0 0 1 .338-.764 1.06 1.06 0 0 1 .775-.324c.3 0 .558.108.775.324l2.774 2.776c.117.117.2.238.251.363a1.04 1.04 0 0 1 0 .775c-.05.124-.134.245-.25.362l-2.8 2.8c-.217.216-.471.32-.762.313a1.096 1.096 0 0 1-.763-.337Zm-11.4 0L2.746 12.75a1.103 1.103 0 0 1-.25-.362 1.04 1.04 0 0 1 0-.775c.05-.125.133-.246.25-.363l2.8-2.8c.216-.216.47-.32.762-.313.292.01.546.121.763.337.217.217.325.476.325.776 0 .3-.108.558-.325.775l-.925.925h2.875c.283 0 .529.104.737.312.208.209.313.455.313.738s-.105.53-.313.738a1.008 1.008 0 0 1-.737.312H6.147l.95.95c.217.217.32.471.312.762a1.09 1.09 0 0 1-.337.764 1.06 1.06 0 0 1-.775.324c-.3 0-.559-.108-.776-.324Z\"/><path stroke=\"%23fff\" stroke-opacity=\".7\" d=\"M9.22 7.912c.436.013.821-.15 1.13-.458l.097-.097v1.668c0 .422.16.793.458 1.09.298.299.67.46 1.092.46.422 0 .793-.161 1.091-.46.298-.297.459-.668.459-1.09V7.357l.071.072c.309.308.693.471 1.13.471.435 0 .82-.163 1.128-.471.301-.303.47-.676.483-1.102v-.001a1.501 1.501 0 0 0-.46-1.13l-2.799-2.8a1.6 1.6 0 0 0-.528-.36l-.003-.001a1.54 1.54 0 0 0-1.145 0l-.002.001a1.6 1.6 0 0 0-.529.36L8.118 5.172l-.001.001a1.56 1.56 0 0 0-.47 1.128c0 .435.163.82.47 1.128.303.303.676.472 1.103.484Zm0 0 .014-.5-.015.5Zm-1.311 6.865a1.497 1.497 0 0 0-.458-1.13l-.097-.097h1.668c.421 0 .793-.16 1.09-.458.298-.299.46-.67.46-1.092a1.51 1.51 0 0 0-.46-1.091 1.507 1.507 0 0 0-1.09-.459H7.354l.071-.072c.309-.308.472-.692.472-1.128 0-.436-.163-.82-.472-1.13a1.596 1.596 0 0 0-1.101-.482h-.002a1.501 1.501 0 0 0-1.129.459l-2.8 2.8a1.6 1.6 0 0 0-.36.528l-.001.003a1.54 1.54 0 0 0 0 1.144v.003c.081.2.208.375.362.529l2.774 2.775c.309.308.693.47 1.129.47.435 0 .82-.162 1.128-.47.303-.302.472-.676.484-1.102Zm0 0-.5-.014.5.015v-.001Zm3.038-8.627-.5.5.5.207V6.15Zm.475 15.814.002.001a1.54 1.54 0 0 0 1.145 0h.002c.2-.081.375-.208.53-.362l2.775-2.774a1.56 1.56 0 0 0 .47-1.129c0-.435-.162-.82-.47-1.128a1.589 1.589 0 0 0-1.103-.484 1.497 1.497 0 0 0-1.13.458l-.096.097v-1.668c0-.421-.161-.793-.459-1.09a1.509 1.509 0 0 0-1.091-.46c-.422 0-.794.161-1.092.46a1.507 1.507 0 0 0-.458 1.09v1.668l-.072-.072a1.558 1.558 0 0 0-1.129-.471c-.436 0-.82.163-1.128.471l-.001.001c-.301.302-.47.675-.483 1.101v.001c-.012.437.151.821.46 1.13l2.8 2.8c.153.153.328.28.528.36Zm5.146-6.085c.303.302.676.47 1.102.484a1.5 1.5 0 0 0 1.13-.46l2.8-2.8a1.6 1.6 0 0 0 .36-.528l.002-.003a1.54 1.54 0 0 0 0-1.144l-.001-.003a1.6 1.6 0 0 0-.361-.529l-2.774-2.775h-.001a1.56 1.56 0 0 0-1.128-.47c-.436 0-.82.162-1.128.47h-.001a1.59 1.59 0 0 0-.484 1.102c-.012.437.15.822.459 1.13l.097.097h-1.668c-.422 0-.793.16-1.09.459-.299.298-.46.67-.46 1.091 0 .422.161.793.46 1.092.297.297.668.458 1.09.458h1.668l-.072.072a1.558 1.558 0 0 0-.472 1.129c0 .435.164.82.472 1.128ZM6.147 13.05l.5.5.207-.5h-.707Z\"/></svg>') 12 12,auto}.unreal-container.dolly{cursor:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" fill=\"none\"><mask id=\"a\" width=\"24\" height=\"24\" x=\"0\" y=\"0\" maskUnits=\"userSpaceOnUse\" style=\"mask-type:alpha\"><path fill=\"%23127392\" d=\"M0 0h24v24H0z\"/></mask><g mask=\"url(%23a)\"><path fill=\"%23000\" d=\"M12.002 20.575a1.026 1.026 0 0 1-.75-.325l-2.55-2.55a.933.933 0 0 1-.287-.713c.008-.275.113-.513.313-.713.2-.2.441-.3.725-.3.283 0 .524.1.724.3l.776.776V6.95l-.8.8c-.2.2-.438.296-.712.288a1.018 1.018 0 0 1-.713-.312c-.2-.2-.3-.442-.3-.726s.1-.525.3-.725l2.524-2.525a1.026 1.026 0 0 1 1.5 0l2.55 2.55c.2.2.296.438.289.713a1.023 1.023 0 0 1-.314.713c-.2.2-.441.3-.724.3a.988.988 0 0 1-.725-.3l-.775-.776v10.1l.8-.8c.2-.2.437-.296.712-.288.275.008.512.112.712.312.2.2.3.442.3.726s-.1.525-.3.725l-2.524 2.525a1.026 1.026 0 0 1-.75.325Z\"/><path stroke=\"%23fff\" stroke-opacity=\".7\" d=\"M13.553 8.153c.28.245.62.373 1 .373.415 0 .784-.153 1.078-.447.287-.287.446-.644.46-1.05v-.002a1.432 1.432 0 0 0-.435-1.08l-2.55-2.55-.354.353.354-.354a1.526 1.526 0 0 0-2.207 0L8.374 5.921A1.487 1.487 0 0 0 7.928 7c0 .416.152.785.446 1.08.288.287.645.446 1.052.457l4.127-.384Zm0 0v7.693m0-7.693a1.667 1.667 0 0 1-.079-.074l-3.021.075v7.693a1.482 1.482 0 0 0-1-.373c-.416 0-.785.153-1.079.447a1.522 1.522 0 0 0-.46 1.05v.002c-.011.417.14.786.435 1.08l2.55 2.55a1.527 1.527 0 0 0 2.207 0l2.525-2.524c.294-.294.446-.663.446-1.079 0-.416-.152-.785-.446-1.08a1.518 1.518 0 0 0-1.052-.457m0 0-.014.5.014-.5Zm0 0a1.424 1.424 0 0 0-1.027.383m0 0a1.583 1.583 0 0 0-.053.05l.354.354m-.3-.404v.104l.3.3m0 0-.3-.3v.6l.3-.3Z\"/></g></svg>') 12 12,auto}.unreal-container.disabled:before{content:\"\";position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}#playerUI{position:absolute;z-index:10;width:100%}#statsContainer{display:none;text-align:left;background-color:#000c}#stats{padding:6px;font-weight:700;font-size:14px;color:#0f0}canvas{position:absolute;image-rendering:crisp-edges}#overlay{position:absolute;top:0;right:2%;z-index:100;padding:4px;border-top-width:0;-webkit-border-bottom-right-radius:5px;-moz-border-radius-bottomright:5px;border-bottom-right-radius:5px;-webkit-border-bottom-left-radius:5px;-moz-border-radius-bottomleft:5px;border-bottom-left-radius:5px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-touch-callout:none}.overlay{font-weight:lighter;font-family:var(--src-font-family-body)}#overlayButton:hover{cursor:pointer}#overlayButton{font-size:40px;text-align:right}#overlaySettings{display:none;width:300px;padding:4px}#videoMessageOverlay{position:absolute;z-index:20;width:100%;margin:auto;font-size:1.8em;font-family:var(--src-font-family-body)}#playButton{display:inline-block;height:auto}img#playButton{width:10%;max-width:241px}#UIInteraction{position:fixed}#UIInteractionButtonBoundary{padding:2px}#UIInteractionButton{cursor:pointer}#hiddenInput{position:absolute;left:-10%;width:0;opacity:0}#editTextButton{position:absolute;width:40px;height:40px}\n"], dependencies: [{ kind: "component", type: AfkRestartScreenLockerComponent, selector: "app-afk-restart-screen-locker" }, { kind: "component", type: ClickableOverlayComponent, selector: "app-clickable-overlay" }, { kind: "component", type: UnrealStatusComponent, selector: "app-unreal-status" }, { kind: "component", type: FreezeFrameComponent, selector: "app-freeze-frame" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4452
4632
|
}
|
|
4453
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
4633
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: UnrealSceneComponent, decorators: [{
|
|
4454
4634
|
type: Component,
|
|
4455
4635
|
args: [{ selector: 'app-unreal-scene', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
4456
4636
|
AfkRestartScreenLockerComponent,
|
|
@@ -4503,6 +4683,7 @@ class VideoLockerComponent {
|
|
|
4503
4683
|
.subscribe((src) => this.createVideo(src));
|
|
4504
4684
|
}
|
|
4505
4685
|
createVideo(src) {
|
|
4686
|
+
const matchAbsolutePath = !!src.match(/.*\.(mp4|WebM)(\?.*)?$/i);
|
|
4506
4687
|
// Select the parent layout where the video will be inserted
|
|
4507
4688
|
const videoContainer = this.videoElement.nativeElement;
|
|
4508
4689
|
videoContainer.innerHTML = ''; // This will remove all existing content within the layout
|
|
@@ -4511,13 +4692,20 @@ class VideoLockerComponent {
|
|
|
4511
4692
|
videoElement.autoplay = true;
|
|
4512
4693
|
videoElement.muted = true;
|
|
4513
4694
|
videoElement.loop = true;
|
|
4514
|
-
|
|
4695
|
+
if (!matchAbsolutePath) {
|
|
4696
|
+
videoElement.poster = `${src}/cover.webp`;
|
|
4697
|
+
}
|
|
4515
4698
|
videoElement.style.position = 'absolute';
|
|
4516
4699
|
videoElement.style.width = '100%';
|
|
4517
4700
|
videoElement.style.height = '100%';
|
|
4518
4701
|
videoElement.style.objectFit = 'cover';
|
|
4519
4702
|
const sourceElement = document.createElement('source');
|
|
4520
|
-
|
|
4703
|
+
if (matchAbsolutePath) {
|
|
4704
|
+
sourceElement.src = src;
|
|
4705
|
+
}
|
|
4706
|
+
else {
|
|
4707
|
+
sourceElement.src = `${src}/video.mp4`;
|
|
4708
|
+
}
|
|
4521
4709
|
sourceElement.type = 'video/mp4';
|
|
4522
4710
|
// Append the source element to the video element
|
|
4523
4711
|
videoElement.appendChild(sourceElement);
|
|
@@ -4526,10 +4714,10 @@ class VideoLockerComponent {
|
|
|
4526
4714
|
// Append the video element to the layout
|
|
4527
4715
|
videoContainer.appendChild(videoElement);
|
|
4528
4716
|
}
|
|
4529
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
4530
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.
|
|
4717
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: VideoLockerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4718
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.2", type: VideoLockerComponent, isStandalone: true, selector: "app-video-locker", viewQueries: [{ propertyName: "videoElement", first: true, predicate: ["videoPlayerCover"], descendants: true }], ngImport: i0, template: "@if (imageIntroSrc$ | async; as url) {\n <div class=\"backImage\">\n <img [ngSrc]=\"url\" fill alt=\"Loading...\" />\n </div>\n} @else if (videoIntroSrc$ | async) {\n <div #videoPlayerCover class=\"backVideo\"></div>\n}\n", styles: [".backVideo{position:absolute;top:0;left:0;display:flex;justify-content:center;align-items:center;width:100%;height:100%}.backVideo video{position:absolute;width:100%;height:100%;object-fit:cover}.backImage{position:absolute;top:0;left:0;display:flex;justify-content:center;align-items:center;width:100%;height:100%}.backImage img{position:absolute;width:100%;height:100%;object-fit:cover}\n"], dependencies: [{ kind: "directive", type: NgOptimizedImage, selector: "img[ngSrc]", inputs: ["ngSrc", "ngSrcset", "sizes", "width", "height", "decoding", "loading", "priority", "loaderParams", "disableOptimizedSrcset", "fill", "placeholder", "placeholderConfig", "src", "srcset"] }, { kind: "pipe", type: AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4531
4719
|
}
|
|
4532
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
4720
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: VideoLockerComponent, decorators: [{
|
|
4533
4721
|
type: Component,
|
|
4534
4722
|
args: [{ selector: 'app-video-locker', imports: [AsyncPipe, NgOptimizedImage], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (imageIntroSrc$ | async; as url) {\n <div class=\"backImage\">\n <img [ngSrc]=\"url\" fill alt=\"Loading...\" />\n </div>\n} @else if (videoIntroSrc$ | async) {\n <div #videoPlayerCover class=\"backVideo\"></div>\n}\n", styles: [".backVideo{position:absolute;top:0;left:0;display:flex;justify-content:center;align-items:center;width:100%;height:100%}.backVideo video{position:absolute;width:100%;height:100%;object-fit:cover}.backImage{position:absolute;top:0;left:0;display:flex;justify-content:center;align-items:center;width:100%;height:100%}.backImage img{position:absolute;width:100%;height:100%;object-fit:cover}\n"] }]
|
|
4535
4723
|
}], propDecorators: { videoElement: [{
|
|
@@ -4551,15 +4739,18 @@ class WebrtcErrorModalComponent {
|
|
|
4551
4739
|
.pipe(first())
|
|
4552
4740
|
.subscribe((isConnected) => {
|
|
4553
4741
|
if (!isConnected) {
|
|
4554
|
-
this.store.dispatch(
|
|
4742
|
+
this.store.dispatch(disconnectStream({
|
|
4743
|
+
reason: DisconnectReason.DropConnection,
|
|
4744
|
+
message: 'Modal Drop Connection',
|
|
4745
|
+
}));
|
|
4555
4746
|
}
|
|
4556
4747
|
this.close();
|
|
4557
4748
|
});
|
|
4558
4749
|
}
|
|
4559
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
4560
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.
|
|
4750
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: WebrtcErrorModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4751
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.2.2", type: WebrtcErrorModalComponent, isStandalone: true, selector: "app-webrtc-error-modal", ngImport: i0, template: "<div [attr.data-testid]=\"'webrtc-error-modal'\" class=\"src-modal\">\n <header class=\"src-modal__header\">\n <div [attr.data-testid]=\"'title'\" class=\"src-modal__title\">\n WebRTC error\n </div>\n </header>\n <section class=\"src-modal__body\">\n <div style=\"text-align: left\">\n An internet connection type (WebRTC) appears to be blocked either by your\n browser settings or your current network. If WebRTC is blocked on your\n browser you may be able to adjust these settings yourself based on\n instructions here:\n <a href=\"https://myownconference.com/blog/en/webrtc/\" target=\"blank\"\n >https://myownconference.com/blog/en/webrtc/</a\n >\n <br /><br />\n Trying a different web browser may help confirm this as well. If WebRTC is\n blocked by your network, try switching to a different network if possible\n or contact your network administrator.<br /><br />\n WebRTC is common, safe and increasingly utilised method for streaming real\n time 3D experiences via a web browser. It typically consumes no more\n bandwidth than streaming an HD video.\n </div>\n </section>\n <footer class=\"src-modal__footer\">\n <src-button\n (onClick)=\"closeModalWithCirrusDisconnect()\"\n [data-testid]=\"'close-webrtc-error-modal'\"\n [colorScheme]=\"'primary'\"\n >\n Ok\n </src-button>\n </footer>\n</div>\n", styles: [".src-modal{--modalBodyPadding: 20px 8px 20px 20px;display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr) auto}.src-modal ::ng-deep .ng-scroll-content{--_scrollbar-content-width: initial;--_viewport-padding-right: 12px}.src-modal__body{width:100%}.src-modal__body p{color:var(--src-color-bg-default, #1f2937);font-size:14px;font-style:normal;font-weight:400;line-height:24px;margin-top:0}.src-modal__body a{word-wrap:break-word;white-space:normal}\n"], dependencies: [{ kind: "component", type: SourceButtonComponent, selector: "src-button", inputs: ["type", "appearance", "colorScheme", "size", "state", "customClass", "hasDisclosure", "isFullWidth", "isPressed", "isDisabled", "isLoading", "iconButton", "srcButtonConfig", "formID", "data-testid"], outputs: ["onClick", "onSubmit"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4561
4752
|
}
|
|
4562
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
4753
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: WebrtcErrorModalComponent, decorators: [{
|
|
4563
4754
|
type: Component,
|
|
4564
4755
|
args: [{ selector: 'app-webrtc-error-modal', changeDetection: ChangeDetectionStrategy.OnPush, imports: [SourceButtonComponent], template: "<div [attr.data-testid]=\"'webrtc-error-modal'\" class=\"src-modal\">\n <header class=\"src-modal__header\">\n <div [attr.data-testid]=\"'title'\" class=\"src-modal__title\">\n WebRTC error\n </div>\n </header>\n <section class=\"src-modal__body\">\n <div style=\"text-align: left\">\n An internet connection type (WebRTC) appears to be blocked either by your\n browser settings or your current network. If WebRTC is blocked on your\n browser you may be able to adjust these settings yourself based on\n instructions here:\n <a href=\"https://myownconference.com/blog/en/webrtc/\" target=\"blank\"\n >https://myownconference.com/blog/en/webrtc/</a\n >\n <br /><br />\n Trying a different web browser may help confirm this as well. If WebRTC is\n blocked by your network, try switching to a different network if possible\n or contact your network administrator.<br /><br />\n WebRTC is common, safe and increasingly utilised method for streaming real\n time 3D experiences via a web browser. It typically consumes no more\n bandwidth than streaming an HD video.\n </div>\n </section>\n <footer class=\"src-modal__footer\">\n <src-button\n (onClick)=\"closeModalWithCirrusDisconnect()\"\n [data-testid]=\"'close-webrtc-error-modal'\"\n [colorScheme]=\"'primary'\"\n >\n Ok\n </src-button>\n </footer>\n</div>\n", styles: [".src-modal{--modalBodyPadding: 20px 8px 20px 20px;display:grid;grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr) auto}.src-modal ::ng-deep .ng-scroll-content{--_scrollbar-content-width: initial;--_viewport-padding-right: 12px}.src-modal__body{width:100%}.src-modal__body p{color:var(--src-color-bg-default, #1f2937);font-size:14px;font-style:normal;font-weight:400;line-height:24px;margin-top:0}.src-modal__body a{word-wrap:break-word;white-space:normal}\n"] }]
|
|
4565
4756
|
}] });
|
|
@@ -4603,10 +4794,10 @@ class FilterSettingsComponent {
|
|
|
4603
4794
|
panelOpen: this.settings.panelOpen,
|
|
4604
4795
|
});
|
|
4605
4796
|
}
|
|
4606
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
4607
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.
|
|
4797
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: FilterSettingsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4798
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.2", type: FilterSettingsComponent, isStandalone: true, selector: "app-filter-settings", ngImport: i0, template: "<div class=\"settings-container\">\n <button (click)=\"togglePanel()\" class=\"gear-button\">LBM</button>\n @if (settings.panelOpen) {\n <div class=\"settings-panel\">\n <h3>LBM Trigger Settings</h3>\n <h5>Data Flow Monitor</h5>\n <form>\n <label>\n Monitoring delay:\n <input\n [(ngModel)]=\"settings.monitoringDelayTime\"\n [placeholder]=\"defaultFilterModel.monitoringDelayTime\"\n type=\"number\"\n name=\"monitoringDelayTime\"\n />\n </label>\n\n <label>\n Minimum Bitrate (kbit/s):\n <input\n [(ngModel)]=\"settings.minimumBitrate\"\n [placeholder]=\"defaultFilterModel.minimumBitrate\"\n type=\"number\"\n name=\"minimumBitrate\"\n />\n </label>\n <label>\n Yellow Flag (%):\n <input\n [(ngModel)]=\"settings.yellowFlag\"\n [placeholder]=\"defaultFilterModel.yellowFlag\"\n type=\"number\"\n name=\"yellowFlag\"\n />\n </label>\n <label>\n Red Flag (%):\n <input\n [(ngModel)]=\"settings.redFlag\"\n [placeholder]=\"defaultFilterModel.redFlag\"\n type=\"number\"\n name=\"redFlag\"\n />\n </label>\n <label>\n Minimum FPS:\n <input\n [(ngModel)]=\"settings.minimumFps\"\n [placeholder]=\"defaultFilterModel.minimumFps\"\n type=\"number\"\n name=\"minimumFps\"\n />\n </label>\n <hr />\n <h5>Kalman Filter</h5>\n <label>\n Initial Bitrate Estimate (kbit/s):\n <input\n [(ngModel)]=\"settings.initialBitrateEstimate\"\n [placeholder]=\"defaultFilterModel.initialBitrateEstimate\"\n type=\"number\"\n name=\"initialBitrateEstimate\"\n />\n </label>\n <label>\n Initial Error Covariance:\n <input\n [(ngModel)]=\"settings.initialErrorCovariance\"\n [placeholder]=\"defaultFilterModel.initialErrorCovariance\"\n type=\"number\"\n name=\"initialErrorCovariance\"\n />\n </label>\n <label>\n Process Noise (Q):\n <input\n [(ngModel)]=\"settings.processNoise\"\n [placeholder]=\"defaultFilterModel.processNoise\"\n type=\"number\"\n name=\"processNoise\"\n />\n </label>\n <label>\n Measurement Noise (R):\n <input\n [(ngModel)]=\"settings.measurementNoise\"\n [placeholder]=\"defaultFilterModel.measurementNoise\"\n type=\"number\"\n name=\"measurementNoise\"\n />\n </label>\n </form>\n <br />\n <br />\n <div class=\"apply-button-container\">\n <button (click)=\"reset()\">Reset</button>\n <button (click)=\"saveSettings()\">Apply</button>\n </div>\n </div>\n }\n</div>\n", styles: [".settings-container{position:absolute;top:65px;right:10px;z-index:1000}.gear-button{right:0;width:50px;position:absolute;cursor:pointer;font-size:10px;background:none;font-weight:500;border:1px solid;border-radius:9px;background:#0162cc;color:#fff;padding:4px}.gear-button>*{color:#e6f419;filter:drop-shadow(1px 1px 1px rgb(0,0,0))}.settings-panel{font-size:13px;background:#fff;border:1px solid #ccc;padding:15px;margin-top:25px;border-radius:4px;box-shadow:0 2px 8px #0003}.settings-panel h3{margin-top:0}.settings-panel form{display:flex;flex-direction:column}.settings-panel label{margin-bottom:10px;display:flex;flex-direction:column}.settings-panel input{padding:4px;margin-top:4px;border:1px solid #ccc;border-radius:2px}.apply-button-container{position:absolute;bottom:15px;right:15px}.apply-button-container button{padding:6px 12px;border:none;background-color:#1976d2;color:#fff;border-radius:4px;cursor:pointer;margin:2px}.apply-button-container button:hover{background-color:#1565c0}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4608
4799
|
}
|
|
4609
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
4800
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: FilterSettingsComponent, decorators: [{
|
|
4610
4801
|
type: Component,
|
|
4611
4802
|
args: [{ selector: 'app-filter-settings', imports: [FormsModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"settings-container\">\n <button (click)=\"togglePanel()\" class=\"gear-button\">LBM</button>\n @if (settings.panelOpen) {\n <div class=\"settings-panel\">\n <h3>LBM Trigger Settings</h3>\n <h5>Data Flow Monitor</h5>\n <form>\n <label>\n Monitoring delay:\n <input\n [(ngModel)]=\"settings.monitoringDelayTime\"\n [placeholder]=\"defaultFilterModel.monitoringDelayTime\"\n type=\"number\"\n name=\"monitoringDelayTime\"\n />\n </label>\n\n <label>\n Minimum Bitrate (kbit/s):\n <input\n [(ngModel)]=\"settings.minimumBitrate\"\n [placeholder]=\"defaultFilterModel.minimumBitrate\"\n type=\"number\"\n name=\"minimumBitrate\"\n />\n </label>\n <label>\n Yellow Flag (%):\n <input\n [(ngModel)]=\"settings.yellowFlag\"\n [placeholder]=\"defaultFilterModel.yellowFlag\"\n type=\"number\"\n name=\"yellowFlag\"\n />\n </label>\n <label>\n Red Flag (%):\n <input\n [(ngModel)]=\"settings.redFlag\"\n [placeholder]=\"defaultFilterModel.redFlag\"\n type=\"number\"\n name=\"redFlag\"\n />\n </label>\n <label>\n Minimum FPS:\n <input\n [(ngModel)]=\"settings.minimumFps\"\n [placeholder]=\"defaultFilterModel.minimumFps\"\n type=\"number\"\n name=\"minimumFps\"\n />\n </label>\n <hr />\n <h5>Kalman Filter</h5>\n <label>\n Initial Bitrate Estimate (kbit/s):\n <input\n [(ngModel)]=\"settings.initialBitrateEstimate\"\n [placeholder]=\"defaultFilterModel.initialBitrateEstimate\"\n type=\"number\"\n name=\"initialBitrateEstimate\"\n />\n </label>\n <label>\n Initial Error Covariance:\n <input\n [(ngModel)]=\"settings.initialErrorCovariance\"\n [placeholder]=\"defaultFilterModel.initialErrorCovariance\"\n type=\"number\"\n name=\"initialErrorCovariance\"\n />\n </label>\n <label>\n Process Noise (Q):\n <input\n [(ngModel)]=\"settings.processNoise\"\n [placeholder]=\"defaultFilterModel.processNoise\"\n type=\"number\"\n name=\"processNoise\"\n />\n </label>\n <label>\n Measurement Noise (R):\n <input\n [(ngModel)]=\"settings.measurementNoise\"\n [placeholder]=\"defaultFilterModel.measurementNoise\"\n type=\"number\"\n name=\"measurementNoise\"\n />\n </label>\n </form>\n <br />\n <br />\n <div class=\"apply-button-container\">\n <button (click)=\"reset()\">Reset</button>\n <button (click)=\"saveSettings()\">Apply</button>\n </div>\n </div>\n }\n</div>\n", styles: [".settings-container{position:absolute;top:65px;right:10px;z-index:1000}.gear-button{right:0;width:50px;position:absolute;cursor:pointer;font-size:10px;background:none;font-weight:500;border:1px solid;border-radius:9px;background:#0162cc;color:#fff;padding:4px}.gear-button>*{color:#e6f419;filter:drop-shadow(1px 1px 1px rgb(0,0,0))}.settings-panel{font-size:13px;background:#fff;border:1px solid #ccc;padding:15px;margin-top:25px;border-radius:4px;box-shadow:0 2px 8px #0003}.settings-panel h3{margin-top:0}.settings-panel form{display:flex;flex-direction:column}.settings-panel label{margin-bottom:10px;display:flex;flex-direction:column}.settings-panel input{padding:4px;margin-top:4px;border:1px solid #ccc;border-radius:2px}.apply-button-container{position:absolute;bottom:15px;right:15px}.apply-button-container button{padding:6px 12px;border:none;background-color:#1976d2;color:#fff;border-radius:4px;cursor:pointer;margin:2px}.apply-button-container button:hover{background-color:#1565c0}\n"] }]
|
|
4612
4803
|
}] });
|
|
@@ -4711,10 +4902,10 @@ class LowBandwidthDetectorComponent {
|
|
|
4711
4902
|
this.store.dispatch(changeLowBandwidth({ lowBandwidth: false }));
|
|
4712
4903
|
});
|
|
4713
4904
|
}
|
|
4714
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.
|
|
4715
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.
|
|
4905
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: LowBandwidthDetectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4906
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.2.2", type: LowBandwidthDetectorComponent, isStandalone: true, selector: "app-low-bandwidth-detector", ngImport: i0, template: "@if (isReducedQuality() || isLowBandwidth()) {\n <div\n [class.expanded]=\"isIndicatorExpanded() && isLowBandwidth()\"\n class=\"lbm-indicator freeze-loader\"\n >\n <div (click)=\"toggleIndicator(true)\" class=\"lbm-icon\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 20 20\">\n <path\n fill=\"#85888E\"\n d=\"M7.189 3.605c-.73.145-1.438.35-2.126.614A14.412 14.412 0 0 0 .896 6.666a1.08 1.08 0 0 0-.375.844c0 .34.118.629.354.865s.524.36.865.375c.34.014.65-.09.927-.313a11.89 11.89 0 0 1 3.385-1.916 10.94 10.94 0 0 1 1.235-.375l-.098-2.541ZM7.385 8.708a9.107 9.107 0 0 0-2.906 1.48c-.264.194-.402.464-.416.812-.014.347.104.646.354.896.236.236.524.364.864.385.34.02.664-.073.97-.281.422-.29.878-.53 1.368-.721a2.545 2.545 0 0 1-.166-.814l-.068-1.757ZM12.386 11.267c.094-.25.15-.52.161-.802l.068-1.755a9.019 9.019 0 0 1 2.927 1.52c.264.193.4.46.406.801.007.34-.114.635-.364.885a1.213 1.213 0 0 1-.865.365A1.614 1.614 0 0 1 13.77 12a6.574 6.574 0 0 0-1.385-.733ZM12.713 6.146l.098-2.542c.73.146 1.438.351 2.127.615 1.541.59 2.93 1.406 4.166 2.447.25.223.379.5.386.834.007.333-.115.625-.365.875a1.253 1.253 0 0 1-.864.375c-.34.014-.65-.09-.927-.313a11.892 11.892 0 0 0-3.386-1.916 10.94 10.94 0 0 0-1.235-.375ZM8.813 16.187c.32.32.715.48 1.187.48.472 0 .868-.16 1.188-.48.32-.32.479-.715.479-1.187 0-.473-.16-.868-.48-1.188-.319-.32-.715-.479-1.187-.479-.472 0-.868.16-1.187.48-.32.319-.48.714-.48 1.187 0 .472.16.868.48 1.187Z\"\n />\n <path\n fill=\"#fff\"\n fill-rule=\"evenodd\"\n d=\"M10 .833c-.91 0-1.637.756-1.602 1.665l.304 7.92a1.299 1.299 0 0 0 2.596 0l.305-7.92A1.604 1.604 0 0 0 10 .833ZM8.813 16.187c.32.32.715.48 1.187.48.472 0 .868-.16 1.188-.48.32-.32.479-.715.479-1.187 0-.473-.16-.868-.48-1.188-.319-.32-.715-.479-1.187-.479-.472 0-.868.16-1.187.48-.32.319-.48.714-.48 1.187 0 .472.16.868.48 1.187Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </div>\n\n <div\n [class.lbm-message--open]=\"isLowBandwidth() && isIndicatorExpanded()\"\n class=\"lbm-message\"\n >\n <p class=\"lbm-description\">\n Fluid Interactivity Modes were disabled due to an unstable connection.\n\n <button\n (click)=\"openLBMDialog()\"\n [attr.data-testid]=\"'learn-more-lbm'\"\n type=\"button\"\n class=\"lbm-learn-more\"\n >\n Learn more\n </button>\n </p>\n <button\n (click)=\"toggleIndicator(false)\"\n [attr.data-testid]=\"'close-lbm-indicator'\"\n type=\"button\"\n class=\"lbm-close\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n >\n <path\n d=\"M10.0001 11.2289L6.68618 14.5428C6.51951 14.7095 6.31818 14.7895 6.08218 14.7828C5.84618 14.7755 5.64485 14.6885 5.47818 14.5218C5.31151 14.3552 5.22818 14.1505 5.22818 13.9078C5.22818 13.6645 5.31151 13.4595 5.47818 13.2928L8.77107 9.99992L5.45718 6.68603C5.29051 6.51936 5.21051 6.3147 5.21718 6.07203C5.22451 5.8287 5.31151 5.6237 5.47818 5.45703C5.64485 5.29036 5.84951 5.20703 6.09218 5.20703C6.33551 5.20703 6.54051 5.29036 6.70718 5.45703L10.0001 8.77092L13.314 5.45703C13.4806 5.29036 13.6853 5.20703 13.928 5.20703C14.1713 5.20703 14.3763 5.29036 14.543 5.45703C14.7096 5.6237 14.793 5.8287 14.793 6.07203C14.793 6.3147 14.7096 6.51936 14.543 6.68603L11.2291 9.99992L14.543 13.3138C14.7096 13.4805 14.793 13.6818 14.793 13.9178C14.793 14.1538 14.7096 14.3552 14.543 14.5218C14.3763 14.6885 14.1713 14.7718 13.928 14.7718C13.6853 14.7718 13.4806 14.6885 13.314 14.5218L10.0001 11.2289Z\"\n fill=\"white\"\n />\n </svg>\n </button>\n </div>\n </div>\n}\n\n@if (devModeService.isDevMode) {\n <app-filter-settings />\n}\n", styles: [".freeze-loader,.lbm-indicator{--lbmPositionTop: 18px;--lbmPositionLeft: 18px;--lbmPositionRight: 18px;--lbmIndicatorSize: 36px;--lbmIndicatorBorderRadius: 8px;--lbmIndicatorCloseSize: 20px;--lbmPadding: 10px;--lbmTextSize: 13px;--lbmLineHeight: 20px;--lbmTextColor: #ffffff;--lbmBackgroundColor: rgba(17, 24, 39, .7);position:absolute;top:var(--lbmPositionTop);left:var(--lbmPositionLeft);z-index:6;display:flex;justify-content:center;align-items:flex-start;min-width:var(--lbmIndicatorSize);min-height:var(--lbmIndicatorSize);overflow:hidden}.freeze-loader.expanded,.lbm-indicator.expanded{--lbmPositionTop: 8px;--lbmPositionLeft: 8px;--lbmPositionRight: 8px;width:auto;max-width:calc(100% - var(--lbmPositionLeft) - var(--lbmPositionRight));padding:var(--lbmPadding);background:var(--lbmBackgroundColor);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border-radius:var(--lbmIndicatorBorderRadius);gap:12px}.freeze-loader .lbm-icon,.lbm-indicator .lbm-icon{display:flex;width:var(--lbmIndicatorSize);height:var(--lbmIndicatorSize);padding:8px;color:#fff;background-color:var(--lbmBackgroundColor);border-radius:50%;flex-shrink:0;cursor:pointer}.freeze-loader .lbm-icon svg,.freeze-loader .lbm-icon img,.lbm-indicator .lbm-icon svg,.lbm-indicator .lbm-icon img{width:100%;height:100%}.freeze-loader .lbm-close,.lbm-indicator .lbm-close{position:absolute;top:0;right:0;width:var(--lbmIndicatorCloseSize);height:var(--lbmIndicatorCloseSize);background-color:transparent;border:none;padding:0;cursor:pointer}.freeze-loader .lbm-message,.lbm-indicator .lbm-message{position:relative;opacity:0;height:0;max-width:0;padding-right:24px;pointer-events:none;visibility:hidden;animation:closeMessage .3s forwards}.freeze-loader .lbm-message--open,.lbm-indicator .lbm-message--open{position:relative;visibility:visible;display:flex;align-items:center;align-self:center;pointer-events:all;gap:12px;max-width:fit-content;height:auto;opacity:1;animation:openMessage .3s forwards}.freeze-loader .lbm-description,.lbm-indicator .lbm-description{margin:0;font-size:var(--lbmTextSize);font-weight:400;line-height:var(--lbmLineHeight);color:var(--lbmTextColor)}.freeze-loader .lbm-learn-more,.lbm-indicator .lbm-learn-more{display:inline-flex;padding:0;font-size:var(--lbmTextSize);font-weight:400;line-height:var(--lbmLineHeight);color:var(--lbmTextColor);-webkit-text-decoration-line:underline;text-decoration-line:underline;background-color:transparent;border:none;cursor:pointer}.freeze-loader .lbm-learn-more:hover,.lbm-indicator .lbm-learn-more:hover{text-decoration:none}@keyframes openMessage{0%{opacity:0;max-width:0;height:0}10%{height:auto;max-width:fit-content}to{opacity:1;height:auto;max-width:fit-content}}@keyframes closeMessage{0%{opacity:1;max-width:fit-content}to{opacity:0;max-width:0}}\n"], dependencies: [{ kind: "component", type: FilterSettingsComponent, selector: "app-filter-settings" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4716
4907
|
}
|
|
4717
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.
|
|
4908
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.2", ngImport: i0, type: LowBandwidthDetectorComponent, decorators: [{
|
|
4718
4909
|
type: Component,
|
|
4719
4910
|
args: [{ selector: 'app-low-bandwidth-detector', changeDetection: ChangeDetectionStrategy.OnPush, imports: [FilterSettingsComponent], template: "@if (isReducedQuality() || isLowBandwidth()) {\n <div\n [class.expanded]=\"isIndicatorExpanded() && isLowBandwidth()\"\n class=\"lbm-indicator freeze-loader\"\n >\n <div (click)=\"toggleIndicator(true)\" class=\"lbm-icon\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 20 20\">\n <path\n fill=\"#85888E\"\n d=\"M7.189 3.605c-.73.145-1.438.35-2.126.614A14.412 14.412 0 0 0 .896 6.666a1.08 1.08 0 0 0-.375.844c0 .34.118.629.354.865s.524.36.865.375c.34.014.65-.09.927-.313a11.89 11.89 0 0 1 3.385-1.916 10.94 10.94 0 0 1 1.235-.375l-.098-2.541ZM7.385 8.708a9.107 9.107 0 0 0-2.906 1.48c-.264.194-.402.464-.416.812-.014.347.104.646.354.896.236.236.524.364.864.385.34.02.664-.073.97-.281.422-.29.878-.53 1.368-.721a2.545 2.545 0 0 1-.166-.814l-.068-1.757ZM12.386 11.267c.094-.25.15-.52.161-.802l.068-1.755a9.019 9.019 0 0 1 2.927 1.52c.264.193.4.46.406.801.007.34-.114.635-.364.885a1.213 1.213 0 0 1-.865.365A1.614 1.614 0 0 1 13.77 12a6.574 6.574 0 0 0-1.385-.733ZM12.713 6.146l.098-2.542c.73.146 1.438.351 2.127.615 1.541.59 2.93 1.406 4.166 2.447.25.223.379.5.386.834.007.333-.115.625-.365.875a1.253 1.253 0 0 1-.864.375c-.34.014-.65-.09-.927-.313a11.892 11.892 0 0 0-3.386-1.916 10.94 10.94 0 0 0-1.235-.375ZM8.813 16.187c.32.32.715.48 1.187.48.472 0 .868-.16 1.188-.48.32-.32.479-.715.479-1.187 0-.473-.16-.868-.48-1.188-.319-.32-.715-.479-1.187-.479-.472 0-.868.16-1.187.48-.32.319-.48.714-.48 1.187 0 .472.16.868.48 1.187Z\"\n />\n <path\n fill=\"#fff\"\n fill-rule=\"evenodd\"\n d=\"M10 .833c-.91 0-1.637.756-1.602 1.665l.304 7.92a1.299 1.299 0 0 0 2.596 0l.305-7.92A1.604 1.604 0 0 0 10 .833ZM8.813 16.187c.32.32.715.48 1.187.48.472 0 .868-.16 1.188-.48.32-.32.479-.715.479-1.187 0-.473-.16-.868-.48-1.188-.319-.32-.715-.479-1.187-.479-.472 0-.868.16-1.187.48-.32.319-.48.714-.48 1.187 0 .472.16.868.48 1.187Z\"\n clip-rule=\"evenodd\"\n />\n </svg>\n </div>\n\n <div\n [class.lbm-message--open]=\"isLowBandwidth() && isIndicatorExpanded()\"\n class=\"lbm-message\"\n >\n <p class=\"lbm-description\">\n Fluid Interactivity Modes were disabled due to an unstable connection.\n\n <button\n (click)=\"openLBMDialog()\"\n [attr.data-testid]=\"'learn-more-lbm'\"\n type=\"button\"\n class=\"lbm-learn-more\"\n >\n Learn more\n </button>\n </p>\n <button\n (click)=\"toggleIndicator(false)\"\n [attr.data-testid]=\"'close-lbm-indicator'\"\n type=\"button\"\n class=\"lbm-close\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 20 20\"\n fill=\"none\"\n >\n <path\n d=\"M10.0001 11.2289L6.68618 14.5428C6.51951 14.7095 6.31818 14.7895 6.08218 14.7828C5.84618 14.7755 5.64485 14.6885 5.47818 14.5218C5.31151 14.3552 5.22818 14.1505 5.22818 13.9078C5.22818 13.6645 5.31151 13.4595 5.47818 13.2928L8.77107 9.99992L5.45718 6.68603C5.29051 6.51936 5.21051 6.3147 5.21718 6.07203C5.22451 5.8287 5.31151 5.6237 5.47818 5.45703C5.64485 5.29036 5.84951 5.20703 6.09218 5.20703C6.33551 5.20703 6.54051 5.29036 6.70718 5.45703L10.0001 8.77092L13.314 5.45703C13.4806 5.29036 13.6853 5.20703 13.928 5.20703C14.1713 5.20703 14.3763 5.29036 14.543 5.45703C14.7096 5.6237 14.793 5.8287 14.793 6.07203C14.793 6.3147 14.7096 6.51936 14.543 6.68603L11.2291 9.99992L14.543 13.3138C14.7096 13.4805 14.793 13.6818 14.793 13.9178C14.793 14.1538 14.7096 14.3552 14.543 14.5218C14.3763 14.6885 14.1713 14.7718 13.928 14.7718C13.6853 14.7718 13.4806 14.6885 13.314 14.5218L10.0001 11.2289Z\"\n fill=\"white\"\n />\n </svg>\n </button>\n </div>\n </div>\n}\n\n@if (devModeService.isDevMode) {\n <app-filter-settings />\n}\n", styles: [".freeze-loader,.lbm-indicator{--lbmPositionTop: 18px;--lbmPositionLeft: 18px;--lbmPositionRight: 18px;--lbmIndicatorSize: 36px;--lbmIndicatorBorderRadius: 8px;--lbmIndicatorCloseSize: 20px;--lbmPadding: 10px;--lbmTextSize: 13px;--lbmLineHeight: 20px;--lbmTextColor: #ffffff;--lbmBackgroundColor: rgba(17, 24, 39, .7);position:absolute;top:var(--lbmPositionTop);left:var(--lbmPositionLeft);z-index:6;display:flex;justify-content:center;align-items:flex-start;min-width:var(--lbmIndicatorSize);min-height:var(--lbmIndicatorSize);overflow:hidden}.freeze-loader.expanded,.lbm-indicator.expanded{--lbmPositionTop: 8px;--lbmPositionLeft: 8px;--lbmPositionRight: 8px;width:auto;max-width:calc(100% - var(--lbmPositionLeft) - var(--lbmPositionRight));padding:var(--lbmPadding);background:var(--lbmBackgroundColor);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border-radius:var(--lbmIndicatorBorderRadius);gap:12px}.freeze-loader .lbm-icon,.lbm-indicator .lbm-icon{display:flex;width:var(--lbmIndicatorSize);height:var(--lbmIndicatorSize);padding:8px;color:#fff;background-color:var(--lbmBackgroundColor);border-radius:50%;flex-shrink:0;cursor:pointer}.freeze-loader .lbm-icon svg,.freeze-loader .lbm-icon img,.lbm-indicator .lbm-icon svg,.lbm-indicator .lbm-icon img{width:100%;height:100%}.freeze-loader .lbm-close,.lbm-indicator .lbm-close{position:absolute;top:0;right:0;width:var(--lbmIndicatorCloseSize);height:var(--lbmIndicatorCloseSize);background-color:transparent;border:none;padding:0;cursor:pointer}.freeze-loader .lbm-message,.lbm-indicator .lbm-message{position:relative;opacity:0;height:0;max-width:0;padding-right:24px;pointer-events:none;visibility:hidden;animation:closeMessage .3s forwards}.freeze-loader .lbm-message--open,.lbm-indicator .lbm-message--open{position:relative;visibility:visible;display:flex;align-items:center;align-self:center;pointer-events:all;gap:12px;max-width:fit-content;height:auto;opacity:1;animation:openMessage .3s forwards}.freeze-loader .lbm-description,.lbm-indicator .lbm-description{margin:0;font-size:var(--lbmTextSize);font-weight:400;line-height:var(--lbmLineHeight);color:var(--lbmTextColor)}.freeze-loader .lbm-learn-more,.lbm-indicator .lbm-learn-more{display:inline-flex;padding:0;font-size:var(--lbmTextSize);font-weight:400;line-height:var(--lbmLineHeight);color:var(--lbmTextColor);-webkit-text-decoration-line:underline;text-decoration-line:underline;background-color:transparent;border:none;cursor:pointer}.freeze-loader .lbm-learn-more:hover,.lbm-indicator .lbm-learn-more:hover{text-decoration:none}@keyframes openMessage{0%{opacity:0;max-width:0;height:0}10%{height:auto;max-width:fit-content}to{opacity:1;height:auto;max-width:fit-content}}@keyframes closeMessage{0%{opacity:1;max-width:fit-content}to{opacity:0;max-width:0}}\n"] }]
|
|
4720
4911
|
}] });
|
|
@@ -4723,5 +4914,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.2.1", ngImpor
|
|
|
4723
4914
|
* Generated bundle index. Do not edit.
|
|
4724
4915
|
*/
|
|
4725
4916
|
|
|
4726
|
-
export { AFKService, AfkRestartScreenLockerComponent, AggregatorService, AnswerHandler, CONSOLE_COMMAND_DISABLE_MESSAGES, CONSOLE_COMMAND_ENABLE_MESSAGES, CONSOLE_COMMAND_PIXEL_QUALITY, ClickableOverlayComponent, CommandTelemetryService, ConfigHandler, ConsoleExtensionsService, DATA_CHANNEL_CONNECTION_TIMEOUT, DEBOUNCE_TO_MANY_RESIZE_CALLS, DEFAULT_AFK_TIMEOUT, DEFAULT_AFK_TIMEOUT_PERIOD, DataFlowMonitor, DevModeService, DisconnectReason, EControlSchemeType, EMessageType, EToClientMessageType, FULL_HD_HEIGHT, FULL_HD_WIDTH, FilterSettingsComponent, FreezeFrameComponent, FreezeFrameService, IceCandidateHandler, InputOptions, InputService, InstanceReadyHandler, InstanceReservedHandler, KalmanFilter1D, LatencyTimings, LowBandwidthDetectorComponent, LowBandwidthModalComponent, MINIMAL_FPS, MouseButton, MouseButtonsMask, OnCloseHandler, OnErrorHandler, OnMessageHandler, OnOpenHandler, OrchestrationMessageTypes, PingHandler, PlayerCountHandler, RegionsPingService, ResetTelemetry, SAME_SIZE_THRESHOLD, SCREEN_LOCKER_CONTAINER_ID, SIGNALLING_PERCENT_VALUE, SSInfoHandler, STREAMING_VIDEO_ID, SafePipe, SignallingService, SpecialKeyCodes, StatGraphComponent, StreamStatusTelemetryService, SubService, TelemetryStart, TelemetryStop, UNREAL_CONFIG, UnrealCommunicatorService, UnrealEffects, UnrealInternalSignalEvents, UnrealSceneComponent, UnrealStatusMessage, VideoLockerComponent, VideoRecorder, VideoService, VideoStatsComponent,
|
|
4917
|
+
export { AFKService, AfkRestartScreenLockerComponent, AggregatorService, AnswerHandler, CONSOLE_COMMAND_DISABLE_MESSAGES, CONSOLE_COMMAND_ENABLE_MESSAGES, CONSOLE_COMMAND_PIXEL_QUALITY, ClickableOverlayComponent, CommandTelemetryService, ConfigHandler, ConsoleExtensionsService, DATA_CHANNEL_CONNECTION_TIMEOUT, DEBOUNCE_TO_MANY_RESIZE_CALLS, DEFAULT_AFK_TIMEOUT, DEFAULT_AFK_TIMEOUT_PERIOD, DataFlowMonitor, DevModeService, DisconnectReason, EControlSchemeType, EMessageType, EToClientMessageType, FULL_HD_HEIGHT, FULL_HD_WIDTH, FilterSettingsComponent, FreezeFrameComponent, FreezeFrameService, IceCandidateHandler, InputOptions, InputService, InstanceReadyHandler, InstanceReservedHandler, KalmanFilter1D, LatencyTimings, LowBandwidthDetectorComponent, LowBandwidthModalComponent, MINIMAL_FPS, MouseButton, MouseButtonsMask, OnCloseHandler, OnErrorHandler, OnMessageHandler, OnOpenHandler, OrchestrationMessageTypes, POLLING_TIME, PingHandler, PlayerCountHandler, RegionsPingService, ResetTelemetry, SAME_SIZE_THRESHOLD, SCREEN_LOCKER_CONTAINER_ID, SIGNALLING_PERCENT_VALUE, SSInfoHandler, STREAMING_VIDEO_ID, SafePipe, SignallingService, SpecialKeyCodes, StatGraphComponent, StreamStatusTelemetryService, SubService, TelemetryStart, TelemetryStop, UNREAL_CONFIG, UnrealCommunicatorService, UnrealEffects, UnrealInternalSignalEvents, UnrealSceneComponent, UnrealStatusMessage, VideoLockerComponent, VideoRecorder, VideoService, VideoStatsComponent, WSCloseCode_CIRRUS_ABNORMAL_CLOSURE, WSCloseCode_CIRRUS_MAX_PLAYERS_ERROR, WSCloseCode_CIRRUS_PLAYER_DISCONNECTED, WSCloseCode_CIRRUS_STREAMER_KIKED_PLAYER, WSCloseCode_FORCE_CIRRUS_CLOSE, WSCloseCode_NORMAL_AFK_TIMEOUT, WSCloseCode_NORMAL_CLOSURE, WSCloseCode_NORMAL_MANUAL_DISCONNECT, WSCloseCodes, WS_OPEN_STATE, WS_TIMEOUT, WebRtcPlayerService, WebrtcErrorModalComponent, abortEstablishingConnection, alignProductsToPlaneCommand, changeLowBandwidth, changeStatusMainVideoOnScene, changeStreamResolutionAction, changeStreamResolutionSuccessAction, clampAndKeepMaxPercents, clampPanToProductsCommand, commandCompleted, commandStarted, decodeData, destroyRemoteConnections, destroyUnrealScene, disconnectStream, dispatchResize, dropConnection, floatToSmoothPercents, forceResizeUnrealVideo, fromResizeObserver, fromSignal, fromUnrealCallBackSignal, getActiveUrl, getApplyCameraPresetCommand, getApplyZoomCommand, getCameraBoxCommand, getCameraRecenterCommand, getCameraSettingsCommand, getChangeGizmoTypeCommand, getChangeResolutionCommand, getClickSnapCommand, getControlSensitivityCommand, getDebugModeCommand, getDragCommand, getDragSequenceCommand, getDropCommand, getEnableComposureCommand, getEnableControlsCommand, getEnableSceneStateCallbackCommand, getEnableSpinnerModeCommand, getEnableTeleportCommand, getExecuteConsoleCommand, getFitToObjectsCommand, getFreezeFrameCommand, getFreezeFrameNative, getImageFromVideoStream, getInitSequenceByObjectNameCommand, getJumpToSequenceCommand, getLoadLevelCommand, getLoadProductCommand, getLoadSceneStateCommand, getLoopBackCommand, getMoveSelectedCommand, getPauseSequenceCommand, getPlaySequenceCommand, getRequestCameraPresetCommand, getResetControlClampsCommand, getRotateSelectedCommand, getRtcErrorMessage, getSelectProductByObjectNameCommand, getSetCameraControlClampsCommand, getSetControlCameraModeCommand, getSetFpsCommand, getSetMaterialCommand, getSetPawnMovementModeCommand, getSetSettingsSequenceCommand, getStopSequenceCommand, getTakeRenderCommand, getTakeSpinnerRenderCommand, getTakeSpinnerRenderPreviewCommand, getUnLoadAllProductsCommand, getUnLoadProductByObjectNameCommand, getUnfreezeFrameNative, getUnselectAllProductsCommand, getWeatherCommand, initSignalling, initialState, isLoaderScreenVisible, mapQpToQuality, observeCommandResponse, provideAngularUnrealModule, removeExileCommands, resetAfk, resetAfkAction, resetConfig, resetIntroSrc, resetWarnTimeout, selectClientAndViewIds, selectCommandProgress, selectCommandsInProgress, selectFreezeFrameCombinedDataUrl, selectFreezeFrameDataUrl, selectFreezeFrameDataUrlFromVideo, selectFreezeFrameProgressMessageFromVideo, selectIsAutostart, selectIsFreezeFrameLoading, selectIsVideoPlayingAndDataChannelConnected, selectLastCommandInProgress, selectLoaderCommands, selectShowLoader, selectShowReconnectPopup, selectSignalingParameters, selectStreamConfig, selectTotalProgress, selectWarnTimeout, sendSignal, setAwsInstance, setCirrusConnected, setCirrusDisconnected, setConfig, setDataChannelConnected, setEstablishingConnection, setFreezeFrame, setFreezeFrameFromVideo, setIntroImageSrc, setIntroVideoSrc, setLoadingImageSrc, setLoopBackCommandIsCompleted, setMatchUrls, setMaxFps, setProductsLocationCommand, setSignalingName, setStatusMessage, setStatusPercentSignallingServer, setStreamClientCompanyId, setStreamViewId, setViewportNotReady, setViewportReady, showPopupWithoutAutoStart, showUnrealErrorMessage, smoothTransition, startStream, trackMixpanelEvent, unLoadAllLevelsCommand, unrealFeature, unrealReducer, updateCirrusInfo };
|
|
4727
4918
|
//# sourceMappingURL=3dsource-angular-unreal-module.mjs.map
|