partey_workadventure/front/src/Administration/ConsoleGlobalMessageManager.ts

499 lines
19 KiB
TypeScript
Raw Normal View History

2020-09-20 17:12:27 +02:00
import {HtmlUtils} from "../WebRtc/HtmlUtils";
2020-09-21 00:34:25 +02:00
import {UserInputManager} from "../Phaser/UserInput/UserInputManager";
import {RoomConnection} from "../Connexion/RoomConnection";
import {PlayGlobalMessageInterface} from "../Connexion/ConnexionModels";
2020-10-24 13:37:33 +02:00
import {ADMIN_URL} from "../Enum/EnvironmentVariable";
import {mediaManager} from "../WebRtc/MediaManager";
export const CLASS_CONSOLE_MESSAGE = 'main-console';
export const INPUT_CONSOLE_MESSAGE = 'input-send-text';
export const UPLOAD_CONSOLE_MESSAGE = 'input-upload-music';
export const INPUT_TYPE_CONSOLE = 'input-type';
export const GAME_QUALITY_SELECT = 'select-game-quality';
export const VIDEO_QUALITY_SELECT = 'select-video-quality';
export const VIDEO_QUALITY_CONSOLE = 'video-quality';
export const AUDIO_TYPE = 'audio';
export const MESSAGE_TYPE = 'message';
2020-09-23 19:07:45 +02:00
interface EventTargetFiles extends EventTarget {
files: Array<File>;
}
export class ConsoleGlobalMessageManager {
2020-10-24 13:37:33 +02:00
private readonly divMainConsole: HTMLDivElement;
private readonly divMessageConsole: HTMLDivElement;
private readonly divSettingConsole: HTMLDivElement;
2020-10-24 13:37:33 +02:00
private readonly buttonMainConsole: HTMLDivElement;
private readonly buttonSendMainConsole: HTMLImageElement;
private readonly buttonAdminMainConsole: HTMLImageElement;
2020-10-24 13:37:33 +02:00
private readonly buttonSettingsMainConsole: HTMLImageElement;
private activeConsole: boolean = false;
private activeMessage: boolean = false;
private activeSetting: boolean = false;
2020-09-21 00:34:25 +02:00
private userInputManager!: UserInputManager;
private static cssLoaded: boolean = false;
constructor(private Connection: RoomConnection, userInputManager : UserInputManager, private isAdmin: Boolean) {
this.buttonMainConsole = document.createElement('div');
2020-09-20 19:31:24 +02:00
this.buttonMainConsole.classList.add('console');
this.divMainConsole = document.createElement('div');
this.divMainConsole.className = CLASS_CONSOLE_MESSAGE;
this.divMessageConsole = document.createElement('div');
this.divMessageConsole.className = 'message';
this.divSettingConsole = document.createElement('div');
this.divSettingConsole.className = 'setting';
2020-10-24 13:37:33 +02:00
this.buttonSendMainConsole = document.createElement('img');
this.buttonSettingsMainConsole = document.createElement('img');
this.buttonAdminMainConsole = document.createElement('img');
2020-09-21 00:34:25 +02:00
this.userInputManager = userInputManager;
this.initialise();
}
initialise() {
2020-10-01 17:16:36 +02:00
for (const elem of document.getElementsByClassName(CLASS_CONSOLE_MESSAGE)) {
elem.remove();
2020-09-23 18:44:24 +02:00
}
2020-09-21 01:16:10 +02:00
const typeConsole = document.createElement('input');
typeConsole.id = INPUT_TYPE_CONSOLE;
typeConsole.value = MESSAGE_TYPE;
typeConsole.type = 'hidden';
2020-09-21 01:16:10 +02:00
const menu = document.createElement('div');
menu.classList.add('menu')
const textMessage = document.createElement('span');
textMessage.innerText = "Message";
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');
2020-09-21 01:16:10 +02:00
textAudio.classList.remove('active');
const audioSection = HtmlUtils.getElementByIdOrFail<HTMLInputElement>(this.getSectionId(UPLOAD_CONSOLE_MESSAGE));
audioSection.classList.remove('active');
typeConsole.value = MESSAGE_TYPE;
2020-09-21 00:42:39 +02:00
});
2020-09-21 01:16:10 +02:00
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');
2020-09-21 01:16:10 +02:00
textMessage.classList.remove('active');
const messageSection = HtmlUtils.getElementByIdOrFail<HTMLInputElement>(this.getSectionId(INPUT_CONSOLE_MESSAGE));
messageSection.classList.remove('active');
typeConsole.value = AUDIO_TYPE;
2020-09-21 01:16:10 +02:00
});
menu.appendChild(textMessage);
menu.appendChild(textAudio);
this.divMessageConsole.appendChild(menu);
2020-09-21 00:42:39 +02:00
2020-10-24 13:37:33 +02:00
this.buttonSendMainConsole.src = 'resources/logos/send-yellow.svg';
this.buttonSendMainConsole.addEventListener('click', () => {
if(this.activeMessage){
this.disabledMessageConsole();
}else{
this.activeMessageConsole();
}
});
2020-10-24 13:37:33 +02:00
this.buttonAdminMainConsole.src = 'resources/logos/setting-yellow.svg';
this.buttonAdminMainConsole.addEventListener('click', () => {
2020-10-24 13:37:33 +02:00
window.open(ADMIN_URL, '_blank');
});
this.buttonSettingsMainConsole.src = 'resources/logos/monitor-yellow.svg';
this.buttonSettingsMainConsole.addEventListener('click', () => {
if(this.activeSetting){
this.disabledSettingConsole();
}else{
this.activeSettingConsole();
}
});
2020-10-24 13:37:33 +02:00
/*const buttonText = document.createElement('p');
buttonText.innerText = 'Console';
this.buttonMainConsole.appendChild(buttonText);*/
this.divMessageConsole.appendChild(typeConsole);
if(this.isAdmin) {
this.buttonMainConsole.appendChild(this.buttonSendMainConsole);
this.buttonMainConsole.appendChild(this.buttonAdminMainConsole);
this.createTextMessagePart();
this.createUploadAudioPart();
}
this.buttonMainConsole.appendChild(this.buttonSettingsMainConsole);
this.createSettings();
this.divMainConsole.appendChild(this.buttonMainConsole);
this.divMainConsole.appendChild(this.divMessageConsole);
this.divMainConsole.appendChild(this.divSettingConsole);
2020-09-21 01:16:10 +02:00
const mainSectionDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>('main-container');
mainSectionDiv.appendChild(this.divMainConsole);
}
createTextMessagePart(){
2020-09-20 19:31:24 +02:00
const div = document.createElement('div');
div.id = INPUT_CONSOLE_MESSAGE
2020-09-20 19:31:24 +02:00
const buttonSend = document.createElement('button');
buttonSend.innerText = 'Envoyer';
2020-09-21 00:34:25 +02:00
buttonSend.classList.add('btn');
buttonSend.addEventListener('click', (event: MouseEvent) => {
this.sendMessage();
this.disabledMessageConsole();
});
2020-09-21 00:34:25 +02:00
const buttonDiv = document.createElement('div');
buttonDiv.classList.add('btn-action');
buttonDiv.appendChild(buttonSend)
2020-09-20 19:31:24 +02:00
const section = document.createElement('section');
section.id = this.getSectionId(INPUT_CONSOLE_MESSAGE);
section.classList.add('active');
2020-09-20 19:31:24 +02:00
section.appendChild(div);
2020-09-21 00:34:25 +02:00
section.appendChild(buttonDiv);
this.divMessageConsole.appendChild(section);
2020-09-20 19:31:24 +02:00
(async () => {
// Start loading CSS
const cssPromise = ConsoleGlobalMessageManager.loadCss();
// Import quill
2020-10-13 15:55:30 +02:00
const Quill:any = await import("quill"); // eslint-disable-line @typescript-eslint/no-explicit-any
// Wait for CSS to be loaded
await cssPromise;
2020-09-20 19:31:24 +02:00
const toolbarOptions = [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['blockquote', 'code-block'],
[{'header': 1}, {'header': 2}], // custom button values
[{'list': 'ordered'}, {'list': 'bullet'}],
[{'script': 'sub'}, {'script': 'super'}], // superscript/subscript
[{'indent': '-1'}, {'indent': '+1'}], // outdent/indent
[{'direction': 'rtl'}], // text direction
2020-09-20 19:31:24 +02:00
[{'size': ['small', false, 'large', 'huge']}], // custom dropdown
[{'header': [1, 2, 3, 4, 5, 6, false]}],
2020-09-20 19:31:24 +02:00
[{'color': []}, {'background': []}], // dropdown with defaults from theme
[{'font': []}],
[{'align': []}],
2020-09-20 19:31:24 +02:00
['clean'],
['link', 'image', 'video']
// remove formatting button
];
2020-09-23 18:37:54 +02:00
new Quill(`#${INPUT_CONSOLE_MESSAGE}`, {
2020-09-20 19:31:24 +02:00
theme: 'snow',
modules: {
toolbar: toolbarOptions
},
});
})();
}
2020-09-21 00:34:25 +02:00
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
2020-09-23 18:44:24 +02:00
input.addEventListener('input', (e: Event) => {
2020-09-23 19:07:45 +02:00
if(!e.target){
return;
}
const eventTarget : EventTargetFiles = (e.target as EventTargetFiles);
if(!eventTarget || !eventTarget.files || eventTarget.files.length === 0){
return;
}
2020-09-23 19:07:45 +02:00
const file : File = eventTarget.files[0];
if(!file){
return;
}
try {
HtmlUtils.removeElementByIdOrFail('audi-message-filename');
2020-09-23 18:44:24 +02:00
}catch (err) {
console.error(err)
}
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.disabledMessageConsole();
});
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.divMessageConsole.appendChild(section);
}
createSettings(){
const labelGame = document.createElement('h1');
labelGame.innerText = "Game quality";
const selectGame = document.createElement('select');
selectGame.id = VIDEO_QUALITY_SELECT;
const option1 : HTMLOptionElement = document.createElement('option');
option1.value = '120';
option1.innerText = 'High video quality (120 fps)';
selectGame.appendChild(option1);
const option2 : HTMLOptionElement = document.createElement('option');
option2.value = '60';
option2.innerText = 'Medium video quality (60 fps, recommended)';
selectGame.appendChild(option2);
const option3 : HTMLOptionElement = document.createElement('option');
option3.value = '40';
option3.innerText = 'Minimum video quality (40 fps)';
selectGame.appendChild(option3);
const option4 : HTMLOptionElement = document.createElement('option');
option4.value = '20';
option4.innerText = 'Small video quality (20 fps)';
selectGame.appendChild(option4);
const labelVideo = document.createElement('h1');
labelVideo.innerText = "Video quality";
const selectVideo = document.createElement('select');
selectVideo.id = GAME_QUALITY_SELECT;
const optionVideo1 : HTMLOptionElement = document.createElement('option');
optionVideo1.value = '30';
optionVideo1.innerText = 'High video quality (30 fps)';
selectVideo.appendChild(optionVideo1);
const optionVideo2 : HTMLOptionElement = document.createElement('option');
optionVideo2.value = '20';
optionVideo2.innerText = 'Medium video quality (20 fps, recommended)';
selectVideo.appendChild(optionVideo2);
const optionVideo3 : HTMLOptionElement = document.createElement('option');
optionVideo3.value = '10';
optionVideo3.innerText = 'Minimum video quality (10 fps)';
selectVideo.appendChild(optionVideo3);
const optionVideo4 : HTMLOptionElement = document.createElement('option');
optionVideo4.value = '5';
optionVideo4.innerText = 'Small video quality (5 fps)';
selectVideo.appendChild(optionVideo4);
selectGame.value = '60';
const localQualityGame = localStorage.getItem(GAME_QUALITY_SELECT);
if(localQualityGame){
selectGame.value = localQualityGame;
}
selectVideo.value = '30';
const localQualityCam = localStorage.getItem(VIDEO_QUALITY_SELECT);
if(localQualityCam){
selectVideo.value = localQualityCam;
}
const divButtonAction = document.createElement('div');
divButtonAction.className = 'btn-action';
const buttonSave = document.createElement('button');
buttonSave.innerText = 'Save';
buttonSave.classList.add('btn');
buttonSave.addEventListener('click', () => {
this.saveSetting(selectGame.value, selectVideo.value);
this.disabledSettingConsole();
});
divButtonAction.appendChild(buttonSave);
const section = document.createElement('section');
section.id = this.getSectionId(VIDEO_QUALITY_CONSOLE);
section.appendChild(labelGame);
section.appendChild(selectGame);
section.appendChild(labelVideo);
section.appendChild(selectVideo);
section.appendChild(divButtonAction);
this.divSettingConsole.appendChild(section);
}
private static loadCss(): Promise<void> {
return new Promise<void>((resolve, reject) => {
if (ConsoleGlobalMessageManager.cssLoaded) {
resolve();
return;
}
const fileref = document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", "https://cdn.quilljs.com/1.3.7/quill.snow.css");
document.getElementsByTagName("head")[0].appendChild(fileref);
ConsoleGlobalMessageManager.cssLoaded = true;
fileref.onload = () => {
resolve();
}
fileref.onerror = () => {
reject();
}
});
}
sendMessage(){
const inputType = HtmlUtils.getElementByIdOrFail<HTMLInputElement>(INPUT_TYPE_CONSOLE);
if(AUDIO_TYPE !== inputType.value && MESSAGE_TYPE !== inputType.value){
throw "Error event type";
}
if(AUDIO_TYPE === inputType.value){
2020-09-20 17:12:27 +02:00
return this.sendAudioMessage();
}
return this.sendTextMessage();
}
private sendTextMessage(){
2020-09-23 18:44:24 +02:00
const elements = document.getElementsByClassName('ql-editor');
const quillEditor = elements.item(0);
2020-09-23 18:07:31 +02:00
if(!quillEditor){
throw "Error get quill node";
}
const GlobalMessage : PlayGlobalMessageInterface = {
id: "1", // FIXME: use another ID?
2020-09-23 18:07:31 +02:00
message: quillEditor.innerHTML,
2020-09-20 17:12:27 +02:00
type: MESSAGE_TYPE
};
2020-09-23 18:07:31 +02:00
quillEditor.innerHTML = '';
this.Connection.emitGlobalMessage(GlobalMessage);
}
2020-09-20 17:12:27 +02:00
private async sendAudioMessage(){
const inputAudio = HtmlUtils.getElementByIdOrFail<HTMLInputElement>(UPLOAD_CONSOLE_MESSAGE);
const selectedFile = inputAudio.files ? inputAudio.files[0] : null;
if(!selectedFile){
throw 'no file selected';
}
const fd = new FormData();
fd.append('file', selectedFile);
2020-09-23 18:44:24 +02:00
const res = await this.Connection.uploadAudio(fd);
2020-09-20 17:12:27 +02:00
const GlobalMessage : PlayGlobalMessageInterface = {
id: (res as {id: string}).id,
2020-09-23 19:07:45 +02:00
message: (res as {path: string}).path,
type: AUDIO_TYPE
2020-09-20 17:12:27 +02:00
};
inputAudio.value = '';
try {
HtmlUtils.removeElementByIdOrFail('audi-message-filename');
2020-09-23 18:44:24 +02:00
}catch (err) {
console.error(err);
}
2020-09-20 17:12:27 +02:00
this.Connection.emitGlobalMessage(GlobalMessage);
}
private saveSetting(valueGame: string, valueVideo: string){
const previousGameValue = localStorage.getItem(GAME_QUALITY_SELECT);
if(!previousGameValue || previousGameValue !== valueGame) {
localStorage.setItem(GAME_QUALITY_SELECT, valueGame);
window.location.reload();
}
const previousVideoValue = localStorage.getItem(VIDEO_QUALITY_SELECT);
if(!previousVideoValue || previousVideoValue !== valueVideo) {
localStorage.setItem(VIDEO_QUALITY_SELECT, valueVideo);
mediaManager.updateCameraQuality(parseInt(valueVideo));
}
}
active(){
2020-09-21 00:34:25 +02:00
this.userInputManager.clearAllInputKeyboard();
this.divMainConsole.style.top = '0';
this.activeConsole = true;
}
disabled(){
2020-09-21 00:34:25 +02:00
this.userInputManager.initKeyBoardEvent();
this.activeConsole = false;
this.divMainConsole.style.top = '-80%';
}
activeMessageConsole(){
this.activeMessage = true;
if(this.activeSetting){
this.disabledSettingConsole();
}
this.active();
this.divMessageConsole.classList.add('active');
this.buttonSendMainConsole.classList.add('active');
}
disabledMessageConsole(){
this.activeMessage = false;
this.disabled();
this.divMessageConsole.classList.remove('active');
2020-10-24 13:37:33 +02:00
this.buttonSendMainConsole.classList.remove('active');
}
activeSettingConsole(){
this.activeSetting = true;
if(this.activeMessage){
this.disabledMessageConsole();
}
this.active();
this.divSettingConsole.classList.add('active');
this.buttonSettingsMainConsole.classList.add('active');
}
disabledSettingConsole(){
this.activeSetting = false;
this.disabled();
this.divSettingConsole.classList.remove('active');
this.buttonSettingsMainConsole.classList.remove('active');
}
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 '';
}
}
}