Create feature to send and read audio message

This commit is contained in:
Gregoire Parant 2020-09-21 15:00:39 +02:00
parent 16b3e48711
commit 8c43c67741
7 changed files with 247 additions and 22 deletions

View file

@ -95,6 +95,9 @@
</div>
</div>
<div id="cowebsite" class="cowebsite"></div>
<div class="audio-playing">
<img src="/resources/logos/megaphone.svg"/>
</div>
</div>
<!--
<div id="webRtc" class="webrtc">

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 451.7 512" style="enable-background:new 0 0 451.7 512;" xml:space="preserve">
<path d="M436.9,212.6L237.2,12.9c-11.7-11.7-30.7-11.7-42.4,0s-11.7,30.7,0,42.4L394.5,255c11.5,11.9,30.5,12.2,42.4,0.7
c11.9-11.5,12.2-30.5,0.7-42.4C437.4,213.1,437.2,212.8,436.9,212.6z"/>
<path d="M179.5,83.1l-1.5,7.5c-10.4,53-36,103.4-70.6,144.3l109,108.3c40.7-34.9,90.2-61.5,143.1-72.3l7.5-1.5L179.5,83.1z"/>
<path d="M87.4,257l-74.2,74.2c-17.6,17.6-17.6,46.1,0,63.6c0,0,0,0,0,0l42.4,42.4c17.6,17.6,46.1,17.6,63.6,0c0,0,0,0,0,0l74.2-74.2
L87.4,257z M98,373.7c-6.1,5.6-15.6,5.3-21.2-0.8c-5.4-5.8-5.4-14.7,0-20.5l21.2-21.2c6-5.8,15.5-5.6,21.2,0.4
c5.6,5.8,5.6,15,0,20.8L98,373.7z"/>
<path d="M256.1,445.3l20.4-20.4c17.6-17.6,17.6-46.1,0-63.6l-15.1-15.2c-8.4,5.7-16.4,11.7-24.2,18.3l18.1,18.1
c5.8,5.9,5.8,15.3,0,21.2l-20.7,20.8l-30.5-29.5l-42.4,42.4l68.1,65.9c11.7,11.7,30.7,11.7,42.4,0c11.7-11.7,11.7-30.7,0-42.4l0,0
L256.1,445.3z"/>
<path d="M316.7,0c-8.3,0-15,6.7-15,15v30c0,8.3,6.7,15,15,15c8.3,0,15-6.7,15-15V15C331.7,6.7,325,0,316.7,0z"/>
<path d="M436.7,120h-30c-8.3,0-15,6.7-15,15s6.7,15,15,15h30c8.3,0,15-6.7,15-15S445,120,436.7,120z"/>
<path d="M417.3,34.4c-5.9-5.9-15.4-5.9-21.2,0l-30,30c-6,5.8-6.1,15.3-0.4,21.2c5.8,6,15.3,6.1,21.2,0.4c0.1-0.1,0.2-0.2,0.4-0.4
l30-30C423.2,49.7,423.2,40.2,417.3,34.4z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 448 448" style="enable-background:new 0 0 448 448;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFDA01;}
</style>
<path class="st0" d="M348,288c-44.2,0-80,35.8-80,80s35.8,80,80,80s80-35.8,80-80C428,323.8,392.2,288,348,288z M387.6,359.6
c-3.1,3.1-8.2,3.1-11.3,0L356,339.3V416c0,4.4-3.6,8-8,8s-8-3.6-8-8v-76.7l-20.3,20.3c-3.1,3-8.1,3-11.2-0.1s-3.1-8.1-0.1-11.2
l33.9-33.9c0.7-0.7,1.6-1.3,2.6-1.7c2-0.8,4.2-0.8,6.1,0c1,0.4,1.9,1,2.6,1.7l33.9,33.9C390.7,351.4,390.7,356.5,387.6,359.6z"/>
<path class="st0" d="M244,154.6L148,182v15.4l96-27.4V154.6z"/>
<path class="st0" d="M244,280c0,8.8-7.2,16-16,16s-16-7.2-16-16s7.2-16,16-16S244,271.2,244,280z"/>
<path class="st0" d="M132,312c0,8.8-7.2,16-16,16s-16-7.2-16-16s7.2-16,16-16S132,303.2,132,312z"/>
<path class="st0" d="M31.3,80H100V11.3L31.3,80z"/>
<path class="st0" d="M20,448h275c-0.1-0.1-0.2-0.1-0.3-0.2c-2.9-2-5.8-4.1-8.5-6.4c-0.7-0.6-1.4-1.3-2.1-1.9
c-1.9-1.7-3.8-3.5-5.6-5.4c-0.8-0.9-1.6-1.8-2.4-2.7c-1.6-1.8-3.2-3.8-4.7-5.7c-0.7-0.9-1.4-1.8-2-2.7c-1.8-2.6-3.5-5.2-5-8
c-0.2-0.4-0.4-0.7-0.6-1c-1.7-3.1-3.2-6.4-4.6-9.7c-0.4-1-0.7-2-1.1-3c-0.9-2.4-1.7-4.9-2.4-7.4c-0.3-1.2-0.6-2.4-0.9-3.6
c-0.6-2.5-1.1-5-1.5-7.6c-0.2-1.1-0.4-2.3-0.5-3.4c-0.9-6.9-1-13.9-0.2-20.8c0.1-1.1,0.3-2.1,0.5-3.1c0.3-2.1,0.5-4.1,0.9-6.2
c0.2-1.2,0.6-2.4,0.9-3.7c0.4-1.8,0.8-3.6,1.4-5.3c0.4-1.3,0.9-2.5,1.3-3.8c0.6-1.6,1.1-3.3,1.8-4.9c0.5-1.3,1.1-2.5,1.7-3.7
c0.7-1.5,1.4-3,2.2-4.5c0.6-1.2,1.4-2.4,2-3.6c0.8-1.4,1.7-2.8,2.6-4.2c0.8-1.2,1.6-2.3,2.4-3.4c0.9-1.3,1.9-2.6,2.9-3.9
c0.9-1.1,1.8-2.1,2.7-3.2c1.1-1.2,2.1-2.4,3.2-3.6c1-1,2-2,3-2.9c1.2-1.1,2.3-2.2,3.6-3.2c1.1-0.9,2.1-1.8,3.2-2.7
c1.3-1,2.6-2,3.9-2.9c1.1-0.8,2.3-1.6,3.5-2.4c1.4-0.9,2.8-1.7,4.2-2.5c1.2-0.7,2.4-1.4,3.6-2c1.5-0.8,2.9-1.5,4.4-2.1
c1.3-0.6,2.5-1.2,3.8-1.7c1.6-0.6,3.1-1.2,4.7-1.7c1.3-0.4,2.6-0.9,3.9-1.3c1.6-0.5,3.3-0.9,5-1.3c1.3-0.3,2.6-0.7,4-0.9
c1.8-0.3,3.5-0.6,5.3-0.8c1.3-0.2,2.6-0.4,4-0.5c0.3,0,0.6-0.1,1-0.1V0H116v88c0,4.4-3.6,8-8,8H20V448z M116,280
c5.6,0,11.2,1.6,16,4.4V176c0-3.6,2.4-6.7,5.8-7.7l112-32c2.4-0.7,5-0.2,7,1.3s3.2,3.9,3.2,6.4v136c0,17.7-14.3,32-32,32
s-32-14.3-32-32s14.3-32,32-32c5.6,0,11.2,1.6,16,4.4v-65.8L148,214v98c0,17.7-14.3,32-32,32s-32-14.3-32-32S98.3,280,116,280z"/>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -0,0 +1 @@
<svg id="Calque_1" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 439.23 480"><defs><style>.cls-1{fill:#ffda01;}</style></defs><path class="cls-1" d="M276,160a8,8,0,0,0-10.19-7.7l-112,32A8,8,0,0,0,148,192V300.45A31.61,31.61,0,0,0,132,296a32,32,0,1,0,32,32V230l96-27.43v65.84A31.61,31.61,0,0,0,244,264a32,32,0,1,0,32,32ZM132,344a16,16,0,1,1,16-16A16,16,0,0,1,132,344Zm32-130.61V198l96-27.42V186ZM244,312a16,16,0,1,1,16-16A16,16,0,0,1,244,312Z" transform="translate(-20)"/><path class="cls-1" d="M372,288.41V8a8,8,0,0,0-8-8H124c-.17,0-.32.09-.49.1a7.75,7.75,0,0,0-2.08.41,7.34,7.34,0,0,0-.74.27,7.67,7.67,0,0,0-2.34,1.6l-96,96a7.67,7.67,0,0,0-1.6,2.34,6.55,6.55,0,0,0-.27.74,7.75,7.75,0,0,0-.41,2.08c0,.17-.1.32-.1.49V472a8,8,0,0,0,8,8H364a96,96,0,0,0,8-191.59ZM116,27.31V96H47.34ZM311,464H36V112h88a8,8,0,0,0,8-8V16H356V288.33c-.32,0-.63.1-1,.13-1.34.11-2.64.34-4,.52-1.79.23-3.57.48-5.34.8-1.34.26-2.65.6-4,.92-1.68.4-3.35.8-5,1.28-1.33.4-2.62.86-3.93,1.31-1.6.55-3.2,1.1-4.73,1.73-1.28.52-2.54,1.1-3.8,1.68-1.5.68-3,1.38-4.45,2.13-1.23.65-2.39,1.34-3.64,2-1.41.8-2.8,1.65-4.16,2.53-1.18.76-2.32,1.55-3.46,2.35-1.31.94-2.6,1.9-3.87,2.9-1.1.86-2.17,1.74-3.2,2.66-1.22,1-2.4,2.13-3.56,3.2s-2,1.93-3,2.94c-1.12,1.16-2.19,2.35-3.25,3.57-.91,1-1.82,2.1-2.69,3.2-1,1.25-2,2.57-2.9,3.88-.81,1.12-1.61,2.25-2.41,3.41-.89,1.36-1.72,2.77-2.55,4.19-.69,1.19-1.41,2.4-2,3.59-.81,1.47-1.48,3-2.18,4.51-.58,1.23-1.18,2.45-1.7,3.71-.64,1.61-1.21,3.2-1.77,4.86-.44,1.26-.92,2.49-1.32,3.77-.52,1.74-.93,3.53-1.36,5.32-.3,1.22-.65,2.4-.9,3.66-.4,2-.67,4.08-.93,6.15-.15,1-.36,2.08-.46,3.14a90.44,90.44,0,0,0,.23,20.8c.14,1.14.34,2.27.52,3.41.39,2.57.87,5.1,1.47,7.6.29,1.22.59,2.4.94,3.63.7,2.5,1.52,5,2.4,7.37.36,1,.68,2,1.09,3a95.94,95.94,0,0,0,4.56,9.68c.19.35.43.68.63,1a92.82,92.82,0,0,0,5,8c.65.94,1.36,1.84,2,2.75,1.49,2,3,3.87,4.66,5.71.8.92,1.6,1.81,2.4,2.69,1.8,1.88,3.67,3.66,5.6,5.4.72.64,1.4,1.32,2.14,1.94a101,101,0,0,0,8.46,6.41A1.45,1.45,0,0,1,311,464Zm53,0a80,80,0,1,1,80-80A80,80,0,0,1,364,464Z" transform="translate(-20)"/><path class="cls-1" d="M369.7,330.35a8.15,8.15,0,0,0-2.61-1.73,8,8,0,0,0-8.72,1.73l-33.93,33.93a8,8,0,0,0,11.31,11.31L356,355.31V432a8,8,0,0,0,16,0V355.31l20.28,20.28a8,8,0,0,0,11.31-11.31Z" transform="translate(-20)"/></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -499,4 +499,63 @@ body {
.main-console .menu span.active {
color: white;
border-bottom: solid 1px white;
}
.main-console section{
text-align: center;
display: none;
}
.main-console section.active{
display: block;
}
.main-console section div.upload{
text-align: center;
border: solid 1px #ffda01;
height: 150px;
margin: 10px 200px;
padding: 20px;
min-height: 200px;
}
.main-console section div.upload label{
color: #ffda01;
}
.main-console section div.upload input{
display: none;
}
.main-console section div.upload label img{
height: 150px;
cursor: pointer;
}
.main-console section div.upload label img{
cursor: pointer;
}
/*audio html when audio message playing*/
.main-container .audio-playing {
position: absolute;
width: 200px;
height: 54px;
right: -210px;
top: 40px;
transition: all 0.1s ease-out;
background-color: black;
border-radius: 30px 0 0 30px;
display: inline-flex;
}
.main-container .audio-playing.active{
right: 0;
}
.main-container .audio-playing img{
width: 30px;
border-radius: 50%;
background-color: #ffda01;
padding: 10px;
}
.main-container .audio-playing p{
color: white;
margin-left: 10px;
}

View file

@ -34,10 +34,14 @@ export class ConsoleGlobalMessageManager {
initialise() {
try {
let mainConsole = HtmlUtils.getElementByIdOrFail<HTMLDivElement>(CLASS_CONSOLE_MESSAGE);
mainConsole.remove();
HtmlUtils.removeElementByIdOrFail(CLASS_CONSOLE_MESSAGE);
}catch (err){}
const typeConsole = document.createElement('input');
typeConsole.id = INPUT_TYPE_CONSOLE;
typeConsole.value = MESSAGE_TYPE;
typeConsole.type = 'hidden';
const menu = document.createElement('div');
menu.classList.add('menu')
const textMessage = document.createElement('span');
@ -45,14 +49,28 @@ export class ConsoleGlobalMessageManager {
textMessage.classList.add('active');
textMessage.addEventListener('click', () => {
textMessage.classList.add('active');
const messageSection = HtmlUtils.getElementByIdOrFail<HTMLInputElement>(this.getSectionId(INPUT_CONSOLE_MESSAGE));
messageSection.classList.add('active');
textAudio.classList.remove('active');
const audioSection = HtmlUtils.getElementByIdOrFail<HTMLInputElement>(this.getSectionId(UPLOAD_CONSOLE_MESSAGE));
audioSection.classList.remove('active');
typeConsole.value = MESSAGE_TYPE;
});
menu.appendChild(textMessage);
const textAudio = document.createElement('span');
textAudio.innerText = "Audio";
textAudio.addEventListener('click', () => {
textAudio.classList.add('active');
const audioSection = HtmlUtils.getElementByIdOrFail<HTMLInputElement>(this.getSectionId(UPLOAD_CONSOLE_MESSAGE));
audioSection.classList.add('active');
textMessage.classList.remove('active');
const messageSection = HtmlUtils.getElementByIdOrFail<HTMLInputElement>(this.getSectionId(INPUT_CONSOLE_MESSAGE));
messageSection.classList.remove('active');
typeConsole.value = AUDIO_TYPE;
});
menu.appendChild(textMessage);
menu.appendChild(textAudio);
@ -72,8 +90,10 @@ export class ConsoleGlobalMessageManager {
this.divMainConsole.className = CLASS_CONSOLE_MESSAGE;
this.divMainConsole.appendChild(this.buttonMainConsole);
this.divMainConsole.appendChild(typeConsole);
this.createTextMessagePart();
this.createUploadAudioPart();
const mainSectionDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>('main-container');
mainSectionDiv.appendChild(this.divMainConsole);
@ -81,8 +101,7 @@ export class ConsoleGlobalMessageManager {
createTextMessagePart(){
const div = document.createElement('div');
div.id = INPUT_CONSOLE_MESSAGE;
div.id = INPUT_CONSOLE_MESSAGE
const buttonSend = document.createElement('button');
buttonSend.innerText = 'Envoyer';
buttonSend.classList.add('btn');
@ -94,15 +113,11 @@ export class ConsoleGlobalMessageManager {
buttonDiv.classList.add('btn-action');
buttonDiv.appendChild(buttonSend)
const typeConsole = document.createElement('input');
typeConsole.id = INPUT_TYPE_CONSOLE;
typeConsole.value = MESSAGE_TYPE;
typeConsole.type = 'hidden';
const section = document.createElement('section');
section.id = this.getSectionId(INPUT_CONSOLE_MESSAGE);
section.classList.add('active');
section.appendChild(div);
section.appendChild(buttonDiv);
section.appendChild(typeConsole);
this.divMainConsole.appendChild(section);
//TODO refactor
@ -140,6 +155,62 @@ export class ConsoleGlobalMessageManager {
}, 1000);
}
createUploadAudioPart(){
const div = document.createElement('div');
div.classList.add('upload');
const label = document.createElement('label');
label.setAttribute('for', UPLOAD_CONSOLE_MESSAGE);
const img = document.createElement('img');
img.setAttribute('for', UPLOAD_CONSOLE_MESSAGE);
img.src = 'resources/logos/music-file.svg';
const input = document.createElement('input');
input.type = 'file';
input.id = UPLOAD_CONSOLE_MESSAGE
input.addEventListener('input', (e: any) => {
if(!e.target || !e.target.files || e.target.files.length === 0){
return;
}
let file : File = e.target.files[0];
if(!file){
return;
}
try {
HtmlUtils.removeElementByIdOrFail('audi-message-filename');
}catch (e) {}
const p = document.createElement('p');
p.id = 'audi-message-filename';
p.innerText = `${file.name} : ${this.getFileSize(file.size)}`;
label.appendChild(p);
});
label.appendChild(img);
div.appendChild(label);
div.appendChild(input);
const buttonSend = document.createElement('button');
buttonSend.innerText = 'Envoyer';
buttonSend.classList.add('btn');
buttonSend.addEventListener('click', (event: MouseEvent) => {
this.sendMessage();
this.disabled();
});
const buttonDiv = document.createElement('div');
buttonDiv.classList.add('btn-action');
buttonDiv.appendChild(buttonSend)
const section = document.createElement('section');
section.id = this.getSectionId(UPLOAD_CONSOLE_MESSAGE);
section.appendChild(div);
section.appendChild(buttonDiv);
this.divMainConsole.appendChild(section);
}
sendMessage(){
const inputType = HtmlUtils.getElementByIdOrFail<HTMLInputElement>(INPUT_TYPE_CONSOLE);
if(AUDIO_TYPE !== inputType.value && MESSAGE_TYPE !== inputType.value){
@ -176,9 +247,12 @@ export class ConsoleGlobalMessageManager {
let GlobalMessage : GlobalMessageInterface = {
id: res.id,
message: res.path,
type: MESSAGE_TYPE
type: AUDIO_TYPE
};
inputAudio.value = '';
try {
HtmlUtils.removeElementByIdOrFail('audi-message-filename');
}catch (e) {}
this.Connection.emitGlobalMessage(GlobalMessage);
}
@ -194,4 +268,20 @@ export class ConsoleGlobalMessageManager {
this.activeConsole = false;
this.divMainConsole.style.top = '-80%';
}
private getSectionId(id: string) : string {
return `section-${id}`;
}
private getFileSize(number: number) :string {
if (number < 1024) {
return number + 'bytes';
} else if (number >= 1024 && number < 1048576) {
return (number / 1024).toFixed(1) + 'KB';
} else if (number >= 1048576) {
return (number / 1048576).toFixed(1) + 'MB';
}else{
return '';
}
}
}

View file

@ -1,6 +1,7 @@
import {HtmlUtils} from "./../WebRtc/HtmlUtils";
import {Connection, GlobalMessageInterface} from "../Connection";
import {AUDIO_TYPE, MESSAGE_TYPE} from "./ConsoleGlobalMessageManager";
import {API_URL} from "../Enum/EnvironmentVariable";
export class GlobalMessageManager {
@ -39,19 +40,45 @@ export class GlobalMessageManager {
}
private playAudioMessage(messageId : number, urlMessage: string){
const messageVideo : HTMLAudioElement = document.createElement('audio');
messageVideo.id = this.getHtmlMessageId(messageId);
messageVideo.src = urlMessage;
messageVideo.onended = () => {
messageVideo.remove();
//delete previous elements
const previousDivAudio = document.getElementsByClassName('audio-playing');
for(let i = 0; i < previousDivAudio.length; i++){
previousDivAudio[i].remove();
}
messageVideo.onloadeddata = () => {
messageVideo.play();
};
const mainSectionDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>('main-container');
mainSectionDiv.appendChild(messageVideo);
//TODO add element when audio message is played
//create new element
const divAudio : HTMLDivElement = document.createElement('div');
divAudio.id = `audio-playing-${messageId}`;
divAudio.classList.add('audio-playing');
const imgAudio : HTMLImageElement = document.createElement('img');
imgAudio.src = '/resources/logos/megaphone.svg';
const pAudio : HTMLParagraphElement = document.createElement('p');
pAudio.textContent = 'Message audio'
divAudio.appendChild(imgAudio);
divAudio.appendChild(pAudio);
const mainSectionDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>('main-container');
mainSectionDiv.appendChild(divAudio);
const messageAudio : HTMLAudioElement = document.createElement('audio');
messageAudio.id = this.getHtmlMessageId(messageId);
messageAudio.autoplay = true;
messageAudio.style.display = 'none';
messageAudio.onended = () => {
divAudio.classList.remove('active');
messageAudio.remove();
setTimeout(() => {
divAudio.remove();
}, 1000);
}
messageAudio.onplay = () => {
console.log('play');
divAudio.classList.add('active');
}
const messageAudioSource : HTMLSourceElement = document.createElement('source');
messageAudioSource.src = `${API_URL}${urlMessage}`;
messageAudio.appendChild(messageAudioSource);
mainSectionDiv.appendChild(messageAudio);
}
private playTextMessage(messageId : number, htmlMessage: string){