From b993017580d19c00a26acbd4e1696347680d28cc Mon Sep 17 00:00:00 2001
From: Steven Jaquet <steven.jaquet@etu.hesge.ch>
Date: Sat, 20 Jul 2024 13:20:27 +0200
Subject: [PATCH] =?UTF-8?q?feat:=20Impl=C3=A9mentation=20de=20la=20communi?=
 =?UTF-8?q?cation=20de=20l'audio=20utilisateur=20avec=20le=20Backend,=20en?=
 =?UTF-8?q?=20utilisant=20le=20nouveau=20bouton=20microphone?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 frontend/src/app/app.module.ts                |  4 +-
 frontend/src/app/audio-recording.service.ts   |  8 ++--
 frontend/src/app/audio-upload.service.ts      |  4 +-
 .../interview-pane.component.html             | 10 +----
 .../interview-pane.component.ts               | 45 ++++++++++++-------
 frontend/src/app/shared.service.ts            | 22 ++++-----
 6 files changed, 50 insertions(+), 43 deletions(-)

diff --git a/frontend/src/app/app.module.ts b/frontend/src/app/app.module.ts
index 1fa5227..949b990 100755
--- a/frontend/src/app/app.module.ts
+++ b/frontend/src/app/app.module.ts
@@ -4,7 +4,7 @@ import { HttpClientModule } from '@angular/common/http';
 import { RouterModule, Routes } from '@angular/router';
 import { AppRoutingModule } from './app-routing.module';
 import { AppComponent } from './app.component';
-import { VideoService } from './audio-upload.service';
+import { AudioService } from './audio-upload.service';
 import { AudioRecordingService } from './audio-recording.service';
 import { InterviewPaneComponent } from './interview-pane/interview-pane.component';
 import { GameMenuComponent } from './game-menu/game-menu.component';
@@ -24,7 +24,7 @@ import { ReactiveFormsModule } from '@angular/forms';
     HttpClientModule,
     ReactiveFormsModule 
   ],
-  providers: [VideoService, AudioRecordingService],
+  providers: [AudioService, AudioRecordingService],
   bootstrap: [AppComponent]
 })
 export class AppModule { }
diff --git a/frontend/src/app/audio-recording.service.ts b/frontend/src/app/audio-recording.service.ts
index d8cc017..8f383d3 100755
--- a/frontend/src/app/audio-recording.service.ts
+++ b/frontend/src/app/audio-recording.service.ts
@@ -74,10 +74,10 @@ export class AudioRecordingService {
   stopRecording() {
     if (this.recorder) {
       this.recorder.stop(
-          blob => {
-            const mp3Name = encodeURIComponent("output.mp3");
-            this.stopMedia();
-            this._recorded.next({ blob: blob, title: mp3Name });
+        blob => {
+          const mp3Name = encodeURIComponent("output.mp3");
+          this.stopMedia();
+          this._recorded.next({ blob: blob, title: mp3Name });
         },
       );
     }
diff --git a/frontend/src/app/audio-upload.service.ts b/frontend/src/app/audio-upload.service.ts
index 829094a..0de4c2d 100755
--- a/frontend/src/app/audio-upload.service.ts
+++ b/frontend/src/app/audio-upload.service.ts
@@ -8,7 +8,7 @@ import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
 @Injectable({
   providedIn: 'root'
 })
-export class VideoService {
+export class AudioService {
   private apiUrl = 'http://localhost:8000/api/upload/';
 
   constructor(
@@ -17,7 +17,7 @@ export class VideoService {
     private sanitizer: DomSanitizer,
   ) { }
 
-  uploadVideo(formData: FormData): Observable<any> {
+  uploadAudio(formData: FormData): Observable<any> {
     return new Observable<any>((observer) => {
       this.http.post(this.apiUrl, formData, { responseType: 'blob' }).subscribe(
         async (response: Blob) => {  
diff --git a/frontend/src/app/interview-pane/interview-pane.component.html b/frontend/src/app/interview-pane/interview-pane.component.html
index f37a154..d0c7770 100644
--- a/frontend/src/app/interview-pane/interview-pane.component.html
+++ b/frontend/src/app/interview-pane/interview-pane.component.html
@@ -18,14 +18,8 @@
   <app-game-menu></app-game-menu>
   <app-options-column></app-options-column>
 
-  <div class="mic" id="mic" style="display: none;">
+  <div class="mic" id="mic" style="display: none;" (click)="toggleRecording()">
     <i class="mic-icon"></i>
     <div class="mic-shadow" id="micShadow"></div>
-    <button class="micro-button" *ngIf="audioBlobUrl" (click)="uploadAudio()">Upload</button>
-    <div *ngIf="audioBlobUrl">
-      <audio controls>
-        <source [src]="audioBlobUrl" type="audio/webm">
-      </audio>
-    </div>
-  </div>
+  </div>  
 </div>
diff --git a/frontend/src/app/interview-pane/interview-pane.component.ts b/frontend/src/app/interview-pane/interview-pane.component.ts
index 8789ff4..184c965 100644
--- a/frontend/src/app/interview-pane/interview-pane.component.ts
+++ b/frontend/src/app/interview-pane/interview-pane.component.ts
@@ -2,7 +2,7 @@ import { Component, OnInit, AfterViewInit } from '@angular/core';
 import { SharedService } from '../shared.service';
 import { AudioRecordingService } from '../audio-recording.service';
 import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
-import { VideoService } from '../audio-upload.service';
+import { AudioService } from '../audio-upload.service';
 
 @Component({
   selector: 'app-interview-pane',
@@ -23,7 +23,7 @@ export class InterviewPaneComponent implements OnInit, AfterViewInit {
     private audioRecordingService: AudioRecordingService,
     private sharedService: SharedService,
     private sanitizer: DomSanitizer,
-    private videoService: VideoService
+    private audioService: AudioService
   ) { }
 
   ngOnInit(): void {
@@ -48,7 +48,7 @@ export class InterviewPaneComponent implements OnInit, AfterViewInit {
 
     if (mic && micShadow) {
       mic.addEventListener('click', () => {
-        this.toggleRecording();
+        micShadow.classList.toggle('alt');
       });
     }
 
@@ -112,18 +112,24 @@ export class InterviewPaneComponent implements OnInit, AfterViewInit {
     }
   }
 
+  private textIntervalId: any;
+
   showText(text: string, container: HTMLElement): void {
     if (!container) return;
 
+    if (this.textIntervalId) {
+      clearInterval(this.textIntervalId);
+    }
+
     container.innerHTML = ''; 
     let index = 0;
 
-    const interval = setInterval(() => {
+    this.textIntervalId = setInterval(() => {
       if (index < text.length) {
         container.innerHTML += text[index];
         index++;
       } else {
-        clearInterval(interval);
+        clearInterval(this.textIntervalId);
       }
     }, 50);
   }
@@ -135,7 +141,7 @@ export class InterviewPaneComponent implements OnInit, AfterViewInit {
       this.stopRecording();
     }
   }
-
+  
   startRecording(): void {
     this.isRecording = true;
     this.audioRecordingService.startRecording();
@@ -144,34 +150,41 @@ export class InterviewPaneComponent implements OnInit, AfterViewInit {
     });
     this.audioRecordingService.getRecordedBlob().subscribe((data) => {
       this.audio = data;
+      console.log("Recorded audio data:", this.audio);
       this.audioBlobUrl = this.sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(this.audio.blob));
     });
   }
-
+  
   stopRecording(): void {
     this.audioRecordingService.stopRecording();
     this.isRecording = false;
+    setTimeout(() => {
+      this.uploadAudio();
+    }, 1000);
   }
-
+  
   uploadAudio(): void {
     if (this.audio && this.audio.blob) {
       const formData = new FormData();
       formData.append('audio', this.audio.blob, 'recording.webm');
+      
+      const videoList = this.sharedService.getCurrentVideoList();
+      if (videoList.length > 0) {
+        const selectedVideoId = videoList[videoList.length - 1].id; 
 
-      const audioList = this.sharedService.getCurrentVideoList();
-      if (audioList.length > 0) {
-        const selectedAudioId = audioList[audioList.length - 1].id;
+        formData.append('id', selectedVideoId);
 
-        formData.append('id', selectedAudioId);
-
-        this.videoService.uploadVideo(formData).subscribe(
-          (response: string) => {
+        this.audioService.uploadAudio(formData).subscribe(
+          (response: String) => {
             console.log("Response (uploadAudio): ", response);
+          },
+          (error) => {
+            console.error('Error uploading audio', error);
           }
         );
       } else {
         console.error('No audio data available');
       }
     }
-  }
+  }  
 }
diff --git a/frontend/src/app/shared.service.ts b/frontend/src/app/shared.service.ts
index 06974e2..fbfc18a 100644
--- a/frontend/src/app/shared.service.ts
+++ b/frontend/src/app/shared.service.ts
@@ -12,9 +12,17 @@ export class SharedService {
   private numQuestions = new BehaviorSubject<number>(0);
   numQuestions$ = this.numQuestions.asObservable();
 
-  private selectedVideoId = new BehaviorSubject<number | null>(null);
-  selectedVideoId$ = this.selectedVideoId.asObservable();
 
+  // Audio from User
+  private audioListSource = new BehaviorSubject<{ id: string, urls: string[] }[]>([]);
+  audioList$ = this.audioListSource.asObservable();
+
+  updateAudioList(audioData: { id: string, urls: string[] }[]): void {
+    this.audioListSource.next(audioData);
+  }
+
+
+  // Hinata Videos
   private videoListSource = new BehaviorSubject<{ id: string, urls: string[], script: string }[]>([]);
   videoList$ = this.videoListSource.asObservable();
 
@@ -45,17 +53,13 @@ export class SharedService {
     this.videoListSource.next(videoData);
   }
 
-  getCurrentVideoList(): { id: string, urls: string[], script: string }[] {
+  getCurrentVideoList(): { id: string, urls: string[] }[] {
     return this.videoListSource.getValue();
   }
 
   private videoUrlsSource = new BehaviorSubject<string[]>([]);
   videoUrls$ = this.videoUrlsSource.asObservable();
 
-  setVideoUrls(videoUrls: string[]) {
-    this.videoUrlsSource.next(videoUrls);
-  }
-
   setJsonUploaded(isUploaded: boolean): void {
     this.jsonUploaded.next(isUploaded);
   }
@@ -63,8 +67,4 @@ export class SharedService {
   setNumQuestions(num: number): void {
     this.numQuestions.next(num);
   }
-
-  setSelectedVideoId(id: number): void {
-    this.selectedVideoId.next(id);
-  }
 }
-- 
GitLab