@testgorilla/tgo-ai-interview-test 2.0.2 → 2.0.3

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.
@@ -10,10 +10,13 @@
10
10
  "AUDIO_PREVIEW": "Audio is only available during practice questions.",
11
11
  "REVIEW_INSTRUCTIONS": "Review Instructions",
12
12
  "GET_READY": "Get ready to answer the customer's question.",
13
+ "WARNING": {
14
+ "MESSAGE": "Something’s off, but your progress is safe. Try refreshing the page.",
15
+ "REFRESH": "Refresh"
16
+ },
13
17
  "TOOL_CALL": {
14
18
  "ALL_FOR_TODAY": "That's all the questions for today. Thank you for your time.",
15
19
  "NEXT_QUESTION": "Let's move to the next question."
16
20
  }
17
21
  }
18
22
  }
19
-
@@ -3,10 +3,10 @@ import { Input, Component, EventEmitter, signal, inject, ChangeDetectorRef, Outp
3
3
  import * as i2 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import DailyIframe from '@daily-co/daily-js';
6
+ import * as i1 from '@testgorilla/tgo-ui';
7
+ import { SnackbarService, ButtonComponentModule, IconComponentModule, DialogService } from '@testgorilla/tgo-ui';
6
8
  import { Subject, firstValueFrom, takeUntil } from 'rxjs';
7
9
  import { trigger, transition, style, animate } from '@angular/animations';
8
- import * as i1 from '@testgorilla/tgo-ui';
9
- import { ButtonComponentModule, IconComponentModule, DialogService } from '@testgorilla/tgo-ui';
10
10
  import { TranslocoService, TRANSLOCO_SCOPE, TranslocoModule } from '@ngneat/transloco';
11
11
  import { MediaService, ThemeService, AudioAnimationComponent, TranslocoLazyModuleUtils, getAvailableLangs, ROOT_TRANSLATIONS_SCOPE } from '@testgorilla/tgo-shared-lib';
12
12
  export { ROOT_TRANSLATIONS_SCOPE } from '@testgorilla/tgo-shared-lib';
@@ -57,10 +57,10 @@ class InterviewVideoComponent {
57
57
  }
58
58
  this.audioStream?.addTrack(track);
59
59
  }
60
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: InterviewVideoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
61
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: InterviewVideoComponent, isStandalone: true, selector: "tgo-interview-video", inputs: { videoTrack: "videoTrack", audioTrack: "audioTrack" }, usesOnChanges: true, ngImport: i0, template: "@if (videoStream) {\n<video autoPlay muted playsInline [srcObject]=\"videoStream\"></video>\n} @if (audioStream) {\n<audio autoPlay playsInline [srcObject]=\"audioStream\">\n <track kind=\"captions\" />\n</audio>\n}\n\n", styles: [":host video{width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
60
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: InterviewVideoComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
61
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: InterviewVideoComponent, isStandalone: true, selector: "tgo-interview-video", inputs: { videoTrack: "videoTrack", audioTrack: "audioTrack" }, usesOnChanges: true, ngImport: i0, template: "@if (videoStream) {\n<video autoPlay muted playsInline [srcObject]=\"videoStream\"></video>\n} @if (audioStream) {\n<audio autoPlay playsInline [srcObject]=\"audioStream\">\n <track kind=\"captions\" />\n</audio>\n}\n\n", styles: [":host video{width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
62
62
  }
63
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: InterviewVideoComponent, decorators: [{
63
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: InterviewVideoComponent, decorators: [{
64
64
  type: Component,
65
65
  args: [{ selector: 'tgo-interview-video', imports: [CommonModule], template: "@if (videoStream) {\n<video autoPlay muted playsInline [srcObject]=\"videoStream\"></video>\n} @if (audioStream) {\n<audio autoPlay playsInline [srcObject]=\"audioStream\">\n <track kind=\"captions\" />\n</audio>\n}\n\n", styles: [":host video{width:100%;height:100%}\n"] }]
66
66
  }], propDecorators: { videoTrack: [{
@@ -82,6 +82,7 @@ class InterviewStreamComponent {
82
82
  avatarParticipant;
83
83
  candidateJoined = signal(false);
84
84
  cdr = inject(ChangeDetectorRef);
85
+ snackbarService = inject(SnackbarService);
85
86
  ngOnInit() {
86
87
  void this.setupCall();
87
88
  }
@@ -97,6 +98,9 @@ class InterviewStreamComponent {
97
98
  .off('track-stopped', this.handleTrackStartedStopped)
98
99
  .off('participant-left', this.handleParticipantLeft)
99
100
  .off('left-meeting', this.handleLeftMeeting)
101
+ .off('nonfatal-error', this.logGenericError)
102
+ .off('load-attempt-failed', this.logGenericError)
103
+ .off('camera-error', this.logGenericError)
100
104
  .off('error', this.handleError);
101
105
  }
102
106
  async setupCall() {
@@ -110,9 +114,6 @@ class InterviewStreamComponent {
110
114
  audioDeviceId: this.selectedMediaDevices.audioDeviceId,
111
115
  });
112
116
  }
113
- this.callObject.startRecording({
114
- type: 'cloud',
115
- });
116
117
  this.callObject
117
118
  .on('joined-meeting', this.candidateJoinMeeting)
118
119
  .on('participant-joined', this.participantJoined)
@@ -121,6 +122,9 @@ class InterviewStreamComponent {
121
122
  .on('track-stopped', this.handleTrackStartedStopped)
122
123
  .on('participant-left', this.handleParticipantLeft)
123
124
  .on('left-meeting', this.handleLeftMeeting)
125
+ .on('nonfatal-error', this.logGenericError)
126
+ .on('load-attempt-failed', this.logGenericError)
127
+ .on('camera-error', this.logGenericError)
124
128
  .on('error', this.handleError);
125
129
  await this.callObject.join({
126
130
  userName: 'Candidate',
@@ -175,6 +179,9 @@ class InterviewStreamComponent {
175
179
  candidateJoinMeeting = (event) => {
176
180
  if (!event || !this.callObject)
177
181
  return;
182
+ this.callObject.startRecording({
183
+ type: 'cloud',
184
+ });
178
185
  this.candidateJoined.set(true);
179
186
  this.streamStart.emit();
180
187
  };
@@ -200,9 +207,24 @@ class InterviewStreamComponent {
200
207
  handleError = (event) => {
201
208
  if (!event)
202
209
  return;
203
- console.error('Interview stream error', event);
210
+ console.error('[AI_INTERVIEW] [DAILY_SDK] AI Interview stream error', event);
204
211
  this.leaveCall();
205
212
  };
213
+ logGenericError = (event) => {
214
+ if (!event)
215
+ return;
216
+ console.error('[AI_INTERVIEW] [DAILY_SDK] AI Interview generic error', event);
217
+ this.showWarningToUser();
218
+ };
219
+ showWarningToUser() {
220
+ this.snackbarService.warning(this.getTranslation("WARNING", "MESSAGE"), undefined, undefined, {
221
+ text: this.getTranslation("WARNING", 'REFRESH'),
222
+ url: '',
223
+ action: () => {
224
+ window.location.reload();
225
+ },
226
+ }, 300);
227
+ }
206
228
  handleLeftMeeting = (event) => {
207
229
  this.callObject?.stopRecording();
208
230
  if (!event || !this.callObject)
@@ -237,7 +259,7 @@ class InterviewStreamComponent {
237
259
  try {
238
260
  const args = JSON.parse(properties.arguments);
239
261
  if (args?.questionsLeft > 0) {
240
- this.sendMessage(this.getToolCallTranslation('NEXT_QUESTION'));
262
+ this.sendMessage(this.getTranslation('TOOL_CALL', 'NEXT_QUESTION'));
241
263
  window.setTimeout(() => {
242
264
  this.sendMessage('Read next question', 'respond');
243
265
  }, 1000);
@@ -248,7 +270,7 @@ class InterviewStreamComponent {
248
270
  }
249
271
  catch (err) {
250
272
  console.error('Failed to parse arguments for next_question tool call', err);
251
- this.sendMessage(this.getToolCallTranslation('ALL_FOR_TODAY'));
273
+ this.sendMessage(this.getTranslation('TOOL_CALL', 'ALL_FOR_TODAY'));
252
274
  window.setTimeout(() => {
253
275
  this.leaveCall();
254
276
  }, 5000);
@@ -280,16 +302,16 @@ class InterviewStreamComponent {
280
302
  },
281
303
  });
282
304
  }
283
- getToolCallTranslation(key) {
284
- const toolCallTranslations = this.translations['TOOL_CALL'];
305
+ getTranslation(group, key) {
306
+ const toolCallTranslations = this.translations[group];
285
307
  return toolCallTranslations[key];
286
308
  }
287
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: InterviewStreamComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
288
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: InterviewStreamComponent, isStandalone: true, selector: "tgo-interview-stream", inputs: { conversationUrl: "conversationUrl", selectedMediaDevices: "selectedMediaDevices", translations: "translations" }, outputs: { streamStart: "streamStart", streamEnd: "streamEnd", checkMediaPermissions: "checkMediaPermissions" }, ngImport: i0, template: "<div class=\"interview-stream\">\n @if (avatarParticipant) {\n <tgo-interview-video\n [videoTrack]=\"avatarParticipant.videoTrack\"\n [audioTrack]=\"avatarParticipant.audioTrack\"\n ></tgo-interview-video>\n }\n</div>\n\n", styles: [".interview-stream{width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: InterviewVideoComponent, selector: "tgo-interview-video", inputs: ["videoTrack", "audioTrack"] }] });
309
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: InterviewStreamComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
310
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.18", type: InterviewStreamComponent, isStandalone: true, selector: "tgo-interview-stream", inputs: { conversationUrl: "conversationUrl", selectedMediaDevices: "selectedMediaDevices", translations: "translations" }, outputs: { streamStart: "streamStart", streamEnd: "streamEnd", checkMediaPermissions: "checkMediaPermissions" }, providers: [SnackbarService], ngImport: i0, template: "<div class=\"interview-stream\">\n @if (avatarParticipant) {\n <tgo-interview-video\n [videoTrack]=\"avatarParticipant.videoTrack\"\n [audioTrack]=\"avatarParticipant.audioTrack\"\n ></tgo-interview-video>\n }\n</div>\n\n", styles: [".interview-stream{width:100%;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: InterviewVideoComponent, selector: "tgo-interview-video", inputs: ["videoTrack", "audioTrack"] }] });
289
311
  }
290
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: InterviewStreamComponent, decorators: [{
312
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: InterviewStreamComponent, decorators: [{
291
313
  type: Component,
292
- args: [{ selector: 'tgo-interview-stream', imports: [CommonModule, InterviewVideoComponent], template: "<div class=\"interview-stream\">\n @if (avatarParticipant) {\n <tgo-interview-video\n [videoTrack]=\"avatarParticipant.videoTrack\"\n [audioTrack]=\"avatarParticipant.audioTrack\"\n ></tgo-interview-video>\n }\n</div>\n\n", styles: [".interview-stream{width:100%;height:100%}\n"] }]
314
+ args: [{ selector: 'tgo-interview-stream', imports: [CommonModule, InterviewVideoComponent], providers: [SnackbarService], template: "<div class=\"interview-stream\">\n @if (avatarParticipant) {\n <tgo-interview-video\n [videoTrack]=\"avatarParticipant.videoTrack\"\n [audioTrack]=\"avatarParticipant.audioTrack\"\n ></tgo-interview-video>\n }\n</div>\n\n", styles: [".interview-stream{width:100%;height:100%}\n"] }]
293
315
  }], propDecorators: { conversationUrl: [{
294
316
  type: Input
295
317
  }], selectedMediaDevices: [{
@@ -314,6 +336,7 @@ class AiInterviewTestComponent {
314
336
  selectedMediaDevices;
315
337
  conversationUrl;
316
338
  mediaAccessChanged;
339
+ isExitFullscreen;
317
340
  submissionStateChanged = new EventEmitter();
318
341
  loadingStateChanged = new EventEmitter();
319
342
  requestMediaAccess = new EventEmitter();
@@ -377,7 +400,7 @@ class AiInterviewTestComponent {
377
400
  }
378
401
  }
379
402
  catch (error) {
380
- console.error('Error initializing video stream:', error);
403
+ console.error('[AI_INTERVIEW] Error initializing user video stream:', error);
381
404
  this.candidateVideoStreamReady.set(false);
382
405
  }
383
406
  }
@@ -392,8 +415,8 @@ class AiInterviewTestComponent {
392
415
  void this.initVideoStream();
393
416
  });
394
417
  }
395
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: AiInterviewTestComponent, deps: [{ token: TRANSLOCO_SCOPE }], target: i0.ɵɵFactoryTarget.Component });
396
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: AiInterviewTestComponent, isStandalone: true, selector: "tgo-ai-interview-test", inputs: { question: "question", test: "test", isFirstQuestion: "isFirstQuestion", selectedMediaDevices: "selectedMediaDevices", conversationUrl: "conversationUrl", mediaAccessChanged: "mediaAccessChanged" }, outputs: { submissionStateChanged: "submissionStateChanged", loadingStateChanged: "loadingStateChanged", requestMediaAccess: "requestMediaAccess" }, providers: [
418
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: AiInterviewTestComponent, deps: [{ token: TRANSLOCO_SCOPE }], target: i0.ɵɵFactoryTarget.Component });
419
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.18", type: AiInterviewTestComponent, isStandalone: true, selector: "tgo-ai-interview-test", inputs: { question: "question", test: "test", isFirstQuestion: "isFirstQuestion", selectedMediaDevices: "selectedMediaDevices", conversationUrl: "conversationUrl", mediaAccessChanged: "mediaAccessChanged", isExitFullscreen: "isExitFullscreen" }, outputs: { submissionStateChanged: "submissionStateChanged", loadingStateChanged: "loadingStateChanged", requestMediaAccess: "requestMediaAccess" }, providers: [
397
420
  TranslocoLazyModuleUtils.getScopeProvider('tgo-ai-interview-test', getAvailableLangs(), ROOT_TRANSLATIONS_SCOPE, (lang) => {
398
421
  // Fetch from app assets; demo app copies the library assets to
399
422
  // /assets/tgo-ai-interview-test via project.json.
@@ -403,14 +426,14 @@ class AiInterviewTestComponent {
403
426
  }),
404
427
  DialogService,
405
428
  ThemeService,
406
- ], viewQueries: [{ propertyName: "videoElement", first: true, predicate: ["video"], descendants: true }, { propertyName: "audioElement", first: true, predicate: ["audio"], descendants: true }], ngImport: i0, template: "<div class=\"ai-interview-test\">\n <div class=\"test-container\">\n <div\n class=\"media-container\"\n [class.is-video-visible]=\"isInterviewInProgress()\"\n >\n <div class=\"candidate-no-camera\" *ngIf=\"!candidateVideoStreamReady()\">\n <h3>&nbsp;</h3>\n <ui-icon name=\"User-profile-in-line\" color=\"white\" size=\"24\"></ui-icon>\n <h3 class=\"bold\">{{ translations['YOU'] }}</h3>\n </div>\n <div class=\"candidate-camera\" [hidden]=\"!candidateVideoStreamReady()\">\n <video\n height\n #video\n id=\"video\"\n playsinline\n (loadedmetadata)=\"onVideoLoad()\"\n ></video>\n <h3 class=\"bold\" *ngIf=\"candidateVideoStreamReady()\">\n {{ translations['YOU'] }}\n </h3>\n </div>\n <tgo-audio-animation\n *ngIf=\"isInterviewInProgress()\"\n [fakeData]=\"true\"\n ></tgo-audio-animation>\n <div class=\"interview-stream-container\">\n <tgo-interview-stream\n *ngIf=\"conversationUrl && hasMediaPermissions()\"\n [selectedMediaDevices]=\"selectedMediaDevices\"\n [conversationUrl]=\"conversationUrl\"\n (streamStart)=\"interviewStarted()\"\n (streamEnd)=\"interviewEnded()\"\n (checkMediaPermissions)=\"checkMediaPermissions()\"\n [translations]=\"translations\"\n ></tgo-interview-stream>\n </div>\n </div>\n </div>\n</div>\n\n", styles: [".bg-teal-60b{background:#1c443c}.bg-teal-30b{background:#31766a}.bg-teal-default{background:#46a997}.bg-teal-30w{background:#7ec3b6}.bg-teal-60w{background:#b5ddd5}.bg-teal-secondary{background:#cbd6cb}.bg-teal-90w{background:#ecf6f5}.bg-petrol-60b{background:#102930}.bg-petrol-30b{background:#1b4754}.bg-petrol-default{background:#276678}.bg-petrol-30w{background:#6894a0}.bg-petrol-60w{background:#a9c2c9}.bg-petrol-secondary{background:#c8d7de}.bg-petrol-90w{background:#e9f0f1}.bg-error-60b{background:#513131}.bg-error-30b{background:#8e5655}.bg-error-60w{background:#e3c3c6}.bg-error-secondary{background:#f0dad9}.bg-error-default{background:#cb7b7a}.bg-warning-secondary{background:#f0d6bb}.bg-warning-default{background:#cca45f}.bg-black{background:#000}.bg-dark{background:#888}.bg-medium{background:#e0e0e0}.bg-grey{background:#ededed}.bg-light{background:#f6f6f6}.bg-white{background:#fff}.bg-box-shadow{background:#00000014}.bg-navigation-subtitle{background:#528593}.bgc-teal-60b{background-color:#1c443c}.bgc-teal-30b{background-color:#31766a}.bgc-teal-default{background-color:#46a997}.bgc-teal-30w{background-color:#7ec3b6}.bgc-teal-60w{background-color:#b5ddd5}.bgc-teal-secondary{background-color:#cbd6cb}.bgc-teal-90w{background-color:#ecf6f5}.bgc-petrol-60b{background-color:#102930}.bgc-petrol-30b{background-color:#1b4754}.bgc-petrol-default{background-color:#276678}.bgc-petrol-30w{background-color:#6894a0}.bgc-petrol-60w{background-color:#a9c2c9}.bgc-petrol-secondary{background-color:#c8d7de}.bgc-petrol-90w{background-color:#e9f0f1}.bgc-error-60b{background-color:#513131}.bgc-error-30b{background-color:#8e5655}.bgc-error-60w{background-color:#e3c3c6}.bgc-error-secondary{background-color:#f0dad9}.bgc-error-default{background-color:#cb7b7a}.bgc-warning-secondary{background-color:#f0d6bb}.bgc-warning-default{background-color:#cca45f}.bgc-black{background-color:#000}.bgc-dark{background-color:#888}.bgc-medium{background-color:#e0e0e0}.bgc-grey{background-color:#ededed}.bgc-light{background-color:#f6f6f6}.bgc-white{background-color:#fff}.bgc-box-shadow{background-color:#00000014}.bgc-navigation-subtitle{background-color:#528593}.ai-interview-test{background-color:#242424;padding:24px;display:flex;justify-content:center;min-height:calc(100vh - 80px)}.ai-interview-test h3{color:#fff}.ai-interview-test .test-container{min-width:360px;width:100%;min-height:300px;height:min(725px,100%,max(100vw,100vh,200px));max-width:calc(177.7777777778vh - 80px - 48px);display:flex;flex-direction:column;justify-content:space-between;position:relative;background-color:#242424}.ai-interview-test .media-container{position:relative;color:#fff;flex-grow:1}.ai-interview-test .media-container .interview-stream-container{border-radius:10px;aspect-ratio:16/9;border:4px solid #0165FC;margin:0 auto}.ai-interview-test .media-container .candidate-no-camera{position:absolute;width:200px;aspect-ratio:16/9;z-index:3;top:32px;left:32px;border-radius:10px;background-color:#1a47aa;display:flex;justify-content:space-between;flex-direction:column;padding:16px}.ai-interview-test .media-container .candidate-no-camera ui-icon{margin:auto}.ai-interview-test .media-container .candidate-camera{position:absolute;width:200px;top:32px;left:32px;z-index:3}.ai-interview-test .media-container .candidate-camera video{width:200px;border-radius:10px}.ai-interview-test .media-container .candidate-camera h3{position:absolute;bottom:16px;left:16px}.ai-interview-test .media-container tgo-audio-animation{position:absolute;top:32px;right:32px;z-index:1}.ai-interview-test .media-container tgo-vimeo-video{display:none;position:absolute;height:100%;width:100%}.ai-interview-test .media-container.is-video-visible tgo-vimeo-video{display:block}.ai-interview-test .media-container.is-playing{border:4px solid #0165FC;border-bottom-width:3px}.ai-interview-test .media-container.is-answering .candidate-camera tgo-audio-animation,.ai-interview-test .media-container.is-answering .candidate-no-camera tgo-audio-animation{position:absolute;top:16px;right:16px}.ai-interview-test .media-container.is-answering .candidate-camera video,.ai-interview-test .media-container.is-answering .candidate-no-camera{border:3px solid #0165FC;border-radius:10px}.ai-interview-test .media-container.is-answering tgo-vimeo-video{display:block}.ai-interview-test .media-container .start,.ai-interview-test .media-container .audio-info,.ai-interview-test .media-container .overlay,.ai-interview-test .media-container .answer{display:flex;justify-content:center;align-items:center;flex-direction:column;gap:40px;height:100%}.ai-interview-test .media-container .preview{height:100%;display:flex;align-items:center;flex-direction:column;justify-content:flex-end;padding:24px}.ai-interview-test .media-container .preview p{color:#d3d3d3;margin:8px 0}.ai-interview-test .media-container .preview audio{margin:16px 0}.ai-interview-test .media-container .preview.hidden{display:none}@media screen and (max-width: 600px){.ai-interview-test{padding:0 24px;margin-top:16px}}\n"], dependencies: [{ kind: "ngmodule", type: TranslocoModule }, { kind: "ngmodule", type: ButtonComponentModule }, { kind: "ngmodule", type: IconComponentModule }, { kind: "component", type: i1.IconComponent, selector: "ui-icon", inputs: ["size", "cssClass", "name", "color", "filled", "toggleIconStyle", "applicationTheme", "useFullIconName"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: AudioAnimationComponent, selector: "tgo-audio-animation", inputs: ["volume", "fakeData"] }, { kind: "component", type: InterviewStreamComponent, selector: "tgo-interview-stream", inputs: ["conversationUrl", "selectedMediaDevices", "translations"], outputs: ["streamStart", "streamEnd", "checkMediaPermissions"] }], animations: [
429
+ ], viewQueries: [{ propertyName: "videoElement", first: true, predicate: ["video"], descendants: true }, { propertyName: "audioElement", first: true, predicate: ["audio"], descendants: true }], ngImport: i0, template: "<div class=\"ai-interview-test\">\n <div class=\"test-container\">\n <div class=\"media-container\" [class.is-video-visible]=\"isInterviewInProgress()\">\n <div\n class=\"candidate-no-camera\"\n *ngIf=\"!candidateVideoStreamReady() || (isExitFullscreen | async)\"\n >\n <h3>&nbsp;</h3>\n <ui-icon name=\"User-profile-in-line\" color=\"white\" size=\"24\"></ui-icon>\n <h3 class=\"bold\">{{ translations['YOU'] }}</h3>\n </div>\n <div class=\"candidate-camera\" [hidden]=\"!candidateVideoStreamReady()\">\n <video height #video id=\"video\" playsinline (loadedmetadata)=\"onVideoLoad()\"></video>\n <h3 class=\"bold\" *ngIf=\"candidateVideoStreamReady()\">\n {{ translations['YOU'] }}\n </h3>\n </div>\n <tgo-audio-animation *ngIf=\"isInterviewInProgress()\" [fakeData]=\"true\"></tgo-audio-animation>\n <div class=\"interview-stream-container\">\n <tgo-interview-stream\n *ngIf=\"\n conversationUrl &&\n hasMediaPermissions() &&\n !(isExitFullscreen && (isExitFullscreen | async))\n \"\n [selectedMediaDevices]=\"selectedMediaDevices\"\n [conversationUrl]=\"conversationUrl\"\n (streamStart)=\"interviewStarted()\"\n (streamEnd)=\"interviewEnded()\"\n (checkMediaPermissions)=\"checkMediaPermissions()\"\n [translations]=\"translations\"\n ></tgo-interview-stream>\n </div>\n </div>\n </div>\n</div>\n", styles: [".bg-teal-60b{background:#1c443c}.bg-teal-30b{background:#31766a}.bg-teal-default{background:#46a997}.bg-teal-30w{background:#7ec3b6}.bg-teal-60w{background:#b5ddd5}.bg-teal-secondary{background:#cbd6cb}.bg-teal-90w{background:#ecf6f5}.bg-petrol-60b{background:#102930}.bg-petrol-30b{background:#1b4754}.bg-petrol-default{background:#276678}.bg-petrol-30w{background:#6894a0}.bg-petrol-60w{background:#a9c2c9}.bg-petrol-secondary{background:#c8d7de}.bg-petrol-90w{background:#e9f0f1}.bg-error-60b{background:#513131}.bg-error-30b{background:#8e5655}.bg-error-60w{background:#e3c3c6}.bg-error-secondary{background:#f0dad9}.bg-error-default{background:#cb7b7a}.bg-warning-secondary{background:#f0d6bb}.bg-warning-default{background:#cca45f}.bg-black{background:#000}.bg-dark{background:#888}.bg-medium{background:#e0e0e0}.bg-grey{background:#ededed}.bg-light{background:#f6f6f6}.bg-white{background:#fff}.bg-box-shadow{background:#00000014}.bg-navigation-subtitle{background:#528593}.bgc-teal-60b{background-color:#1c443c}.bgc-teal-30b{background-color:#31766a}.bgc-teal-default{background-color:#46a997}.bgc-teal-30w{background-color:#7ec3b6}.bgc-teal-60w{background-color:#b5ddd5}.bgc-teal-secondary{background-color:#cbd6cb}.bgc-teal-90w{background-color:#ecf6f5}.bgc-petrol-60b{background-color:#102930}.bgc-petrol-30b{background-color:#1b4754}.bgc-petrol-default{background-color:#276678}.bgc-petrol-30w{background-color:#6894a0}.bgc-petrol-60w{background-color:#a9c2c9}.bgc-petrol-secondary{background-color:#c8d7de}.bgc-petrol-90w{background-color:#e9f0f1}.bgc-error-60b{background-color:#513131}.bgc-error-30b{background-color:#8e5655}.bgc-error-60w{background-color:#e3c3c6}.bgc-error-secondary{background-color:#f0dad9}.bgc-error-default{background-color:#cb7b7a}.bgc-warning-secondary{background-color:#f0d6bb}.bgc-warning-default{background-color:#cca45f}.bgc-black{background-color:#000}.bgc-dark{background-color:#888}.bgc-medium{background-color:#e0e0e0}.bgc-grey{background-color:#ededed}.bgc-light{background-color:#f6f6f6}.bgc-white{background-color:#fff}.bgc-box-shadow{background-color:#00000014}.bgc-navigation-subtitle{background-color:#528593}.ai-interview-test{background-color:#242424;padding:24px;display:flex;justify-content:center;min-height:calc(100vh - 80px)}.ai-interview-test h3{color:#fff}.ai-interview-test .test-container{min-width:360px;width:100%;min-height:300px;height:min(725px,100%,max(100vw,100vh,200px));max-width:calc(177.7777777778vh - 80px - 48px);display:flex;flex-direction:column;justify-content:space-between;position:relative;background-color:#242424}.ai-interview-test .media-container{position:relative;color:#fff;flex-grow:1}.ai-interview-test .media-container .interview-stream-container{border-radius:10px;aspect-ratio:16/9;border:4px solid #0165FC;margin:0 auto}.ai-interview-test .media-container .candidate-no-camera{position:absolute;width:200px;aspect-ratio:16/9;z-index:3;top:32px;left:32px;border-radius:10px;background-color:#1a47aa;display:flex;justify-content:space-between;flex-direction:column;padding:16px}.ai-interview-test .media-container .candidate-no-camera ui-icon{margin:auto}.ai-interview-test .media-container .candidate-camera{position:absolute;width:200px;top:32px;left:32px;z-index:3}.ai-interview-test .media-container .candidate-camera video{width:200px;border-radius:10px}.ai-interview-test .media-container .candidate-camera h3{position:absolute;bottom:16px;left:16px}.ai-interview-test .media-container tgo-audio-animation{position:absolute;top:32px;right:32px;z-index:1}.ai-interview-test .media-container tgo-vimeo-video{display:none;position:absolute;height:100%;width:100%}.ai-interview-test .media-container.is-video-visible tgo-vimeo-video{display:block}.ai-interview-test .media-container.is-playing{border:4px solid #0165FC;border-bottom-width:3px}.ai-interview-test .media-container.is-answering .candidate-camera tgo-audio-animation,.ai-interview-test .media-container.is-answering .candidate-no-camera tgo-audio-animation{position:absolute;top:16px;right:16px}.ai-interview-test .media-container.is-answering .candidate-camera video,.ai-interview-test .media-container.is-answering .candidate-no-camera{border:3px solid #0165FC;border-radius:10px}.ai-interview-test .media-container.is-answering tgo-vimeo-video{display:block}.ai-interview-test .media-container .start,.ai-interview-test .media-container .audio-info,.ai-interview-test .media-container .overlay,.ai-interview-test .media-container .answer{display:flex;justify-content:center;align-items:center;flex-direction:column;gap:40px;height:100%}.ai-interview-test .media-container .preview{height:100%;display:flex;align-items:center;flex-direction:column;justify-content:flex-end;padding:24px}.ai-interview-test .media-container .preview p{color:#d3d3d3;margin:8px 0}.ai-interview-test .media-container .preview audio{margin:16px 0}.ai-interview-test .media-container .preview.hidden{display:none}@media screen and (max-width: 600px){.ai-interview-test{padding:0 24px;margin-top:16px}}\n"], dependencies: [{ kind: "ngmodule", type: TranslocoModule }, { kind: "ngmodule", type: ButtonComponentModule }, { kind: "ngmodule", type: IconComponentModule }, { kind: "component", type: i1.IconComponent, selector: "ui-icon", inputs: ["size", "cssClass", "name", "color", "filled", "toggleIconStyle", "applicationTheme", "useFullIconName"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }, { kind: "component", type: AudioAnimationComponent, selector: "tgo-audio-animation", inputs: ["volume", "fakeData"] }, { kind: "component", type: InterviewStreamComponent, selector: "tgo-interview-stream", inputs: ["conversationUrl", "selectedMediaDevices", "translations"], outputs: ["streamStart", "streamEnd", "checkMediaPermissions"] }], animations: [
407
430
  trigger('fadeInFadeOut', [
408
431
  transition(':enter', [style({ opacity: 0 }), animate('600ms', style({ opacity: 1 }))]),
409
432
  transition(':leave', [animate('600ms', style({ opacity: 0 }))]),
410
433
  ]),
411
434
  ] });
412
435
  }
413
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: AiInterviewTestComponent, decorators: [{
436
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.18", ngImport: i0, type: AiInterviewTestComponent, decorators: [{
414
437
  type: Component,
415
438
  args: [{ selector: 'tgo-ai-interview-test', animations: [
416
439
  trigger('fadeInFadeOut', [
@@ -434,7 +457,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
434
457
  }),
435
458
  DialogService,
436
459
  ThemeService,
437
- ], template: "<div class=\"ai-interview-test\">\n <div class=\"test-container\">\n <div\n class=\"media-container\"\n [class.is-video-visible]=\"isInterviewInProgress()\"\n >\n <div class=\"candidate-no-camera\" *ngIf=\"!candidateVideoStreamReady()\">\n <h3>&nbsp;</h3>\n <ui-icon name=\"User-profile-in-line\" color=\"white\" size=\"24\"></ui-icon>\n <h3 class=\"bold\">{{ translations['YOU'] }}</h3>\n </div>\n <div class=\"candidate-camera\" [hidden]=\"!candidateVideoStreamReady()\">\n <video\n height\n #video\n id=\"video\"\n playsinline\n (loadedmetadata)=\"onVideoLoad()\"\n ></video>\n <h3 class=\"bold\" *ngIf=\"candidateVideoStreamReady()\">\n {{ translations['YOU'] }}\n </h3>\n </div>\n <tgo-audio-animation\n *ngIf=\"isInterviewInProgress()\"\n [fakeData]=\"true\"\n ></tgo-audio-animation>\n <div class=\"interview-stream-container\">\n <tgo-interview-stream\n *ngIf=\"conversationUrl && hasMediaPermissions()\"\n [selectedMediaDevices]=\"selectedMediaDevices\"\n [conversationUrl]=\"conversationUrl\"\n (streamStart)=\"interviewStarted()\"\n (streamEnd)=\"interviewEnded()\"\n (checkMediaPermissions)=\"checkMediaPermissions()\"\n [translations]=\"translations\"\n ></tgo-interview-stream>\n </div>\n </div>\n </div>\n</div>\n\n", styles: [".bg-teal-60b{background:#1c443c}.bg-teal-30b{background:#31766a}.bg-teal-default{background:#46a997}.bg-teal-30w{background:#7ec3b6}.bg-teal-60w{background:#b5ddd5}.bg-teal-secondary{background:#cbd6cb}.bg-teal-90w{background:#ecf6f5}.bg-petrol-60b{background:#102930}.bg-petrol-30b{background:#1b4754}.bg-petrol-default{background:#276678}.bg-petrol-30w{background:#6894a0}.bg-petrol-60w{background:#a9c2c9}.bg-petrol-secondary{background:#c8d7de}.bg-petrol-90w{background:#e9f0f1}.bg-error-60b{background:#513131}.bg-error-30b{background:#8e5655}.bg-error-60w{background:#e3c3c6}.bg-error-secondary{background:#f0dad9}.bg-error-default{background:#cb7b7a}.bg-warning-secondary{background:#f0d6bb}.bg-warning-default{background:#cca45f}.bg-black{background:#000}.bg-dark{background:#888}.bg-medium{background:#e0e0e0}.bg-grey{background:#ededed}.bg-light{background:#f6f6f6}.bg-white{background:#fff}.bg-box-shadow{background:#00000014}.bg-navigation-subtitle{background:#528593}.bgc-teal-60b{background-color:#1c443c}.bgc-teal-30b{background-color:#31766a}.bgc-teal-default{background-color:#46a997}.bgc-teal-30w{background-color:#7ec3b6}.bgc-teal-60w{background-color:#b5ddd5}.bgc-teal-secondary{background-color:#cbd6cb}.bgc-teal-90w{background-color:#ecf6f5}.bgc-petrol-60b{background-color:#102930}.bgc-petrol-30b{background-color:#1b4754}.bgc-petrol-default{background-color:#276678}.bgc-petrol-30w{background-color:#6894a0}.bgc-petrol-60w{background-color:#a9c2c9}.bgc-petrol-secondary{background-color:#c8d7de}.bgc-petrol-90w{background-color:#e9f0f1}.bgc-error-60b{background-color:#513131}.bgc-error-30b{background-color:#8e5655}.bgc-error-60w{background-color:#e3c3c6}.bgc-error-secondary{background-color:#f0dad9}.bgc-error-default{background-color:#cb7b7a}.bgc-warning-secondary{background-color:#f0d6bb}.bgc-warning-default{background-color:#cca45f}.bgc-black{background-color:#000}.bgc-dark{background-color:#888}.bgc-medium{background-color:#e0e0e0}.bgc-grey{background-color:#ededed}.bgc-light{background-color:#f6f6f6}.bgc-white{background-color:#fff}.bgc-box-shadow{background-color:#00000014}.bgc-navigation-subtitle{background-color:#528593}.ai-interview-test{background-color:#242424;padding:24px;display:flex;justify-content:center;min-height:calc(100vh - 80px)}.ai-interview-test h3{color:#fff}.ai-interview-test .test-container{min-width:360px;width:100%;min-height:300px;height:min(725px,100%,max(100vw,100vh,200px));max-width:calc(177.7777777778vh - 80px - 48px);display:flex;flex-direction:column;justify-content:space-between;position:relative;background-color:#242424}.ai-interview-test .media-container{position:relative;color:#fff;flex-grow:1}.ai-interview-test .media-container .interview-stream-container{border-radius:10px;aspect-ratio:16/9;border:4px solid #0165FC;margin:0 auto}.ai-interview-test .media-container .candidate-no-camera{position:absolute;width:200px;aspect-ratio:16/9;z-index:3;top:32px;left:32px;border-radius:10px;background-color:#1a47aa;display:flex;justify-content:space-between;flex-direction:column;padding:16px}.ai-interview-test .media-container .candidate-no-camera ui-icon{margin:auto}.ai-interview-test .media-container .candidate-camera{position:absolute;width:200px;top:32px;left:32px;z-index:3}.ai-interview-test .media-container .candidate-camera video{width:200px;border-radius:10px}.ai-interview-test .media-container .candidate-camera h3{position:absolute;bottom:16px;left:16px}.ai-interview-test .media-container tgo-audio-animation{position:absolute;top:32px;right:32px;z-index:1}.ai-interview-test .media-container tgo-vimeo-video{display:none;position:absolute;height:100%;width:100%}.ai-interview-test .media-container.is-video-visible tgo-vimeo-video{display:block}.ai-interview-test .media-container.is-playing{border:4px solid #0165FC;border-bottom-width:3px}.ai-interview-test .media-container.is-answering .candidate-camera tgo-audio-animation,.ai-interview-test .media-container.is-answering .candidate-no-camera tgo-audio-animation{position:absolute;top:16px;right:16px}.ai-interview-test .media-container.is-answering .candidate-camera video,.ai-interview-test .media-container.is-answering .candidate-no-camera{border:3px solid #0165FC;border-radius:10px}.ai-interview-test .media-container.is-answering tgo-vimeo-video{display:block}.ai-interview-test .media-container .start,.ai-interview-test .media-container .audio-info,.ai-interview-test .media-container .overlay,.ai-interview-test .media-container .answer{display:flex;justify-content:center;align-items:center;flex-direction:column;gap:40px;height:100%}.ai-interview-test .media-container .preview{height:100%;display:flex;align-items:center;flex-direction:column;justify-content:flex-end;padding:24px}.ai-interview-test .media-container .preview p{color:#d3d3d3;margin:8px 0}.ai-interview-test .media-container .preview audio{margin:16px 0}.ai-interview-test .media-container .preview.hidden{display:none}@media screen and (max-width: 600px){.ai-interview-test{padding:0 24px;margin-top:16px}}\n"] }]
460
+ ], template: "<div class=\"ai-interview-test\">\n <div class=\"test-container\">\n <div class=\"media-container\" [class.is-video-visible]=\"isInterviewInProgress()\">\n <div\n class=\"candidate-no-camera\"\n *ngIf=\"!candidateVideoStreamReady() || (isExitFullscreen | async)\"\n >\n <h3>&nbsp;</h3>\n <ui-icon name=\"User-profile-in-line\" color=\"white\" size=\"24\"></ui-icon>\n <h3 class=\"bold\">{{ translations['YOU'] }}</h3>\n </div>\n <div class=\"candidate-camera\" [hidden]=\"!candidateVideoStreamReady()\">\n <video height #video id=\"video\" playsinline (loadedmetadata)=\"onVideoLoad()\"></video>\n <h3 class=\"bold\" *ngIf=\"candidateVideoStreamReady()\">\n {{ translations['YOU'] }}\n </h3>\n </div>\n <tgo-audio-animation *ngIf=\"isInterviewInProgress()\" [fakeData]=\"true\"></tgo-audio-animation>\n <div class=\"interview-stream-container\">\n <tgo-interview-stream\n *ngIf=\"\n conversationUrl &&\n hasMediaPermissions() &&\n !(isExitFullscreen && (isExitFullscreen | async))\n \"\n [selectedMediaDevices]=\"selectedMediaDevices\"\n [conversationUrl]=\"conversationUrl\"\n (streamStart)=\"interviewStarted()\"\n (streamEnd)=\"interviewEnded()\"\n (checkMediaPermissions)=\"checkMediaPermissions()\"\n [translations]=\"translations\"\n ></tgo-interview-stream>\n </div>\n </div>\n </div>\n</div>\n", styles: [".bg-teal-60b{background:#1c443c}.bg-teal-30b{background:#31766a}.bg-teal-default{background:#46a997}.bg-teal-30w{background:#7ec3b6}.bg-teal-60w{background:#b5ddd5}.bg-teal-secondary{background:#cbd6cb}.bg-teal-90w{background:#ecf6f5}.bg-petrol-60b{background:#102930}.bg-petrol-30b{background:#1b4754}.bg-petrol-default{background:#276678}.bg-petrol-30w{background:#6894a0}.bg-petrol-60w{background:#a9c2c9}.bg-petrol-secondary{background:#c8d7de}.bg-petrol-90w{background:#e9f0f1}.bg-error-60b{background:#513131}.bg-error-30b{background:#8e5655}.bg-error-60w{background:#e3c3c6}.bg-error-secondary{background:#f0dad9}.bg-error-default{background:#cb7b7a}.bg-warning-secondary{background:#f0d6bb}.bg-warning-default{background:#cca45f}.bg-black{background:#000}.bg-dark{background:#888}.bg-medium{background:#e0e0e0}.bg-grey{background:#ededed}.bg-light{background:#f6f6f6}.bg-white{background:#fff}.bg-box-shadow{background:#00000014}.bg-navigation-subtitle{background:#528593}.bgc-teal-60b{background-color:#1c443c}.bgc-teal-30b{background-color:#31766a}.bgc-teal-default{background-color:#46a997}.bgc-teal-30w{background-color:#7ec3b6}.bgc-teal-60w{background-color:#b5ddd5}.bgc-teal-secondary{background-color:#cbd6cb}.bgc-teal-90w{background-color:#ecf6f5}.bgc-petrol-60b{background-color:#102930}.bgc-petrol-30b{background-color:#1b4754}.bgc-petrol-default{background-color:#276678}.bgc-petrol-30w{background-color:#6894a0}.bgc-petrol-60w{background-color:#a9c2c9}.bgc-petrol-secondary{background-color:#c8d7de}.bgc-petrol-90w{background-color:#e9f0f1}.bgc-error-60b{background-color:#513131}.bgc-error-30b{background-color:#8e5655}.bgc-error-60w{background-color:#e3c3c6}.bgc-error-secondary{background-color:#f0dad9}.bgc-error-default{background-color:#cb7b7a}.bgc-warning-secondary{background-color:#f0d6bb}.bgc-warning-default{background-color:#cca45f}.bgc-black{background-color:#000}.bgc-dark{background-color:#888}.bgc-medium{background-color:#e0e0e0}.bgc-grey{background-color:#ededed}.bgc-light{background-color:#f6f6f6}.bgc-white{background-color:#fff}.bgc-box-shadow{background-color:#00000014}.bgc-navigation-subtitle{background-color:#528593}.ai-interview-test{background-color:#242424;padding:24px;display:flex;justify-content:center;min-height:calc(100vh - 80px)}.ai-interview-test h3{color:#fff}.ai-interview-test .test-container{min-width:360px;width:100%;min-height:300px;height:min(725px,100%,max(100vw,100vh,200px));max-width:calc(177.7777777778vh - 80px - 48px);display:flex;flex-direction:column;justify-content:space-between;position:relative;background-color:#242424}.ai-interview-test .media-container{position:relative;color:#fff;flex-grow:1}.ai-interview-test .media-container .interview-stream-container{border-radius:10px;aspect-ratio:16/9;border:4px solid #0165FC;margin:0 auto}.ai-interview-test .media-container .candidate-no-camera{position:absolute;width:200px;aspect-ratio:16/9;z-index:3;top:32px;left:32px;border-radius:10px;background-color:#1a47aa;display:flex;justify-content:space-between;flex-direction:column;padding:16px}.ai-interview-test .media-container .candidate-no-camera ui-icon{margin:auto}.ai-interview-test .media-container .candidate-camera{position:absolute;width:200px;top:32px;left:32px;z-index:3}.ai-interview-test .media-container .candidate-camera video{width:200px;border-radius:10px}.ai-interview-test .media-container .candidate-camera h3{position:absolute;bottom:16px;left:16px}.ai-interview-test .media-container tgo-audio-animation{position:absolute;top:32px;right:32px;z-index:1}.ai-interview-test .media-container tgo-vimeo-video{display:none;position:absolute;height:100%;width:100%}.ai-interview-test .media-container.is-video-visible tgo-vimeo-video{display:block}.ai-interview-test .media-container.is-playing{border:4px solid #0165FC;border-bottom-width:3px}.ai-interview-test .media-container.is-answering .candidate-camera tgo-audio-animation,.ai-interview-test .media-container.is-answering .candidate-no-camera tgo-audio-animation{position:absolute;top:16px;right:16px}.ai-interview-test .media-container.is-answering .candidate-camera video,.ai-interview-test .media-container.is-answering .candidate-no-camera{border:3px solid #0165FC;border-radius:10px}.ai-interview-test .media-container.is-answering tgo-vimeo-video{display:block}.ai-interview-test .media-container .start,.ai-interview-test .media-container .audio-info,.ai-interview-test .media-container .overlay,.ai-interview-test .media-container .answer{display:flex;justify-content:center;align-items:center;flex-direction:column;gap:40px;height:100%}.ai-interview-test .media-container .preview{height:100%;display:flex;align-items:center;flex-direction:column;justify-content:flex-end;padding:24px}.ai-interview-test .media-container .preview p{color:#d3d3d3;margin:8px 0}.ai-interview-test .media-container .preview audio{margin:16px 0}.ai-interview-test .media-container .preview.hidden{display:none}@media screen and (max-width: 600px){.ai-interview-test{padding:0 24px;margin-top:16px}}\n"] }]
438
461
  }], ctorParameters: () => [{ type: undefined, decorators: [{
439
462
  type: Inject,
440
463
  args: [TRANSLOCO_SCOPE]
@@ -458,6 +481,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
458
481
  type: Input
459
482
  }], mediaAccessChanged: [{
460
483
  type: Input
484
+ }], isExitFullscreen: [{
485
+ type: Input
461
486
  }], submissionStateChanged: [{
462
487
  type: Output
463
488
  }], loadingStateChanged: [{
@@ -1 +1 @@
1
- {"version":3,"file":"testgorilla-tgo-ai-interview-test.mjs","sources":["../../../../packages/tgo-ai-interview-test/src/lib/components/interview-video/interview-video.component.ts","../../../../packages/tgo-ai-interview-test/src/lib/components/interview-video/interview-video.component.html","../../../../packages/tgo-ai-interview-test/src/lib/components/interview-stream/interview-stream.component.ts","../../../../packages/tgo-ai-interview-test/src/lib/components/interview-stream/interview-stream.component.html","../../../../packages/tgo-ai-interview-test/src/lib/components/ai-interview-test/ai-interview-test.component.ts","../../../../packages/tgo-ai-interview-test/src/lib/components/ai-interview-test/ai-interview-test.component.html","../../../../packages/tgo-ai-interview-test/src/lib/models/translations.ts","../../../../packages/tgo-ai-interview-test/src/lib/models/index.ts","../../../../packages/tgo-ai-interview-test/src/testgorilla-tgo-ai-interview-test.ts"],"sourcesContent":["import { Component, Input, OnInit, SimpleChanges, OnChanges } from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\n@Component({\n selector: 'tgo-interview-video',\n templateUrl: './interview-video.component.html',\n styleUrls: ['./interview-video.component.scss'],\n imports: [CommonModule]\n})\nexport class InterviewVideoComponent implements OnInit, OnChanges {\n @Input() videoTrack: MediaStreamTrack | undefined;\n @Input() audioTrack: MediaStreamTrack | undefined;\n videoStream: MediaStream | undefined;\n audioStream: MediaStream | undefined;\n\n ngOnInit(): void {\n if (this.videoTrack) {\n this.addVideoStream(this.videoTrack);\n }\n if (this.audioTrack) {\n this.addAudioStream(this.audioTrack);\n }\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n const { videoTrack, audioTrack } = changes;\n\n if (videoTrack?.currentValue && !this.videoStream) {\n this.addVideoStream(videoTrack.currentValue);\n }\n\n if (audioTrack?.currentValue && !this.audioStream) {\n this.addAudioStream(audioTrack.currentValue);\n }\n\n if (videoTrack?.currentValue && this.videoStream) {\n this.updateVideoTrack(videoTrack.previousValue, videoTrack.currentValue);\n }\n\n if (audioTrack?.currentValue && this.audioStream) {\n this.updateAudioTrack(audioTrack.previousValue, audioTrack.currentValue);\n }\n }\n\n addVideoStream(track: MediaStreamTrack) {\n this.videoStream = new MediaStream([track]);\n }\n\n addAudioStream(track: MediaStreamTrack) {\n this.audioStream = new MediaStream([track]);\n }\n\n updateVideoTrack(oldTrack: MediaStreamTrack, track: MediaStreamTrack) {\n if (oldTrack) {\n this.videoStream?.removeTrack(oldTrack);\n }\n this.videoStream?.addTrack(track);\n }\n\n updateAudioTrack(oldTrack: MediaStreamTrack, track: MediaStreamTrack) {\n if (oldTrack) {\n this.audioStream?.removeTrack(oldTrack);\n }\n this.audioStream?.addTrack(track);\n }\n}\n\n","@if (videoStream) {\n<video autoPlay muted playsInline [srcObject]=\"videoStream\"></video>\n} @if (audioStream) {\n<audio autoPlay playsInline [srcObject]=\"audioStream\">\n <track kind=\"captions\" />\n</audio>\n}\n\n","import {\n ChangeDetectorRef,\n Component,\n EventEmitter,\n inject,\n Input,\n OnDestroy,\n OnInit,\n Output,\n signal,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport DailyIframe, {\n DailyCall,\n DailyEventObjectParticipant,\n DailyParticipant,\n DailyEventObjectFatalError,\n DailyEventObjectParticipants,\n DailyEventObjectNoPayload,\n DailyEventObjectParticipantLeft,\n DailyEventObjectTrack,\n DailyEventObjectAppMessage,\n} from '@daily-co/daily-js';\nimport { SelectedMediaDevices } from '@testgorilla/tgo-shared-lib';\nimport { InterviewVideoComponent } from '../interview-video/interview-video.component';\n\nexport type Participant = {\n videoTrack?: MediaStreamTrack | undefined;\n audioTrack?: MediaStreamTrack | undefined;\n videoReady: boolean;\n audioReady: boolean;\n userName: string;\n local: boolean;\n sessionId: string;\n};\n\nconst PLAYABLE_STATE = 'playable';\nconst LOADING_STATE = 'loading';\n\ninterface EventData {\n event_type: string;\n properties: {\n name: string;\n arguments: string;\n };\n}\n\n@Component({\n selector: 'tgo-interview-stream',\n templateUrl: './interview-stream.component.html',\n styleUrls: ['./interview-stream.component.scss'],\n imports: [CommonModule, InterviewVideoComponent]\n})\nexport class InterviewStreamComponent implements OnInit, OnDestroy {\n @Input() conversationUrl: string | undefined;\n @Input() selectedMediaDevices: SelectedMediaDevices | undefined;\n @Input() translations: { [key: string]: string } = {};\n @Output() streamStart: EventEmitter<null> = new EventEmitter();\n @Output() streamEnd: EventEmitter<null> = new EventEmitter();\n @Output() checkMediaPermissions: EventEmitter<null> = new EventEmitter();\n\n callObject: DailyCall | undefined;\n avatarParticipant: Participant | undefined;\n candidateJoined = signal(false);\n private cdr = inject(ChangeDetectorRef);\n\n ngOnInit(): void {\n void this.setupCall();\n }\n\n ngOnDestroy(): void {\n if (!this.callObject) return;\n this.leaveCall();\n this.callObject\n .off('joined-meeting', this.candidateJoinMeeting)\n .off('participant-joined', this.participantJoined)\n .off('app-message', this.handleNewMessage)\n .off('track-started', this.handleTrackStartedStopped)\n .off('track-stopped', this.handleTrackStartedStopped)\n .off('participant-left', this.handleParticipantLeft)\n .off('left-meeting', this.handleLeftMeeting)\n .off('error', this.handleError);\n }\n\n private async setupCall() {\n this.callObject = DailyIframe.getCallInstance();\n if (!this.callObject) {\n this.callObject = DailyIframe.createCallObject();\n }\n if (this.selectedMediaDevices) {\n await this.callObject.setInputDevicesAsync({\n videoDeviceId: this.selectedMediaDevices.videoDeviceId,\n audioDeviceId: this.selectedMediaDevices.audioDeviceId,\n });\n }\n this.callObject.startRecording({\n type: 'cloud',\n });\n\n this.callObject\n .on('joined-meeting', this.candidateJoinMeeting)\n .on('participant-joined', this.participantJoined)\n .on('app-message', this.handleNewMessage)\n .on('track-started', this.handleTrackStartedStopped)\n .on('track-stopped', this.handleTrackStartedStopped)\n .on('participant-left', this.handleParticipantLeft)\n .on('left-meeting', this.handleLeftMeeting)\n .on('error', this.handleError);\n\n await this.callObject.join({\n userName: 'Candidate',\n url: this.conversationUrl,\n });\n }\n\n formatParticipantObj(participant: DailyParticipant): Participant {\n const { video, audio } = participant.tracks;\n\n const videoTrack = video?.persistentTrack;\n const audioTrack = audio?.persistentTrack;\n return {\n videoTrack: videoTrack,\n audioTrack: audioTrack,\n videoReady: !!(\n videoTrack &&\n (video.state === PLAYABLE_STATE || video.state === LOADING_STATE)\n ),\n audioReady: !!(\n audioTrack &&\n (audio.state === PLAYABLE_STATE || audio.state === LOADING_STATE)\n ),\n userName: participant.user_name,\n local: participant.local,\n sessionId: participant.session_id,\n };\n }\n\n updateTrack(participant: DailyParticipant, newTrackType: string): void {\n if (\n !this.avatarParticipant ||\n this.avatarParticipant.sessionId !== participant.session_id\n ) {\n return;\n }\n const existingParticipant = this.avatarParticipant as Participant;\n const currentParticipantCopy = this.formatParticipantObj(participant);\n\n if (newTrackType === 'video') {\n if (\n existingParticipant.videoReady !== currentParticipantCopy.videoReady\n ) {\n existingParticipant.videoReady = currentParticipantCopy.videoReady;\n }\n\n if (\n currentParticipantCopy.videoReady &&\n existingParticipant.videoTrack?.id !==\n currentParticipantCopy.videoTrack?.id\n ) {\n existingParticipant.videoTrack = currentParticipantCopy.videoTrack;\n }\n return;\n }\n\n if (newTrackType === 'audio') {\n if (\n existingParticipant.audioReady !== currentParticipantCopy.audioReady\n ) {\n existingParticipant.audioReady = currentParticipantCopy.audioReady;\n }\n\n if (\n currentParticipantCopy.audioReady &&\n existingParticipant.audioTrack?.id !==\n currentParticipantCopy.audioTrack?.id\n ) {\n existingParticipant.audioTrack = currentParticipantCopy.audioTrack;\n }\n }\n }\n\n private candidateJoinMeeting = (\n event: DailyEventObjectParticipants | undefined\n ): void => {\n if (!event || !this.callObject) return;\n this.candidateJoined.set(true);\n this.streamStart.emit();\n };\n\n private participantJoined = (\n event: DailyEventObjectParticipant | undefined\n ) => {\n if (!event) return;\n this.avatarParticipant = this.formatParticipantObj(event.participant);\n };\n\n private handleTrackStartedStopped = (\n event: DailyEventObjectTrack | undefined\n ): void => {\n if (!event || !event.participant || !this.candidateJoined()) return;\n if (event.action === 'track-stopped') {\n this.checkMediaPermissions.emit();\n }\n this.updateTrack(event.participant, event.type);\n this.cdr.detectChanges();\n };\n\n private handleParticipantLeft = (\n event: DailyEventObjectParticipantLeft | undefined\n ): void => {\n if (!event) return;\n this.leaveCall();\n };\n\n private handleError = (\n event: DailyEventObjectFatalError | undefined\n ): void => {\n if (!event) return;\n console.error('Interview stream error', event);\n this.leaveCall();\n };\n\n private handleLeftMeeting = (\n event: DailyEventObjectNoPayload | undefined\n ): void => {\n this.callObject?.stopRecording();\n if (!event || !this.callObject) return;\n this.candidateJoined.set(false);\n this.callObject.destroy();\n this.streamEnd.emit();\n };\n\n private leaveCall(): void {\n if (!this.callObject) return;\n this.callObject.leave();\n }\n\n private handleNewMessage = (\n event: DailyEventObjectAppMessage<EventData> | undefined\n ): void => {\n if (!event) return;\n if (event.data.event_type === 'conversation.tool_call') {\n this.handleToolCall(event.data.properties);\n }\n };\n\n private getConversationId(): string | undefined {\n return this.conversationUrl?.replace('https://tavus.daily.co/', '');\n }\n\n /*\n This is a test implementation of tool calling.\n These events will only be triggered if configured with a Tavus persona. The message content will be further refined by the IP Team.\n https://docs.tavus.io/sections/event-schemas/conversation-toolcall\n */\n private handleToolCall = (properties: {\n name: string;\n arguments: string;\n }): void => {\n switch (properties.name) {\n case 'next_question':\n try {\n const args = JSON.parse(properties.arguments);\n if (args?.questionsLeft > 0) {\n this.sendMessage(this.getToolCallTranslation('NEXT_QUESTION'));\n window.setTimeout(() => {\n this.sendMessage('Read next question', 'respond');\n }, 1000);\n } else {\n throw new Error('No more questions left');\n }\n } catch (err) {\n console.error(\n 'Failed to parse arguments for next_question tool call',\n err\n );\n\n this.sendMessage(this.getToolCallTranslation('ALL_FOR_TODAY'));\n window.setTimeout(() => {\n this.leaveCall();\n }, 5000);\n }\n break;\n case 'end_conversation':\n window.setTimeout(() => {\n this.leaveCall();\n }, 5000);\n break;\n default:\n console.warn('Unknown tool call code:', properties);\n break;\n }\n };\n\n /*\n Echo message is a message that avatar reads and candidate can hear\n Respond message is a message that avatar reads and candidate cannot hear\n */\n\n private sendMessage(text: string, type: 'echo' | 'respond' = 'echo'): void {\n if (!this.callObject) return;\n\n this.callObject.sendAppMessage({\n message_type: 'conversation',\n event_type: 'conversation.' + type,\n conversation_id: this.getConversationId(),\n properties: {\n text,\n },\n });\n }\n\n private getToolCallTranslation(key: string) {\n const toolCallTranslations = this.translations['TOOL_CALL'] as unknown as {\n [key: string]: string;\n };\n return toolCallTranslations[key];\n }\n}\n\n","<div class=\"interview-stream\">\n @if (avatarParticipant) {\n <tgo-interview-video\n [videoTrack]=\"avatarParticipant.videoTrack\"\n [audioTrack]=\"avatarParticipant.audioTrack\"\n ></tgo-interview-video>\n }\n</div>\n\n","import { InterviewStreamComponent } from '../interview-stream/interview-stream.component';\nimport { firstValueFrom, Observable, takeUntil } from 'rxjs';\nimport { transition, style, animate, trigger } from '@angular/animations';\nimport {\n ElementRef,\n OnDestroy,\n signal,\n ViewChild,\n Component,\n EventEmitter,\n Input,\n Output,\n inject,\n OnInit,\n Inject,\n ChangeDetectorRef,\n} from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { ButtonComponentModule, DialogService, IconComponentModule } from '@testgorilla/tgo-ui';\nimport { CommonModule } from '@angular/common';\nimport {\n TRANSLOCO_SCOPE,\n TranslocoModule,\n TranslocoScope,\n TranslocoService,\n} from '@ngneat/transloco';\nimport {\n AudioAnimationComponent,\n Question,\n TestResultRead,\n SelectedMediaDevices,\n ISubmissionState,\n ROOT_TRANSLATIONS_SCOPE,\n MediaService,\n ThemeService,\n TranslocoLazyModuleUtils,\n getAvailableLangs,\n} from '@testgorilla/tgo-shared-lib';\nimport { IQuestionDataContract } from '../../models';\n\n@Component({\n selector: 'tgo-ai-interview-test',\n templateUrl: './ai-interview-test.component.html',\n styleUrl: './ai-interview-test.component.scss',\n animations: [\n trigger('fadeInFadeOut', [\n transition(':enter', [style({ opacity: 0 }), animate('600ms', style({ opacity: 1 }))]),\n transition(':leave', [animate('600ms', style({ opacity: 0 }))]),\n ]),\n ],\n imports: [\n TranslocoModule,\n ButtonComponentModule,\n IconComponentModule,\n CommonModule,\n AudioAnimationComponent,\n InterviewStreamComponent,\n ],\n providers: [\n TranslocoLazyModuleUtils.getScopeProvider(\n 'tgo-ai-interview-test',\n getAvailableLangs(),\n ROOT_TRANSLATIONS_SCOPE,\n (lang: string) => {\n // Fetch from app assets; demo app copies the library assets to\n // /assets/tgo-ai-interview-test via project.json.\n const url = new URL(`assets/tgo-ai-interview-test/i18n/${lang}.json`, document.baseURI)\n .href;\n return fetch(url).then(res => res.json());\n }\n ),\n DialogService,\n ThemeService,\n ],\n})\nexport class AiInterviewTestComponent implements OnInit, OnDestroy, IQuestionDataContract {\n @ViewChild('video') videoElement?: ElementRef<HTMLVideoElement>;\n @ViewChild('audio') audioElement?: ElementRef<HTMLAudioElement>;\n @Input({ required: true }) question!: Question;\n @Input({ required: true }) test!: TestResultRead;\n @Input() isFirstQuestion?: boolean = false;\n @Input() selectedMediaDevices?: SelectedMediaDevices;\n @Input() conversationUrl?: string;\n @Input() mediaAccessChanged?: Observable<SelectedMediaDevices> | undefined;\n\n @Output() submissionStateChanged = new EventEmitter<ISubmissionState | null>();\n @Output() loadingStateChanged: EventEmitter<boolean> = new EventEmitter<boolean>();\n @Output() requestMediaAccess: EventEmitter<void> = new EventEmitter<void>();\n\n isInterviewInProgress = signal(false);\n candidateVideoStreamReady = signal(false);\n translations: { [key: string]: string } = {};\n hasMediaPermissions = signal(false);\n\n private unsubscribe$ = new Subject<void>();\n private mediaService = inject(MediaService);\n private translocoService = inject(TranslocoService);\n private cdr = inject(ChangeDetectorRef);\n private themeService = inject(ThemeService);\n\n companyColor = this.themeService.getCompanyColor();\n\n constructor(@Inject(TRANSLOCO_SCOPE) private translationScope: TranslocoScope) {}\n\n ngOnInit(): void {\n this.initMediaAccessSubscription();\n this.loadingStateChanged.emit(true);\n this.mediaService.setSelectedMediaDevices(this.selectedMediaDevices);\n void this.checkMediaPermissions();\n\n void this.setTranslations();\n void this.initVideoStream();\n }\n\n ngOnDestroy() {\n this.unsubscribe$.next();\n this.unsubscribe$.complete();\n }\n\n onVideoLoad() {\n this.candidateVideoStreamReady.set(true);\n }\n\n interviewStarted() {\n this.isInterviewInProgress.set(true);\n this.loadingStateChanged.emit(false);\n }\n\n interviewEnded() {\n this.isInterviewInProgress.set(false);\n this.submissionStateChanged.emit({\n text: '',\n });\n }\n\n async checkMediaPermissions() {\n if (!(await this.mediaService.checkPermission({ audio: true, video: false }))) {\n this.hasMediaPermissions.set(false);\n this.requestMediaAccess.emit();\n return;\n } else {\n this.hasMediaPermissions.set(true);\n }\n }\n\n private async initVideoStream() {\n try {\n const stream = await this.mediaService.getMediaStream({\n video: true,\n audio: false,\n });\n if (this.videoElement) {\n this.videoElement.nativeElement.srcObject = stream;\n await this.videoElement?.nativeElement.play();\n }\n } catch (error) {\n console.error('Error initializing video stream:', error);\n this.candidateVideoStreamReady.set(false);\n }\n }\n\n private async setTranslations() {\n this.translations = await firstValueFrom(\n this.translocoService.selectTranslateObject(`TEST`, {}, this.translationScope as string)\n );\n this.cdr.markForCheck();\n }\n\n private initMediaAccessSubscription() {\n this.mediaAccessChanged?.pipe(takeUntil(this.unsubscribe$)).subscribe(selectedMediaDevices => {\n this.mediaService.setSelectedMediaDevices(selectedMediaDevices);\n this.checkMediaPermissions();\n void this.initVideoStream();\n });\n }\n}\n","<div class=\"ai-interview-test\">\n <div class=\"test-container\">\n <div\n class=\"media-container\"\n [class.is-video-visible]=\"isInterviewInProgress()\"\n >\n <div class=\"candidate-no-camera\" *ngIf=\"!candidateVideoStreamReady()\">\n <h3>&nbsp;</h3>\n <ui-icon name=\"User-profile-in-line\" color=\"white\" size=\"24\"></ui-icon>\n <h3 class=\"bold\">{{ translations['YOU'] }}</h3>\n </div>\n <div class=\"candidate-camera\" [hidden]=\"!candidateVideoStreamReady()\">\n <video\n height\n #video\n id=\"video\"\n playsinline\n (loadedmetadata)=\"onVideoLoad()\"\n ></video>\n <h3 class=\"bold\" *ngIf=\"candidateVideoStreamReady()\">\n {{ translations['YOU'] }}\n </h3>\n </div>\n <tgo-audio-animation\n *ngIf=\"isInterviewInProgress()\"\n [fakeData]=\"true\"\n ></tgo-audio-animation>\n <div class=\"interview-stream-container\">\n <tgo-interview-stream\n *ngIf=\"conversationUrl && hasMediaPermissions()\"\n [selectedMediaDevices]=\"selectedMediaDevices\"\n [conversationUrl]=\"conversationUrl\"\n (streamStart)=\"interviewStarted()\"\n (streamEnd)=\"interviewEnded()\"\n (checkMediaPermissions)=\"checkMediaPermissions()\"\n [translations]=\"translations\"\n ></tgo-interview-stream>\n </div>\n </div>\n </div>\n</div>\n\n","// Re-export from shared\nexport { ROOT_TRANSLATIONS_SCOPE } from '@testgorilla/tgo-shared-lib';\n\n","// Re-export shared models\nexport {\n Question,\n TestResultRead,\n SelectedMediaDevices,\n ISubmissionState,\n ROOT_TRANSLATIONS_SCOPE,\n} from '@testgorilla/tgo-shared-lib';\n\n// Export library-specific extensions\nexport * from './question-component';\nexport * from './translations';\n\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"testgorilla-tgo-ai-interview-test.mjs","sources":["../../../../packages/tgo-ai-interview-test/src/lib/components/interview-video/interview-video.component.ts","../../../../packages/tgo-ai-interview-test/src/lib/components/interview-video/interview-video.component.html","../../../../packages/tgo-ai-interview-test/src/lib/components/interview-stream/interview-stream.component.ts","../../../../packages/tgo-ai-interview-test/src/lib/components/interview-stream/interview-stream.component.html","../../../../packages/tgo-ai-interview-test/src/lib/components/ai-interview-test/ai-interview-test.component.ts","../../../../packages/tgo-ai-interview-test/src/lib/components/ai-interview-test/ai-interview-test.component.html","../../../../packages/tgo-ai-interview-test/src/lib/models/translations.ts","../../../../packages/tgo-ai-interview-test/src/lib/models/index.ts","../../../../packages/tgo-ai-interview-test/src/testgorilla-tgo-ai-interview-test.ts"],"sourcesContent":["import { Component, Input, OnInit, SimpleChanges, OnChanges } from '@angular/core';\nimport { CommonModule } from '@angular/common';\n\n@Component({\n selector: 'tgo-interview-video',\n templateUrl: './interview-video.component.html',\n styleUrls: ['./interview-video.component.scss'],\n imports: [CommonModule]\n})\nexport class InterviewVideoComponent implements OnInit, OnChanges {\n @Input() videoTrack: MediaStreamTrack | undefined;\n @Input() audioTrack: MediaStreamTrack | undefined;\n videoStream: MediaStream | undefined;\n audioStream: MediaStream | undefined;\n\n ngOnInit(): void {\n if (this.videoTrack) {\n this.addVideoStream(this.videoTrack);\n }\n if (this.audioTrack) {\n this.addAudioStream(this.audioTrack);\n }\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n const { videoTrack, audioTrack } = changes;\n\n if (videoTrack?.currentValue && !this.videoStream) {\n this.addVideoStream(videoTrack.currentValue);\n }\n\n if (audioTrack?.currentValue && !this.audioStream) {\n this.addAudioStream(audioTrack.currentValue);\n }\n\n if (videoTrack?.currentValue && this.videoStream) {\n this.updateVideoTrack(videoTrack.previousValue, videoTrack.currentValue);\n }\n\n if (audioTrack?.currentValue && this.audioStream) {\n this.updateAudioTrack(audioTrack.previousValue, audioTrack.currentValue);\n }\n }\n\n addVideoStream(track: MediaStreamTrack) {\n this.videoStream = new MediaStream([track]);\n }\n\n addAudioStream(track: MediaStreamTrack) {\n this.audioStream = new MediaStream([track]);\n }\n\n updateVideoTrack(oldTrack: MediaStreamTrack, track: MediaStreamTrack) {\n if (oldTrack) {\n this.videoStream?.removeTrack(oldTrack);\n }\n this.videoStream?.addTrack(track);\n }\n\n updateAudioTrack(oldTrack: MediaStreamTrack, track: MediaStreamTrack) {\n if (oldTrack) {\n this.audioStream?.removeTrack(oldTrack);\n }\n this.audioStream?.addTrack(track);\n }\n}\n\n","@if (videoStream) {\n<video autoPlay muted playsInline [srcObject]=\"videoStream\"></video>\n} @if (audioStream) {\n<audio autoPlay playsInline [srcObject]=\"audioStream\">\n <track kind=\"captions\" />\n</audio>\n}\n\n","import {\n ChangeDetectorRef,\n Component,\n EventEmitter,\n inject,\n Input,\n OnDestroy,\n OnInit,\n Output,\n signal,\n} from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport DailyIframe, {\n DailyCall,\n DailyEventObjectParticipant,\n DailyParticipant,\n DailyEventObjectFatalError,\n DailyEventObjectParticipants,\n DailyEventObjectNoPayload,\n DailyEventObjectParticipantLeft,\n DailyEventObjectTrack,\n DailyEventObjectAppMessage,\n} from '@daily-co/daily-js';\nimport { SelectedMediaDevices } from '@testgorilla/tgo-shared-lib';\nimport { InterviewVideoComponent } from '../interview-video/interview-video.component';\nimport { SnackbarService } from '@testgorilla/tgo-ui';\n\nexport type Participant = {\n videoTrack?: MediaStreamTrack | undefined;\n audioTrack?: MediaStreamTrack | undefined;\n videoReady: boolean;\n audioReady: boolean;\n userName: string;\n local: boolean;\n sessionId: string;\n};\n\nconst PLAYABLE_STATE = 'playable';\nconst LOADING_STATE = 'loading';\n\ninterface EventData {\n event_type: string;\n properties: {\n name: string;\n arguments: string;\n };\n}\n\n@Component({\n selector: 'tgo-interview-stream',\n templateUrl: './interview-stream.component.html',\n styleUrls: ['./interview-stream.component.scss'],\n imports: [CommonModule, InterviewVideoComponent],\n providers: [SnackbarService],\n})\nexport class InterviewStreamComponent implements OnInit, OnDestroy {\n @Input() conversationUrl: string | undefined;\n @Input() selectedMediaDevices: SelectedMediaDevices | undefined;\n @Input() translations: { [key: string]: string } = {};\n @Output() streamStart: EventEmitter<null> = new EventEmitter();\n @Output() streamEnd: EventEmitter<null> = new EventEmitter();\n @Output() checkMediaPermissions: EventEmitter<null> = new EventEmitter();\n\n callObject: DailyCall | undefined;\n avatarParticipant: Participant | undefined;\n candidateJoined = signal(false);\n private cdr = inject(ChangeDetectorRef);\n private snackbarService = inject(SnackbarService);\n\n ngOnInit(): void {\n void this.setupCall();\n }\n\n ngOnDestroy(): void {\n if (!this.callObject) return;\n this.leaveCall();\n this.callObject\n .off('joined-meeting', this.candidateJoinMeeting)\n .off('participant-joined', this.participantJoined)\n .off('app-message', this.handleNewMessage)\n .off('track-started', this.handleTrackStartedStopped)\n .off('track-stopped', this.handleTrackStartedStopped)\n .off('participant-left', this.handleParticipantLeft)\n .off('left-meeting', this.handleLeftMeeting)\n .off('nonfatal-error', this.logGenericError)\n .off('load-attempt-failed', this.logGenericError)\n .off('camera-error', this.logGenericError)\n .off('error', this.handleError);\n }\n\n private async setupCall() {\n this.callObject = DailyIframe.getCallInstance();\n if (!this.callObject) {\n this.callObject = DailyIframe.createCallObject();\n }\n if (this.selectedMediaDevices) {\n await this.callObject.setInputDevicesAsync({\n videoDeviceId: this.selectedMediaDevices.videoDeviceId,\n audioDeviceId: this.selectedMediaDevices.audioDeviceId,\n });\n }\n\n this.callObject\n .on('joined-meeting', this.candidateJoinMeeting)\n .on('participant-joined', this.participantJoined)\n .on('app-message', this.handleNewMessage)\n .on('track-started', this.handleTrackStartedStopped)\n .on('track-stopped', this.handleTrackStartedStopped)\n .on('participant-left', this.handleParticipantLeft)\n .on('left-meeting', this.handleLeftMeeting)\n .on('nonfatal-error', this.logGenericError)\n .on('load-attempt-failed', this.logGenericError)\n .on('camera-error', this.logGenericError)\n .on('error', this.handleError);\n\n await this.callObject.join({\n userName: 'Candidate',\n url: this.conversationUrl,\n });\n }\n\n formatParticipantObj(participant: DailyParticipant): Participant {\n const { video, audio } = participant.tracks;\n\n const videoTrack = video?.persistentTrack;\n const audioTrack = audio?.persistentTrack;\n return {\n videoTrack: videoTrack,\n audioTrack: audioTrack,\n videoReady: !!(\n videoTrack &&\n (video.state === PLAYABLE_STATE || video.state === LOADING_STATE)\n ),\n audioReady: !!(\n audioTrack &&\n (audio.state === PLAYABLE_STATE || audio.state === LOADING_STATE)\n ),\n userName: participant.user_name,\n local: participant.local,\n sessionId: participant.session_id,\n };\n }\n\n updateTrack(participant: DailyParticipant, newTrackType: string): void {\n if (\n !this.avatarParticipant ||\n this.avatarParticipant.sessionId !== participant.session_id\n ) {\n return;\n }\n const existingParticipant = this.avatarParticipant as Participant;\n const currentParticipantCopy = this.formatParticipantObj(participant);\n\n if (newTrackType === 'video') {\n if (\n existingParticipant.videoReady !== currentParticipantCopy.videoReady\n ) {\n existingParticipant.videoReady = currentParticipantCopy.videoReady;\n }\n\n if (\n currentParticipantCopy.videoReady &&\n existingParticipant.videoTrack?.id !==\n currentParticipantCopy.videoTrack?.id\n ) {\n existingParticipant.videoTrack = currentParticipantCopy.videoTrack;\n }\n return;\n }\n\n if (newTrackType === 'audio') {\n if (\n existingParticipant.audioReady !== currentParticipantCopy.audioReady\n ) {\n existingParticipant.audioReady = currentParticipantCopy.audioReady;\n }\n\n if (\n currentParticipantCopy.audioReady &&\n existingParticipant.audioTrack?.id !==\n currentParticipantCopy.audioTrack?.id\n ) {\n existingParticipant.audioTrack = currentParticipantCopy.audioTrack;\n }\n }\n }\n\n private candidateJoinMeeting = (\n event: DailyEventObjectParticipants | undefined\n ): void => {\n if (!event || !this.callObject) return;\n this.callObject.startRecording({\n type: 'cloud',\n });\n this.candidateJoined.set(true);\n this.streamStart.emit();\n };\n\n private participantJoined = (\n event: DailyEventObjectParticipant | undefined\n ) => {\n if (!event) return;\n this.avatarParticipant = this.formatParticipantObj(event.participant);\n };\n\n private handleTrackStartedStopped = (\n event: DailyEventObjectTrack | undefined\n ): void => {\n if (!event || !event.participant || !this.candidateJoined()) return;\n if (event.action === 'track-stopped') {\n this.checkMediaPermissions.emit();\n }\n this.updateTrack(event.participant, event.type);\n this.cdr.detectChanges();\n };\n\n private handleParticipantLeft = (\n event: DailyEventObjectParticipantLeft | undefined\n ): void => {\n if (!event) return;\n this.leaveCall();\n };\n\n private handleError = (\n event: DailyEventObjectFatalError | undefined\n ): void => {\n if (!event) return;\n console.error(\n '[AI_INTERVIEW] [DAILY_SDK] AI Interview stream error',\n event\n );\n this.leaveCall();\n };\n\n private logGenericError = (event: any): void => {\n if (!event) return;\n console.error(\n '[AI_INTERVIEW] [DAILY_SDK] AI Interview generic error',\n event\n );\n this.showWarningToUser();\n };\n\n private showWarningToUser(): void {\n this.snackbarService.warning(\n this.getTranslation(\"WARNING\",\"MESSAGE\"),\n undefined,\n undefined,\n {\n text: this.getTranslation(\"WARNING\", 'REFRESH'),\n url: '',\n action: () => {\n window.location.reload();\n },\n },\n 300\n );\n }\n\n private handleLeftMeeting = (\n event: DailyEventObjectNoPayload | undefined\n ): void => {\n this.callObject?.stopRecording();\n if (!event || !this.callObject) return;\n this.candidateJoined.set(false);\n this.callObject.destroy();\n this.streamEnd.emit();\n };\n\n private leaveCall(): void {\n if (!this.callObject) return;\n this.callObject.leave();\n }\n\n private handleNewMessage = (\n event: DailyEventObjectAppMessage<EventData> | undefined\n ): void => {\n if (!event) return;\n if (event.data.event_type === 'conversation.tool_call') {\n this.handleToolCall(event.data.properties);\n }\n };\n\n private getConversationId(): string | undefined {\n return this.conversationUrl?.replace('https://tavus.daily.co/', '');\n }\n\n /*\n This is a test implementation of tool calling.\n These events will only be triggered if configured with a Tavus persona. The message content will be further refined by the IP Team.\n https://docs.tavus.io/sections/event-schemas/conversation-toolcall\n */\n private handleToolCall = (properties: {\n name: string;\n arguments: string;\n }): void => {\n switch (properties.name) {\n case 'next_question':\n try {\n const args = JSON.parse(properties.arguments);\n if (args?.questionsLeft > 0) {\n this.sendMessage(this.getTranslation('TOOL_CALL','NEXT_QUESTION'));\n window.setTimeout(() => {\n this.sendMessage('Read next question', 'respond');\n }, 1000);\n } else {\n throw new Error('No more questions left');\n }\n } catch (err) {\n console.error(\n 'Failed to parse arguments for next_question tool call',\n err\n );\n\n this.sendMessage(this.getTranslation('TOOL_CALL','ALL_FOR_TODAY'));\n window.setTimeout(() => {\n this.leaveCall();\n }, 5000);\n }\n break;\n case 'end_conversation':\n window.setTimeout(() => {\n this.leaveCall();\n }, 5000);\n break;\n default:\n console.warn('Unknown tool call code:', properties);\n break;\n }\n };\n\n /*\n Echo message is a message that avatar reads and candidate can hear\n Respond message is a message that avatar reads and candidate cannot hear\n */\n\n private sendMessage(text: string, type: 'echo' | 'respond' = 'echo'): void {\n if (!this.callObject) return;\n\n this.callObject.sendAppMessage({\n message_type: 'conversation',\n event_type: 'conversation.' + type,\n conversation_id: this.getConversationId(),\n properties: {\n text,\n },\n });\n }\n\n private getTranslation(group: string, key: string) {\n const toolCallTranslations = this.translations[group] as unknown as {\n [key: string]: string;\n };\n return toolCallTranslations[key];\n }\n}\n","<div class=\"interview-stream\">\n @if (avatarParticipant) {\n <tgo-interview-video\n [videoTrack]=\"avatarParticipant.videoTrack\"\n [audioTrack]=\"avatarParticipant.audioTrack\"\n ></tgo-interview-video>\n }\n</div>\n\n","import { InterviewStreamComponent } from '../interview-stream/interview-stream.component';\nimport { firstValueFrom, Observable, takeUntil } from 'rxjs';\nimport { transition, style, animate, trigger } from '@angular/animations';\nimport {\n ElementRef,\n OnDestroy,\n signal,\n ViewChild,\n Component,\n EventEmitter,\n Input,\n Output,\n inject,\n OnInit,\n Inject,\n ChangeDetectorRef,\n} from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { ButtonComponentModule, DialogService, IconComponentModule } from '@testgorilla/tgo-ui';\nimport { CommonModule } from '@angular/common';\nimport {\n TRANSLOCO_SCOPE,\n TranslocoModule,\n TranslocoScope,\n TranslocoService,\n} from '@ngneat/transloco';\nimport {\n AudioAnimationComponent,\n Question,\n TestResultRead,\n SelectedMediaDevices,\n ISubmissionState,\n ROOT_TRANSLATIONS_SCOPE,\n MediaService,\n ThemeService,\n TranslocoLazyModuleUtils,\n getAvailableLangs,\n} from '@testgorilla/tgo-shared-lib';\nimport { IQuestionDataContract } from '../../models';\n\n@Component({\n selector: 'tgo-ai-interview-test',\n templateUrl: './ai-interview-test.component.html',\n styleUrl: './ai-interview-test.component.scss',\n animations: [\n trigger('fadeInFadeOut', [\n transition(':enter', [style({ opacity: 0 }), animate('600ms', style({ opacity: 1 }))]),\n transition(':leave', [animate('600ms', style({ opacity: 0 }))]),\n ]),\n ],\n imports: [\n TranslocoModule,\n ButtonComponentModule,\n IconComponentModule,\n CommonModule,\n AudioAnimationComponent,\n InterviewStreamComponent,\n ],\n providers: [\n TranslocoLazyModuleUtils.getScopeProvider(\n 'tgo-ai-interview-test',\n getAvailableLangs(),\n ROOT_TRANSLATIONS_SCOPE,\n (lang: string) => {\n // Fetch from app assets; demo app copies the library assets to\n // /assets/tgo-ai-interview-test via project.json.\n const url = new URL(`assets/tgo-ai-interview-test/i18n/${lang}.json`, document.baseURI)\n .href;\n return fetch(url).then(res => res.json());\n }\n ),\n DialogService,\n ThemeService,\n ],\n})\nexport class AiInterviewTestComponent implements OnInit, OnDestroy, IQuestionDataContract {\n @ViewChild('video') videoElement?: ElementRef<HTMLVideoElement>;\n @ViewChild('audio') audioElement?: ElementRef<HTMLAudioElement>;\n @Input({ required: true }) question!: Question;\n @Input({ required: true }) test!: TestResultRead;\n @Input() isFirstQuestion?: boolean = false;\n @Input() selectedMediaDevices?: SelectedMediaDevices;\n @Input() conversationUrl?: string;\n @Input() mediaAccessChanged?: Observable<SelectedMediaDevices> | undefined;\n @Input() isExitFullscreen?: Observable<boolean> | undefined;\n\n @Output() submissionStateChanged = new EventEmitter<ISubmissionState | null>();\n @Output() loadingStateChanged: EventEmitter<boolean> = new EventEmitter<boolean>();\n @Output() requestMediaAccess: EventEmitter<void> = new EventEmitter<void>();\n\n isInterviewInProgress = signal(false);\n candidateVideoStreamReady = signal(false);\n translations: { [key: string]: string } = {};\n hasMediaPermissions = signal(false);\n\n private unsubscribe$ = new Subject<void>();\n private mediaService = inject(MediaService);\n private translocoService = inject(TranslocoService);\n private cdr = inject(ChangeDetectorRef);\n private themeService = inject(ThemeService);\n\n companyColor = this.themeService.getCompanyColor();\n\n constructor(@Inject(TRANSLOCO_SCOPE) private translationScope: TranslocoScope) {}\n\n ngOnInit(): void {\n this.initMediaAccessSubscription();\n this.loadingStateChanged.emit(true);\n this.mediaService.setSelectedMediaDevices(this.selectedMediaDevices);\n void this.checkMediaPermissions();\n\n void this.setTranslations();\n void this.initVideoStream();\n }\n\n ngOnDestroy() {\n this.unsubscribe$.next();\n this.unsubscribe$.complete();\n }\n\n onVideoLoad() {\n this.candidateVideoStreamReady.set(true);\n }\n\n interviewStarted() {\n this.isInterviewInProgress.set(true);\n this.loadingStateChanged.emit(false);\n }\n\n interviewEnded() {\n this.isInterviewInProgress.set(false);\n this.submissionStateChanged.emit({\n text: '',\n });\n }\n\n async checkMediaPermissions() {\n if (!(await this.mediaService.checkPermission({ audio: true, video: false }))) {\n this.hasMediaPermissions.set(false);\n this.requestMediaAccess.emit();\n return;\n } else {\n this.hasMediaPermissions.set(true);\n }\n }\n\n private async initVideoStream() {\n try {\n const stream = await this.mediaService.getMediaStream({\n video: true,\n audio: false,\n });\n if (this.videoElement) {\n this.videoElement.nativeElement.srcObject = stream;\n await this.videoElement?.nativeElement.play();\n }\n } catch (error) {\n console.error('[AI_INTERVIEW] Error initializing user video stream:', error);\n this.candidateVideoStreamReady.set(false);\n }\n }\n\n private async setTranslations() {\n this.translations = await firstValueFrom(\n this.translocoService.selectTranslateObject(`TEST`, {}, this.translationScope as string)\n );\n this.cdr.markForCheck();\n }\n\n private initMediaAccessSubscription() {\n this.mediaAccessChanged?.pipe(takeUntil(this.unsubscribe$)).subscribe(selectedMediaDevices => {\n this.mediaService.setSelectedMediaDevices(selectedMediaDevices);\n this.checkMediaPermissions();\n void this.initVideoStream();\n });\n }\n}\n","<div class=\"ai-interview-test\">\n <div class=\"test-container\">\n <div class=\"media-container\" [class.is-video-visible]=\"isInterviewInProgress()\">\n <div\n class=\"candidate-no-camera\"\n *ngIf=\"!candidateVideoStreamReady() || (isExitFullscreen | async)\"\n >\n <h3>&nbsp;</h3>\n <ui-icon name=\"User-profile-in-line\" color=\"white\" size=\"24\"></ui-icon>\n <h3 class=\"bold\">{{ translations['YOU'] }}</h3>\n </div>\n <div class=\"candidate-camera\" [hidden]=\"!candidateVideoStreamReady()\">\n <video height #video id=\"video\" playsinline (loadedmetadata)=\"onVideoLoad()\"></video>\n <h3 class=\"bold\" *ngIf=\"candidateVideoStreamReady()\">\n {{ translations['YOU'] }}\n </h3>\n </div>\n <tgo-audio-animation *ngIf=\"isInterviewInProgress()\" [fakeData]=\"true\"></tgo-audio-animation>\n <div class=\"interview-stream-container\">\n <tgo-interview-stream\n *ngIf=\"\n conversationUrl &&\n hasMediaPermissions() &&\n !(isExitFullscreen && (isExitFullscreen | async))\n \"\n [selectedMediaDevices]=\"selectedMediaDevices\"\n [conversationUrl]=\"conversationUrl\"\n (streamStart)=\"interviewStarted()\"\n (streamEnd)=\"interviewEnded()\"\n (checkMediaPermissions)=\"checkMediaPermissions()\"\n [translations]=\"translations\"\n ></tgo-interview-stream>\n </div>\n </div>\n </div>\n</div>\n","// Re-export from shared\nexport { ROOT_TRANSLATIONS_SCOPE } from '@testgorilla/tgo-shared-lib';\n\n","// Re-export shared models\nexport {\n Question,\n TestResultRead,\n SelectedMediaDevices,\n ISubmissionState,\n ROOT_TRANSLATIONS_SCOPE,\n} from '@testgorilla/tgo-shared-lib';\n\n// Export library-specific extensions\nexport * from './question-component';\nexport * from './translations';\n\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -14,6 +14,7 @@ export declare class AiInterviewTestComponent implements OnInit, OnDestroy, IQue
14
14
  selectedMediaDevices?: SelectedMediaDevices;
15
15
  conversationUrl?: string;
16
16
  mediaAccessChanged?: Observable<SelectedMediaDevices> | undefined;
17
+ isExitFullscreen?: Observable<boolean> | undefined;
17
18
  submissionStateChanged: EventEmitter<ISubmissionState>;
18
19
  loadingStateChanged: EventEmitter<boolean>;
19
20
  requestMediaAccess: EventEmitter<void>;
@@ -40,5 +41,5 @@ export declare class AiInterviewTestComponent implements OnInit, OnDestroy, IQue
40
41
  private setTranslations;
41
42
  private initMediaAccessSubscription;
42
43
  static ɵfac: i0.ɵɵFactoryDeclaration<AiInterviewTestComponent, never>;
43
- static ɵcmp: i0.ɵɵComponentDeclaration<AiInterviewTestComponent, "tgo-ai-interview-test", never, { "question": { "alias": "question"; "required": true; }; "test": { "alias": "test"; "required": true; }; "isFirstQuestion": { "alias": "isFirstQuestion"; "required": false; }; "selectedMediaDevices": { "alias": "selectedMediaDevices"; "required": false; }; "conversationUrl": { "alias": "conversationUrl"; "required": false; }; "mediaAccessChanged": { "alias": "mediaAccessChanged"; "required": false; }; }, { "submissionStateChanged": "submissionStateChanged"; "loadingStateChanged": "loadingStateChanged"; "requestMediaAccess": "requestMediaAccess"; }, never, never, true, never>;
44
+ static ɵcmp: i0.ɵɵComponentDeclaration<AiInterviewTestComponent, "tgo-ai-interview-test", never, { "question": { "alias": "question"; "required": true; }; "test": { "alias": "test"; "required": true; }; "isFirstQuestion": { "alias": "isFirstQuestion"; "required": false; }; "selectedMediaDevices": { "alias": "selectedMediaDevices"; "required": false; }; "conversationUrl": { "alias": "conversationUrl"; "required": false; }; "mediaAccessChanged": { "alias": "mediaAccessChanged"; "required": false; }; "isExitFullscreen": { "alias": "isExitFullscreen"; "required": false; }; }, { "submissionStateChanged": "submissionStateChanged"; "loadingStateChanged": "loadingStateChanged"; "requestMediaAccess": "requestMediaAccess"; }, never, never, true, never>;
44
45
  }
@@ -24,6 +24,7 @@ export declare class InterviewStreamComponent implements OnInit, OnDestroy {
24
24
  avatarParticipant: Participant | undefined;
25
25
  candidateJoined: import("@angular/core").WritableSignal<boolean>;
26
26
  private cdr;
27
+ private snackbarService;
27
28
  ngOnInit(): void;
28
29
  ngOnDestroy(): void;
29
30
  private setupCall;
@@ -34,13 +35,15 @@ export declare class InterviewStreamComponent implements OnInit, OnDestroy {
34
35
  private handleTrackStartedStopped;
35
36
  private handleParticipantLeft;
36
37
  private handleError;
38
+ private logGenericError;
39
+ private showWarningToUser;
37
40
  private handleLeftMeeting;
38
41
  private leaveCall;
39
42
  private handleNewMessage;
40
43
  private getConversationId;
41
44
  private handleToolCall;
42
45
  private sendMessage;
43
- private getToolCallTranslation;
46
+ private getTranslation;
44
47
  static ɵfac: i0.ɵɵFactoryDeclaration<InterviewStreamComponent, never>;
45
48
  static ɵcmp: i0.ɵɵComponentDeclaration<InterviewStreamComponent, "tgo-interview-stream", never, { "conversationUrl": { "alias": "conversationUrl"; "required": false; }; "selectedMediaDevices": { "alias": "selectedMediaDevices"; "required": false; }; "translations": { "alias": "translations"; "required": false; }; }, { "streamStart": "streamStart"; "streamEnd": "streamEnd"; "checkMediaPermissions": "checkMediaPermissions"; }, never, never, true, never>;
46
49
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testgorilla/tgo-ai-interview-test",
3
- "version": "2.0.2",
3
+ "version": "2.0.3",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">= 19.0.0 < 20.0.0",
6
6
  "@angular/core": ">= 19.0.0 < 20.0.0",