Merge remote-tracking branch 'upstream/develop' into main
This commit is contained in:
commit
c8127b3c54
@ -1,4 +1,4 @@
|
|||||||
![](https://github.com/thecodingmachine/workadventure/workflows/Continuous%20Integration/badge.svg)
|
![](https://github.com/thecodingmachine/workadventure/workflows/Continuous%20Integration/badge.svg) [![Discord](https://img.shields.io/discord/821338762134290432?label=Discord)](https://discord.gg/JVVhXzcE)
|
||||||
|
|
||||||
![WorkAdventure landscape image](README-INTRO.jpg)
|
![WorkAdventure landscape image](README-INTRO.jpg)
|
||||||
|
|
||||||
|
4
front/dist/index.tmpl.html
vendored
4
front/dist/index.tmpl.html
vendored
@ -98,12 +98,12 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<div class="audioplayer">
|
<div class="audioplayer">
|
||||||
<input type="range" id="audioplayer_volume" min="0" max="1" step="0.05" value="1" />
|
<input type="range" id="audioplayer_volume" min="0" max="1" step="0.025" value="1" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="audioplayer">
|
<div class="audioplayer">
|
||||||
<label id="label-audioplayer_decrease_while_talking" for="audiooplayer_decrease_while_talking" title="decrease background volume by 50% when entering conversations">
|
<label id="label-audioplayer_decrease_while_talking" for="audiooplayer_decrease_while_talking" title="decrease background volume by 50% when entering conversations">
|
||||||
autoreduce
|
reduce in conversations
|
||||||
<input type="checkbox" id="audioplayer_decrease_while_talking" checked />
|
<input type="checkbox" id="audioplayer_decrease_while_talking" checked />
|
||||||
</label>
|
</label>
|
||||||
<div id="audioplayer" style="visibility: hidden"></div>
|
<div id="audioplayer" style="visibility: hidden"></div>
|
||||||
|
6
front/dist/resources/style/style.css
vendored
6
front/dist/resources/style/style.css
vendored
@ -363,10 +363,14 @@ body {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.audioplayer > div {
|
||||||
|
padding-right: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
#audioplayerctrl {
|
#audioplayerctrl {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 50%;
|
right: calc(50% - 120px);
|
||||||
padding: 0.3rem 0.5rem;
|
padding: 0.3rem 0.5rem;
|
||||||
color: white;
|
color: white;
|
||||||
transition: transform 0.5s;
|
transition: transform 0.5s;
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
import {LocalUser} from "./LocalUser";
|
import {LocalUser} from "./LocalUser";
|
||||||
|
|
||||||
const characterLayersKey = 'characterLayers';
|
const playerNameKey = 'playerName';
|
||||||
const gameQualityKey = 'gameQuality';
|
const selectedPlayerKey = 'selectedPlayer';
|
||||||
const videoQualityKey = 'videoQuality';
|
const customCursorPositionKey = 'customCursorPosition';
|
||||||
|
const characterLayersKey = 'characterLayers';
|
||||||
|
const gameQualityKey = 'gameQuality';
|
||||||
|
const videoQualityKey = 'videoQuality';
|
||||||
|
const audioPlayerVolumeKey = 'audioVolume';
|
||||||
|
const audioPlayerMuteKey = 'audioMute';
|
||||||
|
|
||||||
//todo: add localstorage fallback
|
|
||||||
class LocalUserStore {
|
class LocalUserStore {
|
||||||
|
|
||||||
saveUser(localUser: LocalUser) {
|
saveUser(localUser: LocalUser) {
|
||||||
localStorage.setItem('localUser', JSON.stringify(localUser));
|
localStorage.setItem('localUser', JSON.stringify(localUser));
|
||||||
}
|
}
|
||||||
@ -16,46 +19,60 @@ class LocalUserStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setName(name:string): void {
|
setName(name:string): void {
|
||||||
window.localStorage.setItem('playerName', name);
|
localStorage.setItem(playerNameKey, name);
|
||||||
}
|
}
|
||||||
getName(): string {
|
getName(): string {
|
||||||
return window.localStorage.getItem('playerName') ?? '';
|
return localStorage.getItem(playerNameKey) || '';
|
||||||
}
|
}
|
||||||
|
|
||||||
setPlayerCharacterIndex(playerCharacterIndex: number): void {
|
setPlayerCharacterIndex(playerCharacterIndex: number): void {
|
||||||
window.localStorage.setItem('selectedPlayer', ''+playerCharacterIndex);
|
localStorage.setItem(selectedPlayerKey, ''+playerCharacterIndex);
|
||||||
}
|
}
|
||||||
getPlayerCharacterIndex(): number {
|
getPlayerCharacterIndex(): number {
|
||||||
return parseInt(window.localStorage.getItem('selectedPlayer') || '');
|
return parseInt(localStorage.getItem(selectedPlayerKey) || '');
|
||||||
}
|
}
|
||||||
|
|
||||||
setCustomCursorPosition(activeRow:number, selectedLayers: number[]): void {
|
setCustomCursorPosition(activeRow:number, selectedLayers: number[]): void {
|
||||||
window.localStorage.setItem('customCursorPosition', JSON.stringify({activeRow, selectedLayers}));
|
localStorage.setItem(customCursorPositionKey, JSON.stringify({activeRow, selectedLayers}));
|
||||||
}
|
}
|
||||||
getCustomCursorPosition(): {activeRow:number, selectedLayers:number[]}|null {
|
getCustomCursorPosition(): {activeRow:number, selectedLayers:number[]}|null {
|
||||||
return JSON.parse(window.localStorage.getItem('customCursorPosition') || "null");
|
return JSON.parse(localStorage.getItem(customCursorPositionKey) || "null");
|
||||||
}
|
}
|
||||||
|
|
||||||
setCharacterLayers(layers: string[]): void {
|
setCharacterLayers(layers: string[]): void {
|
||||||
window.localStorage.setItem(characterLayersKey, JSON.stringify(layers));
|
localStorage.setItem(characterLayersKey, JSON.stringify(layers));
|
||||||
}
|
}
|
||||||
getCharacterLayers(): string[]|null {
|
getCharacterLayers(): string[]|null {
|
||||||
return JSON.parse(window.localStorage.getItem(characterLayersKey) || "null");
|
return JSON.parse(localStorage.getItem(characterLayersKey) || "null");
|
||||||
}
|
}
|
||||||
|
|
||||||
getGameQualityValue(): number {
|
|
||||||
return parseInt(window.localStorage.getItem(gameQualityKey) || '') || 60;
|
|
||||||
}
|
|
||||||
setGameQualityValue(value: number): void {
|
setGameQualityValue(value: number): void {
|
||||||
localStorage.setItem(gameQualityKey, '' + value);
|
localStorage.setItem(gameQualityKey, '' + value);
|
||||||
}
|
}
|
||||||
|
getGameQualityValue(): number {
|
||||||
getVideoQualityValue(): number {
|
return parseInt(localStorage.getItem(gameQualityKey) || '60');
|
||||||
return parseInt(window.localStorage.getItem(videoQualityKey) || '') || 20;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setVideoQualityValue(value: number): void {
|
setVideoQualityValue(value: number): void {
|
||||||
localStorage.setItem(videoQualityKey, '' + value);
|
localStorage.setItem(videoQualityKey, '' + value);
|
||||||
}
|
}
|
||||||
|
getVideoQualityValue(): number {
|
||||||
|
return parseInt(localStorage.getItem(videoQualityKey) || '20');
|
||||||
|
}
|
||||||
|
|
||||||
|
setAudioPlayerVolume(value: number): void {
|
||||||
|
localStorage.setItem(audioPlayerVolumeKey, '' + value);
|
||||||
|
}
|
||||||
|
getAudioPlayerVolume(): number {
|
||||||
|
return parseFloat(localStorage.getItem(audioPlayerVolumeKey) || '1');
|
||||||
|
}
|
||||||
|
|
||||||
|
setAudioPlayerMuted(value: boolean): void {
|
||||||
|
localStorage.setItem(audioPlayerMuteKey, value.toString());
|
||||||
|
}
|
||||||
|
getAudioPlayerMuted(): boolean {
|
||||||
|
return localStorage.getItem(audioPlayerMuteKey) === 'true';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const localUserStore = new LocalUserStore();
|
export const localUserStore = new LocalUserStore();
|
@ -29,7 +29,9 @@ import {
|
|||||||
ON_ACTION_TRIGGER_BUTTON,
|
ON_ACTION_TRIGGER_BUTTON,
|
||||||
TRIGGER_JITSI_PROPERTIES,
|
TRIGGER_JITSI_PROPERTIES,
|
||||||
TRIGGER_WEBSITE_PROPERTIES,
|
TRIGGER_WEBSITE_PROPERTIES,
|
||||||
WEBSITE_MESSAGE_PROPERTIES
|
WEBSITE_MESSAGE_PROPERTIES,
|
||||||
|
AUDIO_VOLUME_PROPERTY,
|
||||||
|
AUDIO_LOOP_PROPERTY
|
||||||
} from "../../WebRtc/LayoutManager";
|
} from "../../WebRtc/LayoutManager";
|
||||||
import {GameMap} from "./GameMap";
|
import {GameMap} from "./GameMap";
|
||||||
import {coWebsiteManager} from "../../WebRtc/CoWebsiteManager";
|
import {coWebsiteManager} from "../../WebRtc/CoWebsiteManager";
|
||||||
@ -455,16 +457,12 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.connection.onGroupUpdatedOrCreated((groupPositionMessage: GroupCreatedUpdatedMessageInterface) => {
|
this.connection.onGroupUpdatedOrCreated((groupPositionMessage: GroupCreatedUpdatedMessageInterface) => {
|
||||||
audioManager.decreaseVolume();
|
|
||||||
this.shareGroupPosition(groupPositionMessage);
|
this.shareGroupPosition(groupPositionMessage);
|
||||||
this.openChatIcon.setVisible(true);
|
|
||||||
})
|
})
|
||||||
|
|
||||||
this.connection.onGroupDeleted((groupId: number) => {
|
this.connection.onGroupDeleted((groupId: number) => {
|
||||||
audioManager.restoreVolume();
|
|
||||||
try {
|
try {
|
||||||
this.deleteGroup(groupId);
|
this.deleteGroup(groupId);
|
||||||
this.openChatIcon.setVisible(false);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
@ -517,11 +515,15 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
onConnect(user: UserSimplePeerInterface) {
|
onConnect(user: UserSimplePeerInterface) {
|
||||||
self.presentationModeSprite.setVisible(true);
|
self.presentationModeSprite.setVisible(true);
|
||||||
self.chatModeSprite.setVisible(true);
|
self.chatModeSprite.setVisible(true);
|
||||||
|
self.openChatIcon.setVisible(true);
|
||||||
|
audioManager.decreaseVolume();
|
||||||
},
|
},
|
||||||
onDisconnect(userId: number) {
|
onDisconnect(userId: number) {
|
||||||
if (self.simplePeer.getNbConnections() === 0) {
|
if (self.simplePeer.getNbConnections() === 0) {
|
||||||
self.presentationModeSprite.setVisible(false);
|
self.presentationModeSprite.setVisible(false);
|
||||||
self.chatModeSprite.setVisible(false);
|
self.chatModeSprite.setVisible(false);
|
||||||
|
self.openChatIcon.setVisible(false);
|
||||||
|
audioManager.restoreVolume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -630,7 +632,8 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
}else{
|
}else{
|
||||||
const openJitsiRoomFunction = () => {
|
const openJitsiRoomFunction = () => {
|
||||||
const roomName = jitsiFactory.getRoomName(newValue.toString(), this.instance);
|
const roomName = jitsiFactory.getRoomName(newValue.toString(), this.instance);
|
||||||
if (JITSI_PRIVATE_MODE) {
|
const jitsiUrl = allProps.get("jitsiUrl") as string|undefined;
|
||||||
|
if (JITSI_PRIVATE_MODE && !jitsiUrl) {
|
||||||
const adminTag = allProps.get("jitsiRoomAdminTag") as string|undefined;
|
const adminTag = allProps.get("jitsiRoomAdminTag") as string|undefined;
|
||||||
|
|
||||||
this.connection.emitQueryJitsiJwtMessage(roomName, adminTag);
|
this.connection.emitQueryJitsiJwtMessage(roomName, adminTag);
|
||||||
@ -661,14 +664,15 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
this.connection.setSilent(true);
|
this.connection.setSilent(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.gameMap.onPropertyChange('playAudio', (newValue, oldValue) => {
|
this.gameMap.onPropertyChange('playAudio', (newValue, oldValue, allProps) => {
|
||||||
newValue === undefined ? audioManager.unloadAudio() : audioManager.playAudio(newValue, this.getMapDirUrl());
|
const volume = allProps.get(AUDIO_VOLUME_PROPERTY) as number|undefined;
|
||||||
|
const loop = allProps.get(AUDIO_LOOP_PROPERTY) as boolean|undefined;
|
||||||
|
newValue === undefined ? audioManager.unloadAudio() : audioManager.playAudio(newValue, this.getMapDirUrl(), volume, loop);
|
||||||
});
|
});
|
||||||
|
// TODO: This legacy property should be removed at some point
|
||||||
this.gameMap.onPropertyChange('playAudioLoop', (newValue, oldValue) => {
|
this.gameMap.onPropertyChange('playAudioLoop', (newValue, oldValue) => {
|
||||||
newValue === undefined ? audioManager.unloadAudio() : audioManager.playAudio(newValue, this.getMapDirUrl());
|
newValue === undefined ? audioManager.unloadAudio() : audioManager.playAudio(newValue, this.getMapDirUrl(), undefined, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private getMapDirUrl(): string {
|
private getMapDirUrl(): string {
|
||||||
@ -1206,8 +1210,9 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
const allProps = this.gameMap.getCurrentProperties();
|
const allProps = this.gameMap.getCurrentProperties();
|
||||||
const jitsiConfig = this.safeParseJSONstring(allProps.get("jitsiConfig") as string|undefined, 'jitsiConfig');
|
const jitsiConfig = this.safeParseJSONstring(allProps.get("jitsiConfig") as string|undefined, 'jitsiConfig');
|
||||||
const jitsiInterfaceConfig = this.safeParseJSONstring(allProps.get("jitsiInterfaceConfig") as string|undefined, 'jitsiInterfaceConfig');
|
const jitsiInterfaceConfig = this.safeParseJSONstring(allProps.get("jitsiInterfaceConfig") as string|undefined, 'jitsiInterfaceConfig');
|
||||||
|
const jitsiUrl = allProps.get("jitsiUrl") as string|undefined;
|
||||||
|
|
||||||
jitsiFactory.start(roomName, this.playerName, jwt, jitsiConfig, jitsiInterfaceConfig);
|
jitsiFactory.start(roomName, this.playerName, jwt, jitsiConfig, jitsiInterfaceConfig, jitsiUrl);
|
||||||
this.connection.setSilent(true);
|
this.connection.setSilent(true);
|
||||||
mediaManager.hideGameOverlay();
|
mediaManager.hideGameOverlay();
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import {HtmlUtils} from "./HtmlUtils";
|
import {HtmlUtils} from "./HtmlUtils";
|
||||||
import {isUndefined} from "generic-type-guard";
|
import {isUndefined} from "generic-type-guard";
|
||||||
|
import {localUserStore} from "../Connexion/LocalUserStore";
|
||||||
|
|
||||||
enum audioStates {
|
enum audioStates {
|
||||||
closed = 0,
|
closed = 0,
|
||||||
@ -9,6 +10,8 @@ enum audioStates {
|
|||||||
|
|
||||||
const audioPlayerDivId = "audioplayer";
|
const audioPlayerDivId = "audioplayer";
|
||||||
const audioPlayerCtrlId = "audioplayerctrl";
|
const audioPlayerCtrlId = "audioplayerctrl";
|
||||||
|
const audioPlayerVolId = "audioplayer_volume";
|
||||||
|
const audioPlayerMuteId = "audioplayer_volume_icon_playing";
|
||||||
const animationTime = 500;
|
const animationTime = 500;
|
||||||
|
|
||||||
class AudioManager {
|
class AudioManager {
|
||||||
@ -17,6 +20,8 @@ class AudioManager {
|
|||||||
private audioPlayerDiv: HTMLDivElement;
|
private audioPlayerDiv: HTMLDivElement;
|
||||||
private audioPlayerCtrl: HTMLDivElement;
|
private audioPlayerCtrl: HTMLDivElement;
|
||||||
private audioPlayerElem: HTMLAudioElement | undefined;
|
private audioPlayerElem: HTMLAudioElement | undefined;
|
||||||
|
private audioPlayerVol: HTMLInputElement;
|
||||||
|
private audioPlayerMute: HTMLInputElement;
|
||||||
|
|
||||||
private volume = 1;
|
private volume = 1;
|
||||||
private muted = false;
|
private muted = false;
|
||||||
@ -26,19 +31,19 @@ class AudioManager {
|
|||||||
constructor() {
|
constructor() {
|
||||||
this.audioPlayerDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>(audioPlayerDivId);
|
this.audioPlayerDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>(audioPlayerDivId);
|
||||||
this.audioPlayerCtrl = HtmlUtils.getElementByIdOrFail<HTMLDivElement>(audioPlayerCtrlId);
|
this.audioPlayerCtrl = HtmlUtils.getElementByIdOrFail<HTMLDivElement>(audioPlayerCtrlId);
|
||||||
|
this.audioPlayerVol = HtmlUtils.getElementByIdOrFail<HTMLInputElement>(audioPlayerVolId);
|
||||||
|
this.audioPlayerMute = HtmlUtils.getElementByIdOrFail<HTMLInputElement>(audioPlayerMuteId);
|
||||||
|
|
||||||
const storedVolume = localStorage.getItem('volume')
|
this.volume = localUserStore.getAudioPlayerVolume();
|
||||||
if (storedVolume === null) {
|
this.audioPlayerVol.value = '' + this.volume;
|
||||||
this.setVolume(1);
|
|
||||||
} else {
|
this.muted = localUserStore.getAudioPlayerMuted();
|
||||||
this.volume = parseFloat(storedVolume);
|
if (this.muted) {
|
||||||
HtmlUtils.getElementByIdOrFail<HTMLInputElement>('audioplayer_volume').value = storedVolume;
|
this.audioPlayerMute.classList.add('muted');
|
||||||
}
|
}
|
||||||
|
|
||||||
HtmlUtils.getElementByIdOrFail<HTMLInputElement>('audioplayer_volume').value = '' + this.volume;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public playAudio(url: string|number|boolean, mapDirUrl: string, loop=false): void {
|
public playAudio(url: string|number|boolean, mapDirUrl: string, volume: number|undefined, loop=false): void {
|
||||||
const audioPath = url as string;
|
const audioPath = url as string;
|
||||||
let realAudioPath = '';
|
let realAudioPath = '';
|
||||||
|
|
||||||
@ -50,7 +55,7 @@ class AudioManager {
|
|||||||
realAudioPath = mapDirUrl + '/' + url;
|
realAudioPath = mapDirUrl + '/' + url;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loadAudio(realAudioPath);
|
this.loadAudio(realAudioPath, volume);
|
||||||
|
|
||||||
if (loop) {
|
if (loop) {
|
||||||
this.loop();
|
this.loop();
|
||||||
@ -75,26 +80,29 @@ class AudioManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private changeVolume(talking = false): void {
|
private changeVolume(talking = false): void {
|
||||||
if (!isUndefined(this.audioPlayerElem)) {
|
if (isUndefined(this.audioPlayerElem)) {
|
||||||
this.audioPlayerElem.volume = this.naturalVolume(talking && this.decreaseWhileTalking);
|
return;
|
||||||
this.audioPlayerElem.muted = this.muted;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private naturalVolume(makeSofter: boolean = false): number {
|
const reduceVolume = talking && this.decreaseWhileTalking;
|
||||||
const volume = this.volume
|
if (reduceVolume && !this.volumeReduced) {
|
||||||
const retVol = makeSofter && !this.volumeReduced ? Math.pow(volume * 0.5, 3) : volume
|
this.volume *= 0.5;
|
||||||
this.volumeReduced = makeSofter
|
} else if (!reduceVolume && this.volumeReduced) {
|
||||||
return retVol;
|
this.volume *= 2.0;
|
||||||
|
}
|
||||||
|
this.volumeReduced = reduceVolume;
|
||||||
|
|
||||||
|
this.audioPlayerElem.volume = this.volume;
|
||||||
|
this.audioPlayerVol.value = '' + this.volume;
|
||||||
|
this.audioPlayerElem.muted = this.muted;
|
||||||
}
|
}
|
||||||
|
|
||||||
private setVolume(volume: number): void {
|
private setVolume(volume: number): void {
|
||||||
this.volume = volume;
|
this.volume = volume;
|
||||||
localStorage.setItem('volume', '' + volume);
|
localUserStore.setAudioPlayerVolume(volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private loadAudio(url: string, volume: number|undefined): void {
|
||||||
private loadAudio(url: string): void {
|
|
||||||
this.load();
|
this.load();
|
||||||
|
|
||||||
/* Solution 1, remove whole audio player */
|
/* Solution 1, remove whole audio player */
|
||||||
@ -112,23 +120,24 @@ class AudioManager {
|
|||||||
this.audioPlayerElem.append(srcElem);
|
this.audioPlayerElem.append(srcElem);
|
||||||
|
|
||||||
this.audioPlayerDiv.append(this.audioPlayerElem);
|
this.audioPlayerDiv.append(this.audioPlayerElem);
|
||||||
|
this.volume = volume ? Math.min(volume, this.volume) : this.volume;
|
||||||
this.changeVolume();
|
this.changeVolume();
|
||||||
this.audioPlayerElem.play();
|
this.audioPlayerElem.play();
|
||||||
|
|
||||||
const muteElem = HtmlUtils.getElementByIdOrFail<HTMLInputElement>('audioplayer_mute');
|
const muteElem = HtmlUtils.getElementByIdOrFail<HTMLInputElement>('audioplayer_mute');
|
||||||
muteElem.onclick = (ev: Event)=> {
|
muteElem.onclick = (ev: Event) => {
|
||||||
this.muted = !this.muted;
|
this.muted = !this.muted;
|
||||||
this.changeVolume();
|
this.changeVolume();
|
||||||
|
localUserStore.setAudioPlayerMuted(this.muted);
|
||||||
|
|
||||||
if (this.muted) {
|
if (this.muted) {
|
||||||
HtmlUtils.getElementByIdOrFail<HTMLInputElement>('audioplayer_volume_icon_playing').classList.add('muted');
|
this.audioPlayerMute.classList.add('muted');
|
||||||
} else {
|
} else {
|
||||||
HtmlUtils.getElementByIdOrFail<HTMLInputElement>('audioplayer_volume_icon_playing').classList.remove('muted');
|
this.audioPlayerMute.classList.remove('muted');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const volumeElem = HtmlUtils.getElementByIdOrFail<HTMLInputElement>('audioplayer_volume');
|
this.audioPlayerVol.oninput = (ev: Event)=> {
|
||||||
volumeElem.oninput = (ev: Event)=> {
|
|
||||||
this.setVolume(parseFloat((<HTMLInputElement>ev.currentTarget).value));
|
this.setVolume(parseFloat((<HTMLInputElement>ev.currentTarget).value));
|
||||||
this.changeVolume();
|
this.changeVolume();
|
||||||
|
|
||||||
|
@ -72,6 +72,7 @@ class JitsiFactory {
|
|||||||
private audioCallback = this.onAudioChange.bind(this);
|
private audioCallback = this.onAudioChange.bind(this);
|
||||||
private videoCallback = this.onVideoChange.bind(this);
|
private videoCallback = this.onVideoChange.bind(this);
|
||||||
private previousConfigMeet? : jitsiConfigInterface;
|
private previousConfigMeet? : jitsiConfigInterface;
|
||||||
|
private jitsiScriptLoaded: boolean = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Slugifies the room name and prepends the room name with the instance
|
* Slugifies the room name and prepends the room name with the instance
|
||||||
@ -80,11 +81,11 @@ class JitsiFactory {
|
|||||||
return slugify(instance.replace('/', '-') + "-" + roomName);
|
return slugify(instance.replace('/', '-') + "-" + roomName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public start(roomName: string, playerName:string, jwt?: string, config?: object, interfaceConfig?: object): void {
|
public start(roomName: string, playerName:string, jwt?: string, config?: object, interfaceConfig?: object, jitsiUrl?: string): void {
|
||||||
//save previous config
|
//save previous config
|
||||||
this.previousConfigMeet = getDefaultConfig();
|
this.previousConfigMeet = getDefaultConfig();
|
||||||
|
|
||||||
coWebsiteManager.insertCoWebsite((cowebsiteDiv => {
|
coWebsiteManager.insertCoWebsite((async cowebsiteDiv => {
|
||||||
// Jitsi meet external API maintains some data in local storage
|
// Jitsi meet external API maintains some data in local storage
|
||||||
// which is sent via the appData URL parameter when joining a
|
// which is sent via the appData URL parameter when joining a
|
||||||
// conference. Problem is that this data grows indefinitely. Thus
|
// conference. Problem is that this data grows indefinitely. Thus
|
||||||
@ -93,7 +94,12 @@ class JitsiFactory {
|
|||||||
// clear jitsi local storage before starting a new conference.
|
// clear jitsi local storage before starting a new conference.
|
||||||
window.localStorage.removeItem("jitsiLocalStorage");
|
window.localStorage.removeItem("jitsiLocalStorage");
|
||||||
|
|
||||||
const domain = JITSI_URL;
|
const domain = jitsiUrl || JITSI_URL;
|
||||||
|
if (domain === undefined) {
|
||||||
|
throw new Error('Missing JITSI_URL environment variable or jitsiUrl parameter in the map.')
|
||||||
|
}
|
||||||
|
await this.loadJitsiScript(domain);
|
||||||
|
|
||||||
const options: any = { // eslint-disable-line @typescript-eslint/no-explicit-any
|
const options: any = { // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||||
roomName: roomName,
|
roomName: roomName,
|
||||||
jwt: jwt,
|
jwt: jwt,
|
||||||
@ -157,6 +163,32 @@ class JitsiFactory {
|
|||||||
mediaManager.enableCamera();
|
mediaManager.enableCamera();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async loadJitsiScript(domain: string): Promise<void> {
|
||||||
|
return new Promise<void>((resolve, reject) => {
|
||||||
|
if (this.jitsiScriptLoaded) {
|
||||||
|
resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.jitsiScriptLoaded = true;
|
||||||
|
|
||||||
|
// Load Jitsi if the environment variable is set.
|
||||||
|
const jitsiScript = document.createElement('script');
|
||||||
|
jitsiScript.src = 'https://' + domain + '/external_api.js';
|
||||||
|
jitsiScript.onload = () => {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
jitsiScript.onerror = () => {
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
|
||||||
|
document.head.appendChild(jitsiScript);
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const jitsiFactory = new JitsiFactory();
|
export const jitsiFactory = new JitsiFactory();
|
||||||
|
@ -31,6 +31,9 @@ export const TRIGGER_JITSI_PROPERTIES = 'jitsiTrigger';
|
|||||||
export const WEBSITE_MESSAGE_PROPERTIES = 'openWebsiteTriggerMessage';
|
export const WEBSITE_MESSAGE_PROPERTIES = 'openWebsiteTriggerMessage';
|
||||||
export const JITSI_MESSAGE_PROPERTIES = 'jitsiTriggerMessage';
|
export const JITSI_MESSAGE_PROPERTIES = 'jitsiTriggerMessage';
|
||||||
|
|
||||||
|
export const AUDIO_VOLUME_PROPERTY = 'audioVolume';
|
||||||
|
export const AUDIO_LOOP_PROPERTY = 'audioLoop';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is in charge of the video-conference layout.
|
* This class is in charge of the video-conference layout.
|
||||||
* It receives positioning requests for videos and does its best to place them on the screen depending on the active layout mode.
|
* It receives positioning requests for videos and does its best to place them on the screen depending on the active layout mode.
|
||||||
|
@ -63,7 +63,7 @@ export class SimplePeer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public getNbConnections(): number {
|
public getNbConnections(): number {
|
||||||
return this.PeerConnectionArray.size;
|
return this.Users.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -230,9 +230,6 @@ export class SimplePeer {
|
|||||||
|
|
||||||
this.closeScreenSharingConnection(userId);
|
this.closeScreenSharingConnection(userId);
|
||||||
|
|
||||||
for (const peerConnectionListener of this.peerConnectionListeners) {
|
|
||||||
peerConnectionListener.onDisconnect(userId);
|
|
||||||
}
|
|
||||||
const userIndex = this.Users.findIndex(user => user.userId === userId);
|
const userIndex = this.Users.findIndex(user => user.userId === userId);
|
||||||
if(userIndex < 0){
|
if(userIndex < 0){
|
||||||
throw 'Couln\'t delete user';
|
throw 'Couln\'t delete user';
|
||||||
@ -250,6 +247,10 @@ export class SimplePeer {
|
|||||||
this.PeerScreenSharingConnectionArray.delete(userId);
|
this.PeerScreenSharingConnectionArray.delete(userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const peerConnectionListener of this.peerConnectionListeners) {
|
||||||
|
peerConnectionListener.onDisconnect(userId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,13 +16,6 @@ import {HelpCameraSettingsScene} from "./Phaser/Menu/HelpCameraSettingsScene";
|
|||||||
import {localUserStore} from "./Connexion/LocalUserStore";
|
import {localUserStore} from "./Connexion/LocalUserStore";
|
||||||
import {ErrorScene} from "./Phaser/Reconnecting/ErrorScene";
|
import {ErrorScene} from "./Phaser/Reconnecting/ErrorScene";
|
||||||
|
|
||||||
// Load Jitsi if the environment variable is set.
|
|
||||||
if (JITSI_URL) {
|
|
||||||
const jitsiScript = document.createElement('script');
|
|
||||||
jitsiScript.src = 'https://' + JITSI_URL + '/external_api.js';
|
|
||||||
document.head.appendChild(jitsiScript);
|
|
||||||
}
|
|
||||||
|
|
||||||
const {width, height} = coWebsiteManager.getGameSize();
|
const {width, height} = coWebsiteManager.getGameSize();
|
||||||
|
|
||||||
const valueGameQuality = localUserStore.getGameQualityValue();
|
const valueGameQuality = localUserStore.getGameQualityValue();
|
||||||
|
94
maps/tests/jitsi_custom_url.json
Normal file
94
maps/tests/jitsi_custom_url.json
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
{ "compressionlevel":-1,
|
||||||
|
"editorsettings":
|
||||||
|
{
|
||||||
|
"export":
|
||||||
|
{
|
||||||
|
"target":"."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"height":10,
|
||||||
|
"infinite":false,
|
||||||
|
"layers":[
|
||||||
|
{
|
||||||
|
"data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||||
|
"height":10,
|
||||||
|
"id":1,
|
||||||
|
"name":"floor",
|
||||||
|
"opacity":1,
|
||||||
|
"type":"tilelayer",
|
||||||
|
"visible":true,
|
||||||
|
"width":10,
|
||||||
|
"x":0,
|
||||||
|
"y":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
"height":10,
|
||||||
|
"id":2,
|
||||||
|
"name":"start",
|
||||||
|
"opacity":1,
|
||||||
|
"type":"tilelayer",
|
||||||
|
"visible":true,
|
||||||
|
"width":10,
|
||||||
|
"x":0,
|
||||||
|
"y":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
"height":10,
|
||||||
|
"id":5,
|
||||||
|
"name":"jitsiConf",
|
||||||
|
"opacity":1,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"jitsiRoom",
|
||||||
|
"type":"string",
|
||||||
|
"value":"myRoom"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"jitsiUrl",
|
||||||
|
"type":"string",
|
||||||
|
"value":"meet.jit.si"
|
||||||
|
}],
|
||||||
|
"type":"tilelayer",
|
||||||
|
"visible":true,
|
||||||
|
"width":10,
|
||||||
|
"x":0,
|
||||||
|
"y":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"draworder":"topdown",
|
||||||
|
"id":3,
|
||||||
|
"name":"floorLayer",
|
||||||
|
"objects":[],
|
||||||
|
"opacity":1,
|
||||||
|
"type":"objectgroup",
|
||||||
|
"visible":true,
|
||||||
|
"x":0,
|
||||||
|
"y":0
|
||||||
|
}],
|
||||||
|
"nextlayerid":6,
|
||||||
|
"nextobjectid":1,
|
||||||
|
"orientation":"orthogonal",
|
||||||
|
"renderorder":"right-down",
|
||||||
|
"tiledversion":"1.3.3",
|
||||||
|
"tileheight":32,
|
||||||
|
"tilesets":[
|
||||||
|
{
|
||||||
|
"columns":11,
|
||||||
|
"firstgid":1,
|
||||||
|
"image":"tileset1.png",
|
||||||
|
"imageheight":352,
|
||||||
|
"imagewidth":352,
|
||||||
|
"margin":0,
|
||||||
|
"name":"tileset1",
|
||||||
|
"spacing":0,
|
||||||
|
"tilecount":121,
|
||||||
|
"tileheight":32,
|
||||||
|
"tilewidth":32
|
||||||
|
}],
|
||||||
|
"tilewidth":32,
|
||||||
|
"type":"map",
|
||||||
|
"version":1.2,
|
||||||
|
"width":10
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user