tas-uell-sdk 0.0.1 → 0.0.2
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/README.md +122 -229
- package/esm2020/lib/components/tas-btn/tas-btn.component.mjs +79 -95
- package/esm2020/lib/components/tas-floating-call/tas-floating-call.component.mjs +74 -24
- package/esm2020/lib/components/tas-videocall/tas-videocall.component.mjs +50 -45
- package/esm2020/lib/components/tas-waiting-room/tas-waiting-room.component.mjs +179 -0
- package/esm2020/lib/config/tas.config.mjs +10 -0
- package/esm2020/lib/interfaces/tas.interfaces.mjs +32 -2
- package/esm2020/lib/services/tas.service.mjs +27 -48
- package/esm2020/lib/tas-uell-sdk.module.mjs +82 -0
- package/esm2020/public-api.mjs +13 -12
- package/esm2020/tas-uell-sdk.mjs +1 -1
- package/fesm2015/tas-uell-sdk.mjs +440 -218
- package/fesm2015/tas-uell-sdk.mjs.map +1 -1
- package/fesm2020/tas-uell-sdk.mjs +437 -216
- package/fesm2020/tas-uell-sdk.mjs.map +1 -1
- package/lib/components/tas-btn/tas-btn.component.d.ts +15 -11
- package/lib/components/tas-floating-call/tas-floating-call.component.d.ts +3 -2
- package/lib/components/tas-videocall/tas-videocall.component.d.ts +4 -3
- package/lib/components/tas-waiting-room/tas-waiting-room.component.d.ts +56 -0
- package/lib/config/tas.config.d.ts +28 -0
- package/lib/interfaces/tas.interfaces.d.ts +41 -6
- package/lib/services/tas.service.d.ts +6 -16
- package/lib/tas-uell-sdk.module.d.ts +46 -0
- package/package.json +34 -23
- package/public-api.d.ts +8 -7
- package/esm2020/lib/tas.config.mjs +0 -14
- package/esm2020/lib/tas.module.mjs +0 -73
- package/lib/tas.config.d.ts +0 -51
- package/lib/tas.module.d.ts +0 -34
|
@@ -1,27 +1,40 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, Injectable,
|
|
3
|
-
import * as i3 from '@angular/common';
|
|
4
|
-
import { CommonModule } from '@angular/common';
|
|
5
|
-
import * as i1 from '@ng-bootstrap/ng-bootstrap';
|
|
6
|
-
import { NgbModalModule } from '@ng-bootstrap/ng-bootstrap';
|
|
2
|
+
import { InjectionToken, Injectable, Inject, Component, Input, ViewChild, NgModule } from '@angular/core';
|
|
7
3
|
import { BehaviorSubject, Subscription } from 'rxjs';
|
|
8
4
|
import { map, catchError, switchMap } from 'rxjs/operators';
|
|
9
5
|
import * as OT from '@opentok/client';
|
|
10
6
|
import interact from 'interactjs';
|
|
7
|
+
import * as i1 from '@ng-bootstrap/ng-bootstrap';
|
|
8
|
+
import * as i3 from '@angular/common';
|
|
9
|
+
import { CommonModule } from '@angular/common';
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* Injection token for TAS configuration
|
|
14
13
|
*/
|
|
15
|
-
const TAS_CONFIG = new InjectionToken(
|
|
16
|
-
/**
|
|
17
|
-
* Injection token for HTTP client
|
|
18
|
-
*/
|
|
19
|
-
const TAS_HTTP_CLIENT = new InjectionToken("TAS_HTTP_CLIENT");
|
|
14
|
+
const TAS_CONFIG = new InjectionToken('TAS_CONFIG');
|
|
20
15
|
/**
|
|
21
|
-
* Injection token for
|
|
16
|
+
* Injection token for HTTP client adapter
|
|
22
17
|
*/
|
|
23
|
-
const
|
|
18
|
+
const TAS_HTTP_CLIENT = new InjectionToken('TAS_HTTP_CLIENT');
|
|
24
19
|
|
|
20
|
+
var TasRoomType;
|
|
21
|
+
(function (TasRoomType) {
|
|
22
|
+
TasRoomType["TAS"] = "TAS";
|
|
23
|
+
TasRoomType["JM"] = "JM";
|
|
24
|
+
TasRoomType["WEBINAR"] = "WEBINAR";
|
|
25
|
+
})(TasRoomType || (TasRoomType = {}));
|
|
26
|
+
var TasSessionType;
|
|
27
|
+
(function (TasSessionType) {
|
|
28
|
+
TasSessionType["SPONTANEOUS"] = "SPONTANEOUS";
|
|
29
|
+
TasSessionType["SCHEDULED"] = "SCHEDULED";
|
|
30
|
+
})(TasSessionType || (TasSessionType = {}));
|
|
31
|
+
var TasUserRole;
|
|
32
|
+
(function (TasUserRole) {
|
|
33
|
+
TasUserRole["OWNER"] = "OWNER";
|
|
34
|
+
TasUserRole["USER"] = "USER";
|
|
35
|
+
TasUserRole["MODERATOR"] = "MODERATOR";
|
|
36
|
+
})(TasUserRole || (TasUserRole = {}));
|
|
37
|
+
// Enums for TAS Service state management
|
|
25
38
|
var CallState;
|
|
26
39
|
(function (CallState) {
|
|
27
40
|
CallState["IDLE"] = "IDLE";
|
|
@@ -35,10 +48,11 @@ var ViewMode;
|
|
|
35
48
|
ViewMode["FULLSCREEN"] = "FULLSCREEN";
|
|
36
49
|
ViewMode["PIP"] = "PIP";
|
|
37
50
|
})(ViewMode || (ViewMode = {}));
|
|
51
|
+
|
|
38
52
|
class TasService {
|
|
39
|
-
constructor(
|
|
40
|
-
this.config = config;
|
|
53
|
+
constructor(httpClient, config) {
|
|
41
54
|
this.httpClient = httpClient;
|
|
55
|
+
this.config = config;
|
|
42
56
|
this.session = null;
|
|
43
57
|
this.publisher = null;
|
|
44
58
|
this.subscribers = [];
|
|
@@ -51,9 +65,6 @@ class TasService {
|
|
|
51
65
|
// Session info for PiP mode restoration
|
|
52
66
|
this.currentSessionId = null;
|
|
53
67
|
this.currentToken = null;
|
|
54
|
-
if (!this.config || !this.httpClient) {
|
|
55
|
-
console.warn("TasService: Configuration not provided. Make sure to use TasModule.forRoot()");
|
|
56
|
-
}
|
|
57
68
|
}
|
|
58
69
|
// Getters
|
|
59
70
|
get currentSession() {
|
|
@@ -89,9 +100,17 @@ class TasService {
|
|
|
89
100
|
}
|
|
90
101
|
// Audio Control
|
|
91
102
|
toggleMute() {
|
|
103
|
+
var _a, _b;
|
|
92
104
|
if (this.publisher) {
|
|
93
105
|
const newMuteState = !this.isMutedSubject.getValue();
|
|
94
|
-
|
|
106
|
+
const shouldEnableAudio = !newMuteState;
|
|
107
|
+
// Use OpenTok's publishAudio
|
|
108
|
+
this.publisher.publishAudio(shouldEnableAudio);
|
|
109
|
+
// Also directly control the MediaStreamTrack as backup
|
|
110
|
+
const audioTrack = (_b = (_a = this.publisher).getAudioSource) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
111
|
+
if (audioTrack) {
|
|
112
|
+
audioTrack.enabled = shouldEnableAudio;
|
|
113
|
+
}
|
|
95
114
|
this.isMutedSubject.next(newMuteState);
|
|
96
115
|
}
|
|
97
116
|
}
|
|
@@ -111,7 +130,7 @@ class TasService {
|
|
|
111
130
|
this.subscribers = [];
|
|
112
131
|
this.currentSessionId = null;
|
|
113
132
|
this.currentToken = null;
|
|
114
|
-
this.isMutedSubject.next(false);
|
|
133
|
+
this.isMutedSubject.next(false); // Reset mute state
|
|
115
134
|
this.viewModeSubject.next(ViewMode.FULLSCREEN);
|
|
116
135
|
this.callStateSubject.next(CallState.DISCONNECTED);
|
|
117
136
|
}
|
|
@@ -120,21 +139,13 @@ class TasService {
|
|
|
120
139
|
}
|
|
121
140
|
// API Methods
|
|
122
141
|
createRoom(payload) {
|
|
123
|
-
|
|
124
|
-
throw new Error("TasService not configured. Use TasModule.forRoot()");
|
|
125
|
-
}
|
|
126
|
-
const url = `${this.config.apiBaseUrl}/v2/room`;
|
|
127
|
-
return this.httpClient.post(url, payload).pipe(map((response) => response), catchError((error) => {
|
|
142
|
+
return this.httpClient.post("v2/room", { body: payload, headers: {} }).pipe(map((response) => response), catchError((error) => {
|
|
128
143
|
console.error("TAS Service: createRoom failed", error);
|
|
129
144
|
throw error;
|
|
130
145
|
}));
|
|
131
146
|
}
|
|
132
147
|
generateToken(payload) {
|
|
133
|
-
|
|
134
|
-
throw new Error("TasService not configured. Use TasModule.forRoot()");
|
|
135
|
-
}
|
|
136
|
-
const url = `${this.config.apiBaseUrl}/v2/room/token`;
|
|
137
|
-
return this.httpClient.post(url, payload).pipe(map((response) => response), catchError((error) => {
|
|
148
|
+
return this.httpClient.post("v2/room/token", { body: payload, headers: {} }).pipe(map((response) => response), catchError((error) => {
|
|
138
149
|
console.error("TAS Service: generateToken failed", error);
|
|
139
150
|
throw error;
|
|
140
151
|
}));
|
|
@@ -147,11 +158,6 @@ class TasService {
|
|
|
147
158
|
this.currentSessionId = sessionId;
|
|
148
159
|
this.currentToken = token;
|
|
149
160
|
return new Promise((resolve, reject) => {
|
|
150
|
-
if (!this.config) {
|
|
151
|
-
this.callStateSubject.next(CallState.ERROR);
|
|
152
|
-
reject(new Error("TasService not configured. Use TasModule.forRoot()"));
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
161
|
if (!OT.checkSystemRequirements()) {
|
|
156
162
|
this.callStateSubject.next(CallState.ERROR);
|
|
157
163
|
reject(new Error("Browser not compatible with TokBox"));
|
|
@@ -263,26 +269,24 @@ class TasService {
|
|
|
263
269
|
* Moves videos back to fullscreen containers
|
|
264
270
|
*/
|
|
265
271
|
moveVideosToFullscreen() {
|
|
266
|
-
this.moveSubscribersTo(
|
|
267
|
-
this.movePublisherTo(
|
|
272
|
+
this.moveSubscribersTo('subscriber-container');
|
|
273
|
+
this.movePublisherTo('publisher-container');
|
|
268
274
|
}
|
|
269
275
|
}
|
|
270
|
-
TasService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasService, deps: [{ token:
|
|
276
|
+
TasService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasService, deps: [{ token: TAS_HTTP_CLIENT }, { token: TAS_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
271
277
|
TasService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasService, providedIn: "root" });
|
|
272
278
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasService, decorators: [{
|
|
273
279
|
type: Injectable,
|
|
274
|
-
args: [{
|
|
280
|
+
args: [{
|
|
281
|
+
providedIn: "root",
|
|
282
|
+
}]
|
|
275
283
|
}], ctorParameters: function () {
|
|
276
284
|
return [{ type: undefined, decorators: [{
|
|
277
|
-
type: Optional
|
|
278
|
-
}, {
|
|
279
285
|
type: Inject,
|
|
280
|
-
args: [
|
|
286
|
+
args: [TAS_HTTP_CLIENT]
|
|
281
287
|
}] }, { type: undefined, decorators: [{
|
|
282
|
-
type: Optional
|
|
283
|
-
}, {
|
|
284
288
|
type: Inject,
|
|
285
|
-
args: [
|
|
289
|
+
args: [TAS_CONFIG]
|
|
286
290
|
}] }];
|
|
287
291
|
} });
|
|
288
292
|
|
|
@@ -305,10 +309,11 @@ class TasVideocallComponent {
|
|
|
305
309
|
}
|
|
306
310
|
ngOnDestroy() {
|
|
307
311
|
this.subscriptions.unsubscribe();
|
|
312
|
+
// Only disconnect if not in PiP mode (keep session alive for floating window)
|
|
308
313
|
if (!this.tasService.isPipMode()) {
|
|
309
314
|
this.tasService.disconnectSession();
|
|
310
315
|
}
|
|
311
|
-
interact(
|
|
316
|
+
interact('.publisher-view').unset();
|
|
312
317
|
}
|
|
313
318
|
// Public Methods
|
|
314
319
|
hangUp() {
|
|
@@ -318,7 +323,8 @@ class TasVideocallComponent {
|
|
|
318
323
|
this.tasService.toggleMute();
|
|
319
324
|
}
|
|
320
325
|
minimize() {
|
|
321
|
-
this.tasService.moveMainVideoTo(
|
|
326
|
+
this.tasService.moveMainVideoTo('pip-main-video');
|
|
327
|
+
// Small delay to ensure video is moved before closing modal
|
|
322
328
|
setTimeout(() => this.tasService.enterPipMode(), 50);
|
|
323
329
|
}
|
|
324
330
|
toggleSwap() {
|
|
@@ -331,30 +337,33 @@ class TasVideocallComponent {
|
|
|
331
337
|
}
|
|
332
338
|
// Private Methods
|
|
333
339
|
setupSubscriptions() {
|
|
334
|
-
|
|
340
|
+
// Call state subscription
|
|
341
|
+
this.subscriptions.add(this.tasService.callState$.subscribe(state => {
|
|
335
342
|
this.callState = state;
|
|
336
343
|
if (state === CallState.DISCONNECTED) {
|
|
337
|
-
this.activeModal.close(
|
|
344
|
+
this.activeModal.close('hangup');
|
|
338
345
|
}
|
|
339
346
|
}));
|
|
340
|
-
|
|
347
|
+
// View mode subscription
|
|
348
|
+
this.subscriptions.add(this.tasService.viewMode$.subscribe(mode => {
|
|
341
349
|
if (mode === ViewMode.PIP) {
|
|
342
|
-
this.activeModal.close(
|
|
350
|
+
this.activeModal.close('pip');
|
|
343
351
|
}
|
|
344
352
|
}));
|
|
345
|
-
|
|
353
|
+
// Mute state subscription
|
|
354
|
+
this.subscriptions.add(this.tasService.isMuted$.subscribe(muted => {
|
|
346
355
|
this.isMuted = muted;
|
|
347
356
|
}));
|
|
348
357
|
}
|
|
349
358
|
initializeCall() {
|
|
350
359
|
if (this.isReturningFromPip) {
|
|
360
|
+
// Returning from PiP - just move videos back
|
|
351
361
|
setTimeout(() => this.tasService.moveVideosToFullscreen(), 100);
|
|
352
362
|
}
|
|
353
363
|
else if (this.sessionId && this.token) {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
.
|
|
357
|
-
console.error("Error connecting to video call:", err);
|
|
364
|
+
// New call - connect to session
|
|
365
|
+
this.tasService.connectSession(this.sessionId, this.token, 'publisher-container', 'subscriber-container').catch(err => {
|
|
366
|
+
console.error('Error connecting to video call:', err);
|
|
358
367
|
});
|
|
359
368
|
}
|
|
360
369
|
}
|
|
@@ -363,69 +372,69 @@ class TasVideocallComponent {
|
|
|
363
372
|
const publisherEl = (_a = this.publisherContainer) === null || _a === void 0 ? void 0 : _a.nativeElement;
|
|
364
373
|
const subscriberEl = (_b = this.subscriberContainer) === null || _b === void 0 ? void 0 : _b.nativeElement;
|
|
365
374
|
if (publisherEl) {
|
|
366
|
-
publisherEl.removeAttribute(
|
|
367
|
-
publisherEl.removeAttribute(
|
|
368
|
-
publisherEl.removeAttribute(
|
|
375
|
+
publisherEl.removeAttribute('style');
|
|
376
|
+
publisherEl.removeAttribute('data-x');
|
|
377
|
+
publisherEl.removeAttribute('data-y');
|
|
369
378
|
}
|
|
370
379
|
if (subscriberEl) {
|
|
371
|
-
subscriberEl.removeAttribute(
|
|
372
|
-
subscriberEl.removeAttribute(
|
|
373
|
-
subscriberEl.removeAttribute(
|
|
380
|
+
subscriberEl.removeAttribute('style');
|
|
381
|
+
subscriberEl.removeAttribute('data-x');
|
|
382
|
+
subscriberEl.removeAttribute('data-y');
|
|
374
383
|
}
|
|
375
384
|
}
|
|
376
385
|
initInteract() {
|
|
377
|
-
interact(
|
|
378
|
-
interact(
|
|
386
|
+
interact('.publisher-view').unset();
|
|
387
|
+
interact('.publisher-view')
|
|
379
388
|
.draggable({
|
|
380
389
|
inertia: true,
|
|
381
390
|
modifiers: [
|
|
382
391
|
interact.modifiers.restrictRect({
|
|
383
|
-
restriction:
|
|
384
|
-
endOnly: true
|
|
385
|
-
})
|
|
392
|
+
restriction: 'parent',
|
|
393
|
+
endOnly: true
|
|
394
|
+
})
|
|
386
395
|
],
|
|
387
396
|
autoScroll: true,
|
|
388
397
|
listeners: {
|
|
389
398
|
move: (event) => {
|
|
390
399
|
const target = event.target;
|
|
391
|
-
const x = (parseFloat(target.getAttribute(
|
|
392
|
-
const y = (parseFloat(target.getAttribute(
|
|
400
|
+
const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
|
|
401
|
+
const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
|
|
393
402
|
target.style.transform = `translate(${x}px, ${y}px)`;
|
|
394
|
-
target.setAttribute(
|
|
395
|
-
target.setAttribute(
|
|
396
|
-
}
|
|
397
|
-
}
|
|
403
|
+
target.setAttribute('data-x', String(x));
|
|
404
|
+
target.setAttribute('data-y', String(y));
|
|
405
|
+
}
|
|
406
|
+
}
|
|
398
407
|
})
|
|
399
408
|
.resizable({
|
|
400
409
|
edges: { left: false, right: true, bottom: true, top: false },
|
|
401
410
|
listeners: {
|
|
402
411
|
move: (event) => {
|
|
403
412
|
const target = event.target;
|
|
404
|
-
let x = parseFloat(target.getAttribute(
|
|
405
|
-
let y = parseFloat(target.getAttribute(
|
|
413
|
+
let x = parseFloat(target.getAttribute('data-x')) || 0;
|
|
414
|
+
let y = parseFloat(target.getAttribute('data-y')) || 0;
|
|
406
415
|
target.style.width = `${event.rect.width}px`;
|
|
407
416
|
target.style.height = `${event.rect.height}px`;
|
|
408
417
|
x += event.deltaRect.left;
|
|
409
418
|
y += event.deltaRect.top;
|
|
410
419
|
target.style.transform = `translate(${x}px, ${y}px)`;
|
|
411
|
-
target.setAttribute(
|
|
412
|
-
target.setAttribute(
|
|
413
|
-
}
|
|
420
|
+
target.setAttribute('data-x', String(x));
|
|
421
|
+
target.setAttribute('data-y', String(y));
|
|
422
|
+
}
|
|
414
423
|
},
|
|
415
424
|
modifiers: [
|
|
416
|
-
interact.modifiers.restrictEdges({ outer:
|
|
425
|
+
interact.modifiers.restrictEdges({ outer: 'parent' }),
|
|
417
426
|
interact.modifiers.restrictSize({ min: { width: 150, height: 100 } }),
|
|
418
|
-
interact.modifiers.aspectRatio({ ratio:
|
|
427
|
+
interact.modifiers.aspectRatio({ ratio: 'preserve' })
|
|
419
428
|
],
|
|
420
|
-
inertia: true
|
|
429
|
+
inertia: true
|
|
421
430
|
});
|
|
422
431
|
}
|
|
423
432
|
}
|
|
424
433
|
TasVideocallComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasVideocallComponent, deps: [{ token: i1.NgbActiveModal }, { token: TasService }], target: i0.ɵɵFactoryTarget.Component });
|
|
425
|
-
TasVideocallComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: TasVideocallComponent, selector: "tas-videocall", inputs: { sessionId: "sessionId", token: "token", isReturningFromPip: "isReturningFromPip" }, viewQueries: [{ propertyName: "publisherContainer", first: true, predicate: ["publisherContainer"], descendants: true }, { propertyName: "subscriberContainer", first: true, predicate: ["subscriberContainer"], descendants: true }], ngImport: i0, template: "<div class=\"tas-videocall-container\">\n
|
|
434
|
+
TasVideocallComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: TasVideocallComponent, selector: "tas-videocall", inputs: { sessionId: "sessionId", token: "token", isReturningFromPip: "isReturningFromPip" }, viewQueries: [{ propertyName: "publisherContainer", first: true, predicate: ["publisherContainer"], descendants: true }, { propertyName: "subscriberContainer", first: true, predicate: ["subscriberContainer"], descendants: true }], ngImport: i0, template: "<div class=\"tas-videocall-container\">\n\t<div id=\"subscriber-container\" \n\t\t[class.subscriber-view]=\"isPublisherSmall\" \n\t\t[class.publisher-view]=\"!isPublisherSmall\"\n\t\t#subscriberContainer\n\t\t(dblclick)=\"onDoubleClick()\">\n\t</div>\n\n\t<div id=\"publisher-container\" \n\t\t[class.publisher-view]=\"isPublisherSmall\" \n\t\t[class.subscriber-view]=\"!isPublisherSmall\"\n\t\t#publisherContainer \n\t\t(dblclick)=\"onDoubleClick()\">\n\t</div>\n\t\n\t<div class=\"controls-container\">\n\t\t<button class=\"btn swap-btn\" (click)=\"toggleSwap()\" title=\"Swap view\">\n\t\t\t<i class=\"fa fa-refresh\"></i>\n\t\t</button>\n\t\t<button class=\"btn pip-btn\" (click)=\"minimize()\" title=\"Minimize (Picture in Picture)\">\n\t\t\t<i class=\"fa fa-compress\"></i>\n\t\t</button>\n\t\t<button class=\"btn mute-btn\" [class.muted]=\"isMuted\" (click)=\"toggleMute()\" [title]=\"isMuted ? 'Unmute microphone' : 'Mute microphone'\">\n\t\t\t<i class=\"fa\" [class.fa-microphone]=\"!isMuted\" [class.fa-microphone-slash]=\"isMuted\"></i>\n\t\t</button>\n\t\t<button class=\"btn hangup-btn\" (click)=\"hangUp()\" title=\"Hang up\">\n\t\t\t<i class=\"fa fa-phone\" style=\"transform: rotate(135deg);\"></i>\n\t\t</button>\n\t</div>\n</div>\n\n", styles: [".tas-videocall-container{position:relative;width:100vw;height:100vh;background-color:#000;overflow:hidden}.tas-videocall-container ::ng-deep .OT_edge-bar-item,.tas-videocall-container ::ng-deep .OT_mute,.tas-videocall-container ::ng-deep .OT_audio-level-meter,.tas-videocall-container ::ng-deep .OT_bar,.tas-videocall-container ::ng-deep .OT_name{display:none!important}.tas-videocall-container .subscriber-view{width:100%;height:100%;z-index:1}.tas-videocall-container .publisher-view{position:absolute;top:20px;right:20px;width:200px;height:150px;z-index:2;border:2px solid #fff;border-radius:8px;background-color:#333}.tas-videocall-container .controls-container{display:flex;flex-direction:row;gap:20px;position:absolute;bottom:30px;left:50%;transform:translate(-50%);z-index:3;background-color:#00000080;padding:15px 25px;border-radius:50px;-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px)}.tas-videocall-container .controls-container .hangup-btn,.tas-videocall-container .controls-container .swap-btn,.tas-videocall-container .controls-container .pip-btn,.tas-videocall-container .controls-container .mute-btn{width:60px;height:60px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:24px;border:none;box-shadow:0 4px 6px #0000004d;transition:all .2s ease}.tas-videocall-container .controls-container .hangup-btn i,.tas-videocall-container .controls-container .swap-btn i,.tas-videocall-container .controls-container .pip-btn i,.tas-videocall-container .controls-container .mute-btn i{color:#fff}.tas-videocall-container .controls-container .hangup-btn{background:#dc3545}.tas-videocall-container .controls-container .hangup-btn:hover{background:#c82333;transform:scale(1.05)}.tas-videocall-container .controls-container .swap-btn{background:rgba(255,255,255,.2)}.tas-videocall-container .controls-container .swap-btn:hover{background:rgba(255,255,255,.35);transform:scale(1.05)}.tas-videocall-container .controls-container .pip-btn{background:rgba(255,255,255,.2)}.tas-videocall-container .controls-container .pip-btn:hover{background:rgba(255,255,255,.35);transform:scale(1.05)}.tas-videocall-container .controls-container .mute-btn{background:rgba(255,255,255,.2)}.tas-videocall-container .controls-container .mute-btn:hover{background:rgba(255,255,255,.35);transform:scale(1.05)}.tas-videocall-container .controls-container .mute-btn.muted{background:#f39c12}.tas-videocall-container .controls-container .mute-btn.muted:hover{background:#e67e22}\n"] });
|
|
426
435
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasVideocallComponent, decorators: [{
|
|
427
436
|
type: Component,
|
|
428
|
-
args: [{ selector:
|
|
437
|
+
args: [{ selector: 'tas-videocall', template: "<div class=\"tas-videocall-container\">\n\t<div id=\"subscriber-container\" \n\t\t[class.subscriber-view]=\"isPublisherSmall\" \n\t\t[class.publisher-view]=\"!isPublisherSmall\"\n\t\t#subscriberContainer\n\t\t(dblclick)=\"onDoubleClick()\">\n\t</div>\n\n\t<div id=\"publisher-container\" \n\t\t[class.publisher-view]=\"isPublisherSmall\" \n\t\t[class.subscriber-view]=\"!isPublisherSmall\"\n\t\t#publisherContainer \n\t\t(dblclick)=\"onDoubleClick()\">\n\t</div>\n\t\n\t<div class=\"controls-container\">\n\t\t<button class=\"btn swap-btn\" (click)=\"toggleSwap()\" title=\"Swap view\">\n\t\t\t<i class=\"fa fa-refresh\"></i>\n\t\t</button>\n\t\t<button class=\"btn pip-btn\" (click)=\"minimize()\" title=\"Minimize (Picture in Picture)\">\n\t\t\t<i class=\"fa fa-compress\"></i>\n\t\t</button>\n\t\t<button class=\"btn mute-btn\" [class.muted]=\"isMuted\" (click)=\"toggleMute()\" [title]=\"isMuted ? 'Unmute microphone' : 'Mute microphone'\">\n\t\t\t<i class=\"fa\" [class.fa-microphone]=\"!isMuted\" [class.fa-microphone-slash]=\"isMuted\"></i>\n\t\t</button>\n\t\t<button class=\"btn hangup-btn\" (click)=\"hangUp()\" title=\"Hang up\">\n\t\t\t<i class=\"fa fa-phone\" style=\"transform: rotate(135deg);\"></i>\n\t\t</button>\n\t</div>\n</div>\n\n", styles: [".tas-videocall-container{position:relative;width:100vw;height:100vh;background-color:#000;overflow:hidden}.tas-videocall-container ::ng-deep .OT_edge-bar-item,.tas-videocall-container ::ng-deep .OT_mute,.tas-videocall-container ::ng-deep .OT_audio-level-meter,.tas-videocall-container ::ng-deep .OT_bar,.tas-videocall-container ::ng-deep .OT_name{display:none!important}.tas-videocall-container .subscriber-view{width:100%;height:100%;z-index:1}.tas-videocall-container .publisher-view{position:absolute;top:20px;right:20px;width:200px;height:150px;z-index:2;border:2px solid #fff;border-radius:8px;background-color:#333}.tas-videocall-container .controls-container{display:flex;flex-direction:row;gap:20px;position:absolute;bottom:30px;left:50%;transform:translate(-50%);z-index:3;background-color:#00000080;padding:15px 25px;border-radius:50px;-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px)}.tas-videocall-container .controls-container .hangup-btn,.tas-videocall-container .controls-container .swap-btn,.tas-videocall-container .controls-container .pip-btn,.tas-videocall-container .controls-container .mute-btn{width:60px;height:60px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:24px;border:none;box-shadow:0 4px 6px #0000004d;transition:all .2s ease}.tas-videocall-container .controls-container .hangup-btn i,.tas-videocall-container .controls-container .swap-btn i,.tas-videocall-container .controls-container .pip-btn i,.tas-videocall-container .controls-container .mute-btn i{color:#fff}.tas-videocall-container .controls-container .hangup-btn{background:#dc3545}.tas-videocall-container .controls-container .hangup-btn:hover{background:#c82333;transform:scale(1.05)}.tas-videocall-container .controls-container .swap-btn{background:rgba(255,255,255,.2)}.tas-videocall-container .controls-container .swap-btn:hover{background:rgba(255,255,255,.35);transform:scale(1.05)}.tas-videocall-container .controls-container .pip-btn{background:rgba(255,255,255,.2)}.tas-videocall-container .controls-container .pip-btn:hover{background:rgba(255,255,255,.35);transform:scale(1.05)}.tas-videocall-container .controls-container .mute-btn{background:rgba(255,255,255,.2)}.tas-videocall-container .controls-container .mute-btn:hover{background:rgba(255,255,255,.35);transform:scale(1.05)}.tas-videocall-container .controls-container .mute-btn.muted{background:#f39c12}.tas-videocall-container .controls-container .mute-btn.muted:hover{background:#e67e22}\n"] }]
|
|
429
438
|
}], ctorParameters: function () { return [{ type: i1.NgbActiveModal }, { type: TasService }]; }, propDecorators: { sessionId: [{
|
|
430
439
|
type: Input
|
|
431
440
|
}], token: [{
|
|
@@ -434,126 +443,281 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
434
443
|
type: Input
|
|
435
444
|
}], publisherContainer: [{
|
|
436
445
|
type: ViewChild,
|
|
437
|
-
args: [
|
|
446
|
+
args: ['publisherContainer']
|
|
438
447
|
}], subscriberContainer: [{
|
|
439
448
|
type: ViewChild,
|
|
440
|
-
args: [
|
|
449
|
+
args: ['subscriberContainer']
|
|
441
450
|
}] } });
|
|
442
451
|
|
|
443
|
-
|
|
444
|
-
|
|
452
|
+
var WaitingRoomState;
|
|
453
|
+
(function (WaitingRoomState) {
|
|
454
|
+
WaitingRoomState["IDLE"] = "IDLE";
|
|
455
|
+
WaitingRoomState["CREATING_ROOM"] = "CREATING_ROOM";
|
|
456
|
+
WaitingRoomState["GETTING_TOKEN"] = "GETTING_TOKEN";
|
|
457
|
+
WaitingRoomState["READY"] = "READY";
|
|
458
|
+
WaitingRoomState["ERROR"] = "ERROR";
|
|
459
|
+
})(WaitingRoomState || (WaitingRoomState = {}));
|
|
460
|
+
class TasWaitingRoomComponent {
|
|
461
|
+
constructor(activeModal, tasService, modalService) {
|
|
462
|
+
this.activeModal = activeModal;
|
|
445
463
|
this.tasService = tasService;
|
|
446
464
|
this.modalService = modalService;
|
|
447
|
-
|
|
448
|
-
this.
|
|
449
|
-
this.
|
|
450
|
-
this.tenantId =
|
|
465
|
+
// Room configuration inputs
|
|
466
|
+
this.appointmentId = 1;
|
|
467
|
+
this.product = 'uell';
|
|
468
|
+
this.tenantId = '';
|
|
469
|
+
this.regularUserIds = [];
|
|
470
|
+
this.moderatorUserIds = [];
|
|
471
|
+
// Component state
|
|
472
|
+
this.state = WaitingRoomState.IDLE;
|
|
473
|
+
this.WaitingRoomState = WaitingRoomState; // Expose enum to template
|
|
474
|
+
this.errorMessage = '';
|
|
475
|
+
// Session data
|
|
476
|
+
this.sessionId = '';
|
|
477
|
+
this.token = '';
|
|
478
|
+
this.users = [];
|
|
451
479
|
this.subscriptions = new Subscription();
|
|
452
|
-
this.
|
|
480
|
+
this.videoCallModalRef = null;
|
|
453
481
|
}
|
|
454
482
|
ngOnInit() {
|
|
455
|
-
this.
|
|
483
|
+
this.buildUsersArray();
|
|
456
484
|
this.setupViewModeSubscription();
|
|
457
485
|
}
|
|
458
486
|
ngOnDestroy() {
|
|
459
487
|
this.subscriptions.unsubscribe();
|
|
460
488
|
}
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
489
|
+
/**
|
|
490
|
+
* Creates the room and fetches the token
|
|
491
|
+
*/
|
|
492
|
+
createRoom() {
|
|
493
|
+
var _a;
|
|
494
|
+
if (!this.tenantId || !((_a = this.currentUser) === null || _a === void 0 ? void 0 : _a.name)) {
|
|
495
|
+
this.state = WaitingRoomState.ERROR;
|
|
496
|
+
this.errorMessage = 'Missing configuration data (tenant or user)';
|
|
464
497
|
return;
|
|
465
498
|
}
|
|
466
|
-
this.
|
|
467
|
-
this.
|
|
468
|
-
|
|
499
|
+
this.state = WaitingRoomState.CREATING_ROOM;
|
|
500
|
+
this.errorMessage = '';
|
|
501
|
+
const body = {
|
|
502
|
+
roomType: TasRoomType.TAS,
|
|
503
|
+
type: TasSessionType.SPONTANEOUS,
|
|
469
504
|
tenant: this.tenantId,
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
.
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
.
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
sessionId,
|
|
488
|
-
token: tokenResponse.content.token,
|
|
489
|
-
},
|
|
490
|
-
];
|
|
491
|
-
}));
|
|
492
|
-
}))
|
|
493
|
-
.subscribe({
|
|
494
|
-
next: ({ sessionId, token }) => {
|
|
495
|
-
this.isLoading = false;
|
|
496
|
-
this.openVideoCallModal(sessionId, token);
|
|
505
|
+
appointmentId: this.appointmentId,
|
|
506
|
+
users: this.users,
|
|
507
|
+
product: this.product
|
|
508
|
+
};
|
|
509
|
+
this.subscriptions.add(this.tasService.createRoom(body).pipe(switchMap(response => {
|
|
510
|
+
this.sessionId = response.content.sessionId;
|
|
511
|
+
this.state = WaitingRoomState.GETTING_TOKEN;
|
|
512
|
+
return this.tasService.generateToken({
|
|
513
|
+
sessionId: this.sessionId,
|
|
514
|
+
name: this.currentUser.name,
|
|
515
|
+
lastname: this.currentUser.lastname,
|
|
516
|
+
roleVC: this.currentUser.role
|
|
517
|
+
});
|
|
518
|
+
})).subscribe({
|
|
519
|
+
next: (tokenResponse) => {
|
|
520
|
+
this.token = tokenResponse.content.token;
|
|
521
|
+
this.state = WaitingRoomState.READY;
|
|
497
522
|
},
|
|
498
523
|
error: (err) => {
|
|
499
|
-
console.error(
|
|
500
|
-
this.
|
|
501
|
-
|
|
524
|
+
console.error('Error creating room or getting token:', err);
|
|
525
|
+
this.state = WaitingRoomState.ERROR;
|
|
526
|
+
this.errorMessage = 'Error creating room. Please try again.';
|
|
527
|
+
}
|
|
502
528
|
}));
|
|
503
529
|
}
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
530
|
+
/**
|
|
531
|
+
* Joins the video call session
|
|
532
|
+
*/
|
|
533
|
+
joinSession() {
|
|
534
|
+
if (!this.sessionId || !this.token) {
|
|
535
|
+
this.errorMessage = 'Cannot join session. Incomplete data.';
|
|
508
536
|
return;
|
|
509
537
|
}
|
|
510
|
-
|
|
511
|
-
this.
|
|
538
|
+
// Close waiting room and open video call
|
|
539
|
+
this.activeModal.close('joining');
|
|
540
|
+
this.openVideoCallModal();
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Closes the waiting room
|
|
544
|
+
*/
|
|
545
|
+
cancel() {
|
|
546
|
+
this.activeModal.dismiss('cancel');
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Retry after an error
|
|
550
|
+
*/
|
|
551
|
+
retry() {
|
|
552
|
+
this.state = WaitingRoomState.IDLE;
|
|
553
|
+
this.errorMessage = '';
|
|
554
|
+
this.sessionId = '';
|
|
555
|
+
this.token = '';
|
|
556
|
+
}
|
|
557
|
+
// Private Methods
|
|
558
|
+
buildUsersArray() {
|
|
559
|
+
this.users = [];
|
|
560
|
+
// Add owners from input
|
|
561
|
+
this.ownerUserIds.forEach(id => {
|
|
562
|
+
this.users.push({ userExternalId: id, rol: TasUserRole.OWNER });
|
|
563
|
+
});
|
|
564
|
+
// Add regular users from input
|
|
565
|
+
this.regularUserIds.forEach(id => {
|
|
566
|
+
this.users.push({ userExternalId: id, rol: TasUserRole.USER });
|
|
567
|
+
});
|
|
568
|
+
// Add moderators from input
|
|
569
|
+
this.moderatorUserIds.forEach(id => {
|
|
570
|
+
this.users.push({ userExternalId: id, rol: TasUserRole.MODERATOR });
|
|
571
|
+
});
|
|
512
572
|
}
|
|
513
573
|
setupViewModeSubscription() {
|
|
514
|
-
this.subscriptions.add(this.tasService.viewMode$.subscribe(
|
|
574
|
+
this.subscriptions.add(this.tasService.viewMode$.subscribe(mode => {
|
|
575
|
+
// Re-open video call modal when returning from PiP mode
|
|
576
|
+
if (mode === ViewMode.FULLSCREEN &&
|
|
577
|
+
this.tasService.isCallActive() &&
|
|
578
|
+
!this.videoCallModalRef) {
|
|
579
|
+
const sessionId = this.tasService.sessionId;
|
|
580
|
+
const token = this.tasService.token;
|
|
581
|
+
if (sessionId && token) {
|
|
582
|
+
this.openVideoCallModal(true);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
}));
|
|
586
|
+
}
|
|
587
|
+
openVideoCallModal(isReturningFromPip = false) {
|
|
588
|
+
this.videoCallModalRef = this.modalService.open(TasVideocallComponent, {
|
|
589
|
+
size: 'xl',
|
|
590
|
+
windowClass: 'tas-video-modal',
|
|
591
|
+
backdrop: 'static',
|
|
592
|
+
keyboard: false
|
|
593
|
+
});
|
|
594
|
+
const sessionIdToUse = this.sessionId || this.tasService.sessionId;
|
|
595
|
+
const tokenToUse = this.token || this.tasService.token;
|
|
596
|
+
this.videoCallModalRef.componentInstance.sessionId = sessionIdToUse;
|
|
597
|
+
this.videoCallModalRef.componentInstance.token = tokenToUse;
|
|
598
|
+
this.videoCallModalRef.componentInstance.isReturningFromPip = isReturningFromPip;
|
|
599
|
+
this.videoCallModalRef.result.then(() => { this.videoCallModalRef = null; }, () => { this.videoCallModalRef = null; });
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
TasWaitingRoomComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasWaitingRoomComponent, deps: [{ token: i1.NgbActiveModal }, { token: TasService }, { token: i1.NgbModal }], target: i0.ɵɵFactoryTarget.Component });
|
|
603
|
+
TasWaitingRoomComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: TasWaitingRoomComponent, selector: "tas-waiting-room", inputs: { appointmentId: "appointmentId", product: "product", tenantId: "tenantId", currentUser: "currentUser", ownerUserIds: "ownerUserIds", regularUserIds: "regularUserIds", moderatorUserIds: "moderatorUserIds" }, ngImport: i0, template: "<div class=\"tas-waiting-room\">\n\t<!-- Header -->\n\t<div class=\"waiting-room-header\">\n\t\t<div class=\"header-icon\">\n\t\t\t<i class=\"fa fa-video-camera\"></i>\n\t\t</div>\n\t\t<h2 class=\"header-title\">Waiting Room</h2>\n\t\t<p class=\"header-subtitle\">Prepare for your video call</p>\n\t\t<button type=\"button\" class=\"close-btn\" (click)=\"cancel()\" aria-label=\"Close\">\n\t\t\t<span aria-hidden=\"true\">×</span>\n\t\t</button>\n\t</div>\n\n\t<!-- Content -->\n\t<div class=\"waiting-room-content\">\n\t\t<!-- IDLE State -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.IDLE\">\n\t\t\t<div class=\"state-icon idle\">\n\t\t\t\t<i class=\"fa fa-plus-circle\"></i>\n\t\t\t</div>\n\t\t\t<p class=\"state-message\">\n\t\t\t\tCreate a new video call room\n\t\t\t</p>\n\t\t\t<p class=\"state-submessage\">\n\t\t\t\tPress the button to begin\n\t\t\t</p>\n\t\t\t<button \n\t\t\t\ttype=\"button\" \n\t\t\t\tclass=\"btn action-btn create-btn\"\n\t\t\t\t(click)=\"createRoom()\">\n\t\t\t\t<i class=\"fa fa-plus\"></i>\n\t\t\t\tCreate Room\n\t\t\t</button>\n\t\t</div>\n\n\t\t<!-- CREATING_ROOM State -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.CREATING_ROOM\">\n\t\t\t<div class=\"state-icon loading\">\n\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t</div>\n\t\t\t<p class=\"state-message\">\n\t\t\t\tCreating video call room...\n\t\t\t</p>\n\t\t\t<div class=\"progress-steps\">\n\t\t\t\t<div class=\"step active\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Creating</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Access</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Ready</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<!-- GETTING_TOKEN State -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.GETTING_TOKEN\">\n\t\t\t<div class=\"state-icon loading\">\n\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t</div>\n\t\t\t<p class=\"state-message\">\n\t\t\t\tPreparing room access...\n\t\t\t</p>\n\t\t\t<div class=\"progress-steps\">\n\t\t\t\t<div class=\"step completed\">\n\t\t\t\t\t<span class=\"step-indicator\"><i class=\"fa fa-check\"></i></span>\n\t\t\t\t\t<span class=\"step-label\">Created</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step active\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Access</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Ready</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<!-- READY State -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.READY\">\n\t\t\t<div class=\"state-icon ready\">\n\t\t\t\t<i class=\"fa fa-check-circle\"></i>\n\t\t\t</div>\n\t\t\t<p class=\"state-message success\">\n\t\t\t\tRoom is ready!\n\t\t\t</p>\n\t\t\t<p class=\"state-submessage\">\n\t\t\t\tYou can join the video call when ready\n\t\t\t</p>\n\t\t\t<div class=\"progress-steps\">\n\t\t\t\t<div class=\"step completed\">\n\t\t\t\t\t<span class=\"step-indicator\"><i class=\"fa fa-check\"></i></span>\n\t\t\t\t\t<span class=\"step-label\">Created</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step completed\">\n\t\t\t\t\t<span class=\"step-indicator\"><i class=\"fa fa-check\"></i></span>\n\t\t\t\t\t<span class=\"step-label\">Access</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step completed\">\n\t\t\t\t\t<span class=\"step-indicator\"><i class=\"fa fa-check\"></i></span>\n\t\t\t\t\t<span class=\"step-label\">Ready</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<button \n\t\t\t\ttype=\"button\" \n\t\t\t\tclass=\"btn action-btn join-btn\"\n\t\t\t\t(click)=\"joinSession()\">\n\t\t\t\t<i class=\"fa fa-sign-in\"></i>\n\t\t\t\tJoin Session\n\t\t\t</button>\n\t\t</div>\n\n\t\t<!-- ERROR State -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.ERROR\">\n\t\t\t<div class=\"state-icon error\">\n\t\t\t\t<i class=\"fa fa-exclamation-triangle\"></i>\n\t\t\t</div>\n\t\t\t<p class=\"state-message error\">\n\t\t\t\tAn error occurred\n\t\t\t</p>\n\t\t\t<p class=\"error-details\" *ngIf=\"errorMessage\">\n\t\t\t\t{{ errorMessage }}\n\t\t\t</p>\n\t\t\t<button \n\t\t\t\ttype=\"button\" \n\t\t\t\tclass=\"btn action-btn retry-btn\"\n\t\t\t\t(click)=\"retry()\">\n\t\t\t\t<i class=\"fa fa-refresh\"></i>\n\t\t\t\tRetry\n\t\t\t</button>\n\t\t</div>\n\t</div>\n\n\t<!-- Footer -->\n\t<div class=\"waiting-room-footer\">\n\t\t<button \n\t\t\ttype=\"button\" \n\t\t\tclass=\"btn cancel-btn\"\n\t\t\t(click)=\"cancel()\">\n\t\t\tCancel\n\t\t</button>\n\t</div>\n</div>\n\n", styles: [".tas-waiting-room{display:flex;flex-direction:column;min-height:420px;background:#ffffff;border-radius:5px;overflow:hidden}.waiting-room-header{position:relative;padding:32px 40px 24px;text-align:center;border-bottom:1px solid #e9ecef}.waiting-room-header .header-icon{width:72px;height:72px;margin:0 auto 16px;background:linear-gradient(135deg,#1da4b1 0%,#0077b3 100%);border-radius:50%;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 16px #1da4b140}.waiting-room-header .header-icon i{font-size:28px;color:#fff}.waiting-room-header .header-title{margin:0 0 8px;font-size:20px;font-weight:700;line-height:28px;color:#212529}.waiting-room-header .header-subtitle{margin:0;font-size:14px;color:#6c757d;font-weight:400}.waiting-room-header .close-btn{position:absolute;top:16px;right:16px;width:32px;height:32px;border:none;background:transparent;border-radius:4px;color:#6c757d;cursor:pointer;transition:all .2s ease;font-size:20px}.waiting-room-header .close-btn:hover{background:#f8f9fa;color:#212529}.waiting-room-content{flex:1;display:flex;align-items:center;justify-content:center;padding:32px 40px;background:#ffffff}.state-container{text-align:center;max-width:360px;width:100%}.state-icon{width:80px;height:80px;margin:0 auto 24px;border-radius:50%;display:flex;align-items:center;justify-content:center}.state-icon i{font-size:36px}.state-icon.idle{background:rgba(29,164,177,.1);border:2px dashed #1da4b1}.state-icon.idle i{color:#1da4b1}.state-icon.loading{background:rgba(29,164,177,.1);border:2px solid #1da4b1}.state-icon.ready{background:linear-gradient(135deg,#1da4b1 0%,#38b89a 100%);box-shadow:0 4px 16px #1da4b14d}.state-icon.ready i{color:#fff}.state-icon.error{background:rgba(238,49,107,.1);border:2px solid #ee316b}.state-icon.error i{color:#ee316b}.spinner{width:40px;height:40px;border:3px solid #e9ecef;border-top-color:#1da4b1;border-radius:50%;animation:spin 1s linear infinite}.state-message{font-size:16px;font-weight:600;margin:0 0 8px;color:#212529;line-height:24px}.state-message.success{color:#1da4b1}.state-message.error{color:#ee316b}.state-submessage{font-size:14px;color:#6c757d;margin:0 0 24px;font-weight:400}.error-details{font-size:13px;color:#ee316b;margin:0 0 24px;padding:12px 16px;background:rgba(238,49,107,.08);border-radius:8px;border:1px solid rgba(238,49,107,.2)}.progress-steps{display:flex;justify-content:center;gap:24px;margin:24px 0 32px}.step{display:flex;flex-direction:column;align-items:center;gap:8px}.step .step-indicator{width:32px;height:32px;border-radius:50%;background:#f8f9fa;border:2px solid #e9ecef;display:flex;align-items:center;justify-content:center;transition:all .3s ease}.step .step-indicator i{font-size:12px;color:#fff}.step .step-label{font-size:11px;color:#6c757d;text-transform:uppercase;letter-spacing:.5px;font-weight:500}.step.active .step-indicator{background:rgba(29,164,177,.1);border-color:#1da4b1;animation:pulse-active 1.5s infinite}.step.active .step-label{color:#1da4b1;font-weight:600}.step.completed .step-indicator{background:#1da4b1;border-color:#1da4b1}.step.completed .step-label{color:#1da4b1;font-weight:600}.action-btn{padding:12px 32px;font-size:16px;font-weight:600;border-radius:4px;border:none;cursor:pointer;transition:all .2s ease;display:inline-flex;align-items:center;gap:10px}.action-btn i{font-size:16px}.action-btn.create-btn{background:#0077b3;color:#fff;box-shadow:0 2px 8px #0077b340}.action-btn.create-btn:hover{background:#005c8a;box-shadow:0 4px 12px #0077b359}.action-btn.create-btn:active{transform:translateY(1px)}.action-btn.join-btn{background:#1da4b1;color:#fff;box-shadow:0 2px 8px #1da4b140;animation:pulse-ready 2s infinite}.action-btn.join-btn:hover{background:#17848e;box-shadow:0 4px 12px #1da4b159}.action-btn.join-btn:active{transform:translateY(1px)}.action-btn.retry-btn{background:transparent;color:#6c757d;border:1px solid #e9ecef}.action-btn.retry-btn:hover{background:#f8f9fa;border-color:#6c757d;color:#212529}.waiting-room-footer{padding:16px 40px 24px;background:#ffffff;border-top:1px solid #e9ecef;display:flex;justify-content:center}.waiting-room-footer .cancel-btn{padding:10px 24px;font-size:14px;font-weight:600;border-radius:4px;background:transparent;color:#6c757d;border:none;cursor:pointer;transition:all .2s ease}.waiting-room-footer .cancel-btn:hover{background:#f8f9fa;color:#212529}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse-active{0%,to{box-shadow:0 0 #1da4b166}50%{box-shadow:0 0 0 8px #1da4b100}}@keyframes pulse-ready{0%,to{box-shadow:0 2px 8px #1da4b140}50%{box-shadow:0 4px 16px #1da4b166}}@media (max-width: 576px){.tas-waiting-room{min-height:380px}.waiting-room-header{padding:24px 24px 20px}.waiting-room-header .header-icon{width:56px;height:56px}.waiting-room-header .header-icon i{font-size:22px}.waiting-room-header .header-title{font-size:18px}.waiting-room-content{padding:24px}.state-icon{width:64px;height:64px}.state-icon i{font-size:28px}.spinner{width:32px;height:32px}.progress-steps{gap:12px}.step .step-indicator{width:28px;height:28px}.step .step-label{font-size:9px}.action-btn{padding:10px 24px;font-size:14px}.waiting-room-footer{padding:16px 24px 20px}}\n"], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
604
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasWaitingRoomComponent, decorators: [{
|
|
605
|
+
type: Component,
|
|
606
|
+
args: [{ selector: 'tas-waiting-room', template: "<div class=\"tas-waiting-room\">\n\t<!-- Header -->\n\t<div class=\"waiting-room-header\">\n\t\t<div class=\"header-icon\">\n\t\t\t<i class=\"fa fa-video-camera\"></i>\n\t\t</div>\n\t\t<h2 class=\"header-title\">Waiting Room</h2>\n\t\t<p class=\"header-subtitle\">Prepare for your video call</p>\n\t\t<button type=\"button\" class=\"close-btn\" (click)=\"cancel()\" aria-label=\"Close\">\n\t\t\t<span aria-hidden=\"true\">×</span>\n\t\t</button>\n\t</div>\n\n\t<!-- Content -->\n\t<div class=\"waiting-room-content\">\n\t\t<!-- IDLE State -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.IDLE\">\n\t\t\t<div class=\"state-icon idle\">\n\t\t\t\t<i class=\"fa fa-plus-circle\"></i>\n\t\t\t</div>\n\t\t\t<p class=\"state-message\">\n\t\t\t\tCreate a new video call room\n\t\t\t</p>\n\t\t\t<p class=\"state-submessage\">\n\t\t\t\tPress the button to begin\n\t\t\t</p>\n\t\t\t<button \n\t\t\t\ttype=\"button\" \n\t\t\t\tclass=\"btn action-btn create-btn\"\n\t\t\t\t(click)=\"createRoom()\">\n\t\t\t\t<i class=\"fa fa-plus\"></i>\n\t\t\t\tCreate Room\n\t\t\t</button>\n\t\t</div>\n\n\t\t<!-- CREATING_ROOM State -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.CREATING_ROOM\">\n\t\t\t<div class=\"state-icon loading\">\n\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t</div>\n\t\t\t<p class=\"state-message\">\n\t\t\t\tCreating video call room...\n\t\t\t</p>\n\t\t\t<div class=\"progress-steps\">\n\t\t\t\t<div class=\"step active\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Creating</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Access</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Ready</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<!-- GETTING_TOKEN State -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.GETTING_TOKEN\">\n\t\t\t<div class=\"state-icon loading\">\n\t\t\t\t<div class=\"spinner\"></div>\n\t\t\t</div>\n\t\t\t<p class=\"state-message\">\n\t\t\t\tPreparing room access...\n\t\t\t</p>\n\t\t\t<div class=\"progress-steps\">\n\t\t\t\t<div class=\"step completed\">\n\t\t\t\t\t<span class=\"step-indicator\"><i class=\"fa fa-check\"></i></span>\n\t\t\t\t\t<span class=\"step-label\">Created</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step active\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Access</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step\">\n\t\t\t\t\t<span class=\"step-indicator\"></span>\n\t\t\t\t\t<span class=\"step-label\">Ready</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\n\t\t<!-- READY State -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.READY\">\n\t\t\t<div class=\"state-icon ready\">\n\t\t\t\t<i class=\"fa fa-check-circle\"></i>\n\t\t\t</div>\n\t\t\t<p class=\"state-message success\">\n\t\t\t\tRoom is ready!\n\t\t\t</p>\n\t\t\t<p class=\"state-submessage\">\n\t\t\t\tYou can join the video call when ready\n\t\t\t</p>\n\t\t\t<div class=\"progress-steps\">\n\t\t\t\t<div class=\"step completed\">\n\t\t\t\t\t<span class=\"step-indicator\"><i class=\"fa fa-check\"></i></span>\n\t\t\t\t\t<span class=\"step-label\">Created</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step completed\">\n\t\t\t\t\t<span class=\"step-indicator\"><i class=\"fa fa-check\"></i></span>\n\t\t\t\t\t<span class=\"step-label\">Access</span>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"step completed\">\n\t\t\t\t\t<span class=\"step-indicator\"><i class=\"fa fa-check\"></i></span>\n\t\t\t\t\t<span class=\"step-label\">Ready</span>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<button \n\t\t\t\ttype=\"button\" \n\t\t\t\tclass=\"btn action-btn join-btn\"\n\t\t\t\t(click)=\"joinSession()\">\n\t\t\t\t<i class=\"fa fa-sign-in\"></i>\n\t\t\t\tJoin Session\n\t\t\t</button>\n\t\t</div>\n\n\t\t<!-- ERROR State -->\n\t\t<div class=\"state-container\" *ngIf=\"state === WaitingRoomState.ERROR\">\n\t\t\t<div class=\"state-icon error\">\n\t\t\t\t<i class=\"fa fa-exclamation-triangle\"></i>\n\t\t\t</div>\n\t\t\t<p class=\"state-message error\">\n\t\t\t\tAn error occurred\n\t\t\t</p>\n\t\t\t<p class=\"error-details\" *ngIf=\"errorMessage\">\n\t\t\t\t{{ errorMessage }}\n\t\t\t</p>\n\t\t\t<button \n\t\t\t\ttype=\"button\" \n\t\t\t\tclass=\"btn action-btn retry-btn\"\n\t\t\t\t(click)=\"retry()\">\n\t\t\t\t<i class=\"fa fa-refresh\"></i>\n\t\t\t\tRetry\n\t\t\t</button>\n\t\t</div>\n\t</div>\n\n\t<!-- Footer -->\n\t<div class=\"waiting-room-footer\">\n\t\t<button \n\t\t\ttype=\"button\" \n\t\t\tclass=\"btn cancel-btn\"\n\t\t\t(click)=\"cancel()\">\n\t\t\tCancel\n\t\t</button>\n\t</div>\n</div>\n\n", styles: [".tas-waiting-room{display:flex;flex-direction:column;min-height:420px;background:#ffffff;border-radius:5px;overflow:hidden}.waiting-room-header{position:relative;padding:32px 40px 24px;text-align:center;border-bottom:1px solid #e9ecef}.waiting-room-header .header-icon{width:72px;height:72px;margin:0 auto 16px;background:linear-gradient(135deg,#1da4b1 0%,#0077b3 100%);border-radius:50%;display:flex;align-items:center;justify-content:center;box-shadow:0 4px 16px #1da4b140}.waiting-room-header .header-icon i{font-size:28px;color:#fff}.waiting-room-header .header-title{margin:0 0 8px;font-size:20px;font-weight:700;line-height:28px;color:#212529}.waiting-room-header .header-subtitle{margin:0;font-size:14px;color:#6c757d;font-weight:400}.waiting-room-header .close-btn{position:absolute;top:16px;right:16px;width:32px;height:32px;border:none;background:transparent;border-radius:4px;color:#6c757d;cursor:pointer;transition:all .2s ease;font-size:20px}.waiting-room-header .close-btn:hover{background:#f8f9fa;color:#212529}.waiting-room-content{flex:1;display:flex;align-items:center;justify-content:center;padding:32px 40px;background:#ffffff}.state-container{text-align:center;max-width:360px;width:100%}.state-icon{width:80px;height:80px;margin:0 auto 24px;border-radius:50%;display:flex;align-items:center;justify-content:center}.state-icon i{font-size:36px}.state-icon.idle{background:rgba(29,164,177,.1);border:2px dashed #1da4b1}.state-icon.idle i{color:#1da4b1}.state-icon.loading{background:rgba(29,164,177,.1);border:2px solid #1da4b1}.state-icon.ready{background:linear-gradient(135deg,#1da4b1 0%,#38b89a 100%);box-shadow:0 4px 16px #1da4b14d}.state-icon.ready i{color:#fff}.state-icon.error{background:rgba(238,49,107,.1);border:2px solid #ee316b}.state-icon.error i{color:#ee316b}.spinner{width:40px;height:40px;border:3px solid #e9ecef;border-top-color:#1da4b1;border-radius:50%;animation:spin 1s linear infinite}.state-message{font-size:16px;font-weight:600;margin:0 0 8px;color:#212529;line-height:24px}.state-message.success{color:#1da4b1}.state-message.error{color:#ee316b}.state-submessage{font-size:14px;color:#6c757d;margin:0 0 24px;font-weight:400}.error-details{font-size:13px;color:#ee316b;margin:0 0 24px;padding:12px 16px;background:rgba(238,49,107,.08);border-radius:8px;border:1px solid rgba(238,49,107,.2)}.progress-steps{display:flex;justify-content:center;gap:24px;margin:24px 0 32px}.step{display:flex;flex-direction:column;align-items:center;gap:8px}.step .step-indicator{width:32px;height:32px;border-radius:50%;background:#f8f9fa;border:2px solid #e9ecef;display:flex;align-items:center;justify-content:center;transition:all .3s ease}.step .step-indicator i{font-size:12px;color:#fff}.step .step-label{font-size:11px;color:#6c757d;text-transform:uppercase;letter-spacing:.5px;font-weight:500}.step.active .step-indicator{background:rgba(29,164,177,.1);border-color:#1da4b1;animation:pulse-active 1.5s infinite}.step.active .step-label{color:#1da4b1;font-weight:600}.step.completed .step-indicator{background:#1da4b1;border-color:#1da4b1}.step.completed .step-label{color:#1da4b1;font-weight:600}.action-btn{padding:12px 32px;font-size:16px;font-weight:600;border-radius:4px;border:none;cursor:pointer;transition:all .2s ease;display:inline-flex;align-items:center;gap:10px}.action-btn i{font-size:16px}.action-btn.create-btn{background:#0077b3;color:#fff;box-shadow:0 2px 8px #0077b340}.action-btn.create-btn:hover{background:#005c8a;box-shadow:0 4px 12px #0077b359}.action-btn.create-btn:active{transform:translateY(1px)}.action-btn.join-btn{background:#1da4b1;color:#fff;box-shadow:0 2px 8px #1da4b140;animation:pulse-ready 2s infinite}.action-btn.join-btn:hover{background:#17848e;box-shadow:0 4px 12px #1da4b159}.action-btn.join-btn:active{transform:translateY(1px)}.action-btn.retry-btn{background:transparent;color:#6c757d;border:1px solid #e9ecef}.action-btn.retry-btn:hover{background:#f8f9fa;border-color:#6c757d;color:#212529}.waiting-room-footer{padding:16px 40px 24px;background:#ffffff;border-top:1px solid #e9ecef;display:flex;justify-content:center}.waiting-room-footer .cancel-btn{padding:10px 24px;font-size:14px;font-weight:600;border-radius:4px;background:transparent;color:#6c757d;border:none;cursor:pointer;transition:all .2s ease}.waiting-room-footer .cancel-btn:hover{background:#f8f9fa;color:#212529}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse-active{0%,to{box-shadow:0 0 #1da4b166}50%{box-shadow:0 0 0 8px #1da4b100}}@keyframes pulse-ready{0%,to{box-shadow:0 2px 8px #1da4b140}50%{box-shadow:0 4px 16px #1da4b166}}@media (max-width: 576px){.tas-waiting-room{min-height:380px}.waiting-room-header{padding:24px 24px 20px}.waiting-room-header .header-icon{width:56px;height:56px}.waiting-room-header .header-icon i{font-size:22px}.waiting-room-header .header-title{font-size:18px}.waiting-room-content{padding:24px}.state-icon{width:64px;height:64px}.state-icon i{font-size:28px}.spinner{width:32px;height:32px}.progress-steps{gap:12px}.step .step-indicator{width:28px;height:28px}.step .step-label{font-size:9px}.action-btn{padding:10px 24px;font-size:14px}.waiting-room-footer{padding:16px 24px 20px}}\n"] }]
|
|
607
|
+
}], ctorParameters: function () { return [{ type: i1.NgbActiveModal }, { type: TasService }, { type: i1.NgbModal }]; }, propDecorators: { appointmentId: [{
|
|
608
|
+
type: Input
|
|
609
|
+
}], product: [{
|
|
610
|
+
type: Input
|
|
611
|
+
}], tenantId: [{
|
|
612
|
+
type: Input
|
|
613
|
+
}], currentUser: [{
|
|
614
|
+
type: Input
|
|
615
|
+
}], ownerUserIds: [{
|
|
616
|
+
type: Input
|
|
617
|
+
}], regularUserIds: [{
|
|
618
|
+
type: Input
|
|
619
|
+
}], moderatorUserIds: [{
|
|
620
|
+
type: Input
|
|
621
|
+
}] } });
|
|
622
|
+
|
|
623
|
+
class TasButtonComponent {
|
|
624
|
+
constructor(modalService, tasService) {
|
|
625
|
+
this.modalService = modalService;
|
|
626
|
+
this.tasService = tasService;
|
|
627
|
+
this.appointmentId = 1;
|
|
628
|
+
this.product = "uell";
|
|
629
|
+
this.tenantId = "";
|
|
630
|
+
this.regularUserIds = [];
|
|
631
|
+
this.moderatorUserIds = [];
|
|
632
|
+
this.isLoading = false;
|
|
633
|
+
this.subscriptions = new Subscription();
|
|
634
|
+
this.currentModalRef = null;
|
|
635
|
+
this.videoCallModalRef = null;
|
|
636
|
+
}
|
|
637
|
+
ngOnInit() {
|
|
638
|
+
if (!this.ownerUserIds || this.ownerUserIds.length !== 1) {
|
|
639
|
+
throw new Error('tas-btn: ownerUserIds input is required and must contain exactly one user');
|
|
640
|
+
}
|
|
641
|
+
// Subscribe to viewMode to handle PiP return
|
|
642
|
+
this.subscriptions.add(this.tasService.viewMode$.subscribe(mode => {
|
|
643
|
+
// Reopen video call modal when returning from PiP
|
|
515
644
|
if (mode === ViewMode.FULLSCREEN &&
|
|
516
645
|
this.tasService.isCallActive() &&
|
|
517
|
-
!this.
|
|
646
|
+
!this.videoCallModalRef) {
|
|
518
647
|
const sessionId = this.tasService.sessionId;
|
|
519
648
|
const token = this.tasService.token;
|
|
520
649
|
if (sessionId && token) {
|
|
521
|
-
this.openVideoCallModal(
|
|
650
|
+
this.openVideoCallModal(true);
|
|
522
651
|
}
|
|
523
652
|
}
|
|
653
|
+
// When entering PiP, clear the videoCallModalRef since modal will close
|
|
654
|
+
if (mode === ViewMode.PIP) {
|
|
655
|
+
this.videoCallModalRef = null;
|
|
656
|
+
}
|
|
524
657
|
}));
|
|
525
658
|
}
|
|
526
|
-
|
|
527
|
-
this.
|
|
528
|
-
|
|
529
|
-
|
|
659
|
+
ngOnDestroy() {
|
|
660
|
+
this.subscriptions.unsubscribe();
|
|
661
|
+
}
|
|
662
|
+
onClick() {
|
|
663
|
+
var _a;
|
|
664
|
+
if (!this.tenantId || !((_a = this.currentUser) === null || _a === void 0 ? void 0 : _a.name)) {
|
|
665
|
+
console.error("Tenant ID or current user not available");
|
|
666
|
+
return;
|
|
667
|
+
}
|
|
668
|
+
this.openWaitingRoomModal();
|
|
669
|
+
}
|
|
670
|
+
openWaitingRoomModal() {
|
|
671
|
+
this.currentModalRef = this.modalService.open(TasWaitingRoomComponent, {
|
|
672
|
+
size: "lg",
|
|
673
|
+
windowClass: "tas-waiting-room-modal",
|
|
530
674
|
backdrop: "static",
|
|
531
675
|
keyboard: false,
|
|
676
|
+
centered: true
|
|
532
677
|
});
|
|
533
|
-
|
|
534
|
-
this.currentModalRef.componentInstance.
|
|
535
|
-
this.currentModalRef.componentInstance.
|
|
536
|
-
|
|
537
|
-
this.currentModalRef.
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
678
|
+
// Pass all necessary inputs to the waiting room component
|
|
679
|
+
this.currentModalRef.componentInstance.appointmentId = this.appointmentId;
|
|
680
|
+
this.currentModalRef.componentInstance.product = this.product;
|
|
681
|
+
this.currentModalRef.componentInstance.tenantId = this.tenantId;
|
|
682
|
+
this.currentModalRef.componentInstance.currentUser = this.currentUser;
|
|
683
|
+
this.currentModalRef.componentInstance.ownerUserIds = this.ownerUserIds;
|
|
684
|
+
this.currentModalRef.componentInstance.regularUserIds = this.regularUserIds;
|
|
685
|
+
this.currentModalRef.componentInstance.moderatorUserIds = this.moderatorUserIds;
|
|
686
|
+
this.currentModalRef.result.then(() => { this.currentModalRef = null; }, () => { this.currentModalRef = null; });
|
|
687
|
+
}
|
|
688
|
+
openVideoCallModal(isReturningFromPip = false) {
|
|
689
|
+
this.videoCallModalRef = this.modalService.open(TasVideocallComponent, {
|
|
690
|
+
size: 'xl',
|
|
691
|
+
windowClass: 'tas-video-modal',
|
|
692
|
+
backdrop: 'static',
|
|
693
|
+
keyboard: false
|
|
541
694
|
});
|
|
695
|
+
this.videoCallModalRef.componentInstance.sessionId = this.tasService.sessionId;
|
|
696
|
+
this.videoCallModalRef.componentInstance.token = this.tasService.token;
|
|
697
|
+
this.videoCallModalRef.componentInstance.isReturningFromPip = isReturningFromPip;
|
|
698
|
+
this.videoCallModalRef.result.then(() => { this.videoCallModalRef = null; }, () => { this.videoCallModalRef = null; });
|
|
542
699
|
}
|
|
543
700
|
}
|
|
544
|
-
TasButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasButtonComponent, deps: [{ token:
|
|
545
|
-
TasButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: TasButtonComponent, selector: "tas-btn", ngImport: i0, template: "<button\n
|
|
701
|
+
TasButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasButtonComponent, deps: [{ token: i1.NgbModal }, { token: TasService }], target: i0.ɵɵFactoryTarget.Component });
|
|
702
|
+
TasButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: TasButtonComponent, selector: "tas-btn", inputs: { appointmentId: "appointmentId", product: "product", tenantId: "tenantId", currentUser: "currentUser", ownerUserIds: "ownerUserIds", regularUserIds: "regularUserIds", moderatorUserIds: "moderatorUserIds" }, ngImport: i0, template: "<button\n\ttype=\"button\"\n\tclass=\"btn btn-primary tas-btn\"\n\t(click)=\"onClick()\"\n\t[disabled]=\"isLoading\"\n>\n\t<i class=\"fa fa-video-camera\" aria-hidden=\"true\" *ngIf=\"!isLoading\"></i>\n\t<span *ngIf=\"!isLoading\"> Iniciar TAS</span>\n\t<span *ngIf=\"isLoading\"> Processing...</span>\n</button>\n\n", styles: [":host{display:inline-block}.tas-btn{background-color:#ee316b!important;color:#fff!important;border-color:#ee316b!important;margin-right:24px}.tas-btn:disabled{background-color:#ccc!important;border-color:#ccc!important;cursor:not-allowed}.tas-btn:hover:not(:disabled){background-color:#d62a5f!important;border-color:#d62a5f!important}.tas-btn i{margin-right:5px}\n"], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
|
|
546
703
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasButtonComponent, decorators: [{
|
|
547
704
|
type: Component,
|
|
548
|
-
args: [{ selector: "tas-btn", template: "<button\n
|
|
549
|
-
}], ctorParameters: function () {
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
705
|
+
args: [{ selector: "tas-btn", template: "<button\n\ttype=\"button\"\n\tclass=\"btn btn-primary tas-btn\"\n\t(click)=\"onClick()\"\n\t[disabled]=\"isLoading\"\n>\n\t<i class=\"fa fa-video-camera\" aria-hidden=\"true\" *ngIf=\"!isLoading\"></i>\n\t<span *ngIf=\"!isLoading\"> Iniciar TAS</span>\n\t<span *ngIf=\"isLoading\"> Processing...</span>\n</button>\n\n", styles: [":host{display:inline-block}.tas-btn{background-color:#ee316b!important;color:#fff!important;border-color:#ee316b!important;margin-right:24px}.tas-btn:disabled{background-color:#ccc!important;border-color:#ccc!important;cursor:not-allowed}.tas-btn:hover:not(:disabled){background-color:#d62a5f!important;border-color:#d62a5f!important}.tas-btn i{margin-right:5px}\n"] }]
|
|
706
|
+
}], ctorParameters: function () { return [{ type: i1.NgbModal }, { type: TasService }]; }, propDecorators: { appointmentId: [{
|
|
707
|
+
type: Input
|
|
708
|
+
}], product: [{
|
|
709
|
+
type: Input
|
|
710
|
+
}], tenantId: [{
|
|
711
|
+
type: Input
|
|
712
|
+
}], currentUser: [{
|
|
713
|
+
type: Input
|
|
714
|
+
}], ownerUserIds: [{
|
|
715
|
+
type: Input
|
|
716
|
+
}], regularUserIds: [{
|
|
717
|
+
type: Input
|
|
718
|
+
}], moderatorUserIds: [{
|
|
719
|
+
type: Input
|
|
720
|
+
}] } });
|
|
557
721
|
|
|
558
722
|
class TasFloatingCallComponent {
|
|
559
723
|
constructor(tasService) {
|
|
@@ -561,13 +725,15 @@ class TasFloatingCallComponent {
|
|
|
561
725
|
this.isVisible = false;
|
|
562
726
|
this.isMuted = false;
|
|
563
727
|
this.subscriptions = new Subscription();
|
|
728
|
+
// Margin from screen edges (in pixels)
|
|
729
|
+
this.PIP_MARGIN = 20;
|
|
564
730
|
}
|
|
565
731
|
ngOnInit() {
|
|
566
732
|
this.setupSubscriptions();
|
|
567
733
|
}
|
|
568
734
|
ngOnDestroy() {
|
|
569
735
|
this.subscriptions.unsubscribe();
|
|
570
|
-
interact(
|
|
736
|
+
interact('.tas-floating-container').unset();
|
|
571
737
|
}
|
|
572
738
|
// Public Methods
|
|
573
739
|
onExpand() {
|
|
@@ -581,115 +747,171 @@ class TasFloatingCallComponent {
|
|
|
581
747
|
}
|
|
582
748
|
// Private Methods
|
|
583
749
|
setupSubscriptions() {
|
|
584
|
-
|
|
750
|
+
// Call state subscription
|
|
751
|
+
this.subscriptions.add(this.tasService.callState$.subscribe(state => {
|
|
585
752
|
if (state === CallState.DISCONNECTED) {
|
|
586
753
|
this.isVisible = false;
|
|
587
754
|
}
|
|
588
755
|
}));
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
756
|
+
// View mode subscription
|
|
757
|
+
this.subscriptions.add(this.tasService.viewMode$.subscribe(mode => {
|
|
758
|
+
this.isVisible = mode === ViewMode.PIP && this.tasService.isCallActive();
|
|
592
759
|
if (this.isVisible) {
|
|
593
760
|
setTimeout(() => this.initInteract(), 100);
|
|
594
761
|
}
|
|
595
762
|
}));
|
|
596
|
-
|
|
763
|
+
// Mute state subscription
|
|
764
|
+
this.subscriptions.add(this.tasService.isMuted$.subscribe(muted => {
|
|
597
765
|
this.isMuted = muted;
|
|
598
766
|
}));
|
|
599
767
|
}
|
|
600
768
|
initInteract() {
|
|
601
|
-
interact(
|
|
602
|
-
|
|
769
|
+
interact('.tas-floating-container').unset();
|
|
770
|
+
// Create restriction area with margin
|
|
771
|
+
const margin = this.PIP_MARGIN;
|
|
772
|
+
const restrictToBodyWithMargin = {
|
|
773
|
+
restriction: () => {
|
|
774
|
+
return {
|
|
775
|
+
left: margin,
|
|
776
|
+
top: margin,
|
|
777
|
+
right: window.innerWidth - margin,
|
|
778
|
+
bottom: window.innerHeight - margin
|
|
779
|
+
};
|
|
780
|
+
},
|
|
781
|
+
elementRect: { left: 0, right: 1, top: 0, bottom: 1 }
|
|
782
|
+
};
|
|
783
|
+
interact('.tas-floating-container')
|
|
784
|
+
.draggable({
|
|
603
785
|
inertia: true,
|
|
604
786
|
modifiers: [
|
|
605
|
-
interact.modifiers.
|
|
606
|
-
restriction: "body",
|
|
607
|
-
endOnly: true,
|
|
608
|
-
}),
|
|
787
|
+
interact.modifiers.restrict(restrictToBodyWithMargin)
|
|
609
788
|
],
|
|
610
789
|
autoScroll: false,
|
|
611
790
|
listeners: {
|
|
612
791
|
move: (event) => {
|
|
613
792
|
const target = event.target;
|
|
614
|
-
const x = (parseFloat(target.getAttribute(
|
|
615
|
-
const y = (parseFloat(target.getAttribute(
|
|
793
|
+
const x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx;
|
|
794
|
+
const y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
|
|
795
|
+
target.style.transform = `translate(${x}px, ${y}px)`;
|
|
796
|
+
target.setAttribute('data-x', String(x));
|
|
797
|
+
target.setAttribute('data-y', String(y));
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
})
|
|
801
|
+
.resizable({
|
|
802
|
+
edges: { left: false, right: true, bottom: true, top: false },
|
|
803
|
+
listeners: {
|
|
804
|
+
move: (event) => {
|
|
805
|
+
const target = event.target;
|
|
806
|
+
let x = parseFloat(target.getAttribute('data-x')) || 0;
|
|
807
|
+
let y = parseFloat(target.getAttribute('data-y')) || 0;
|
|
808
|
+
// Update element size
|
|
809
|
+
target.style.width = `${event.rect.width}px`;
|
|
810
|
+
target.style.height = `${event.rect.height}px`;
|
|
811
|
+
// Translate when resizing from top or left edges
|
|
812
|
+
x += event.deltaRect.left;
|
|
813
|
+
y += event.deltaRect.top;
|
|
616
814
|
target.style.transform = `translate(${x}px, ${y}px)`;
|
|
617
|
-
target.setAttribute(
|
|
618
|
-
target.setAttribute(
|
|
619
|
-
}
|
|
815
|
+
target.setAttribute('data-x', String(x));
|
|
816
|
+
target.setAttribute('data-y', String(y));
|
|
817
|
+
}
|
|
620
818
|
},
|
|
819
|
+
modifiers: [
|
|
820
|
+
interact.modifiers.restrictEdges({
|
|
821
|
+
outer: {
|
|
822
|
+
left: margin,
|
|
823
|
+
top: margin,
|
|
824
|
+
right: window.innerWidth - margin,
|
|
825
|
+
bottom: window.innerHeight - margin
|
|
826
|
+
}
|
|
827
|
+
}),
|
|
828
|
+
interact.modifiers.restrictSize({
|
|
829
|
+
min: { width: 200, height: 130 },
|
|
830
|
+
max: { width: 500, height: 350 }
|
|
831
|
+
}),
|
|
832
|
+
interact.modifiers.aspectRatio({ ratio: 'preserve' })
|
|
833
|
+
],
|
|
834
|
+
inertia: true
|
|
621
835
|
});
|
|
622
836
|
}
|
|
623
837
|
}
|
|
624
838
|
TasFloatingCallComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasFloatingCallComponent, deps: [{ token: TasService }], target: i0.ɵɵFactoryTarget.Component });
|
|
625
|
-
TasFloatingCallComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: TasFloatingCallComponent, selector: "tas-floating-call", ngImport: i0, template: "<div class=\"tas-floating-container\" [class.visible]=\"isVisible\">\n
|
|
839
|
+
TasFloatingCallComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: TasFloatingCallComponent, selector: "tas-floating-call", ngImport: i0, template: "<div class=\"tas-floating-container\" [class.visible]=\"isVisible\">\n\t<!-- Video content area - shows main video only -->\n\t<div class=\"floating-content\">\n\t\t<!-- Main video container (subscriber if available, otherwise publisher) -->\n\t\t<div id=\"pip-main-video\" class=\"pip-main-video\"></div>\n\n\t\t<!-- Bottom controls -->\n\t\t<div class=\"floating-controls\">\n\t\t\t<button class=\"action-btn expand-btn\" (click)=\"onExpand()\" title=\"Expand to fullscreen\">\n\t\t\t\t<i class=\"fa fa-expand\"></i>\n\t\t\t</button>\n\t\t\t<button class=\"action-btn mute-btn\" [class.muted]=\"isMuted\" (click)=\"toggleMute()\" [title]=\"isMuted ? 'Unmute microphone' : 'Mute microphone'\">\n\t\t\t\t<i class=\"fa\" [class.fa-microphone]=\"!isMuted\" [class.fa-microphone-slash]=\"isMuted\"></i>\n\t\t\t</button>\n\t\t\t<button class=\"action-btn hangup-btn\" (click)=\"onHangUp()\" title=\"Hang up call\">\n\t\t\t\t<i class=\"fa fa-phone\" style=\"transform: rotate(135deg);\"></i>\n\t\t\t</button>\n\t\t</div>\n\t</div>\n</div>\n\n", styles: [".tas-floating-container{position:fixed;bottom:20px;right:20px;width:280px;height:180px;background:#000;border-radius:12px;box-shadow:0 8px 32px #00000080;z-index:9999;overflow:hidden;touch-action:none;-webkit-user-select:none;user-select:none;transition:opacity .3s ease,visibility .3s ease,box-shadow .2s ease;opacity:0;visibility:hidden;pointer-events:none}.tas-floating-container.visible{opacity:1;visibility:visible;pointer-events:auto}.tas-floating-container:hover{box-shadow:0 8px 32px #00000080,0 0 0 2px #ffffff4d}.floating-content{position:relative;width:100%;height:100%;overflow:hidden}.pip-main-video{position:absolute;top:0;left:0;width:100%;height:100%;background:#000}.pip-main-video ::ng-deep video{width:100%;height:100%;object-fit:cover}.pip-main-video ::ng-deep .OT_subscriber,.pip-main-video ::ng-deep .OT_publisher{width:100%!important;height:100%!important}.pip-main-video ::ng-deep .OT_edge-bar-item,.pip-main-video ::ng-deep .OT_mute,.pip-main-video ::ng-deep .OT_audio-level-meter,.pip-main-video ::ng-deep .OT_bar,.pip-main-video ::ng-deep .OT_name{display:none!important}.floating-controls{position:absolute;bottom:10px;left:50%;transform:translate(-50%);display:flex;gap:12px;padding:6px 14px;background:rgba(0,0,0,.7);border-radius:24px;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);opacity:0;visibility:hidden;transition:opacity .3s ease,visibility .3s ease}.tas-floating-container:hover .floating-controls{opacity:1;visibility:visible}.action-btn{width:32px;height:32px;border:none;border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:13px;transition:all .2s ease}.action-btn.expand-btn{background:rgba(255,255,255,.2);color:#fff}.action-btn.expand-btn:hover{background:rgba(255,255,255,.35);transform:scale(1.1)}.action-btn.mute-btn{background:rgba(255,255,255,.2);color:#fff}.action-btn.mute-btn:hover{background:rgba(255,255,255,.35);transform:scale(1.1)}.action-btn.mute-btn.muted{background:#f39c12;color:#fff}.action-btn.mute-btn.muted:hover{background:#e67e22}.action-btn.hangup-btn{background:#dc3545;color:#fff}.action-btn.hangup-btn:hover{background:#c82333;transform:scale(1.1)}\n"] });
|
|
626
840
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasFloatingCallComponent, decorators: [{
|
|
627
841
|
type: Component,
|
|
628
|
-
args: [{ selector:
|
|
842
|
+
args: [{ selector: 'tas-floating-call', template: "<div class=\"tas-floating-container\" [class.visible]=\"isVisible\">\n\t<!-- Video content area - shows main video only -->\n\t<div class=\"floating-content\">\n\t\t<!-- Main video container (subscriber if available, otherwise publisher) -->\n\t\t<div id=\"pip-main-video\" class=\"pip-main-video\"></div>\n\n\t\t<!-- Bottom controls -->\n\t\t<div class=\"floating-controls\">\n\t\t\t<button class=\"action-btn expand-btn\" (click)=\"onExpand()\" title=\"Expand to fullscreen\">\n\t\t\t\t<i class=\"fa fa-expand\"></i>\n\t\t\t</button>\n\t\t\t<button class=\"action-btn mute-btn\" [class.muted]=\"isMuted\" (click)=\"toggleMute()\" [title]=\"isMuted ? 'Unmute microphone' : 'Mute microphone'\">\n\t\t\t\t<i class=\"fa\" [class.fa-microphone]=\"!isMuted\" [class.fa-microphone-slash]=\"isMuted\"></i>\n\t\t\t</button>\n\t\t\t<button class=\"action-btn hangup-btn\" (click)=\"onHangUp()\" title=\"Hang up call\">\n\t\t\t\t<i class=\"fa fa-phone\" style=\"transform: rotate(135deg);\"></i>\n\t\t\t</button>\n\t\t</div>\n\t</div>\n</div>\n\n", styles: [".tas-floating-container{position:fixed;bottom:20px;right:20px;width:280px;height:180px;background:#000;border-radius:12px;box-shadow:0 8px 32px #00000080;z-index:9999;overflow:hidden;touch-action:none;-webkit-user-select:none;user-select:none;transition:opacity .3s ease,visibility .3s ease,box-shadow .2s ease;opacity:0;visibility:hidden;pointer-events:none}.tas-floating-container.visible{opacity:1;visibility:visible;pointer-events:auto}.tas-floating-container:hover{box-shadow:0 8px 32px #00000080,0 0 0 2px #ffffff4d}.floating-content{position:relative;width:100%;height:100%;overflow:hidden}.pip-main-video{position:absolute;top:0;left:0;width:100%;height:100%;background:#000}.pip-main-video ::ng-deep video{width:100%;height:100%;object-fit:cover}.pip-main-video ::ng-deep .OT_subscriber,.pip-main-video ::ng-deep .OT_publisher{width:100%!important;height:100%!important}.pip-main-video ::ng-deep .OT_edge-bar-item,.pip-main-video ::ng-deep .OT_mute,.pip-main-video ::ng-deep .OT_audio-level-meter,.pip-main-video ::ng-deep .OT_bar,.pip-main-video ::ng-deep .OT_name{display:none!important}.floating-controls{position:absolute;bottom:10px;left:50%;transform:translate(-50%);display:flex;gap:12px;padding:6px 14px;background:rgba(0,0,0,.7);border-radius:24px;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);opacity:0;visibility:hidden;transition:opacity .3s ease,visibility .3s ease}.tas-floating-container:hover .floating-controls{opacity:1;visibility:visible}.action-btn{width:32px;height:32px;border:none;border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:13px;transition:all .2s ease}.action-btn.expand-btn{background:rgba(255,255,255,.2);color:#fff}.action-btn.expand-btn:hover{background:rgba(255,255,255,.35);transform:scale(1.1)}.action-btn.mute-btn{background:rgba(255,255,255,.2);color:#fff}.action-btn.mute-btn:hover{background:rgba(255,255,255,.35);transform:scale(1.1)}.action-btn.mute-btn.muted{background:#f39c12;color:#fff}.action-btn.mute-btn.muted:hover{background:#e67e22}.action-btn.hangup-btn{background:#dc3545;color:#fff}.action-btn.hangup-btn:hover{background:#c82333;transform:scale(1.1)}\n"] }]
|
|
629
843
|
}], ctorParameters: function () { return [{ type: TasService }]; } });
|
|
630
844
|
|
|
631
|
-
class
|
|
845
|
+
class TasUellSdkModule {
|
|
632
846
|
/**
|
|
633
|
-
* Use
|
|
847
|
+
* Use forRoot() to configure the TAS SDK module with required dependencies.
|
|
848
|
+
* This should only be called once in your root AppModule.
|
|
634
849
|
*
|
|
635
850
|
* @example
|
|
636
851
|
* ```typescript
|
|
637
|
-
*
|
|
638
|
-
*
|
|
639
|
-
*
|
|
640
|
-
*
|
|
641
|
-
*
|
|
642
|
-
*
|
|
643
|
-
*
|
|
852
|
+
* import { TasUellSdkModule, TasHttpClient } from 'tas-uell-sdk';
|
|
853
|
+
*
|
|
854
|
+
* // Create an adapter that implements TasHttpClient
|
|
855
|
+
* @Injectable({ providedIn: 'root' })
|
|
856
|
+
* export class MyHttpAdapter implements TasHttpClient {
|
|
857
|
+
* constructor(private http: HttpClient) {}
|
|
858
|
+
* post<T>(url: string, options: { body: any; headers?: Record<string, string> }): Observable<T> {
|
|
859
|
+
* return this.http.post<T>(url, options.body, { headers: options.headers });
|
|
860
|
+
* }
|
|
861
|
+
* }
|
|
862
|
+
*
|
|
863
|
+
* // In your AppModule
|
|
864
|
+
* @NgModule({
|
|
865
|
+
* imports: [
|
|
866
|
+
* TasUellSdkModule.forRoot({
|
|
867
|
+
* config: { tokBoxApiKey: 'YOUR_TOKBOX_API_KEY' },
|
|
868
|
+
* httpClient: MyHttpAdapter
|
|
869
|
+
* })
|
|
870
|
+
* ]
|
|
644
871
|
* })
|
|
872
|
+
* export class AppModule { }
|
|
645
873
|
* ```
|
|
646
874
|
*/
|
|
647
|
-
static forRoot(
|
|
648
|
-
const providers = [
|
|
649
|
-
{
|
|
650
|
-
provide: TAS_CONFIG,
|
|
651
|
-
useValue: moduleConfig.config,
|
|
652
|
-
},
|
|
653
|
-
];
|
|
654
|
-
if (moduleConfig.httpClient) {
|
|
655
|
-
providers.push({
|
|
656
|
-
provide: TAS_HTTP_CLIENT,
|
|
657
|
-
useClass: moduleConfig.httpClient,
|
|
658
|
-
});
|
|
659
|
-
}
|
|
660
|
-
if (moduleConfig.userDataProvider) {
|
|
661
|
-
providers.push({
|
|
662
|
-
provide: TAS_USER_DATA_PROVIDER,
|
|
663
|
-
useClass: moduleConfig.userDataProvider,
|
|
664
|
-
});
|
|
665
|
-
}
|
|
875
|
+
static forRoot(options) {
|
|
666
876
|
return {
|
|
667
|
-
ngModule:
|
|
668
|
-
providers
|
|
877
|
+
ngModule: TasUellSdkModule,
|
|
878
|
+
providers: [
|
|
879
|
+
{ provide: TAS_CONFIG, useValue: options.config },
|
|
880
|
+
{ provide: TAS_HTTP_CLIENT, useClass: options.httpClient },
|
|
881
|
+
TasService
|
|
882
|
+
]
|
|
669
883
|
};
|
|
670
884
|
}
|
|
671
885
|
}
|
|
672
|
-
|
|
673
|
-
|
|
886
|
+
TasUellSdkModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasUellSdkModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
|
|
887
|
+
TasUellSdkModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasUellSdkModule, declarations: [TasButtonComponent,
|
|
674
888
|
TasVideocallComponent,
|
|
675
|
-
TasFloatingCallComponent
|
|
889
|
+
TasFloatingCallComponent,
|
|
890
|
+
TasWaitingRoomComponent], imports: [CommonModule], exports: [TasButtonComponent,
|
|
676
891
|
TasVideocallComponent,
|
|
677
|
-
TasFloatingCallComponent
|
|
678
|
-
|
|
679
|
-
i0.ɵɵ
|
|
892
|
+
TasFloatingCallComponent,
|
|
893
|
+
TasWaitingRoomComponent] });
|
|
894
|
+
TasUellSdkModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasUellSdkModule, imports: [[
|
|
895
|
+
CommonModule,
|
|
896
|
+
]] });
|
|
897
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: TasUellSdkModule, decorators: [{
|
|
680
898
|
type: NgModule,
|
|
681
899
|
args: [{
|
|
682
900
|
declarations: [
|
|
683
901
|
TasButtonComponent,
|
|
684
902
|
TasVideocallComponent,
|
|
685
903
|
TasFloatingCallComponent,
|
|
904
|
+
TasWaitingRoomComponent
|
|
905
|
+
],
|
|
906
|
+
imports: [
|
|
907
|
+
CommonModule,
|
|
686
908
|
],
|
|
687
|
-
imports: [CommonModule, NgbModalModule],
|
|
688
909
|
exports: [
|
|
689
910
|
TasButtonComponent,
|
|
690
911
|
TasVideocallComponent,
|
|
691
912
|
TasFloatingCallComponent,
|
|
692
|
-
|
|
913
|
+
TasWaitingRoomComponent
|
|
914
|
+
]
|
|
693
915
|
}]
|
|
694
916
|
}] });
|
|
695
917
|
|
|
@@ -701,5 +923,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImpor
|
|
|
701
923
|
* Generated bundle index. Do not edit.
|
|
702
924
|
*/
|
|
703
925
|
|
|
704
|
-
export { CallState, TAS_CONFIG, TAS_HTTP_CLIENT,
|
|
926
|
+
export { CallState, TAS_CONFIG, TAS_HTTP_CLIENT, TasButtonComponent, TasFloatingCallComponent, TasRoomType, TasService, TasSessionType, TasUellSdkModule, TasUserRole, TasVideocallComponent, TasWaitingRoomComponent, ViewMode, WaitingRoomState };
|
|
705
927
|
//# sourceMappingURL=tas-uell-sdk.mjs.map
|