Merge branch 'develop' of github.com:thecodingmachine/workadventure into svelte_video_overlay
# Conflicts: # front/package.json # front/src/Components/App.svelte # front/src/Phaser/Game/GameScene.ts # front/src/Phaser/Menu/MenuScene.ts # front/src/WebRtc/MediaManager.ts
This commit is contained in:
commit
e4708149e0
172 changed files with 15268 additions and 2850 deletions
|
@ -23,6 +23,8 @@
|
|||
import ErrorDialog from "./UI/ErrorDialog.svelte";
|
||||
import VideoOverlay from "./Video/VideoOverlay.svelte";
|
||||
import {gameOverlayVisibilityStore} from "../Stores/GameOverlayStoreVisibility";
|
||||
import {consoleGlobalMessageManagerVisibleStore} from "../Stores/ConsoleGlobalMessageManagerStore";
|
||||
import ConsoleGlobalMessageManager from "./ConsoleGlobalMessageManager/ConsoleGlobalMessageManager.svelte";
|
||||
|
||||
export let game: Game;
|
||||
|
||||
|
@ -74,6 +76,11 @@
|
|||
<CameraControls></CameraControls>
|
||||
</div>
|
||||
{/if}
|
||||
{#if $consoleGlobalMessageManagerVisibleStore}
|
||||
<div>
|
||||
<ConsoleGlobalMessageManager game={game}></ConsoleGlobalMessageManager>
|
||||
</div>
|
||||
{/if}
|
||||
{#if $helpCameraSettingsVisibleStore}
|
||||
<div>
|
||||
<HelpCameraSettingsPopup></HelpCameraSettingsPopup>
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
<script lang="typescript">
|
||||
import InputTextGlobalMessage from "./InputTextGlobalMessage.svelte";
|
||||
import UploadAudioGlobalMessage from "./UploadAudioGlobalMessage.svelte";
|
||||
import {gameManager} from "../../Phaser/Game/GameManager";
|
||||
import type {Game} from "../../Phaser/Game/Game";
|
||||
|
||||
export let game: Game;
|
||||
let inputSendTextActive = true;
|
||||
let uploadMusicActive = false;
|
||||
|
||||
function inputSendTextActivate() {
|
||||
inputSendTextActive = true;
|
||||
uploadMusicActive = false;
|
||||
}
|
||||
|
||||
function inputUploadMusicActivate() {
|
||||
uploadMusicActive = true;
|
||||
inputSendTextActive = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<div class="main-console nes-container is-rounded">
|
||||
<!-- <div class="console nes-container is-rounded">
|
||||
<img class="btn-close" src="resources/logos/send-yellow.svg" alt="Close">
|
||||
</div>-->
|
||||
<div class="main-global-message">
|
||||
<h2> Global Message </h2>
|
||||
<div class="global-message">
|
||||
<div class="menu">
|
||||
<button class="nes-btn {inputSendTextActive ? 'is-disabled' : ''}" on:click|preventDefault={inputSendTextActivate}>Message</button>
|
||||
<button class="nes-btn {uploadMusicActive ? 'is-disabled' : ''}" on:click|preventDefault={inputUploadMusicActivate}>Audio</button>
|
||||
</div>
|
||||
<div class="main-input">
|
||||
{#if inputSendTextActive}
|
||||
<InputTextGlobalMessage game={game} gameManager={gameManager}></InputTextGlobalMessage>
|
||||
{/if}
|
||||
{#if uploadMusicActive}
|
||||
<UploadAudioGlobalMessage game={game} gameManager={gameManager}></UploadAudioGlobalMessage>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,99 @@
|
|||
<script lang="ts">
|
||||
import {consoleGlobalMessageManagerFocusStore, consoleGlobalMessageManagerVisibleStore } from "../../Stores/ConsoleGlobalMessageManagerStore";
|
||||
import {onMount} from "svelte";
|
||||
import type {Game} from "../../Phaser/Game/Game";
|
||||
import type {GameManager} from "../../Phaser/Game/GameManager";
|
||||
import type {PlayGlobalMessageInterface} from "../../Connexion/ConnexionModels";
|
||||
import {AdminMessageEventTypes} from "../../Connexion/AdminMessagesService";
|
||||
import type {Quill} from "quill";
|
||||
import {LoginSceneName} from "../../Phaser/Login/LoginScene";
|
||||
|
||||
//toolbar
|
||||
export 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
|
||||
|
||||
[{'size': ['small', false, 'large', 'huge']}], // custom dropdown
|
||||
[{'header': [1, 2, 3, 4, 5, 6, false]}],
|
||||
|
||||
[{'color': []}, {'background': []}], // dropdown with defaults from theme
|
||||
[{'font': []}],
|
||||
[{'align': []}],
|
||||
|
||||
['clean'],
|
||||
|
||||
['link', 'image', 'video']
|
||||
// remove formatting button
|
||||
];
|
||||
|
||||
export let game: Game;
|
||||
export let gameManager: GameManager;
|
||||
|
||||
let gameScene = gameManager.getCurrentGameScene(game.scene.getScene(LoginSceneName));
|
||||
let quill: Quill;
|
||||
let INPUT_CONSOLE_MESSAGE: HTMLDivElement;
|
||||
|
||||
const MESSAGE_TYPE = AdminMessageEventTypes.admin;
|
||||
|
||||
//Quill
|
||||
onMount(async () => {
|
||||
|
||||
// Import quill
|
||||
const {default: Quill} = await import("quill"); // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
|
||||
quill = new Quill(INPUT_CONSOLE_MESSAGE, {
|
||||
theme: 'snow',
|
||||
modules: {
|
||||
toolbar: toolbarOptions
|
||||
},
|
||||
});
|
||||
|
||||
quill.on('selection-change', function (range, oldRange) {
|
||||
if (range === null && oldRange !== null) {
|
||||
consoleGlobalMessageManagerFocusStore.set(false);
|
||||
} else if (range !== null && oldRange === null)
|
||||
consoleGlobalMessageManagerFocusStore.set(true);
|
||||
});
|
||||
});
|
||||
|
||||
function disableConsole() {
|
||||
consoleGlobalMessageManagerVisibleStore.set(false);
|
||||
consoleGlobalMessageManagerFocusStore.set(false);
|
||||
}
|
||||
|
||||
function SendTextMessage() {
|
||||
if (gameScene == undefined) {
|
||||
return;
|
||||
}
|
||||
const text = quill.getText(0, quill.getLength());
|
||||
|
||||
const GlobalMessage: PlayGlobalMessageInterface = {
|
||||
id: "1", // FIXME: use another ID?
|
||||
message: text,
|
||||
type: MESSAGE_TYPE
|
||||
};
|
||||
|
||||
quill.deleteText(0, quill.getLength());
|
||||
gameScene.connection?.emitGlobalMessage(GlobalMessage);
|
||||
disableConsole();
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<section class="section-input-send-text">
|
||||
<div class="input-send-text" bind:this={INPUT_CONSOLE_MESSAGE}></div>
|
||||
<div class="btn-action">
|
||||
<button class="nes-btn is-primary" on:click|preventDefault={SendTextMessage}>Send</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
@import 'https://cdn.quilljs.com/1.3.7/quill.snow.css';
|
||||
</style>
|
|
@ -0,0 +1,130 @@
|
|||
<script lang="ts">
|
||||
import {HtmlUtils} from "../../WebRtc/HtmlUtils";
|
||||
import type {Game} from "../../Phaser/Game/Game";
|
||||
import type {GameManager} from "../../Phaser/Game/GameManager";
|
||||
import {consoleGlobalMessageManagerFocusStore, consoleGlobalMessageManagerVisibleStore} from "../../Stores/ConsoleGlobalMessageManagerStore";
|
||||
import {AdminMessageEventTypes} from "../../Connexion/AdminMessagesService";
|
||||
import type {PlayGlobalMessageInterface} from "../../Connexion/ConnexionModels";
|
||||
import uploadFile from "../images/music-file.svg";
|
||||
import {LoginSceneName} from "../../Phaser/Login/LoginScene";
|
||||
|
||||
interface EventTargetFiles extends EventTarget {
|
||||
files: Array<File>;
|
||||
}
|
||||
|
||||
export let game: Game;
|
||||
export let gameManager: GameManager;
|
||||
|
||||
let gameScene = gameManager.getCurrentGameScene(game.scene.getScene(LoginSceneName));
|
||||
let fileinput: HTMLInputElement;
|
||||
let filename: string;
|
||||
let filesize: string;
|
||||
let errorfile: boolean;
|
||||
|
||||
const AUDIO_TYPE = AdminMessageEventTypes.audio;
|
||||
|
||||
|
||||
async function SendAudioMessage() {
|
||||
if (gameScene == undefined) {
|
||||
return;
|
||||
}
|
||||
const inputAudio = HtmlUtils.getElementByIdOrFail<HTMLInputElement>("input-send-audio");
|
||||
const selectedFile = inputAudio.files ? inputAudio.files[0] : null;
|
||||
if (!selectedFile) {
|
||||
errorfile = true;
|
||||
throw 'no file selected';
|
||||
}
|
||||
|
||||
const fd = new FormData();
|
||||
fd.append('file', selectedFile);
|
||||
const res = await gameScene.connection?.uploadAudio(fd);
|
||||
|
||||
const GlobalMessage: PlayGlobalMessageInterface = {
|
||||
id: (res as { id: string }).id,
|
||||
message: (res as { path: string }).path,
|
||||
type: AUDIO_TYPE
|
||||
}
|
||||
inputAudio.value = '';
|
||||
gameScene.connection?.emitGlobalMessage(GlobalMessage);
|
||||
disableConsole();
|
||||
}
|
||||
|
||||
function inputAudioFile(event: Event) {
|
||||
const eventTarget : EventTargetFiles = (event.target as EventTargetFiles);
|
||||
if(!eventTarget || !eventTarget.files || eventTarget.files.length === 0){
|
||||
return;
|
||||
}
|
||||
|
||||
const file = eventTarget.files[0];
|
||||
if(!file) {
|
||||
return;
|
||||
}
|
||||
|
||||
filename = file.name;
|
||||
filesize = getFileSize(file.size);
|
||||
errorfile = false;
|
||||
}
|
||||
|
||||
function getFileSize(number: number) {
|
||||
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 '';
|
||||
}
|
||||
}
|
||||
|
||||
function disableConsole() {
|
||||
consoleGlobalMessageManagerVisibleStore.set(false);
|
||||
consoleGlobalMessageManagerFocusStore.set(false);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<section class="section-input-send-audio">
|
||||
<div class="input-send-audio">
|
||||
<img src="{uploadFile}" alt="Upload a file" on:click|preventDefault={ () => {fileinput.click();}}>
|
||||
{#if filename != undefined}
|
||||
<label for="input-send-audio">{filename} : {filesize}</label>
|
||||
{/if}
|
||||
{#if errorfile}
|
||||
<p class="err">No file selected. You need to upload a file before sending it.</p>
|
||||
{/if}
|
||||
<input type="file" id="input-send-audio" bind:this={fileinput} on:change={(e) => {inputAudioFile(e)}}>
|
||||
</div>
|
||||
<div class="btn-action">
|
||||
<button class="nes-btn is-primary" on:click|preventDefault={SendAudioMessage}>Send</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<style lang="scss">
|
||||
//UploadAudioGlobalMessage
|
||||
.section-input-send-audio {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.section-input-send-audio .input-send-audio {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.section-input-send-audio #input-send-audio{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.section-input-send-audio div.input-send-audio label{
|
||||
color: white;
|
||||
}
|
||||
|
||||
.section-input-send-audio div.input-send-audio p.err {
|
||||
color: #ce372b;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.section-input-send-audio div.input-send-audio img{
|
||||
height: 150px;
|
||||
cursor: url('../../../style/images/cursor_pointer.png'), pointer;
|
||||
}
|
||||
</style>
|
27
front/src/Components/images/music-file.svg
Normal file
27
front/src/Components/images/music-file.svg
Normal 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 |
Loading…
Add table
Add a link
Reference in a new issue