Merge pull request #390 from thecodingmachine/develop
Release 2020/11/04
This commit is contained in:
commit
4606f23d8f
2
.github/workflows/build-and-deploy.yml
vendored
2
.github/workflows/build-and-deploy.yml
vendored
@ -20,7 +20,7 @@ jobs:
|
|||||||
|
|
||||||
|
|
||||||
# Create a slugified value of the branch
|
# Create a slugified value of the branch
|
||||||
- uses: rlespinasse/github-slug-action@master
|
- uses: rlespinasse/github-slug-action@1.1.1
|
||||||
|
|
||||||
- name: "Build and push front image"
|
- name: "Build and push front image"
|
||||||
uses: docker/build-push-action@v1
|
uses: docker/build-push-action@v1
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
"multer": "^1.4.2",
|
"multer": "^1.4.2",
|
||||||
"prom-client": "^12.0.0",
|
"prom-client": "^12.0.0",
|
||||||
"query-string": "^6.13.3",
|
"query-string": "^6.13.3",
|
||||||
"systeminformation": "^4.26.5",
|
"systeminformation": "^4.27.11",
|
||||||
"ts-node-dev": "^1.0.0-pre.44",
|
"ts-node-dev": "^1.0.0-pre.44",
|
||||||
"typescript": "^3.8.3",
|
"typescript": "^3.8.3",
|
||||||
"uWebSockets.js": "uNetworking/uWebSockets.js#v18.5.0",
|
"uWebSockets.js": "uNetworking/uWebSockets.js#v18.5.0",
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import {App} from "../Server/sifrr.server";
|
import {App} from "../Server/sifrr.server";
|
||||||
import {IoSocketController} from "_Controller/IoSocketController";
|
|
||||||
import {HttpRequest, HttpResponse} from "uWebSockets.js";
|
import {HttpRequest, HttpResponse} from "uWebSockets.js";
|
||||||
const register = require('prom-client').register;
|
const register = require('prom-client').register;
|
||||||
const collectDefaultMetrics = require('prom-client').collectDefaultMetrics;
|
const collectDefaultMetrics = require('prom-client').collectDefaultMetrics;
|
||||||
|
@ -152,7 +152,7 @@ export class GameRoom {
|
|||||||
closestItem.join(user);
|
closestItem.join(user);
|
||||||
} else {
|
} else {
|
||||||
const closestUser : User = closestItem;
|
const closestUser : User = closestItem;
|
||||||
const group: Group = new Group([
|
const group: Group = new Group(this.roomId,[
|
||||||
user,
|
user,
|
||||||
closestUser
|
closestUser
|
||||||
], this.connectCallback, this.disconnectCallback, this.positionNotifier);
|
], this.connectCallback, this.disconnectCallback, this.positionNotifier);
|
||||||
@ -200,7 +200,6 @@ export class GameRoom {
|
|||||||
if (group === undefined) {
|
if (group === undefined) {
|
||||||
throw new Error("The user is part of no group");
|
throw new Error("The user is part of no group");
|
||||||
}
|
}
|
||||||
const oldPosition = group.getPosition();
|
|
||||||
group.leave(user);
|
group.leave(user);
|
||||||
if (group.isEmpty()) {
|
if (group.isEmpty()) {
|
||||||
this.positionNotifier.leave(group);
|
this.positionNotifier.leave(group);
|
||||||
@ -209,6 +208,7 @@ export class GameRoom {
|
|||||||
throw new Error("Could not find group "+group.getId()+" referenced by user "+user.id+" in World.");
|
throw new Error("Could not find group "+group.getId()+" referenced by user "+user.id+" in World.");
|
||||||
}
|
}
|
||||||
this.groups.delete(group);
|
this.groups.delete(group);
|
||||||
|
//todo: is the group garbage collected?
|
||||||
} else {
|
} else {
|
||||||
group.updatePosition();
|
group.updatePosition();
|
||||||
//this.positionNotifier.updatePosition(group, group.getPosition(), oldPosition);
|
//this.positionNotifier.updatePosition(group, group.getPosition(), oldPosition);
|
||||||
|
@ -3,6 +3,7 @@ import { User } from "./User";
|
|||||||
import {PositionInterface} from "_Model/PositionInterface";
|
import {PositionInterface} from "_Model/PositionInterface";
|
||||||
import {Movable} from "_Model/Movable";
|
import {Movable} from "_Model/Movable";
|
||||||
import {PositionNotifier} from "_Model/PositionNotifier";
|
import {PositionNotifier} from "_Model/PositionNotifier";
|
||||||
|
import {gaugeManager} from "../Services/GaugeManager";
|
||||||
|
|
||||||
export class Group implements Movable {
|
export class Group implements Movable {
|
||||||
static readonly MAX_PER_GROUP = 4;
|
static readonly MAX_PER_GROUP = 4;
|
||||||
@ -13,12 +14,23 @@ export class Group implements Movable {
|
|||||||
private users: Set<User>;
|
private users: Set<User>;
|
||||||
private x!: number;
|
private x!: number;
|
||||||
private y!: number;
|
private y!: number;
|
||||||
|
private hasEditedGauge: boolean = false;
|
||||||
|
private wasDestroyed: boolean = false;
|
||||||
|
private roomId: string;
|
||||||
|
|
||||||
|
|
||||||
constructor(users: User[], private connectCallback: ConnectCallback, private disconnectCallback: DisconnectCallback, private positionNotifier: PositionNotifier) {
|
constructor(roomId: string, users: User[], private connectCallback: ConnectCallback, private disconnectCallback: DisconnectCallback, private positionNotifier: PositionNotifier) {
|
||||||
|
this.roomId = roomId;
|
||||||
this.users = new Set<User>();
|
this.users = new Set<User>();
|
||||||
this.id = Group.nextId;
|
this.id = Group.nextId;
|
||||||
Group.nextId++;
|
Group.nextId++;
|
||||||
|
//we only send a event for prometheus metrics if the group lives more than 5 seconds
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!this.wasDestroyed) {
|
||||||
|
this.hasEditedGauge = true;
|
||||||
|
gaugeManager.incNbGroupsPerRoomGauge(roomId);
|
||||||
|
}
|
||||||
|
}, 5000);
|
||||||
|
|
||||||
users.forEach((user: User) => {
|
users.forEach((user: User) => {
|
||||||
this.join(user);
|
this.join(user);
|
||||||
@ -113,9 +125,11 @@ export class Group implements Movable {
|
|||||||
*/
|
*/
|
||||||
destroy(): void
|
destroy(): void
|
||||||
{
|
{
|
||||||
|
if (this.hasEditedGauge) gaugeManager.decNbGroupsPerRoomGauge(this.roomId);
|
||||||
for (const user of this.users) {
|
for (const user of this.users) {
|
||||||
this.leave(user);
|
this.leave(user);
|
||||||
}
|
}
|
||||||
|
this.wasDestroyed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
get getSize(){
|
get getSize(){
|
||||||
|
54
back/src/Services/GaugeManager.ts
Normal file
54
back/src/Services/GaugeManager.ts
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import {Counter, Gauge} from "prom-client";
|
||||||
|
|
||||||
|
//this class should manage all the custom metrics used by prometheus
|
||||||
|
class GaugeManager {
|
||||||
|
private nbClientsGauge: Gauge<string>;
|
||||||
|
private nbClientsPerRoomGauge: Gauge<string>;
|
||||||
|
private nbGroupsPerRoomGauge: Gauge<string>;
|
||||||
|
private nbGroupsPerRoomCounter: Counter<string>;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.nbClientsGauge = new Gauge({
|
||||||
|
name: 'workadventure_nb_sockets',
|
||||||
|
help: 'Number of connected sockets',
|
||||||
|
labelNames: [ ]
|
||||||
|
});
|
||||||
|
this.nbClientsPerRoomGauge = new Gauge({
|
||||||
|
name: 'workadventure_nb_clients_per_room',
|
||||||
|
help: 'Number of clients per room',
|
||||||
|
labelNames: [ 'room' ]
|
||||||
|
});
|
||||||
|
|
||||||
|
this.nbGroupsPerRoomCounter = new Counter({
|
||||||
|
name: 'workadventure_counter_groups_per_room',
|
||||||
|
help: 'Counter of groups per room',
|
||||||
|
labelNames: [ 'room' ]
|
||||||
|
});
|
||||||
|
this.nbGroupsPerRoomGauge = new Gauge({
|
||||||
|
name: 'workadventure_nb_groups_per_room',
|
||||||
|
help: 'Number of groups per room',
|
||||||
|
labelNames: [ 'room' ]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
incNbClientPerRoomGauge(roomId: string): void {
|
||||||
|
this.nbClientsGauge.inc();
|
||||||
|
this.nbClientsPerRoomGauge.inc({ room: roomId });
|
||||||
|
}
|
||||||
|
|
||||||
|
decNbClientPerRoomGauge(roomId: string): void {
|
||||||
|
this.nbClientsGauge.dec();
|
||||||
|
this.nbClientsPerRoomGauge.dec({ room: roomId });
|
||||||
|
}
|
||||||
|
|
||||||
|
incNbGroupsPerRoomGauge(roomId: string): void {
|
||||||
|
this.nbGroupsPerRoomCounter.inc({ room: roomId })
|
||||||
|
this.nbGroupsPerRoomGauge.inc({ room: roomId })
|
||||||
|
}
|
||||||
|
|
||||||
|
decNbGroupsPerRoomGauge(roomId: string): void {
|
||||||
|
this.nbGroupsPerRoomGauge.dec({ room: roomId })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const gaugeManager = new GaugeManager();
|
@ -23,7 +23,6 @@ import {
|
|||||||
WebRtcStartMessage,
|
WebRtcStartMessage,
|
||||||
QueryJitsiJwtMessage,
|
QueryJitsiJwtMessage,
|
||||||
SendJitsiJwtMessage,
|
SendJitsiJwtMessage,
|
||||||
CharacterLayerMessage,
|
|
||||||
SendUserMessage
|
SendUserMessage
|
||||||
} from "../Messages/generated/messages_pb";
|
} from "../Messages/generated/messages_pb";
|
||||||
import {PointInterface} from "../Model/Websocket/PointInterface";
|
import {PointInterface} from "../Model/Websocket/PointInterface";
|
||||||
@ -37,11 +36,11 @@ import {Movable} from "../Model/Movable";
|
|||||||
import {PositionInterface} from "../Model/PositionInterface";
|
import {PositionInterface} from "../Model/PositionInterface";
|
||||||
import {adminApi, CharacterTexture} from "./AdminApi";
|
import {adminApi, CharacterTexture} from "./AdminApi";
|
||||||
import Direction = PositionMessage.Direction;
|
import Direction = PositionMessage.Direction;
|
||||||
import {Gauge} from "prom-client";
|
|
||||||
import {emitError, emitInBatch} from "./IoSocketHelpers";
|
import {emitError, emitInBatch} from "./IoSocketHelpers";
|
||||||
import Jwt from "jsonwebtoken";
|
import Jwt from "jsonwebtoken";
|
||||||
import {JITSI_URL} from "../Enum/EnvironmentVariable";
|
import {JITSI_URL} from "../Enum/EnvironmentVariable";
|
||||||
import {clientEventsEmitter} from "./ClientEventsEmitter";
|
import {clientEventsEmitter} from "./ClientEventsEmitter";
|
||||||
|
import {gaugeManager} from "./GaugeManager";
|
||||||
|
|
||||||
interface AdminSocketRoomsList {
|
interface AdminSocketRoomsList {
|
||||||
[index: string]: number;
|
[index: string]: number;
|
||||||
@ -58,30 +57,13 @@ export interface AdminSocketData {
|
|||||||
export class SocketManager {
|
export class SocketManager {
|
||||||
private Worlds: Map<string, GameRoom> = new Map<string, GameRoom>();
|
private Worlds: Map<string, GameRoom> = new Map<string, GameRoom>();
|
||||||
private sockets: Map<number, ExSocketInterface> = new Map<number, ExSocketInterface>();
|
private sockets: Map<number, ExSocketInterface> = new Map<number, ExSocketInterface>();
|
||||||
private nbClientsGauge: Gauge<string>;
|
|
||||||
private nbClientsPerRoomGauge: Gauge<string>;
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.nbClientsGauge = new Gauge({
|
clientEventsEmitter.registerToClientJoin((clientUUid: string, roomId: string) => {
|
||||||
name: 'workadventure_nb_sockets',
|
gaugeManager.incNbClientPerRoomGauge(roomId);
|
||||||
help: 'Number of connected sockets',
|
|
||||||
labelNames: [ ]
|
|
||||||
});
|
});
|
||||||
this.nbClientsPerRoomGauge = new Gauge({
|
clientEventsEmitter.registerToClientLeave((clientUUid: string, roomId: string) => {
|
||||||
name: 'workadventure_nb_clients_per_room',
|
gaugeManager.decNbClientPerRoomGauge(roomId);
|
||||||
help: 'Number of clients per room',
|
|
||||||
labelNames: [ 'room' ]
|
|
||||||
});
|
|
||||||
|
|
||||||
clientEventsEmitter.registerToClientJoin((clientUUid, roomId) => {
|
|
||||||
this.nbClientsGauge.inc();
|
|
||||||
// Let's log server load when a user joins
|
|
||||||
console.log(new Date().toISOString() + ' A user joined (', this.sockets.size, ' connected users)');
|
|
||||||
});
|
|
||||||
clientEventsEmitter.registerToClientLeave((clientUUid, roomId) => {
|
|
||||||
this.nbClientsGauge.dec();
|
|
||||||
// Let's log server load when a user leaves
|
|
||||||
console.log('A user left (', this.sockets.size, ' connected users)');
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,7 +89,6 @@ export class SocketManager {
|
|||||||
const viewport = client.viewport;
|
const viewport = client.viewport;
|
||||||
try {
|
try {
|
||||||
this.sockets.set(client.userId, client); //todo: should this be at the end of the function?
|
this.sockets.set(client.userId, client); //todo: should this be at the end of the function?
|
||||||
clientEventsEmitter.emitClientJoin(client.userUuid, client.roomId);
|
|
||||||
//join new previous room
|
//join new previous room
|
||||||
const gameRoom = this.joinRoom(client, position);
|
const gameRoom = this.joinRoom(client, position);
|
||||||
|
|
||||||
@ -377,8 +358,8 @@ export class SocketManager {
|
|||||||
} finally {
|
} finally {
|
||||||
//delete Client.roomId;
|
//delete Client.roomId;
|
||||||
this.sockets.delete(Client.userId);
|
this.sockets.delete(Client.userId);
|
||||||
this.nbClientsPerRoomGauge.dec({ room: Client.roomId });
|
|
||||||
clientEventsEmitter.emitClientLeave(Client.userUuid, Client.roomId);
|
clientEventsEmitter.emitClientLeave(Client.userUuid, Client.roomId);
|
||||||
|
console.log('A user left (', this.sockets.size, ' connected users)');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -410,8 +391,6 @@ export class SocketManager {
|
|||||||
private joinRoom(client : ExSocketInterface, position: PointInterface): GameRoom {
|
private joinRoom(client : ExSocketInterface, position: PointInterface): GameRoom {
|
||||||
|
|
||||||
const roomId = client.roomId;
|
const roomId = client.roomId;
|
||||||
//join user in room
|
|
||||||
this.nbClientsPerRoomGauge.inc({ room: roomId });
|
|
||||||
client.position = position;
|
client.position = position;
|
||||||
|
|
||||||
const world = this.Worlds.get(roomId)
|
const world = this.Worlds.get(roomId)
|
||||||
@ -425,6 +404,8 @@ export class SocketManager {
|
|||||||
});
|
});
|
||||||
//join world
|
//join world
|
||||||
world.join(client, client.position);
|
world.join(client, client.position);
|
||||||
|
clientEventsEmitter.emitClientJoin(client.userUuid, client.roomId);
|
||||||
|
console.log(new Date().toISOString() + ' A user joined (', this.sockets.size, ' connected users)');
|
||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2345,10 +2345,10 @@ supports-color@^7.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
has-flag "^4.0.0"
|
has-flag "^4.0.0"
|
||||||
|
|
||||||
systeminformation@^4.26.5:
|
systeminformation@^4.27.11:
|
||||||
version "4.27.5"
|
version "4.27.11"
|
||||||
resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-4.27.5.tgz#af304fbfd0e7ba51c87512333691b58b4ad90e43"
|
resolved "https://registry.yarnpkg.com/systeminformation/-/systeminformation-4.27.11.tgz#6dbe96e48091444f80dab6c05ee1901286826b60"
|
||||||
integrity sha512-EysogxKqREk54ZYDEFcsCODv8GymKZcyiSfegYit8dKhPjzuQr+KX4GFHjssWjYrWFEIM2bYNsFrZX5eufeAXg==
|
integrity sha512-U7bigXbOnsB8k1vNHS0Y13RCsRz5/UohiUmND+3mMUL6vfzrpbe/h4ZqewowB+B+tJNnmGFDj08Z8xGfYo45dQ==
|
||||||
|
|
||||||
table@^5.2.3:
|
table@^5.2.3:
|
||||||
version "5.4.6"
|
version "5.4.6"
|
||||||
|
22
front/dist/index.html
vendored
22
front/dist/index.html
vendored
@ -42,30 +42,14 @@
|
|||||||
<body id="body" style="margin: 0">
|
<body id="body" style="margin: 0">
|
||||||
<div class="main-container" id="main-container">
|
<div class="main-container" id="main-container">
|
||||||
<!-- Create the editor container -->
|
<!-- Create the editor container -->
|
||||||
<div id="game" class="game" style="/*background: red;*/">
|
<div id="game" class="game">
|
||||||
<div id="game-overlay" class="game-overlay" style="/*background: violet*/;">
|
<div id="game-overlay" class="game-overlay">
|
||||||
<div id="main-section" class="main-section">
|
<div id="main-section" class="main-section">
|
||||||
<!--<div style="background: lightpink;">a</div>
|
|
||||||
<div style="background: lightpink;">a</div> -->
|
|
||||||
</div>
|
</div>
|
||||||
<aside id="sidebar" class="sidebar">
|
<aside id="sidebar" class="sidebar">
|
||||||
<!--<div style="background: lightgreen;">a</div>
|
|
||||||
<div style="background: green;">b</div>
|
|
||||||
<div style="background: darkgreen;">c</div>
|
|
||||||
<div style="background: darkgreen;">d</div>-->
|
|
||||||
</aside>
|
</aside>
|
||||||
<div id="chat-mode" class="chat-mode three-col" style="display: none;">
|
<div id="chat-mode" class="chat-mode three-col" style="display: none;">
|
||||||
<!--<div style="background: lightgreen;">a</div>
|
|
||||||
<div style="background: green;">b</div>
|
|
||||||
<div style="background: darkgreen;">c</div>
|
|
||||||
<div style="background: darkolivegreen;">d</div>
|
|
||||||
<div style="background: darkolivegreen;">d</div>
|
|
||||||
<div style="background: darkgreen;">c</div>
|
|
||||||
<div style="background: green;">b</div>
|
|
||||||
<div style="background: lightgreen;">last elem for game</div>-->
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div id="activeCam" class="activeCam">
|
<div id="activeCam" class="activeCam">
|
||||||
<div id="div-myCamVideo" class="video-container">
|
<div id="div-myCamVideo" class="video-container">
|
||||||
<video id="myCamVideo" autoplay muted></video>
|
<video id="myCamVideo" autoplay muted></video>
|
||||||
@ -88,7 +72,7 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="cowebsite" class="cowebsite"></div>
|
<div id="cowebsite" class="cowebsite hidden"></div>
|
||||||
<div class="audio-playing">
|
<div class="audio-playing">
|
||||||
<img src="/resources/logos/megaphone.svg"/>
|
<img src="/resources/logos/megaphone.svg"/>
|
||||||
</div>
|
</div>
|
||||||
|
43
front/dist/resources/logos/send-bkack.svg
vendored
Normal file
43
front/dist/resources/logos/send-bkack.svg
vendored
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.0.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 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path d="M481.508,210.336L68.414,38.926c-17.403-7.222-37.064-4.045-51.309,8.287C2.86,59.547-3.098,78.551,1.558,96.808
|
||||||
|
L38.327,241h180.026c8.284,0,15.001,6.716,15.001,15.001c0,8.284-6.716,15.001-15.001,15.001H38.327L1.558,415.193
|
||||||
|
c-4.656,18.258,1.301,37.262,15.547,49.595c14.274,12.357,33.937,15.495,51.31,8.287l413.094-171.409
|
||||||
|
C500.317,293.862,512,276.364,512,256.001C512,235.638,500.317,218.139,481.508,210.336z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 985 B |
1
front/dist/resources/logos/send-white.svg
vendored
Normal file
1
front/dist/resources/logos/send-white.svg
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg id="Capa_1" data-name="Capa 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 441.78"><defs><style>.cls-1{fill:#fff;}</style></defs><path class="cls-1" d="M481.51,210.34,68.41,38.93A49.44,49.44,0,0,0,1.56,96.81L38.33,241h180a15,15,0,1,1,0,30h-180L1.56,415.19a49.43,49.43,0,0,0,66.86,57.88l413.09-171.4a49.44,49.44,0,0,0,0-91.33Z" transform="translate(0 -35.11)"/></svg>
|
After Width: | Height: | Size: 379 B |
1
front/dist/resources/logos/send-yellow.svg
vendored
Normal file
1
front/dist/resources/logos/send-yellow.svg
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg id="Capa_1" data-name="Capa 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 441.78"><defs><style>.cls-1{fill:#ffda01;}</style></defs><path class="cls-1" d="M481.51,210.34,68.41,38.93A49.44,49.44,0,0,0,1.56,96.81L38.33,241h180a15,15,0,1,1,0,30h-180L1.56,415.19a49.43,49.43,0,0,0,66.86,57.88l413.09-171.4a49.44,49.44,0,0,0,0-91.33Z" transform="translate(0 -35.11)"/></svg>
|
After Width: | Height: | Size: 382 B |
20
front/dist/resources/logos/setting-black.svg
vendored
Normal file
20
front/dist/resources/logos/setting-black.svg
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?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 512 512" style="enable-background:new 0 0 512 512;" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path d="M453.6,237.3c-1.5-18.8-5.6-37-12.3-54.5l46.1-37l-75-93.6L366.5,89c-15.8-10.7-33-18.9-51.1-24.6V6.1h-120v58.7
|
||||||
|
c-19,6.1-36.8,15-53.2,26.5l-46.3-36L22.3,150l47.2,36.6c-6.3,17.5-10,35.8-11.2,54.5L0,255l27.9,116.7l41-9.8
|
||||||
|
c20.2-20.2,38.4-38.4,62.4-62.4C99.4,213,163.5,120.6,256.1,120.6c73.4,0,132.9,59.5,132.9,132.9c0,90.7-89,154.7-174.8,126.2
|
||||||
|
c-6.9,6.9-77.9,77.9-88.9,88.9l79.1,37.3l26.3-55.8c18.2,2.3,36.3,2.1,54.1-0.5l26.9,55.1L419.6,452l-26.9-54.9
|
||||||
|
c13.3-12.7,24.7-27,34.1-42.8l59,13.2L512,250.4L453.6,237.3z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path d="M336,219.4l-7.6-19.1L282.6,246L262,225.4l45.8-45.8l-19.1-7.6c-74.9-29.8-144.2,52.2-104.9,120.7
|
||||||
|
C82.6,393.9,169.1,307.5,47.6,429c-17,17,18.4,52.5,35.4,35.4c70.6-70.6,2-2,137.5-137.5C289.6,360.5,364.5,291,336,219.4z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
1
front/dist/resources/logos/setting-white.svg
vendored
Normal file
1
front/dist/resources/logos/setting-white.svg
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg id="Capa_1" data-name="Capa 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 499.81"><defs><style>.cls-1{fill:#fff;}</style></defs><path class="cls-1" d="M453.58,237.31a195.46,195.46,0,0,0-12.33-54.5l46.14-37-75-93.62L366.55,89a196.1,196.1,0,0,0-51.12-24.58V6.1h-120V64.75a195.85,195.85,0,0,0-53.23,26.53l-46.34-36L22.3,150l47.16,36.64a196.64,196.64,0,0,0-11.19,54.46L0,255,27.91,371.68l41-9.81,62.4-62.39C99.44,213,163.49,120.57,256.09,120.57A133,133,0,0,1,389,253.51c0,90.69-89,154.71-174.78,126.22l-88.88,88.89,79.1,37.28,26.31-55.81a199.26,199.26,0,0,0,54.12-.45l27,55.07L419.6,452l-26.88-54.93a197.42,197.42,0,0,0,34.06-42.84l59,13.22,26.2-117Z" transform="translate(0 -6.1)"/><path class="cls-1" d="M336,219.37l-7.61-19.14L282.55,246,262,225.44l45.79-45.78L288.63,172c-74.92-29.8-144.18,52.17-104.87,120.7C82.63,393.88,169.06,307.46,47.55,429,30.51,446,66,481.44,83,464.4c70.58-70.59,2-2,137.48-137.47C289.61,360.46,364.47,291,336,219.37Z" transform="translate(0 -6.1)"/></svg>
|
After Width: | Height: | Size: 994 B |
1
front/dist/resources/logos/setting-yellow.svg
vendored
Normal file
1
front/dist/resources/logos/setting-yellow.svg
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg id="Capa_1" data-name="Capa 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 499.81"><defs><style>.cls-1{fill:#ffda01;}</style></defs><path class="cls-1" d="M453.58,237.31a195.46,195.46,0,0,0-12.33-54.5l46.14-37-75-93.62L366.55,89a196.1,196.1,0,0,0-51.12-24.58V6.1h-120V64.75a195.85,195.85,0,0,0-53.23,26.53l-46.34-36L22.3,150l47.16,36.64a196.64,196.64,0,0,0-11.19,54.46L0,255,27.91,371.68l41-9.81,62.4-62.39C99.44,213,163.49,120.57,256.09,120.57A133,133,0,0,1,389,253.51c0,90.69-89,154.71-174.78,126.22l-88.88,88.89,79.1,37.28,26.31-55.81a199.26,199.26,0,0,0,54.12-.45l27,55.07L419.6,452l-26.88-54.93a197.42,197.42,0,0,0,34.06-42.84l59,13.22,26.2-117Z" transform="translate(0 -6.1)"/><path class="cls-1" d="M336,219.37l-7.61-19.14L282.55,246,262,225.44l45.79-45.78L288.63,172c-74.92-29.8-144.18,52.17-104.87,120.7C82.63,393.88,169.06,307.46,47.55,429,30.51,446,66,481.44,83,464.4c70.58-70.59,2-2,137.48-137.47C289.61,360.46,364.47,291,336,219.37Z" transform="translate(0 -6.1)"/></svg>
|
After Width: | Height: | Size: 997 B |
96
front/dist/resources/style/style.css
vendored
96
front/dist/resources/style/style.css
vendored
@ -242,15 +242,10 @@ body {
|
|||||||
.main-container {
|
.main-container {
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
display: flex;
|
position: absolute;
|
||||||
align-items: stretch;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-aspect-ratio: 1/1) {
|
@media (min-aspect-ratio: 1/1) {
|
||||||
.main-container {
|
|
||||||
flex-direction: row;
|
|
||||||
}
|
|
||||||
|
|
||||||
.game-overlay {
|
.game-overlay {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
@ -266,12 +261,21 @@ body {
|
|||||||
.sidebar > div:hover {
|
.sidebar > div:hover {
|
||||||
max-height: 25%;
|
max-height: 25%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#cowebsite {
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 50%;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
#cowebsite.loading {
|
||||||
|
transform: translateX(90%);
|
||||||
|
}
|
||||||
|
#cowebsite.hidden {
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@media (max-aspect-ratio: 1/1) {
|
@media (max-aspect-ratio: 1/1) {
|
||||||
.main-container {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.game-overlay {
|
.game-overlay {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
@ -288,24 +292,36 @@ body {
|
|||||||
.sidebar > div:hover {
|
.sidebar > div:hover {
|
||||||
max-width: 25%;
|
max-width: 25%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#cowebsite {
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 50%;
|
||||||
|
}
|
||||||
|
#cowebsite.loading {
|
||||||
|
transform: translateY(90%);
|
||||||
|
}
|
||||||
|
#cowebsite.hidden {
|
||||||
|
transform: translateY(100%);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.game {
|
#game {
|
||||||
flex-basis: 100%;
|
width: 100%;
|
||||||
position: relative; /* Position relative is needed for the game-overlay. */
|
position: relative; /* Position relative is needed for the game-overlay. */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A potentially shared website could appear in an iframe in the cowebsite space. */
|
/* A potentially shared website could appear in an iframe in the cowebsite space. */
|
||||||
.cowebsite {
|
#cowebsite {
|
||||||
flex-basis: 100%;
|
position: fixed;
|
||||||
transition: flex-basis 0.5s;
|
transition: transform 0.5s;
|
||||||
|
}
|
||||||
|
#cowebsite.loading {
|
||||||
|
background-color: gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*.cowebsite:hover {
|
#cowebsite > iframe {
|
||||||
flex-basis: 100%;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
.cowebsite > iframe {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
@ -445,23 +461,51 @@ body {
|
|||||||
color: white;
|
color: white;
|
||||||
z-index: 200;
|
z-index: 200;
|
||||||
transition: all 0.1s ease-out;
|
transition: all 0.1s ease-out;
|
||||||
top: 100%;
|
top: calc(100% + 2px);
|
||||||
width: 100px;
|
width: 200px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
background-color: black;
|
background-color: #2d2d2dba;
|
||||||
left: calc(50% - 50px);
|
left: calc(50% - 100px);
|
||||||
border-radius: 0 0 10px 10px;
|
border-radius: 15px 15px 15px 15px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.message-container div.clear{
|
||||||
|
width: 100px;
|
||||||
|
left: calc(50% - 50px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-console div.console img,
|
||||||
|
.message-container div.clear img{
|
||||||
|
margin-top: 6px;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0 5px;
|
||||||
|
transition: all .5s ease;
|
||||||
|
transform: rotateY(0);
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
.main-console div.console img:hover,
|
||||||
|
.message-container div.clear img:hover{
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-console div.console img.active,
|
||||||
|
.message-container div.clear img{
|
||||||
|
transform: rotateY(3.142rad);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.main-console div.console p,
|
.main-console div.console p,
|
||||||
.message-container div.clear p{
|
.message-container div.clear p{
|
||||||
margin-top: 6px;
|
margin-top: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-console div.console:hover,
|
.main-console div.console:hover,
|
||||||
.message-container div.clear:hover {
|
.message-container div.clear:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
top: calc(100% + 5px);
|
||||||
transform: scale(1.2) translateY(3px);
|
transform: scale(1.2) translateY(3px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import {HtmlUtils} from "../WebRtc/HtmlUtils";
|
|||||||
import {UserInputManager} from "../Phaser/UserInput/UserInputManager";
|
import {UserInputManager} from "../Phaser/UserInput/UserInputManager";
|
||||||
import {RoomConnection} from "../Connexion/RoomConnection";
|
import {RoomConnection} from "../Connexion/RoomConnection";
|
||||||
import {PlayGlobalMessageInterface} from "../Connexion/ConnexionModels";
|
import {PlayGlobalMessageInterface} from "../Connexion/ConnexionModels";
|
||||||
|
import {ADMIN_URL} from "../Enum/EnvironmentVariable";
|
||||||
|
|
||||||
export const CLASS_CONSOLE_MESSAGE = 'main-console';
|
export const CLASS_CONSOLE_MESSAGE = 'main-console';
|
||||||
export const INPUT_CONSOLE_MESSAGE = 'input-send-text';
|
export const INPUT_CONSOLE_MESSAGE = 'input-send-text';
|
||||||
@ -17,8 +18,10 @@ interface EventTargetFiles extends EventTarget {
|
|||||||
|
|
||||||
export class ConsoleGlobalMessageManager {
|
export class ConsoleGlobalMessageManager {
|
||||||
|
|
||||||
private divMainConsole: HTMLDivElement;
|
private readonly divMainConsole: HTMLDivElement;
|
||||||
private buttonMainConsole: HTMLDivElement;
|
private readonly buttonMainConsole: HTMLDivElement;
|
||||||
|
private readonly buttonSendMainConsole: HTMLImageElement;
|
||||||
|
private readonly buttonSettingsMainConsole: HTMLImageElement;
|
||||||
private activeConsole: boolean = false;
|
private activeConsole: boolean = false;
|
||||||
private userInputManager!: UserInputManager;
|
private userInputManager!: UserInputManager;
|
||||||
private static cssLoaded: boolean = false;
|
private static cssLoaded: boolean = false;
|
||||||
@ -27,6 +30,8 @@ export class ConsoleGlobalMessageManager {
|
|||||||
this.buttonMainConsole = document.createElement('div');
|
this.buttonMainConsole = document.createElement('div');
|
||||||
this.buttonMainConsole.classList.add('console');
|
this.buttonMainConsole.classList.add('console');
|
||||||
this.divMainConsole = document.createElement('div');
|
this.divMainConsole = document.createElement('div');
|
||||||
|
this.buttonSendMainConsole = document.createElement('img');
|
||||||
|
this.buttonSettingsMainConsole = document.createElement('img');
|
||||||
this.userInputManager = userInputManager;
|
this.userInputManager = userInputManager;
|
||||||
this.initialise();
|
this.initialise();
|
||||||
}
|
}
|
||||||
@ -75,17 +80,26 @@ export class ConsoleGlobalMessageManager {
|
|||||||
menu.appendChild(textAudio);
|
menu.appendChild(textAudio);
|
||||||
this.divMainConsole.appendChild(menu);
|
this.divMainConsole.appendChild(menu);
|
||||||
|
|
||||||
const buttonText = document.createElement('p');
|
this.buttonSendMainConsole.src = 'resources/logos/send-yellow.svg';
|
||||||
buttonText.innerText = 'Console';
|
this.buttonSendMainConsole.addEventListener('click', () => {
|
||||||
|
|
||||||
this.buttonMainConsole.appendChild(buttonText);
|
|
||||||
this.buttonMainConsole.addEventListener('click', () => {
|
|
||||||
if(this.activeConsole){
|
if(this.activeConsole){
|
||||||
this.disabled();
|
this.disabled();
|
||||||
}else{
|
}else{
|
||||||
|
this.buttonSendMainConsole.classList.add('active');
|
||||||
this.active();
|
this.active();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
this.buttonMainConsole.appendChild(this.buttonSendMainConsole);
|
||||||
|
|
||||||
|
this.buttonSettingsMainConsole.src = 'resources/logos/setting-yellow.svg';
|
||||||
|
this.buttonSettingsMainConsole.addEventListener('click', () => {
|
||||||
|
window.open(ADMIN_URL, '_blank');
|
||||||
|
});
|
||||||
|
this.buttonMainConsole.appendChild(this.buttonSettingsMainConsole);
|
||||||
|
|
||||||
|
/*const buttonText = document.createElement('p');
|
||||||
|
buttonText.innerText = 'Console';
|
||||||
|
this.buttonMainConsole.appendChild(buttonText);*/
|
||||||
|
|
||||||
this.divMainConsole.className = CLASS_CONSOLE_MESSAGE;
|
this.divMainConsole.className = CLASS_CONSOLE_MESSAGE;
|
||||||
this.divMainConsole.appendChild(this.buttonMainConsole);
|
this.divMainConsole.appendChild(this.buttonMainConsole);
|
||||||
@ -293,17 +307,18 @@ export class ConsoleGlobalMessageManager {
|
|||||||
this.Connection.emitGlobalMessage(GlobalMessage);
|
this.Connection.emitGlobalMessage(GlobalMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
active(){
|
active(){
|
||||||
this.userInputManager.clearAllInputKeyboard();
|
this.userInputManager.clearAllInputKeyboard();
|
||||||
this.activeConsole = true;
|
this.activeConsole = true;
|
||||||
this.divMainConsole.style.top = '0';
|
this.divMainConsole.style.top = '0';
|
||||||
|
this.buttonSendMainConsole.classList.add('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
disabled(){
|
disabled(){
|
||||||
this.userInputManager.initKeyBoardEvent();
|
this.userInputManager.initKeyBoardEvent();
|
||||||
this.activeConsole = false;
|
this.activeConsole = false;
|
||||||
this.divMainConsole.style.top = '-80%';
|
this.divMainConsole.style.top = '-80%';
|
||||||
|
this.buttonSendMainConsole.classList.remove('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
private getSectionId(id: string) : string {
|
private getSectionId(id: string) : string {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
const DEBUG_MODE: boolean = process.env.DEBUG_MODE == "true";
|
const DEBUG_MODE: boolean = process.env.DEBUG_MODE == "true";
|
||||||
const API_URL = (process.env.API_PROTOCOL || (typeof(window) !== 'undefined' ? window.location.protocol : 'http:')) + '//' + (process.env.API_URL || "api.workadventure.localhost");
|
const API_URL = (process.env.API_PROTOCOL || (typeof(window) !== 'undefined' ? window.location.protocol : 'http:')) + '//' + (process.env.API_URL || "api.workadventure.localhost");
|
||||||
|
const ADMIN_URL = API_URL.replace('api', 'admin');
|
||||||
const TURN_SERVER: string = process.env.TURN_SERVER || "turn:numb.viagenie.ca";
|
const TURN_SERVER: string = process.env.TURN_SERVER || "turn:numb.viagenie.ca";
|
||||||
const TURN_USER: string = process.env.TURN_USER || 'g.parant@thecodingmachine.com';
|
const TURN_USER: string = process.env.TURN_USER || 'g.parant@thecodingmachine.com';
|
||||||
const TURN_PASSWORD: string = process.env.TURN_PASSWORD || 'itcugcOHxle9Acqi$';
|
const TURN_PASSWORD: string = process.env.TURN_PASSWORD || 'itcugcOHxle9Acqi$';
|
||||||
@ -13,6 +14,7 @@ const MAX_EXTRAPOLATION_TIME = 100; // Extrapolate a maximum of 250ms if no new
|
|||||||
export {
|
export {
|
||||||
DEBUG_MODE,
|
DEBUG_MODE,
|
||||||
API_URL,
|
API_URL,
|
||||||
|
ADMIN_URL,
|
||||||
RESOLUTION,
|
RESOLUTION,
|
||||||
ZOOM_LEVEL,
|
ZOOM_LEVEL,
|
||||||
POSITION_DELAY,
|
POSITION_DELAY,
|
||||||
|
@ -12,7 +12,6 @@ import {CurrentGamerInterface, hasMovedEventName, Player} from "../Player/Player
|
|||||||
import {
|
import {
|
||||||
DEBUG_MODE,
|
DEBUG_MODE,
|
||||||
JITSI_PRIVATE_MODE,
|
JITSI_PRIVATE_MODE,
|
||||||
JITSI_URL,
|
|
||||||
POSITION_DELAY,
|
POSITION_DELAY,
|
||||||
RESOLUTION,
|
RESOLUTION,
|
||||||
ZOOM_LEVEL
|
ZOOM_LEVEL
|
||||||
@ -23,7 +22,6 @@ import {
|
|||||||
ITiledMapLayerProperty, ITiledMapObject,
|
ITiledMapLayerProperty, ITiledMapObject,
|
||||||
ITiledTileSet
|
ITiledTileSet
|
||||||
} from "../Map/ITiledMap";
|
} from "../Map/ITiledMap";
|
||||||
import {PLAYER_RESOURCES, PlayerResourceDescriptionInterface} from "../Entity/Character";
|
|
||||||
import {AddPlayerInterface} from "./AddPlayerInterface";
|
import {AddPlayerInterface} from "./AddPlayerInterface";
|
||||||
import {PlayerAnimationNames} from "../Player/Animation";
|
import {PlayerAnimationNames} from "../Player/Animation";
|
||||||
import {PlayerMovement} from "./PlayerMovement";
|
import {PlayerMovement} from "./PlayerMovement";
|
||||||
@ -32,7 +30,7 @@ import {RemotePlayer} from "../Entity/RemotePlayer";
|
|||||||
import {Queue} from 'queue-typescript';
|
import {Queue} from 'queue-typescript';
|
||||||
import {SimplePeer, UserSimplePeerInterface} from "../../WebRtc/SimplePeer";
|
import {SimplePeer, UserSimplePeerInterface} from "../../WebRtc/SimplePeer";
|
||||||
import {ReconnectingSceneName} from "../Reconnecting/ReconnectingScene";
|
import {ReconnectingSceneName} from "../Reconnecting/ReconnectingScene";
|
||||||
import {loadAllLayers, loadCustomTexture, loadObject, loadPlayerCharacters} from "../Entity/body_character";
|
import {loadAllLayers, loadObject, loadPlayerCharacters} from "../Entity/body_character";
|
||||||
import {CenterListener, layoutManager, LayoutMode} from "../../WebRtc/LayoutManager";
|
import {CenterListener, layoutManager, LayoutMode} from "../../WebRtc/LayoutManager";
|
||||||
import Texture = Phaser.Textures.Texture;
|
import Texture = Phaser.Textures.Texture;
|
||||||
import Sprite = Phaser.GameObjects.Sprite;
|
import Sprite = Phaser.GameObjects.Sprite;
|
||||||
@ -40,7 +38,7 @@ import CanvasTexture = Phaser.Textures.CanvasTexture;
|
|||||||
import GameObject = Phaser.GameObjects.GameObject;
|
import GameObject = Phaser.GameObjects.GameObject;
|
||||||
import FILE_LOAD_ERROR = Phaser.Loader.Events.FILE_LOAD_ERROR;
|
import FILE_LOAD_ERROR = Phaser.Loader.Events.FILE_LOAD_ERROR;
|
||||||
import {GameMap} from "./GameMap";
|
import {GameMap} from "./GameMap";
|
||||||
import {CoWebsiteManager} from "../../WebRtc/CoWebsiteManager";
|
import {coWebsiteManager} from "../../WebRtc/CoWebsiteManager";
|
||||||
import {mediaManager} from "../../WebRtc/MediaManager";
|
import {mediaManager} from "../../WebRtc/MediaManager";
|
||||||
import {FourOFourSceneName} from "../Reconnecting/FourOFourScene";
|
import {FourOFourSceneName} from "../Reconnecting/FourOFourScene";
|
||||||
import {ItemFactoryInterface} from "../Items/ItemFactoryInterface";
|
import {ItemFactoryInterface} from "../Items/ItemFactoryInterface";
|
||||||
@ -55,11 +53,7 @@ import {UserMessageManager} from "../../Administration/UserMessageManager";
|
|||||||
import {ConsoleGlobalMessageManager} from "../../Administration/ConsoleGlobalMessageManager";
|
import {ConsoleGlobalMessageManager} from "../../Administration/ConsoleGlobalMessageManager";
|
||||||
import {ResizableScene} from "../Login/ResizableScene";
|
import {ResizableScene} from "../Login/ResizableScene";
|
||||||
import {Room} from "../../Connexion/Room";
|
import {Room} from "../../Connexion/Room";
|
||||||
|
import {jitsiFactory} from "../../WebRtc/JitsiFactory";
|
||||||
|
|
||||||
export enum Textures {
|
|
||||||
Player = "male1"
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GameSceneInitInterface {
|
export interface GameSceneInitInterface {
|
||||||
initPosition: PointInterface|null
|
initPosition: PointInterface|null
|
||||||
@ -147,8 +141,6 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
private outlinedItem: ActionableItem|null = null;
|
private outlinedItem: ActionableItem|null = null;
|
||||||
private userInputManager!: UserInputManager;
|
private userInputManager!: UserInputManager;
|
||||||
|
|
||||||
private jitsiApi: any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
||||||
|
|
||||||
static createFromUrl(room: Room, mapUrlFile: string, gameSceneKey: string|null = null): GameScene {
|
static createFromUrl(room: Room, mapUrlFile: string, gameSceneKey: string|null = null): GameScene {
|
||||||
// We use the map URL as a key
|
// We use the map URL as a key
|
||||||
if (gameSceneKey === null) {
|
if (gameSceneKey === null) {
|
||||||
@ -300,13 +292,6 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
// });
|
// });
|
||||||
// });
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
// TEST: let's load a module dynamically!
|
|
||||||
/*let foo = "http://maps.workadventure.localhost/computer.js";
|
|
||||||
import(/* webpackIgnore: true * / foo).then(result => {
|
|
||||||
console.log(result);
|
|
||||||
|
|
||||||
});*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//hook initialisation
|
//hook initialisation
|
||||||
@ -484,9 +469,9 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
|
|
||||||
this.gameMap.onPropertyChange('openWebsite', (newValue, oldValue) => {
|
this.gameMap.onPropertyChange('openWebsite', (newValue, oldValue) => {
|
||||||
if (newValue === undefined) {
|
if (newValue === undefined) {
|
||||||
CoWebsiteManager.closeCoWebsite();
|
coWebsiteManager.closeCoWebsite();
|
||||||
} else {
|
} else {
|
||||||
CoWebsiteManager.loadCoWebsite(newValue as string);
|
coWebsiteManager.loadCoWebsite(newValue as string);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.gameMap.onPropertyChange('jitsiRoom', (newValue, oldValue, allProps) => {
|
this.gameMap.onPropertyChange('jitsiRoom', (newValue, oldValue, allProps) => {
|
||||||
@ -1231,53 +1216,14 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public startJitsi(roomName: string, jwt?: string): void {
|
public startJitsi(roomName: string, jwt?: string): void {
|
||||||
CoWebsiteManager.insertCoWebsite((cowebsiteDiv => {
|
jitsiFactory.start(roomName, gameManager.getPlayerName(), jwt);
|
||||||
const domain = JITSI_URL;
|
|
||||||
const options = {
|
|
||||||
roomName: roomName,
|
|
||||||
jwt: jwt,
|
|
||||||
width: "100%",
|
|
||||||
height: "100%",
|
|
||||||
parentNode: cowebsiteDiv,
|
|
||||||
configOverwrite: {
|
|
||||||
prejoinPageEnabled: false
|
|
||||||
},
|
|
||||||
interfaceConfigOverwrite: {
|
|
||||||
SHOW_CHROME_EXTENSION_BANNER: false,
|
|
||||||
MOBILE_APP_PROMO: false,
|
|
||||||
|
|
||||||
HIDE_INVITE_MORE_HEADER: true,
|
|
||||||
|
|
||||||
// Note: hiding brand does not seem to work, we probably need to put this on the server side.
|
|
||||||
SHOW_BRAND_WATERMARK: false,
|
|
||||||
SHOW_JITSI_WATERMARK: false,
|
|
||||||
SHOW_POWERED_BY: false,
|
|
||||||
SHOW_PROMOTIONAL_CLOSE_PAGE: false,
|
|
||||||
SHOW_WATERMARK_FOR_GUESTS: false,
|
|
||||||
|
|
||||||
TOOLBAR_BUTTONS: [
|
|
||||||
'microphone', 'camera', 'closedcaptions', 'desktop', /*'embedmeeting',*/ 'fullscreen',
|
|
||||||
'fodeviceselection', 'hangup', 'profile', 'chat', 'recording',
|
|
||||||
'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand',
|
|
||||||
'videoquality', 'filmstrip', /*'invite',*/ 'feedback', 'stats', 'shortcuts',
|
|
||||||
'tileview', 'videobackgroundblur', 'download', 'help', 'mute-everyone', /*'security'*/
|
|
||||||
],
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (!options.jwt) {
|
|
||||||
delete options.jwt;
|
|
||||||
}
|
|
||||||
this.jitsiApi = new (window as any).JitsiMeetExternalAPI(domain, options); // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
||||||
this.jitsiApi.executeCommand('displayName', gameManager.getPlayerName());
|
|
||||||
}));
|
|
||||||
this.connection.setSilent(true);
|
this.connection.setSilent(true);
|
||||||
mediaManager.hideGameOverlay();
|
mediaManager.hideGameOverlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
public stopJitsi(): void {
|
public stopJitsi(): void {
|
||||||
this.connection.setSilent(false);
|
this.connection.setSilent(false);
|
||||||
this.jitsiApi?.dispose();
|
jitsiFactory.stop();
|
||||||
CoWebsiteManager.closeCoWebsite();
|
|
||||||
mediaManager.showGameOverlay();
|
mediaManager.showGameOverlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import {Textures} from "../Game/GameScene";
|
|
||||||
|
|
||||||
export enum PlayerAnimationNames {
|
export enum PlayerAnimationNames {
|
||||||
WalkDown = 'down',
|
WalkDown = 'down',
|
||||||
|
@ -2,47 +2,90 @@ import {HtmlUtils} from "./HtmlUtils";
|
|||||||
|
|
||||||
export type CoWebsiteStateChangedCallback = () => void;
|
export type CoWebsiteStateChangedCallback = () => void;
|
||||||
|
|
||||||
export class CoWebsiteManager {
|
enum iframeStates {
|
||||||
|
closed = 1,
|
||||||
|
loading, // loading an iframe can be slow, so we show some placeholder until it is ready
|
||||||
|
opened,
|
||||||
|
}
|
||||||
|
|
||||||
private static observers = new Array<CoWebsiteStateChangedCallback>();
|
const cowebsiteDivId = "cowebsite"; // the id of the parent div of the iframe.
|
||||||
|
const animationTime = 500; //time used by the css transitions, in ms.
|
||||||
|
|
||||||
public static loadCoWebsite(url: string): void {
|
class CoWebsiteManager {
|
||||||
const cowebsiteDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>("cowebsite");
|
|
||||||
|
private opened: iframeStates = iframeStates.closed;
|
||||||
|
|
||||||
|
private observers = new Array<CoWebsiteStateChangedCallback>();
|
||||||
|
|
||||||
|
private close(): HTMLDivElement {
|
||||||
|
const cowebsiteDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>(cowebsiteDivId);
|
||||||
|
cowebsiteDiv.classList.remove('loaded'); //edit the css class to trigger the transition
|
||||||
|
cowebsiteDiv.classList.add('hidden');
|
||||||
|
this.opened = iframeStates.closed;
|
||||||
|
return cowebsiteDiv;
|
||||||
|
}
|
||||||
|
private load(): HTMLDivElement {
|
||||||
|
const cowebsiteDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>(cowebsiteDivId);
|
||||||
|
cowebsiteDiv.classList.remove('hidden'); //edit the css class to trigger the transition
|
||||||
|
cowebsiteDiv.classList.add('loading');
|
||||||
|
this.opened = iframeStates.loading;
|
||||||
|
return cowebsiteDiv;
|
||||||
|
}
|
||||||
|
private open(): HTMLDivElement {
|
||||||
|
const cowebsiteDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>(cowebsiteDivId);
|
||||||
|
cowebsiteDiv.classList.remove('loading', 'hidden'); //edit the css class to trigger the transition
|
||||||
|
this.opened = iframeStates.opened;
|
||||||
|
return cowebsiteDiv;
|
||||||
|
}
|
||||||
|
|
||||||
|
public loadCoWebsite(url: string): void {
|
||||||
|
const cowebsiteDiv = this.load();
|
||||||
cowebsiteDiv.innerHTML = '';
|
cowebsiteDiv.innerHTML = '';
|
||||||
|
|
||||||
const iframe = document.createElement('iframe');
|
const iframe = document.createElement('iframe');
|
||||||
iframe.id = 'cowebsite-iframe';
|
iframe.id = 'cowebsite-iframe';
|
||||||
iframe.src = url;
|
iframe.src = url;
|
||||||
|
const onloadPromise = new Promise((resolve) => {
|
||||||
|
iframe.onload = () => resolve();
|
||||||
|
});
|
||||||
cowebsiteDiv.appendChild(iframe);
|
cowebsiteDiv.appendChild(iframe);
|
||||||
//iframe.onload = () => {
|
const onTimeoutPromise = new Promise((resolve) => {
|
||||||
// onload can be long to trigger. Maybe we should display the website, whatever happens, after 1 second?
|
setTimeout(() => resolve(), 2000);
|
||||||
CoWebsiteManager.fire();
|
});
|
||||||
//}
|
Promise.race([onloadPromise, onTimeoutPromise]).then(() => {
|
||||||
|
this.open();
|
||||||
|
setTimeout(() => {
|
||||||
|
this.fire();
|
||||||
|
}, animationTime)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Just like loadCoWebsite but the div can be filled by the user.
|
* Just like loadCoWebsite but the div can be filled by the user.
|
||||||
*/
|
*/
|
||||||
public static insertCoWebsite(callback: (cowebsite: HTMLDivElement) => void): void {
|
public insertCoWebsite(callback: (cowebsite: HTMLDivElement) => Promise<void>): void {
|
||||||
const cowebsiteDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>("cowebsite");
|
const cowebsiteDiv = this.load();
|
||||||
cowebsiteDiv.innerHTML = '';
|
callback(cowebsiteDiv).then(() => {
|
||||||
|
this.open();
|
||||||
callback(cowebsiteDiv);
|
setTimeout(() => {
|
||||||
//iframe.onload = () => {
|
this.fire();
|
||||||
// onload can be long to trigger. Maybe we should display the website, whatever happens, after 1 second?
|
}, animationTime)
|
||||||
CoWebsiteManager.fire();
|
});
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static closeCoWebsite(): void {
|
public closeCoWebsite(): Promise<void> {
|
||||||
const cowebsiteDiv = HtmlUtils.getElementByIdOrFail<HTMLDivElement>("cowebsite");
|
return new Promise((resolve, reject) => {
|
||||||
cowebsiteDiv.innerHTML = '';
|
const cowebsiteDiv = this.close();
|
||||||
CoWebsiteManager.fire();
|
this.fire();
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve();
|
||||||
|
setTimeout(() => cowebsiteDiv.innerHTML = '', 500)
|
||||||
|
}, animationTime)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static getGameSize(): {width: number, height: number} {
|
public getGameSize(): {width: number, height: number} {
|
||||||
const hasChildren = HtmlUtils.getElementByIdOrFail<HTMLDivElement>("cowebsite").children.length > 0;
|
if (this.opened !== iframeStates.opened) {
|
||||||
if (hasChildren === false) {
|
|
||||||
return {
|
return {
|
||||||
width: window.innerWidth,
|
width: window.innerWidth,
|
||||||
height: window.innerHeight
|
height: window.innerHeight
|
||||||
@ -61,13 +104,15 @@ export class CoWebsiteManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static onStateChange(observer: CoWebsiteStateChangedCallback) {
|
public onStateChange(observer: CoWebsiteStateChangedCallback) {
|
||||||
CoWebsiteManager.observers.push(observer);
|
this.observers.push(observer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static fire(): void {
|
private fire(): void {
|
||||||
for (const callback of CoWebsiteManager.observers) {
|
for (const callback of this.observers) {
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const coWebsiteManager = new CoWebsiteManager();
|
89
front/src/WebRtc/JitsiFactory.ts
Normal file
89
front/src/WebRtc/JitsiFactory.ts
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import {JITSI_URL} from "../Enum/EnvironmentVariable";
|
||||||
|
import {mediaManager} from "./MediaManager";
|
||||||
|
import {coWebsiteManager} from "./CoWebsiteManager";
|
||||||
|
declare const window:any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||||
|
|
||||||
|
const interfaceConfig = {
|
||||||
|
SHOW_CHROME_EXTENSION_BANNER: false,
|
||||||
|
MOBILE_APP_PROMO: false,
|
||||||
|
|
||||||
|
HIDE_INVITE_MORE_HEADER: true,
|
||||||
|
|
||||||
|
// Note: hiding brand does not seem to work, we probably need to put this on the server side.
|
||||||
|
SHOW_BRAND_WATERMARK: false,
|
||||||
|
SHOW_JITSI_WATERMARK: false,
|
||||||
|
SHOW_POWERED_BY: false,
|
||||||
|
SHOW_PROMOTIONAL_CLOSE_PAGE: false,
|
||||||
|
SHOW_WATERMARK_FOR_GUESTS: false,
|
||||||
|
|
||||||
|
TOOLBAR_BUTTONS: [
|
||||||
|
'microphone', 'camera', 'closedcaptions', 'desktop', /*'embedmeeting',*/ 'fullscreen',
|
||||||
|
'fodeviceselection', 'hangup', 'profile', 'chat', 'recording',
|
||||||
|
'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand',
|
||||||
|
'videoquality', 'filmstrip', /*'invite',*/ 'feedback', 'stats', 'shortcuts',
|
||||||
|
'tileview', 'videobackgroundblur', 'download', 'help', 'mute-everyone', /*'security'*/
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
class JitsiFactory {
|
||||||
|
private jitsiApi: any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||||
|
private audioCallback = this.onAudioChange.bind(this);
|
||||||
|
private videoCallback = this.onVideoChange.bind(this);
|
||||||
|
|
||||||
|
public start(roomName: string, playerName:string, jwt?: string): void {
|
||||||
|
coWebsiteManager.insertCoWebsite((cowebsiteDiv => {
|
||||||
|
const domain = JITSI_URL;
|
||||||
|
const options: any = { // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||||
|
roomName: roomName,
|
||||||
|
jwt: jwt,
|
||||||
|
width: "100%",
|
||||||
|
height: "100%",
|
||||||
|
parentNode: cowebsiteDiv,
|
||||||
|
configOverwrite: {
|
||||||
|
startWithAudioMuted: !mediaManager.constraintsMedia.audio,
|
||||||
|
startWithVideoMuted: mediaManager.constraintsMedia.video === false,
|
||||||
|
prejoinPageEnabled: false
|
||||||
|
},
|
||||||
|
interfaceConfigOverwrite: interfaceConfig,
|
||||||
|
};
|
||||||
|
if (!options.jwt) {
|
||||||
|
delete options.jwt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
options.onload = () => resolve(); //we want for the iframe to be loaded before triggering animations.
|
||||||
|
this.jitsiApi = new window.JitsiMeetExternalAPI(domain, options);
|
||||||
|
this.jitsiApi.executeCommand('displayName', playerName);
|
||||||
|
|
||||||
|
this.jitsiApi.addListener('audioMuteStatusChanged', this.audioCallback);
|
||||||
|
this.jitsiApi.addListener('videoMuteStatusChanged', this.videoCallback);
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async stop(): Promise<void> {
|
||||||
|
await coWebsiteManager.closeCoWebsite();
|
||||||
|
this.jitsiApi.removeListener('audioMuteStatusChanged', this.audioCallback);
|
||||||
|
this.jitsiApi.removeListener('videoMuteStatusChanged', this.videoCallback);
|
||||||
|
this.jitsiApi?.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private onAudioChange({muted}: {muted: boolean}): void {
|
||||||
|
if (muted && mediaManager.constraintsMedia.audio === true) {
|
||||||
|
mediaManager.disableMicrophone();
|
||||||
|
} else if(!muted && mediaManager.constraintsMedia.audio === false) {
|
||||||
|
mediaManager.enableMicrophone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private onVideoChange({muted}: {muted: boolean}): void {
|
||||||
|
if (muted && mediaManager.constraintsMedia.video !== false) {
|
||||||
|
mediaManager.disableCamera();
|
||||||
|
} else if(!muted && mediaManager.constraintsMedia.video === false) {
|
||||||
|
mediaManager.enableCamera();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const jitsiFactory = new JitsiFactory();
|
@ -1,5 +1,6 @@
|
|||||||
import {DivImportance, layoutManager} from "./LayoutManager";
|
import {DivImportance, layoutManager} from "./LayoutManager";
|
||||||
import {HtmlUtils} from "./HtmlUtils";
|
import {HtmlUtils} from "./HtmlUtils";
|
||||||
|
declare const navigator:any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||||
|
|
||||||
const videoConstraint: boolean|MediaTrackConstraints = {
|
const videoConstraint: boolean|MediaTrackConstraints = {
|
||||||
width: { ideal: 1280 },
|
width: { ideal: 1280 },
|
||||||
@ -134,7 +135,7 @@ export class MediaManager {
|
|||||||
gameOverlay.classList.remove('active');
|
gameOverlay.classList.remove('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
private enableCamera() {
|
public enableCamera() {
|
||||||
this.cinemaClose.style.display = "none";
|
this.cinemaClose.style.display = "none";
|
||||||
this.cinemaBtn.classList.remove("disabled");
|
this.cinemaBtn.classList.remove("disabled");
|
||||||
this.cinema.style.display = "block";
|
this.cinema.style.display = "block";
|
||||||
@ -144,7 +145,7 @@ export class MediaManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async disableCamera() {
|
public async disableCamera() {
|
||||||
this.cinemaClose.style.display = "block";
|
this.cinemaClose.style.display = "block";
|
||||||
this.cinema.style.display = "none";
|
this.cinema.style.display = "none";
|
||||||
this.cinemaBtn.classList.add("disabled");
|
this.cinemaBtn.classList.add("disabled");
|
||||||
@ -160,7 +161,7 @@ export class MediaManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private enableMicrophone() {
|
public enableMicrophone() {
|
||||||
this.microphoneClose.style.display = "none";
|
this.microphoneClose.style.display = "none";
|
||||||
this.microphone.style.display = "block";
|
this.microphone.style.display = "block";
|
||||||
this.microphoneBtn.classList.remove("disabled");
|
this.microphoneBtn.classList.remove("disabled");
|
||||||
@ -171,7 +172,7 @@ export class MediaManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async disableMicrophone() {
|
public async disableMicrophone() {
|
||||||
this.microphoneClose.style.display = "block";
|
this.microphoneClose.style.display = "block";
|
||||||
this.microphone.style.display = "none";
|
this.microphone.style.display = "none";
|
||||||
this.microphoneBtn.classList.add("disabled");
|
this.microphoneBtn.classList.add("disabled");
|
||||||
@ -245,15 +246,11 @@ export class MediaManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _startScreenCapture() {
|
private _startScreenCapture() {
|
||||||
// getDisplayMedia was moved to mediaDevices in 2018. Typescript definitions are not up to date yet.
|
if (navigator.getDisplayMedia) {
|
||||||
// See: https://github.com/w3c/mediacapture-screen-share/pull/86
|
return navigator.getDisplayMedia({video: true});
|
||||||
// https://github.com/microsoft/TypeScript/issues/31821
|
} else if (navigator.mediaDevices.getDisplayMedia) {
|
||||||
if ((navigator as any).getDisplayMedia) { // eslint-disable-line @typescript-eslint/no-explicit-any
|
return navigator.mediaDevices.getDisplayMedia({video: true});
|
||||||
return (navigator as any).getDisplayMedia({video: true}); // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
||||||
} else if ((navigator.mediaDevices as any).getDisplayMedia) { // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
||||||
return (navigator.mediaDevices as any).getDisplayMedia({video: true}); // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
||||||
} else {
|
} else {
|
||||||
//return navigator.mediaDevices.getUserMedia(({video: {mediaSource: 'screen'}} as any));
|
|
||||||
return new Promise((resolve, reject) => { // eslint-disable-line no-unused-vars
|
return new Promise((resolve, reject) => { // eslint-disable-line no-unused-vars
|
||||||
reject("error sharing screen");
|
reject("error sharing screen");
|
||||||
});
|
});
|
||||||
@ -336,12 +333,6 @@ export class MediaManager {
|
|||||||
return this.getCamera();
|
return this.getCamera();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param userId
|
|
||||||
* @param reportCallBack
|
|
||||||
* @param userName
|
|
||||||
*/
|
|
||||||
addActiveVideo(userId: string, reportCallBack: ReportCallback|undefined, userName: string = ""){
|
addActiveVideo(userId: string, reportCallBack: ReportCallback|undefined, userName: string = ""){
|
||||||
this.webrtcInAudio.play();
|
this.webrtcInAudio.play();
|
||||||
|
|
||||||
@ -373,13 +364,8 @@ export class MediaManager {
|
|||||||
|
|
||||||
this.remoteVideo.set(userId, this.getElementByIdOrFail<HTMLVideoElement>(userId));
|
this.remoteVideo.set(userId, this.getElementByIdOrFail<HTMLVideoElement>(userId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param userId
|
|
||||||
*/
|
|
||||||
addScreenSharingActiveVideo(userId: string, divImportance: DivImportance = DivImportance.Important){
|
addScreenSharingActiveVideo(userId: string, divImportance: DivImportance = DivImportance.Important){
|
||||||
//this.webrtcInAudio.play();
|
|
||||||
|
|
||||||
userId = `screen-sharing-${userId}`;
|
userId = `screen-sharing-${userId}`;
|
||||||
const html = `
|
const html = `
|
||||||
@ -392,11 +378,7 @@ export class MediaManager {
|
|||||||
|
|
||||||
this.remoteVideo.set(userId, this.getElementByIdOrFail<HTMLVideoElement>(userId));
|
this.remoteVideo.set(userId, this.getElementByIdOrFail<HTMLVideoElement>(userId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param userId
|
|
||||||
*/
|
|
||||||
disabledMicrophoneByUserId(userId: number){
|
disabledMicrophoneByUserId(userId: number){
|
||||||
const element = document.getElementById(`microphone-${userId}`);
|
const element = document.getElementById(`microphone-${userId}`);
|
||||||
if(!element){
|
if(!element){
|
||||||
@ -404,11 +386,7 @@ export class MediaManager {
|
|||||||
}
|
}
|
||||||
element.classList.add('active')
|
element.classList.add('active')
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param userId
|
|
||||||
*/
|
|
||||||
enabledMicrophoneByUserId(userId: number){
|
enabledMicrophoneByUserId(userId: number){
|
||||||
const element = document.getElementById(`microphone-${userId}`);
|
const element = document.getElementById(`microphone-${userId}`);
|
||||||
if(!element){
|
if(!element){
|
||||||
@ -416,11 +394,7 @@ export class MediaManager {
|
|||||||
}
|
}
|
||||||
element.classList.remove('active')
|
element.classList.remove('active')
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param userId
|
|
||||||
*/
|
|
||||||
disabledVideoByUserId(userId: number) {
|
disabledVideoByUserId(userId: number) {
|
||||||
let element = document.getElementById(`${userId}`);
|
let element = document.getElementById(`${userId}`);
|
||||||
if (element) {
|
if (element) {
|
||||||
@ -431,11 +405,7 @@ export class MediaManager {
|
|||||||
element.style.display = "block";
|
element.style.display = "block";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param userId
|
|
||||||
*/
|
|
||||||
enabledVideoByUserId(userId: number){
|
enabledVideoByUserId(userId: number){
|
||||||
let element = document.getElementById(`${userId}`);
|
let element = document.getElementById(`${userId}`);
|
||||||
if(element){
|
if(element){
|
||||||
@ -447,11 +417,6 @@ export class MediaManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param userId
|
|
||||||
* @param stream
|
|
||||||
*/
|
|
||||||
addStreamRemoteVideo(userId: string, stream : MediaStream){
|
addStreamRemoteVideo(userId: string, stream : MediaStream){
|
||||||
const remoteVideo = this.remoteVideo.get(userId);
|
const remoteVideo = this.remoteVideo.get(userId);
|
||||||
if (remoteVideo === undefined) {
|
if (remoteVideo === undefined) {
|
||||||
@ -468,11 +433,7 @@ export class MediaManager {
|
|||||||
|
|
||||||
this.addStreamRemoteVideo(`screen-sharing-${userId}`, stream);
|
this.addStreamRemoteVideo(`screen-sharing-${userId}`, stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param userId
|
|
||||||
*/
|
|
||||||
removeActiveVideo(userId: string){
|
removeActiveVideo(userId: string){
|
||||||
layoutManager.remove(userId);
|
layoutManager.remove(userId);
|
||||||
this.remoteVideo.delete(userId);
|
this.remoteVideo.delete(userId);
|
||||||
@ -522,11 +483,7 @@ export class MediaManager {
|
|||||||
const connnectingSpinnerDiv = element.getElementsByClassName('connecting-spinner').item(0) as HTMLDivElement|null;
|
const connnectingSpinnerDiv = element.getElementsByClassName('connecting-spinner').item(0) as HTMLDivElement|null;
|
||||||
return connnectingSpinnerDiv;
|
return connnectingSpinnerDiv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param str
|
|
||||||
*/
|
|
||||||
private getColorByString(str: String) : String|null {
|
private getColorByString(str: String) : String|null {
|
||||||
let hash = 0;
|
let hash = 0;
|
||||||
if (str.length === 0) return null;
|
if (str.length === 0) return null;
|
||||||
|
@ -10,12 +10,9 @@ import {FourOFourScene} from "./Phaser/Reconnecting/FourOFourScene";
|
|||||||
import WebGLRenderer = Phaser.Renderer.WebGL.WebGLRenderer;
|
import WebGLRenderer = Phaser.Renderer.WebGL.WebGLRenderer;
|
||||||
import {OutlinePipeline} from "./Phaser/Shaders/OutlinePipeline";
|
import {OutlinePipeline} from "./Phaser/Shaders/OutlinePipeline";
|
||||||
import {CustomizeScene} from "./Phaser/Login/CustomizeScene";
|
import {CustomizeScene} from "./Phaser/Login/CustomizeScene";
|
||||||
import {CoWebsiteManager} from "./WebRtc/CoWebsiteManager";
|
|
||||||
import {gameManager} from "./Phaser/Game/GameManager";
|
|
||||||
import {ResizableScene} from "./Phaser/Login/ResizableScene";
|
import {ResizableScene} from "./Phaser/Login/ResizableScene";
|
||||||
import {EntryScene} from "./Phaser/Login/EntryScene";
|
import {EntryScene} from "./Phaser/Login/EntryScene";
|
||||||
|
import {coWebsiteManager} from "./WebRtc/CoWebsiteManager";
|
||||||
//CoWebsiteManager.loadCoWebsite('https://thecodingmachine.com');
|
|
||||||
|
|
||||||
// Load Jitsi if the environment variable is set.
|
// Load Jitsi if the environment variable is set.
|
||||||
if (JITSI_URL) {
|
if (JITSI_URL) {
|
||||||
@ -24,7 +21,7 @@ if (JITSI_URL) {
|
|||||||
document.head.appendChild(jitsiScript);
|
document.head.appendChild(jitsiScript);
|
||||||
}
|
}
|
||||||
|
|
||||||
const {width, height} = CoWebsiteManager.getGameSize();
|
const {width, height} = coWebsiteManager.getGameSize();
|
||||||
|
|
||||||
const config: GameConfig = {
|
const config: GameConfig = {
|
||||||
title: "WorkAdventure",
|
title: "WorkAdventure",
|
||||||
@ -53,8 +50,7 @@ cypressAsserter.gameStarted();
|
|||||||
const game = new Phaser.Game(config);
|
const game = new Phaser.Game(config);
|
||||||
|
|
||||||
window.addEventListener('resize', function (event) {
|
window.addEventListener('resize', function (event) {
|
||||||
const {width, height} = CoWebsiteManager.getGameSize();
|
const {width, height} = coWebsiteManager.getGameSize();
|
||||||
|
|
||||||
game.scale.resize(width / RESOLUTION, height / RESOLUTION);
|
game.scale.resize(width / RESOLUTION, height / RESOLUTION);
|
||||||
|
|
||||||
// Let's trigger the onResize method of any active scene that is a ResizableScene
|
// Let's trigger the onResize method of any active scene that is a ResizableScene
|
||||||
@ -64,8 +60,7 @@ window.addEventListener('resize', function (event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
CoWebsiteManager.onStateChange(() => {
|
coWebsiteManager.onStateChange(() => {
|
||||||
const {width, height} = CoWebsiteManager.getGameSize();
|
const {width, height} = coWebsiteManager.getGameSize();
|
||||||
|
|
||||||
game.scale.resize(width / RESOLUTION, height / RESOLUTION);
|
game.scale.resize(width / RESOLUTION, height / RESOLUTION);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user