Merge branch 'develop' of github.com:thecodingmachine/workadventure into metadataScriptingApi
This commit is contained in:
commit
2ee62c9e9e
@ -10,6 +10,8 @@ START_ROOM_URL=/_/global/maps.workadventure.localhost/Floor0/floor0.json
|
|||||||
# If you are using Coturn, this is the value of the "static-auth-secret" parameter in your coturn config file.
|
# If you are using Coturn, this is the value of the "static-auth-secret" parameter in your coturn config file.
|
||||||
# Keep empty if you are sharing hard coded / clear text credentials.
|
# Keep empty if you are sharing hard coded / clear text credentials.
|
||||||
TURN_STATIC_AUTH_SECRET=
|
TURN_STATIC_AUTH_SECRET=
|
||||||
|
DISABLE_NOTIFICATIONS=true
|
||||||
|
SKIP_RENDER_OPTIMIZATIONS=false
|
||||||
|
|
||||||
# The email address used by Let's encrypt to send renewal warnings (compulsory)
|
# The email address used by Let's encrypt to send renewal warnings (compulsory)
|
||||||
ACME_EMAIL=
|
ACME_EMAIL=
|
||||||
|
30
.github/workflows/build-and-deploy.yml
vendored
30
.github/workflows/build-and-deploy.yml
vendored
@ -2,7 +2,7 @@ name: Build, push and deploy Docker image
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branch: [master]
|
branches: [master]
|
||||||
release:
|
release:
|
||||||
types: [created]
|
types: [created]
|
||||||
pull_request:
|
pull_request:
|
||||||
@ -16,7 +16,7 @@ env:
|
|||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
build-front:
|
build-front:
|
||||||
if: ${{ github.event.release || github.event.push || contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
if: ${{ github.event_name == 'push' || github.event_name == 'release' || github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@ -36,11 +36,11 @@ jobs:
|
|||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
repository: thecodingmachine/workadventure-front
|
repository: thecodingmachine/workadventure-front
|
||||||
tags: ${{ github.event.pull_request && env.GITHUB_HEAD_REF_SLUG || github.event.release && env.GITHUB_REF_SLUG || 'master' }}
|
tags: ${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }}
|
||||||
add_git_labels: true
|
add_git_labels: true
|
||||||
|
|
||||||
build-back:
|
build-back:
|
||||||
if: ${{ github.event.release || github.event.push || contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
if: ${{ github.event_name == 'push' || github.event_name == 'release' || github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@ -59,11 +59,11 @@ jobs:
|
|||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
repository: thecodingmachine/workadventure-back
|
repository: thecodingmachine/workadventure-back
|
||||||
tags: ${{ github.event.pull_request && env.GITHUB_HEAD_REF_SLUG || github.event.release && env.GITHUB_REF_SLUG || 'master' }}
|
tags: ${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }}
|
||||||
add_git_labels: true
|
add_git_labels: true
|
||||||
|
|
||||||
build-pusher:
|
build-pusher:
|
||||||
if: ${{ github.event.release || github.event.push || contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
if: ${{ github.event_name == 'push' || github.event_name == 'release' || github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@ -82,11 +82,11 @@ jobs:
|
|||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
repository: thecodingmachine/workadventure-pusher
|
repository: thecodingmachine/workadventure-pusher
|
||||||
tags: ${{ github.event.pull_request && env.GITHUB_HEAD_REF_SLUG || github.event.release && env.GITHUB_REF_SLUG || 'master' }}
|
tags: ${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }}
|
||||||
add_git_labels: true
|
add_git_labels: true
|
||||||
|
|
||||||
build-uploader:
|
build-uploader:
|
||||||
if: ${{ github.event.release || github.event.push || contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
if: ${{ github.event_name == 'push' || github.event_name == 'release' || github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@ -105,11 +105,11 @@ jobs:
|
|||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
repository: thecodingmachine/workadventure-uploader
|
repository: thecodingmachine/workadventure-uploader
|
||||||
tags: ${{ github.event.pull_request && env.GITHUB_HEAD_REF_SLUG || github.event.release && env.GITHUB_REF_SLUG || 'master' }}
|
tags: ${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }}
|
||||||
add_git_labels: true
|
add_git_labels: true
|
||||||
|
|
||||||
build-maps:
|
build-maps:
|
||||||
if: ${{ github.event.release || github.event.push || contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
if: ${{ github.event_name == 'push' || github.event_name == 'release' || github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
@ -129,7 +129,7 @@ jobs:
|
|||||||
username: ${{ secrets.DOCKER_USERNAME }}
|
username: ${{ secrets.DOCKER_USERNAME }}
|
||||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||||
repository: thecodingmachine/workadventure-maps
|
repository: thecodingmachine/workadventure-maps
|
||||||
tags: ${{ github.event.pull_request && env.GITHUB_HEAD_REF_SLUG || github.event.release && env.GITHUB_REF_SLUG || 'master' }}
|
tags: ${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }}
|
||||||
add_git_labels: true
|
add_git_labels: true
|
||||||
|
|
||||||
deeploy:
|
deeploy:
|
||||||
@ -140,7 +140,7 @@ jobs:
|
|||||||
- build-maps
|
- build-maps
|
||||||
- build-uploader
|
- build-uploader
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: ${{ github.event.push || contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
if: ${{ github.event_name == 'push' || github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'deploy') }}
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
@ -158,13 +158,13 @@ jobs:
|
|||||||
JITSI_URL: ${{ secrets.JITSI_URL }}
|
JITSI_URL: ${{ secrets.JITSI_URL }}
|
||||||
SECRET_JITSI_KEY: ${{ secrets.SECRET_JITSI_KEY }}
|
SECRET_JITSI_KEY: ${{ secrets.SECRET_JITSI_KEY }}
|
||||||
TURN_STATIC_AUTH_SECRET: ${{ secrets.TURN_STATIC_AUTH_SECRET }}
|
TURN_STATIC_AUTH_SECRET: ${{ secrets.TURN_STATIC_AUTH_SECRET }}
|
||||||
DEPLOY_REF: ${{ github.event.pull_request && env.GITHUB_HEAD_REF_SLUG || 'master' }}
|
DEPLOY_REF: ${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }}
|
||||||
with:
|
with:
|
||||||
namespace: workadventure-${{ github.event.pull_request && env.GITHUB_HEAD_REF_SLUG || 'master' }}
|
namespace: workadventure-${{ github.event_name == 'pull_request' && env.GITHUB_HEAD_REF_SLUG || env.GITHUB_REF_SLUG }}
|
||||||
|
|
||||||
- name: Add a comment in PR
|
- name: Add a comment in PR
|
||||||
uses: unsplash/comment-on-pr@v1.2.0
|
uses: unsplash/comment-on-pr@v1.2.0
|
||||||
if: ${{ github.event.pull_request }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
with:
|
||||||
|
2
.github/workflows/continuous_integration.yml
vendored
2
.github/workflows/continuous_integration.yml
vendored
@ -49,7 +49,7 @@ jobs:
|
|||||||
- name: "Build"
|
- name: "Build"
|
||||||
run: yarn run build
|
run: yarn run build
|
||||||
env:
|
env:
|
||||||
API_URL: "localhost:8080"
|
PUSHER_URL: "//localhost:8080"
|
||||||
working-directory: "front"
|
working-directory: "front"
|
||||||
|
|
||||||
- name: "Lint"
|
- name: "Lint"
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
local env = std.extVar("env"),
|
local env = std.extVar("env"),
|
||||||
local namespace = env.DEPLOY_REF,
|
local namespace = env.DEPLOY_REF,
|
||||||
local tag = namespace,
|
local tag = namespace,
|
||||||
local url = if namespace == "master" then "workadventu.re" else namespace+".test.workadventu.re",
|
local url = namespace+".test.workadventu.re",
|
||||||
// develop branch does not use admin because of issue with SSL certificate of admin as of now.
|
// develop branch does not use admin because of issue with SSL certificate of admin as of now.
|
||||||
local adminUrl = if namespace == "master" || namespace == "develop" || std.startsWith(namespace, "admin") then "https://"+url else null,
|
local adminUrl = if namespace == "master" || namespace == "develop" || std.startsWith(namespace, "admin") then "https://"+url else null,
|
||||||
"$schema": "https://raw.githubusercontent.com/thecodingmachine/deeployer/master/deeployer.schema.json",
|
"$schema": "https://raw.githubusercontent.com/thecodingmachine/deeployer/master/deeployer.schema.json",
|
||||||
@ -25,10 +25,7 @@
|
|||||||
"TURN_STATIC_AUTH_SECRET": env.TURN_STATIC_AUTH_SECRET,
|
"TURN_STATIC_AUTH_SECRET": env.TURN_STATIC_AUTH_SECRET,
|
||||||
} + (if adminUrl != null then {
|
} + (if adminUrl != null then {
|
||||||
"ADMIN_API_URL": adminUrl,
|
"ADMIN_API_URL": adminUrl,
|
||||||
} else {}) + if namespace != "master" then {
|
} else {})
|
||||||
// Absolutely ugly WorkAround to circumvent broken certificates on the K8S test cluster. Don't do this in production kids!
|
|
||||||
"NODE_TLS_REJECT_UNAUTHORIZED": "0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"back2": {
|
"back2": {
|
||||||
"image": "thecodingmachine/workadventure-back:"+tag,
|
"image": "thecodingmachine/workadventure-back:"+tag,
|
||||||
@ -47,10 +44,7 @@
|
|||||||
"TURN_STATIC_AUTH_SECRET": env.TURN_STATIC_AUTH_SECRET,
|
"TURN_STATIC_AUTH_SECRET": env.TURN_STATIC_AUTH_SECRET,
|
||||||
} + (if adminUrl != null then {
|
} + (if adminUrl != null then {
|
||||||
"ADMIN_API_URL": adminUrl,
|
"ADMIN_API_URL": adminUrl,
|
||||||
} else {}) + if namespace != "master" then {
|
} else {})
|
||||||
// Absolutely ugly WorkAround to circumvent broken certificates on the K8S test cluster. Don't do this in production kids!
|
|
||||||
"NODE_TLS_REJECT_UNAUTHORIZED": "0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"pusher": {
|
"pusher": {
|
||||||
"replicas": 2,
|
"replicas": 2,
|
||||||
@ -69,10 +63,7 @@
|
|||||||
"SECRET_JITSI_KEY": env.SECRET_JITSI_KEY,
|
"SECRET_JITSI_KEY": env.SECRET_JITSI_KEY,
|
||||||
} + (if adminUrl != null then {
|
} + (if adminUrl != null then {
|
||||||
"ADMIN_API_URL": adminUrl,
|
"ADMIN_API_URL": adminUrl,
|
||||||
} else {}) + if namespace != "master" then {
|
} else {})
|
||||||
// Absolutely ugly WorkAround to circumvent broken certificates on the K8S test cluster. Don't do this in production kids!
|
|
||||||
"NODE_TLS_REJECT_UNAUTHORIZED": "0"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"front": {
|
"front": {
|
||||||
"image": "thecodingmachine/workadventure-front:"+tag,
|
"image": "thecodingmachine/workadventure-front:"+tag,
|
||||||
|
@ -33,6 +33,8 @@ services:
|
|||||||
STARTUP_COMMAND_1: ./templater.sh
|
STARTUP_COMMAND_1: ./templater.sh
|
||||||
STARTUP_COMMAND_2: yarn install
|
STARTUP_COMMAND_2: yarn install
|
||||||
TURN_SERVER: "turn:localhost:3478,turns:localhost:5349"
|
TURN_SERVER: "turn:localhost:3478,turns:localhost:5349"
|
||||||
|
DISABLE_NOTIFICATIONS: "$DISABLE_NOTIFICATIONS"
|
||||||
|
SKIP_RENDER_OPTIMIZATIONS: "$SKIP_RENDER_OPTIMIZATIONS"
|
||||||
# Use TURN_USER/TURN_PASSWORD if your Coturn server is secured via hard coded credentials.
|
# Use TURN_USER/TURN_PASSWORD if your Coturn server is secured via hard coded credentials.
|
||||||
# Advice: you should instead use Coturn REST API along the TURN_STATIC_AUTH_SECRET in the Back container
|
# Advice: you should instead use Coturn REST API along the TURN_STATIC_AUTH_SECRET in the Back container
|
||||||
TURN_USER: ""
|
TURN_USER: ""
|
||||||
|
@ -33,6 +33,8 @@ services:
|
|||||||
STARTUP_COMMAND_2: yarn install
|
STARTUP_COMMAND_2: yarn install
|
||||||
STUN_SERVER: "stun:stun.l.google.com:19302"
|
STUN_SERVER: "stun:stun.l.google.com:19302"
|
||||||
TURN_SERVER: "turn:coturn.workadventure.localhost:3478,turns:coturn.workadventure.localhost:5349"
|
TURN_SERVER: "turn:coturn.workadventure.localhost:3478,turns:coturn.workadventure.localhost:5349"
|
||||||
|
DISABLE_NOTIFICATIONS: "$DISABLE_NOTIFICATIONS"
|
||||||
|
SKIP_RENDER_OPTIMIZATIONS: "$SKIP_RENDER_OPTIMIZATIONS"
|
||||||
# Use TURN_USER/TURN_PASSWORD if your Coturn server is secured via hard coded credentials.
|
# Use TURN_USER/TURN_PASSWORD if your Coturn server is secured via hard coded credentials.
|
||||||
# Advice: you should instead use Coturn REST API along the TURN_STATIC_AUTH_SECRET in the Back container
|
# Advice: you should instead use Coturn REST API along the TURN_STATIC_AUTH_SECRET in the Back container
|
||||||
TURN_USER: ""
|
TURN_USER: ""
|
||||||
|
@ -25,6 +25,15 @@
|
|||||||
],
|
],
|
||||||
"rules": {
|
"rules": {
|
||||||
"no-unused-vars": "off",
|
"no-unused-vars": "off",
|
||||||
"@typescript-eslint/no-explicit-any": "error"
|
"@typescript-eslint/no-explicit-any": "error",
|
||||||
|
|
||||||
|
// TODO: remove those ignored rules and write a stronger code!
|
||||||
|
"@typescript-eslint/no-floating-promises": "off",
|
||||||
|
"@typescript-eslint/no-unsafe-call": "off",
|
||||||
|
"@typescript-eslint/restrict-plus-operands": "off",
|
||||||
|
"@typescript-eslint/no-unsafe-assignment": "off",
|
||||||
|
"@typescript-eslint/no-unsafe-return": "off",
|
||||||
|
"@typescript-eslint/no-unsafe-member-access": "off",
|
||||||
|
"@typescript-eslint/restrict-template-expressions": "off"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
front/dist/index.tmpl.html
vendored
2
front/dist/index.tmpl.html
vendored
@ -38,6 +38,8 @@
|
|||||||
<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">
|
<div id="game" class="game">
|
||||||
|
<div id="svelte-overlay">
|
||||||
|
</div>
|
||||||
<div id="game-overlay" class="game-overlay">
|
<div id="game-overlay" class="game-overlay">
|
||||||
<div id="main-section" class="main-section">
|
<div id="main-section" class="main-section">
|
||||||
</div>
|
</div>
|
||||||
|
BIN
front/dist/resources/logos/logo-WA-min.png
vendored
Normal file
BIN
front/dist/resources/logos/logo-WA-min.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
@ -4,25 +4,34 @@
|
|||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"license": "SEE LICENSE IN LICENSE.txt",
|
"license": "SEE LICENSE IN LICENSE.txt",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@tsconfig/svelte": "^1.0.10",
|
||||||
"@types/google-protobuf": "^3.7.3",
|
"@types/google-protobuf": "^3.7.3",
|
||||||
"@types/jasmine": "^3.5.10",
|
"@types/jasmine": "^3.5.10",
|
||||||
|
"@types/mini-css-extract-plugin": "^1.4.3",
|
||||||
|
"@types/node": "^15.3.0",
|
||||||
"@types/quill": "^1.3.7",
|
"@types/quill": "^1.3.7",
|
||||||
"@typescript-eslint/eslint-plugin": "^2.26.0",
|
"@types/webpack-dev-server": "^3.11.4",
|
||||||
"@typescript-eslint/parser": "^2.26.0",
|
"@typescript-eslint/eslint-plugin": "^4.23.0",
|
||||||
"css-loader": "^5.1.3",
|
"@typescript-eslint/parser": "^4.23.0",
|
||||||
"eslint": "^6.8.0",
|
"css-loader": "^5.2.4",
|
||||||
"html-webpack-plugin": "^4.3.0",
|
"eslint": "^7.26.0",
|
||||||
|
"fork-ts-checker-webpack-plugin": "^6.2.9",
|
||||||
|
"html-webpack-plugin": "^5.3.1",
|
||||||
"jasmine": "^3.5.0",
|
"jasmine": "^3.5.0",
|
||||||
"mini-css-extract-plugin": "^1.3.9",
|
"mini-css-extract-plugin": "^1.6.0",
|
||||||
"sass": "^1.32.8",
|
"node-polyfill-webpack-plugin": "^1.1.2",
|
||||||
"sass-loader": "10.1.1",
|
"sass": "^1.32.12",
|
||||||
"ts-loader": "^6.2.2",
|
"sass-loader": "^11.1.0",
|
||||||
"ts-node": "^8.10.2",
|
"svelte": "^3.38.2",
|
||||||
"typescript": "^3.8.3",
|
"svelte-loader": "^3.1.1",
|
||||||
"webpack": "^4.42.1",
|
"svelte-preprocess": "^4.7.3",
|
||||||
"webpack-cli": "^3.3.11",
|
"ts-loader": "^9.1.2",
|
||||||
"webpack-dev-server": "^3.10.3",
|
"ts-node": "^9.1.1",
|
||||||
"webpack-merge": "^4.2.2"
|
"tsconfig-paths": "^3.9.0",
|
||||||
|
"typescript": "^4.2.4",
|
||||||
|
"webpack": "^5.37.0",
|
||||||
|
"webpack-cli": "^4.7.0",
|
||||||
|
"webpack-dev-server": "^3.11.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/simple-peer": "^9.6.0",
|
"@types/simple-peer": "^9.6.0",
|
||||||
@ -36,13 +45,12 @@
|
|||||||
"quill": "1.3.6",
|
"quill": "1.3.6",
|
||||||
"rxjs": "^6.6.3",
|
"rxjs": "^6.6.3",
|
||||||
"simple-peer": "^9.6.2",
|
"simple-peer": "^9.6.2",
|
||||||
"socket.io-client": "^2.3.0",
|
"socket.io-client": "^2.3.0"
|
||||||
"webpack-require-http": "^0.4.3"
|
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "webpack-dev-server --open",
|
"start": "TS_NODE_PROJECT=\"tsconfig-for-webpack.json\" webpack serve --open",
|
||||||
"build": "webpack --config webpack.prod.js",
|
"build": "TS_NODE_PROJECT=\"tsconfig-for-webpack.json\" NODE_ENV=production webpack",
|
||||||
"test": "ts-node node_modules/jasmine/bin/jasmine --config=jasmine.json",
|
"test": "TS_NODE_PROJECT=\"tsconfig-for-jasmine.json\" ts-node node_modules/jasmine/bin/jasmine --config=jasmine.json",
|
||||||
"lint": "node_modules/.bin/eslint src/ . --ext .ts",
|
"lint": "node_modules/.bin/eslint src/ . --ext .ts",
|
||||||
"fix": "node_modules/.bin/eslint --fix src/ . --ext .ts"
|
"fix": "node_modules/.bin/eslint --fix src/ . --ext .ts"
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import {HtmlUtils} from "../WebRtc/HtmlUtils";
|
import {HtmlUtils} from "../WebRtc/HtmlUtils";
|
||||||
import {UserInputManager} from "../Phaser/UserInput/UserInputManager";
|
import type {UserInputManager} from "../Phaser/UserInput/UserInputManager";
|
||||||
import {RoomConnection} from "../Connexion/RoomConnection";
|
import type {RoomConnection} from "../Connexion/RoomConnection";
|
||||||
import {PlayGlobalMessageInterface} from "../Connexion/ConnexionModels";
|
import type {PlayGlobalMessageInterface} from "../Connexion/ConnexionModels";
|
||||||
import {AdminMessageEventTypes} from "../Connexion/AdminMessagesService";
|
import {AdminMessageEventTypes} from "../Connexion/AdminMessagesService";
|
||||||
|
|
||||||
export const CLASS_CONSOLE_MESSAGE = 'main-console';
|
export const CLASS_CONSOLE_MESSAGE = 'main-console';
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import {HtmlUtils} from "./../WebRtc/HtmlUtils";
|
import {HtmlUtils} from "./../WebRtc/HtmlUtils";
|
||||||
import {AUDIO_TYPE, MESSAGE_TYPE} from "./ConsoleGlobalMessageManager";
|
import {AUDIO_TYPE, MESSAGE_TYPE} from "./ConsoleGlobalMessageManager";
|
||||||
import {PUSHER_URL, UPLOADER_URL} from "../Enum/EnvironmentVariable";
|
import {PUSHER_URL, UPLOADER_URL} from "../Enum/EnvironmentVariable";
|
||||||
import {RoomConnection} from "../Connexion/RoomConnection";
|
import type {RoomConnection} from "../Connexion/RoomConnection";
|
||||||
import {PlayGlobalMessageInterface} from "../Connexion/ConnexionModels";
|
import type {PlayGlobalMessageInterface} from "../Connexion/ConnexionModels";
|
||||||
|
|
||||||
export class GlobalMessageManager {
|
export class GlobalMessageManager {
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {TypeMessageInterface} from "./UserMessageManager";
|
import type {TypeMessageInterface} from "./UserMessageManager";
|
||||||
import {HtmlUtils} from "../WebRtc/HtmlUtils";
|
import {HtmlUtils} from "../WebRtc/HtmlUtils";
|
||||||
|
|
||||||
let modalTimeOut : NodeJS.Timeout;
|
let modalTimeOut : NodeJS.Timeout;
|
||||||
@ -86,4 +86,4 @@ export class Banned extends TypeMessageExt {
|
|||||||
showMessage(message: string){
|
showMessage(message: string){
|
||||||
super.showMessage(message, false);
|
super.showMessage(message, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
|
|
||||||
|
|
||||||
import { ButtonClickedEvent } from './ButtonClickedEvent';
|
import type { ButtonClickedEvent } from './ButtonClickedEvent';
|
||||||
import { ChatEvent } from './ChatEvent';
|
import type { ChatEvent } from './ChatEvent';
|
||||||
import { ClosePopupEvent } from './ClosePopupEvent';
|
import type { ClosePopupEvent } from './ClosePopupEvent';
|
||||||
import { EnterLeaveEvent } from './EnterLeaveEvent';
|
import type { EnterLeaveEvent } from './EnterLeaveEvent';
|
||||||
import { GoToPageEvent } from './GoToPageEvent';
|
import type { GoToPageEvent } from './GoToPageEvent';
|
||||||
import { OpenCoWebSiteEvent } from './OpenCoWebSiteEvent';
|
import type { OpenCoWebSiteEvent } from './OpenCoWebSiteEvent';
|
||||||
import { OpenPopupEvent } from './OpenPopupEvent';
|
import type { OpenPopupEvent } from './OpenPopupEvent';
|
||||||
import { OpenTabEvent } from './OpenTabEvent';
|
import type { OpenTabEvent } from './OpenTabEvent';
|
||||||
import { UserInputChatEvent } from './UserInputChatEvent';
|
import type { UserInputChatEvent } from './UserInputChatEvent';
|
||||||
import { LayerEvent } from './LayerEvent';
|
import type { LayerEvent } from './LayerEvent';
|
||||||
import { SetPropertyEvent } from "./setPropertyEvent";
|
import type { SetPropertyEvent } from "./setPropertyEvent";
|
||||||
|
|
||||||
|
|
||||||
export interface TypedMessageEvent<T> extends MessageEvent {
|
export interface TypedMessageEvent<T> extends MessageEvent {
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
import { Subject } from "rxjs";
|
import { Subject } from "rxjs";
|
||||||
import { ChatEvent, isChatEvent } from "./Events/ChatEvent";
|
import { ChatEvent, isChatEvent } from "./Events/ChatEvent";
|
||||||
import * as crypto from "crypto";
|
|
||||||
import { HtmlUtils } from "../WebRtc/HtmlUtils";
|
import { HtmlUtils } from "../WebRtc/HtmlUtils";
|
||||||
import { EnterLeaveEvent } from "./Events/EnterLeaveEvent";
|
import type { EnterLeaveEvent } from "./Events/EnterLeaveEvent";
|
||||||
import { isOpenPopupEvent, OpenPopupEvent } from "./Events/OpenPopupEvent";
|
import { isOpenPopupEvent, OpenPopupEvent } from "./Events/OpenPopupEvent";
|
||||||
import { isOpenTabEvent, OpenTabEvent } from "./Events/OpenTabEvent";
|
import { isOpenTabEvent, OpenTabEvent } from "./Events/OpenTabEvent";
|
||||||
import { ButtonClickedEvent } from "./Events/ButtonClickedEvent";
|
import type { ButtonClickedEvent } from "./Events/ButtonClickedEvent";
|
||||||
import { ClosePopupEvent, isClosePopupEvent } from "./Events/ClosePopupEvent";
|
import { ClosePopupEvent, isClosePopupEvent } from "./Events/ClosePopupEvent";
|
||||||
import { scriptUtils } from "./ScriptUtils";
|
import { scriptUtils } from "./ScriptUtils";
|
||||||
import { GoToPageEvent, isGoToPageEvent } from "./Events/GoToPageEvent";
|
import { GoToPageEvent, isGoToPageEvent } from "./Events/GoToPageEvent";
|
||||||
import { isOpenCoWebsite, OpenCoWebSiteEvent } from "./Events/OpenCoWebSiteEvent";
|
import { isOpenCoWebsite, OpenCoWebSiteEvent } from "./Events/OpenCoWebSiteEvent";
|
||||||
import { IframeEventMap, IframeEvent, IframeResponseEvent, IframeResponseEventMap, isIframeEventWrapper, TypedMessageEvent } from "./Events/IframeEvent";
|
import { IframeEventMap, IframeEvent, IframeResponseEvent, IframeResponseEventMap, isIframeEventWrapper, TypedMessageEvent } from "./Events/IframeEvent";
|
||||||
import { UserInputChatEvent } from "./Events/UserInputChatEvent";
|
import type { UserInputChatEvent } from "./Events/UserInputChatEvent";
|
||||||
import { isLayerEvent, LayerEvent } from "./Events/LayerEvent";
|
import { isLayerEvent, LayerEvent } from "./Events/LayerEvent";
|
||||||
import { isSetPropertyEvent, SetPropertyEvent} from "./Events/setPropertyEvent";
|
import { isSetPropertyEvent, SetPropertyEvent} from "./Events/setPropertyEvent";
|
||||||
|
|
||||||
@ -193,7 +192,7 @@ class IframeListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private getIFrameId(scriptUrl: string): string {
|
private getIFrameId(scriptUrl: string): string {
|
||||||
return 'script' + crypto.createHash('md5').update(scriptUrl).digest("hex");
|
return 'script' + btoa(scriptUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
unregisterScript(scriptUrl: string): void {
|
unregisterScript(scriptUrl: string): void {
|
||||||
|
11
front/src/Components/App.svelte
Normal file
11
front/src/Components/App.svelte
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<script lang="typescript">
|
||||||
|
import MenuIcon from "./Menu/MenuIcon.svelte";
|
||||||
|
import {menuIconVisible} from "../Stores/MenuStore";
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<!-- {#if $menuIconVisible}
|
||||||
|
<MenuIcon />
|
||||||
|
{/if} -->
|
||||||
|
</div>
|
33
front/src/Components/Menu/MenuIcon.svelte
Normal file
33
front/src/Components/Menu/MenuIcon.svelte
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<script lang="typescript">
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<main class="menuIcon">
|
||||||
|
<section>
|
||||||
|
<button>
|
||||||
|
<img src="/static/images/menu.svg" alt="Open menu">
|
||||||
|
</button>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.menuIcon button {
|
||||||
|
background-color: black;
|
||||||
|
color: white;
|
||||||
|
border-radius: 7px;
|
||||||
|
padding: 2px 8px;
|
||||||
|
img {
|
||||||
|
width: 14px;
|
||||||
|
padding-top: 0;
|
||||||
|
/*cursor: url('/resources/logos/cursor_pointer.png'), pointer;*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.menuIcon section {
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
@media only screen and (max-height: 700px) {
|
||||||
|
.menuIcon section {
|
||||||
|
margin: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,5 +1,5 @@
|
|||||||
import {Subject} from "rxjs";
|
import {Subject} from "rxjs";
|
||||||
import {BanUserMessage, SendUserMessage} from "../Messages/generated/messages_pb";
|
import type {BanUserMessage, SendUserMessage} from "../Messages/generated/messages_pb";
|
||||||
|
|
||||||
export enum AdminMessageEventTypes {
|
export enum AdminMessageEventTypes {
|
||||||
admin = 'message',
|
admin = 'message',
|
||||||
@ -19,11 +19,11 @@ interface AdminMessageEvent {
|
|||||||
class AdminMessagesService {
|
class AdminMessagesService {
|
||||||
private _messageStream: Subject<AdminMessageEvent> = new Subject();
|
private _messageStream: Subject<AdminMessageEvent> = new Subject();
|
||||||
public messageStream = this._messageStream.asObservable();
|
public messageStream = this._messageStream.asObservable();
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.messageStream.subscribe((event) => console.log('message', event))
|
this.messageStream.subscribe((event) => console.log('message', event))
|
||||||
}
|
}
|
||||||
|
|
||||||
onSendusermessage(message: SendUserMessage|BanUserMessage) {
|
onSendusermessage(message: SendUserMessage|BanUserMessage) {
|
||||||
this._messageStream.next({
|
this._messageStream.next({
|
||||||
type: message.getType() as unknown as AdminMessageEventTypes,
|
type: message.getType() as unknown as AdminMessageEventTypes,
|
||||||
@ -32,4 +32,4 @@ class AdminMessagesService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const adminMessagesService = new AdminMessagesService();
|
export const adminMessagesService = new AdminMessagesService();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Axios from "axios";
|
import Axios from "axios";
|
||||||
import {PUSHER_URL, START_ROOM_URL} from "../Enum/EnvironmentVariable";
|
import {PUSHER_URL, START_ROOM_URL} from "../Enum/EnvironmentVariable";
|
||||||
import {RoomConnection} from "./RoomConnection";
|
import {RoomConnection} from "./RoomConnection";
|
||||||
import {OnConnectInterface, PositionInterface, ViewportInterface} from "./ConnexionModels";
|
import type {OnConnectInterface, PositionInterface, ViewportInterface} from "./ConnexionModels";
|
||||||
import {GameConnexionTypes, urlManager} from "../Url/UrlManager";
|
import {GameConnexionTypes, urlManager} from "../Url/UrlManager";
|
||||||
import {localUserStore} from "./LocalUserStore";
|
import {localUserStore} from "./LocalUserStore";
|
||||||
import {LocalUser} from "./LocalUser";
|
import {LocalUser} from "./LocalUser";
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import {PlayerAnimationDirections} from "../Phaser/Player/Animation";
|
import {PlayerAnimationDirections} from "../Phaser/Player/Animation";
|
||||||
import {UserSimplePeerInterface} from "../WebRtc/SimplePeer";
|
import {UserSimplePeerInterface} from "../WebRtc/SimplePeer";
|
||||||
import {SignalData} from "simple-peer";
|
import type {SignalData} from "simple-peer";
|
||||||
import {RoomConnection} from "./RoomConnection";
|
import type {RoomConnection} from "./RoomConnection";
|
||||||
import {BodyResourceDescriptionInterface} from "../Phaser/Entity/PlayerTextures";
|
import type {BodyResourceDescriptionInterface} from "../Phaser/Entity/PlayerTextures";
|
||||||
|
|
||||||
export enum EventMessage{
|
export enum EventMessage{
|
||||||
CONNECT = "connect",
|
CONNECT = "connect",
|
||||||
|
@ -27,11 +27,11 @@ import {
|
|||||||
SendJitsiJwtMessage,
|
SendJitsiJwtMessage,
|
||||||
CharacterLayerMessage,
|
CharacterLayerMessage,
|
||||||
PingMessage,
|
PingMessage,
|
||||||
SendUserMessage,
|
SendUserMessage,
|
||||||
BanUserMessage
|
BanUserMessage
|
||||||
} from "../Messages/generated/messages_pb"
|
} from "../Messages/generated/messages_pb"
|
||||||
|
|
||||||
import {UserSimplePeerInterface} from "../WebRtc/SimplePeer";
|
import type {UserSimplePeerInterface} from "../WebRtc/SimplePeer";
|
||||||
import Direction = PositionMessage.Direction;
|
import Direction = PositionMessage.Direction;
|
||||||
import {ProtobufClientUtils} from "../Network/ProtobufClientUtils";
|
import {ProtobufClientUtils} from "../Network/ProtobufClientUtils";
|
||||||
import {
|
import {
|
||||||
@ -42,7 +42,7 @@ import {
|
|||||||
ViewportInterface, WebRtcDisconnectMessageInterface,
|
ViewportInterface, WebRtcDisconnectMessageInterface,
|
||||||
WebRtcSignalReceivedMessageInterface,
|
WebRtcSignalReceivedMessageInterface,
|
||||||
} from "./ConnexionModels";
|
} from "./ConnexionModels";
|
||||||
import {BodyResourceDescriptionInterface} from "../Phaser/Entity/PlayerTextures";
|
import type {BodyResourceDescriptionInterface} from "../Phaser/Entity/PlayerTextures";
|
||||||
import {adminMessagesService} from "./AdminMessagesService";
|
import {adminMessagesService} from "./AdminMessagesService";
|
||||||
import {worldFullMessageStream} from "./WorldFullMessageStream";
|
import {worldFullMessageStream} from "./WorldFullMessageStream";
|
||||||
import {worldFullWarningStream} from "./WorldFullWarningStream";
|
import {worldFullWarningStream} from "./WorldFullWarningStream";
|
||||||
@ -86,7 +86,7 @@ export class RoomConnection implements RoomConnection {
|
|||||||
url += '&bottom='+Math.floor(viewport.bottom);
|
url += '&bottom='+Math.floor(viewport.bottom);
|
||||||
url += '&left='+Math.floor(viewport.left);
|
url += '&left='+Math.floor(viewport.left);
|
||||||
url += '&right='+Math.floor(viewport.right);
|
url += '&right='+Math.floor(viewport.right);
|
||||||
|
|
||||||
if (typeof companion === 'string') {
|
if (typeof companion === 'string') {
|
||||||
url += '&companion='+encodeURIComponent(companion);
|
url += '&companion='+encodeURIComponent(companion);
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
const DEBUG_MODE: boolean = process.env.DEBUG_MODE == "true";
|
const DEBUG_MODE: boolean = process.env.DEBUG_MODE == "true";
|
||||||
const START_ROOM_URL : string = process.env.START_ROOM_URL || '/_/global/maps.workadventure.localhost/Floor0/floor0.json';
|
const START_ROOM_URL : string = process.env.START_ROOM_URL || '/_/global/maps.workadventure.localhost/Floor0/floor0.json';
|
||||||
// For compatibility reasons with older versions, API_URL is the old host name of PUSHER_URL
|
const PUSHER_URL = process.env.PUSHER_URL || '//pusher.workadventure.localhost';
|
||||||
const PUSHER_URL = process.env.PUSHER_URL || (process.env.API_URL ? '//'+process.env.API_URL : "//pusher.workadventure.localhost");
|
|
||||||
const UPLOADER_URL = process.env.UPLOADER_URL || '//uploader.workadventure.localhost';
|
const UPLOADER_URL = process.env.UPLOADER_URL || '//uploader.workadventure.localhost';
|
||||||
const ADMIN_URL = process.env.ADMIN_URL || "//workadventure.localhost";
|
|
||||||
const STUN_SERVER: string = process.env.STUN_SERVER || "stun:stun.l.google.com:19302";
|
const STUN_SERVER: string = process.env.STUN_SERVER || "stun:stun.l.google.com:19302";
|
||||||
const TURN_SERVER: string = process.env.TURN_SERVER || "";
|
const TURN_SERVER: string = process.env.TURN_SERVER || "";
|
||||||
|
const SKIP_RENDER_OPTIMIZATIONS: boolean = process.env.SKIP_RENDER_OPTIMIZATIONS == "true";
|
||||||
|
const DISABLE_NOTIFICATIONS: boolean = process.env.DISABLE_NOTIFICATIONS == "true";
|
||||||
const TURN_USER: string = process.env.TURN_USER || '';
|
const TURN_USER: string = process.env.TURN_USER || '';
|
||||||
const TURN_PASSWORD: string = process.env.TURN_PASSWORD || '';
|
const TURN_PASSWORD: string = process.env.TURN_PASSWORD || '';
|
||||||
const JITSI_URL : string|undefined = (process.env.JITSI_URL === '') ? undefined : process.env.JITSI_URL;
|
const JITSI_URL : string|undefined = (process.env.JITSI_URL === '') ? undefined : process.env.JITSI_URL;
|
||||||
@ -20,9 +20,10 @@ export const isMobile = ():boolean => ( ( window.innerWidth <= 800 ) || ( window
|
|||||||
export {
|
export {
|
||||||
DEBUG_MODE,
|
DEBUG_MODE,
|
||||||
START_ROOM_URL,
|
START_ROOM_URL,
|
||||||
|
SKIP_RENDER_OPTIMIZATIONS,
|
||||||
|
DISABLE_NOTIFICATIONS,
|
||||||
PUSHER_URL,
|
PUSHER_URL,
|
||||||
UPLOADER_URL,
|
UPLOADER_URL,
|
||||||
ADMIN_URL,
|
|
||||||
POSITION_DELAY,
|
POSITION_DELAY,
|
||||||
MAX_EXTRAPOLATION_TIME,
|
MAX_EXTRAPOLATION_TIME,
|
||||||
STUN_SERVER,
|
STUN_SERVER,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import {PositionMessage} from "../Messages/generated/messages_pb";
|
import {PositionMessage} from "../Messages/generated/messages_pb";
|
||||||
import Direction = PositionMessage.Direction;
|
import Direction = PositionMessage.Direction;
|
||||||
import {PointInterface} from "../Connexion/ConnexionModels";
|
import type {PointInterface} from "../Connexion/ConnexionModels";
|
||||||
|
|
||||||
export class ProtobufClientUtils {
|
export class ProtobufClientUtils {
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import Sprite = Phaser.GameObjects.Sprite;
|
import Sprite = Phaser.GameObjects.Sprite;
|
||||||
import Container = Phaser.GameObjects.Container;
|
import Container = Phaser.GameObjects.Container;
|
||||||
import { lazyLoadCompanionResource } from "./CompanionTexturesLoadingManager";
|
|
||||||
import { PlayerAnimationDirections, PlayerAnimationTypes } from "../Player/Animation";
|
import { PlayerAnimationDirections, PlayerAnimationTypes } from "../Player/Animation";
|
||||||
|
|
||||||
export interface CompanionStatus {
|
export interface CompanionStatus {
|
||||||
@ -25,7 +24,7 @@ export class Companion extends Container {
|
|||||||
|
|
||||||
constructor(scene: Phaser.Scene, x: number, y: number, name: string, texturePromise: Promise<string>) {
|
constructor(scene: Phaser.Scene, x: number, y: number, name: string, texturePromise: Promise<string>) {
|
||||||
super(scene, x + 14, y + 4);
|
super(scene, x + 14, y + 4);
|
||||||
|
|
||||||
this.sprites = new Map<string, Sprite>();
|
this.sprites = new Map<string, Sprite>();
|
||||||
|
|
||||||
this.delta = 0;
|
this.delta = 0;
|
||||||
@ -104,7 +103,7 @@ export class Companion extends Container {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setDepth(this.y);
|
this.setDepth(this.y);
|
||||||
this.playAnimation(this.direction, this.animationType);
|
this.playAnimation(this.direction, this.animationType);
|
||||||
}
|
}
|
||||||
@ -137,7 +136,7 @@ export class Companion extends Container {
|
|||||||
this.getAnimations(resource).forEach(animation => {
|
this.getAnimations(resource).forEach(animation => {
|
||||||
this.scene.anims.create(animation);
|
this.scene.anims.create(animation);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.scene.sys.updateList.add(sprite);
|
this.scene.sys.updateList.add(sprite);
|
||||||
this.sprites.set(resource, sprite);
|
this.sprites.set(resource, sprite);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import VirtualJoystick from 'phaser3-rex-plugins/plugins/virtualjoystick.js';
|
import VirtualJoystick from 'phaser3-rex-plugins/plugins/virtualjoystick.js';
|
||||||
import ScaleManager = Phaser.Scale.ScaleManager;
|
|
||||||
import {waScaleManager} from "../Services/WaScaleManager";
|
import {waScaleManager} from "../Services/WaScaleManager";
|
||||||
|
|
||||||
//the assets were found here: https://hannemann.itch.io/virtual-joystick-pack-free
|
//the assets were found here: https://hannemann.itch.io/virtual-joystick-pack-free
|
||||||
|
@ -17,14 +17,12 @@ export class SoundMeter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private init(context: AudioContext) {
|
private init(context: AudioContext) {
|
||||||
if (this.context === undefined) {
|
this.context = context;
|
||||||
this.context = context;
|
this.analyser = this.context.createAnalyser();
|
||||||
this.analyser = this.context.createAnalyser();
|
|
||||||
|
|
||||||
this.analyser.fftSize = 2048;
|
this.analyser.fftSize = 2048;
|
||||||
const bufferLength = this.analyser.fftSize;
|
const bufferLength = this.analyser.fftSize;
|
||||||
this.dataArray = new Uint8Array(bufferLength);
|
this.dataArray = new Uint8Array(bufferLength);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public connectToSource(stream: MediaStream, context: AudioContext): void
|
public connectToSource(stream: MediaStream, context: AudioContext): void
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Container = Phaser.GameObjects.Container;
|
import Container = Phaser.GameObjects.Container;
|
||||||
import {Scene} from "phaser";
|
import type {Scene} from "phaser";
|
||||||
import GameObject = Phaser.GameObjects.GameObject;
|
import GameObject = Phaser.GameObjects.GameObject;
|
||||||
import Rectangle = Phaser.GameObjects.Rectangle;
|
import Rectangle = Phaser.GameObjects.Rectangle;
|
||||||
|
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
import {ITiledMapObject} from "../Map/ITiledMap";
|
import type {ITiledMapObject} from "../Map/ITiledMap";
|
||||||
import Text = Phaser.GameObjects.Text;
|
import type {GameScene} from "../Game/GameScene";
|
||||||
import {GameScene} from "../Game/GameScene";
|
|
||||||
import TextStyle = Phaser.GameObjects.TextStyle;
|
|
||||||
|
|
||||||
export class TextUtils {
|
export class TextUtils {
|
||||||
public static createTextFromITiledMapObject(scene: GameScene, object: ITiledMapObject): void {
|
public static createTextFromITiledMapObject(scene: GameScene, object: ITiledMapObject): void {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import LoaderPlugin = Phaser.Loader.LoaderPlugin;
|
import LoaderPlugin = Phaser.Loader.LoaderPlugin;
|
||||||
import TextureManager = Phaser.Textures.TextureManager;
|
import type {CharacterTexture} from "../../Connexion/LocalUser";
|
||||||
import {CharacterTexture} from "../../Connexion/LocalUser";
|
|
||||||
import {BodyResourceDescriptionInterface, LAYERS, PLAYER_RESOURCES} from "./PlayerTextures";
|
import {BodyResourceDescriptionInterface, LAYERS, PLAYER_RESOURCES} from "./PlayerTextures";
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import {GameScene} from "../Game/GameScene";
|
import type {GameScene} from "../Game/GameScene";
|
||||||
import {PointInterface} from "../../Connexion/ConnexionModels";
|
import type {PointInterface} from "../../Connexion/ConnexionModels";
|
||||||
import {Character} from "../Entity/Character";
|
import {Character} from "../Entity/Character";
|
||||||
import {PlayerAnimationDirections} from "../Player/Animation";
|
import type {PlayerAnimationDirections} from "../Player/Animation";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing the sprite of a remote player (a player that plays on another computer)
|
* Class representing the sprite of a remote player (a player that plays on another computer)
|
||||||
@ -22,7 +22,7 @@ export class RemotePlayer extends Character {
|
|||||||
companionTexturePromise?: Promise<string>
|
companionTexturePromise?: Promise<string>
|
||||||
) {
|
) {
|
||||||
super(Scene, x, y, texturesPromise, name, direction, moving, 1);
|
super(Scene, x, y, texturesPromise, name, direction, moving, 1);
|
||||||
|
|
||||||
//set data
|
//set data
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
|
|
||||||
@ -35,9 +35,9 @@ export class RemotePlayer extends Character {
|
|||||||
this.playAnimation(position.direction as PlayerAnimationDirections, position.moving);
|
this.playAnimation(position.direction as PlayerAnimationDirections, position.moving);
|
||||||
this.setX(position.x);
|
this.setX(position.x);
|
||||||
this.setY(position.y);
|
this.setY(position.y);
|
||||||
|
|
||||||
this.setDepth(position.y); //this is to make sure the perspective (player models closer the bottom of the screen will appear in front of models nearer the top of the screen).
|
this.setDepth(position.y); //this is to make sure the perspective (player models closer the bottom of the screen will appear in front of models nearer the top of the screen).
|
||||||
|
|
||||||
if (this.companion) {
|
if (this.companion) {
|
||||||
this.companion.setTarget(position.x, position.y, position.direction as PlayerAnimationDirections);
|
this.companion.setTarget(position.x, position.y, position.direction as PlayerAnimationDirections);
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import Scene = Phaser.Scene;
|
import Scene = Phaser.Scene;
|
||||||
import {Character} from "./Character";
|
import type {Character} from "./Character";
|
||||||
|
|
||||||
//todo: improve this WIP
|
//todo: improve this WIP
|
||||||
export class SpeechBubble {
|
export class SpeechBubble {
|
||||||
private bubble: Phaser.GameObjects.Graphics;
|
private bubble: Phaser.GameObjects.Graphics;
|
||||||
private content: Phaser.GameObjects.Text;
|
private content: Phaser.GameObjects.Text;
|
||||||
|
|
||||||
|
|
||||||
constructor(scene: Scene, player: Character, text: string = "") {
|
constructor(scene: Scene, player: Character, text: string = "") {
|
||||||
|
|
||||||
const bubbleHeight = 50;
|
const bubbleHeight = 50;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {PointInterface} from "../../Connexion/ConnexionModels";
|
import type {PointInterface} from "../../Connexion/ConnexionModels";
|
||||||
import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
import type {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
||||||
|
|
||||||
export interface AddPlayerInterface {
|
export interface AddPlayerInterface {
|
||||||
userId: number;
|
userId: number;
|
||||||
|
@ -2,6 +2,8 @@ import {ResizableScene} from "../Login/ResizableScene";
|
|||||||
import GameObject = Phaser.GameObjects.GameObject;
|
import GameObject = Phaser.GameObjects.GameObject;
|
||||||
import Events = Phaser.Scenes.Events;
|
import Events = Phaser.Scenes.Events;
|
||||||
import AnimationEvents = Phaser.Animations.Events;
|
import AnimationEvents = Phaser.Animations.Events;
|
||||||
|
import StructEvents = Phaser.Structs.Events;
|
||||||
|
import {SKIP_RENDER_OPTIMIZATIONS} from "../../Enum/EnvironmentVariable";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A scene that can track its dirty/pristine state.
|
* A scene that can track its dirty/pristine state.
|
||||||
@ -18,17 +20,16 @@ export abstract class DirtyScene extends ResizableScene {
|
|||||||
* Note: this does not work with animations from sprites inside containers.
|
* Note: this does not work with animations from sprites inside containers.
|
||||||
*/
|
*/
|
||||||
protected trackDirtyAnims(): void {
|
protected trackDirtyAnims(): void {
|
||||||
if (this.isAlreadyTracking) {
|
if (this.isAlreadyTracking || SKIP_RENDER_OPTIMIZATIONS) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.isAlreadyTracking = true;
|
this.isAlreadyTracking = true;
|
||||||
const trackAnimationFunction = this.trackAnimation.bind(this);
|
const trackAnimationFunction = this.trackAnimation.bind(this);
|
||||||
this.events.on(Events.ADDED_TO_SCENE, (gameObject: GameObject) => {
|
this.sys.updateList.on(StructEvents.PROCESS_QUEUE_ADD, (gameObject: GameObject) => {
|
||||||
this.objectListChanged = true;
|
this.objectListChanged = true;
|
||||||
gameObject.on(AnimationEvents.ANIMATION_UPDATE, trackAnimationFunction);
|
gameObject.on(AnimationEvents.ANIMATION_UPDATE, trackAnimationFunction);
|
||||||
});
|
});
|
||||||
|
this.sys.updateList.on(StructEvents.PROCESS_QUEUE_REMOVE, (gameObject: GameObject) => {
|
||||||
this.events.on(Events.REMOVED_FROM_SCENE, (gameObject: GameObject) => {
|
|
||||||
this.objectListChanged = true;
|
this.objectListChanged = true;
|
||||||
gameObject.removeListener(AnimationEvents.ANIMATION_UPDATE, trackAnimationFunction);
|
gameObject.removeListener(AnimationEvents.ANIMATION_UPDATE, trackAnimationFunction);
|
||||||
});
|
});
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
import {SKIP_RENDER_OPTIMIZATIONS} from "../../Enum/EnvironmentVariable";
|
||||||
|
import {coWebsiteManager} from "../../WebRtc/CoWebsiteManager";
|
||||||
|
import {waScaleManager} from "../Services/WaScaleManager";
|
||||||
|
import {ResizableScene} from "../Login/ResizableScene";
|
||||||
|
|
||||||
const Events = Phaser.Core.Events;
|
const Events = Phaser.Core.Events;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -5,8 +10,27 @@ const Events = Phaser.Core.Events;
|
|||||||
* It comes with an optimization to skip rendering.
|
* It comes with an optimization to skip rendering.
|
||||||
*
|
*
|
||||||
* Beware, the "step" function might vary in future versions of Phaser.
|
* Beware, the "step" function might vary in future versions of Phaser.
|
||||||
|
*
|
||||||
|
* It also automatically calls "onResize" on any scenes extending ResizableScene.
|
||||||
*/
|
*/
|
||||||
export class Game extends Phaser.Game {
|
export class Game extends Phaser.Game {
|
||||||
|
|
||||||
|
private _isDirty = false;
|
||||||
|
|
||||||
|
|
||||||
|
constructor(GameConfig: Phaser.Types.Core.GameConfig) {
|
||||||
|
super(GameConfig);
|
||||||
|
|
||||||
|
window.addEventListener('resize', (event) => {
|
||||||
|
// Let's trigger the onResize method of any active scene that is a ResizableScene
|
||||||
|
for (const scene of this.scene.getScenes(true)) {
|
||||||
|
if (scene instanceof ResizableScene) {
|
||||||
|
scene.onResize(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public step(time: number, delta: number)
|
public step(time: number, delta: number)
|
||||||
{
|
{
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@ -35,7 +59,7 @@ export class Game extends Phaser.Game {
|
|||||||
eventEmitter.emit(Events.POST_STEP, time, delta);
|
eventEmitter.emit(Events.POST_STEP, time, delta);
|
||||||
|
|
||||||
// This "if" is the changed introduced by the new "Game" class to avoid rendering unnecessarily.
|
// This "if" is the changed introduced by the new "Game" class to avoid rendering unnecessarily.
|
||||||
if (this.isDirty()) {
|
if (SKIP_RENDER_OPTIMIZATIONS || this.isDirty()) {
|
||||||
const renderer = this.renderer;
|
const renderer = this.renderer;
|
||||||
|
|
||||||
// Run the Pre-render (clearing the canvas, setting background colors, etc)
|
// Run the Pre-render (clearing the canvas, setting background colors, etc)
|
||||||
@ -62,6 +86,11 @@ export class Game extends Phaser.Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private isDirty(): boolean {
|
private isDirty(): boolean {
|
||||||
|
if (this._isDirty) {
|
||||||
|
this._isDirty = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Loop through the scenes in forward order
|
// Loop through the scenes in forward order
|
||||||
for (let i = 0; i < this.scene.scenes.length; i++)
|
for (let i = 0; i < this.scene.scenes.length; i++)
|
||||||
{
|
{
|
||||||
@ -85,4 +114,11 @@ export class Game extends Phaser.Game {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks the game as needing to be redrawn.
|
||||||
|
*/
|
||||||
|
public markDirty(): void {
|
||||||
|
this._isDirty = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import {GameScene} from "./GameScene";
|
import {GameScene} from "./GameScene";
|
||||||
import {connectionManager} from "../../Connexion/ConnectionManager";
|
import {connectionManager} from "../../Connexion/ConnectionManager";
|
||||||
import {Room} from "../../Connexion/Room";
|
import type {Room} from "../../Connexion/Room";
|
||||||
import {MenuScene, MenuSceneName} from "../Menu/MenuScene";
|
import {MenuScene, MenuSceneName} from "../Menu/MenuScene";
|
||||||
import {HelpCameraSettingsScene, HelpCameraSettingsSceneName} from "../Menu/HelpCameraSettingsScene";
|
import {HelpCameraSettingsScene, HelpCameraSettingsSceneName} from "../Menu/HelpCameraSettingsScene";
|
||||||
import {LoginSceneName} from "../Login/LoginScene";
|
import {LoginSceneName} from "../Login/LoginScene";
|
||||||
@ -24,7 +24,7 @@ export class GameManager {
|
|||||||
private companion: string|null;
|
private companion: string|null;
|
||||||
private startRoom!:Room;
|
private startRoom!:Room;
|
||||||
currentGameSceneName: string|null = null;
|
currentGameSceneName: string|null = null;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.playerName = localUserStore.getName();
|
this.playerName = localUserStore.getName();
|
||||||
this.characterLayers = localUserStore.getCharacterLayers();
|
this.characterLayers = localUserStore.getCharacterLayers();
|
||||||
@ -65,7 +65,7 @@ export class GameManager {
|
|||||||
return this.characterLayers;
|
return this.characterLayers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
setCompanion(companion: string|null): void {
|
setCompanion(companion: string|null): void {
|
||||||
this.companion = companion;
|
this.companion = companion;
|
||||||
}
|
}
|
||||||
@ -91,7 +91,7 @@ export class GameManager {
|
|||||||
scenePlugin.launch(MenuSceneName);
|
scenePlugin.launch(MenuSceneName);
|
||||||
scenePlugin.launch(HelpCameraSettingsSceneName);//700
|
scenePlugin.launch(HelpCameraSettingsSceneName);//700
|
||||||
}
|
}
|
||||||
|
|
||||||
public gameSceneIsCreated(scene: GameScene) {
|
public gameSceneIsCreated(scene: GameScene) {
|
||||||
this.currentGameSceneName = scene.scene.key;
|
this.currentGameSceneName = scene.scene.key;
|
||||||
const menuScene: MenuScene = scene.scene.get(MenuSceneName) as MenuScene;
|
const menuScene: MenuScene = scene.scene.get(MenuSceneName) as MenuScene;
|
||||||
@ -125,7 +125,7 @@ export class GameManager {
|
|||||||
scene.scene.run(fallbackSceneName)
|
scene.scene.run(fallbackSceneName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public getCurrentGameScene(scene: Phaser.Scene): GameScene {
|
public getCurrentGameScene(scene: Phaser.Scene): GameScene {
|
||||||
if (this.currentGameSceneName === null) throw 'No current scene id set!';
|
if (this.currentGameSceneName === null) throw 'No current scene id set!';
|
||||||
return scene.scene.get(this.currentGameSceneName) as GameScene
|
return scene.scene.get(this.currentGameSceneName) as GameScene
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {ITiledMap, ITiledMapLayer, ITiledMapTileLayer} from "../Map/ITiledMap";
|
import type {ITiledMap, ITiledMapLayer, ITiledMapTileLayer} from "../Map/ITiledMap";
|
||||||
import { flattenGroupLayersMap } from "../Map/LayersFlattener";
|
import { flattenGroupLayersMap } from "../Map/LayersFlattener";
|
||||||
|
|
||||||
export type PropertyChangeCallback = (newValue: string | number | boolean | undefined, oldValue: string | number | boolean | undefined, allProps: Map<string, string | boolean | number>) => void;
|
export type PropertyChangeCallback = (newValue: string | number | boolean | undefined, oldValue: string | number | boolean | undefined, allProps: Map<string, string | boolean | number>) => void;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {gameManager, HasMovedEvent} from "./GameManager";
|
import {gameManager, HasMovedEvent} from "./GameManager";
|
||||||
import {
|
import type {
|
||||||
GroupCreatedUpdatedMessageInterface,
|
GroupCreatedUpdatedMessageInterface,
|
||||||
MessageUserJoined,
|
MessageUserJoined,
|
||||||
MessageUserMovedInterface,
|
MessageUserMovedInterface,
|
||||||
@ -16,7 +16,7 @@ import {
|
|||||||
MAX_PER_GROUP,
|
MAX_PER_GROUP,
|
||||||
POSITION_DELAY,
|
POSITION_DELAY,
|
||||||
} from "../../Enum/EnvironmentVariable";
|
} from "../../Enum/EnvironmentVariable";
|
||||||
import {
|
import type {
|
||||||
ITiledMap,
|
ITiledMap,
|
||||||
ITiledMapLayer,
|
ITiledMapLayer,
|
||||||
ITiledMapLayerProperty,
|
ITiledMapLayerProperty,
|
||||||
@ -25,7 +25,7 @@ import {
|
|||||||
ITiledMapTileLayer,
|
ITiledMapTileLayer,
|
||||||
ITiledTileSet
|
ITiledTileSet
|
||||||
} from "../Map/ITiledMap";
|
} from "../Map/ITiledMap";
|
||||||
import {AddPlayerInterface} from "./AddPlayerInterface";
|
import type {AddPlayerInterface} from "./AddPlayerInterface";
|
||||||
import {PlayerAnimationDirections} from "../Player/Animation";
|
import {PlayerAnimationDirections} from "../Player/Animation";
|
||||||
import {PlayerMovement} from "./PlayerMovement";
|
import {PlayerMovement} from "./PlayerMovement";
|
||||||
import {PlayersPositionInterpolator} from "./PlayersPositionInterpolator";
|
import {PlayersPositionInterpolator} from "./PlayersPositionInterpolator";
|
||||||
@ -49,13 +49,13 @@ import {
|
|||||||
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 {ItemFactoryInterface} from "../Items/ItemFactoryInterface";
|
import type {ItemFactoryInterface} from "../Items/ItemFactoryInterface";
|
||||||
import {ActionableItem} from "../Items/ActionableItem";
|
import type {ActionableItem} from "../Items/ActionableItem";
|
||||||
import {UserInputManager} from "../UserInput/UserInputManager";
|
import {UserInputManager} from "../UserInput/UserInputManager";
|
||||||
import {UserMovedMessage} from "../../Messages/generated/messages_pb";
|
import type {UserMovedMessage} from "../../Messages/generated/messages_pb";
|
||||||
import {ProtobufClientUtils} from "../../Network/ProtobufClientUtils";
|
import {ProtobufClientUtils} from "../../Network/ProtobufClientUtils";
|
||||||
import {connectionManager} from "../../Connexion/ConnectionManager";
|
import {connectionManager} from "../../Connexion/ConnectionManager";
|
||||||
import {RoomConnection} from "../../Connexion/RoomConnection";
|
import type {RoomConnection} from "../../Connexion/RoomConnection";
|
||||||
import {GlobalMessageManager} from "../../Administration/GlobalMessageManager";
|
import {GlobalMessageManager} from "../../Administration/GlobalMessageManager";
|
||||||
import {userMessageManager} from "../../Administration/UserMessageManager";
|
import {userMessageManager} from "../../Administration/UserMessageManager";
|
||||||
import {ConsoleGlobalMessageManager} from "../../Administration/ConsoleGlobalMessageManager";
|
import {ConsoleGlobalMessageManager} from "../../Administration/ConsoleGlobalMessageManager";
|
||||||
@ -80,7 +80,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 DOMElement = Phaser.GameObjects.DOMElement;
|
import DOMElement = Phaser.GameObjects.DOMElement;
|
||||||
import {Subscription} from "rxjs";
|
import type {Subscription} from "rxjs";
|
||||||
import {worldFullMessageStream} from "../../Connexion/WorldFullMessageStream";
|
import {worldFullMessageStream} from "../../Connexion/WorldFullMessageStream";
|
||||||
import { lazyLoadCompanionResource } from "../Companion/CompanionTexturesLoadingManager";
|
import { lazyLoadCompanionResource } from "../Companion/CompanionTexturesLoadingManager";
|
||||||
import RenderTexture = Phaser.GameObjects.RenderTexture;
|
import RenderTexture = Phaser.GameObjects.RenderTexture;
|
||||||
@ -152,7 +152,7 @@ export class GameScene extends DirtyScene implements CenterListener {
|
|||||||
private GlobalMessageManager!: GlobalMessageManager;
|
private GlobalMessageManager!: GlobalMessageManager;
|
||||||
public ConsoleGlobalMessageManager!: ConsoleGlobalMessageManager;
|
public ConsoleGlobalMessageManager!: ConsoleGlobalMessageManager;
|
||||||
private connectionAnswerPromise: Promise<RoomJoinedMessageInterface>;
|
private connectionAnswerPromise: Promise<RoomJoinedMessageInterface>;
|
||||||
private connectionAnswerPromiseResolve!: (value?: RoomJoinedMessageInterface | PromiseLike<RoomJoinedMessageInterface>) => void;
|
private connectionAnswerPromiseResolve!: (value: RoomJoinedMessageInterface | PromiseLike<RoomJoinedMessageInterface>) => void;
|
||||||
// A promise that will resolve when the "create" method is called (signaling loading is ended)
|
// A promise that will resolve when the "create" method is called (signaling loading is ended)
|
||||||
private createPromise: Promise<void>;
|
private createPromise: Promise<void>;
|
||||||
private createPromiseResolve!: (value?: void | PromiseLike<void>) => void;
|
private createPromiseResolve!: (value?: void | PromiseLike<void>) => void;
|
||||||
@ -187,6 +187,9 @@ export class GameScene extends DirtyScene implements CenterListener {
|
|||||||
private popUpElements : Map<number, DOMElement> = new Map<number, Phaser.GameObjects.DOMElement>();
|
private popUpElements : Map<number, DOMElement> = new Map<number, Phaser.GameObjects.DOMElement>();
|
||||||
private originalMapUrl: string|undefined;
|
private originalMapUrl: string|undefined;
|
||||||
private pinchManager: PinchManager|undefined;
|
private pinchManager: PinchManager|undefined;
|
||||||
|
private physicsEnabled: boolean = true;
|
||||||
|
private mapTransitioning: boolean = false; //used to prevent transitions happenning at the same time.
|
||||||
|
private onVisibilityChangeCallback: () => void;
|
||||||
|
|
||||||
constructor(private room: Room, MapUrlFile: string, customKey?: string|undefined) {
|
constructor(private room: Room, MapUrlFile: string, customKey?: string|undefined) {
|
||||||
super({
|
super({
|
||||||
@ -202,10 +205,11 @@ export class GameScene extends DirtyScene implements CenterListener {
|
|||||||
|
|
||||||
this.createPromise = new Promise<void>((resolve, reject): void => {
|
this.createPromise = new Promise<void>((resolve, reject): void => {
|
||||||
this.createPromiseResolve = resolve;
|
this.createPromiseResolve = resolve;
|
||||||
})
|
});
|
||||||
this.connectionAnswerPromise = new Promise<RoomJoinedMessageInterface>((resolve, reject): void => {
|
this.connectionAnswerPromise = new Promise<RoomJoinedMessageInterface>((resolve, reject): void => {
|
||||||
this.connectionAnswerPromiseResolve = resolve;
|
this.connectionAnswerPromiseResolve = resolve;
|
||||||
});
|
});
|
||||||
|
this.onVisibilityChangeCallback = this.onVisibilityChange.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
//hook preload scene
|
//hook preload scene
|
||||||
@ -495,6 +499,8 @@ export class GameScene extends DirtyScene implements CenterListener {
|
|||||||
if (!this.room.isDisconnected()) {
|
if (!this.room.isDisconnected()) {
|
||||||
this.connect();
|
this.connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.addEventListener('visibilitychange', this.onVisibilityChangeCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -616,6 +622,7 @@ export class GameScene extends DirtyScene implements CenterListener {
|
|||||||
self.chatModeSprite.setVisible(false);
|
self.chatModeSprite.setVisible(false);
|
||||||
self.openChatIcon.setVisible(false);
|
self.openChatIcon.setVisible(false);
|
||||||
audioManager.restoreVolume();
|
audioManager.restoreVolume();
|
||||||
|
self.onVisibilityChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -916,6 +923,8 @@ ${escapedMessage}
|
|||||||
}
|
}
|
||||||
|
|
||||||
private onMapExit(exitKey: string) {
|
private onMapExit(exitKey: string) {
|
||||||
|
if (this.mapTransitioning) return;
|
||||||
|
this.mapTransitioning = true;
|
||||||
const {roomId, hash} = Room.getIdFromIdentifier(exitKey, this.MapUrlFile, this.instance);
|
const {roomId, hash} = Room.getIdFromIdentifier(exitKey, this.MapUrlFile, this.instance);
|
||||||
if (!roomId) throw new Error('Could not find the room from its exit key: '+exitKey);
|
if (!roomId) throw new Error('Could not find the room from its exit key: '+exitKey);
|
||||||
urlManager.pushStartLayerNameToUrl(hash);
|
urlManager.pushStartLayerNameToUrl(hash);
|
||||||
@ -933,6 +942,7 @@ ${escapedMessage}
|
|||||||
this.initPositionFromLayerName(hash || defaultStartLayerName);
|
this.initPositionFromLayerName(hash || defaultStartLayerName);
|
||||||
this.CurrentPlayer.x = this.startX;
|
this.CurrentPlayer.x = this.startX;
|
||||||
this.CurrentPlayer.y = this.startY;
|
this.CurrentPlayer.y = this.startY;
|
||||||
|
setTimeout(() => this.mapTransitioning = false, 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -958,6 +968,8 @@ ${escapedMessage}
|
|||||||
for(const iframeEvents of this.iframeSubscriptionList){
|
for(const iframeEvents of this.iframeSubscriptionList){
|
||||||
iframeEvents.unsubscribe();
|
iframeEvents.unsubscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.removeEventListener('visibilitychange', this.onVisibilityChangeCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
private removeAllRemotePlayers(): void {
|
private removeAllRemotePlayers(): void {
|
||||||
@ -1107,6 +1119,7 @@ ${escapedMessage}
|
|||||||
|
|
||||||
createCollisionWithPlayer() {
|
createCollisionWithPlayer() {
|
||||||
this.physics.disableUpdate();
|
this.physics.disableUpdate();
|
||||||
|
this.physicsEnabled = false;
|
||||||
//add collision layer
|
//add collision layer
|
||||||
for (const Layer of this.gameMap.flatLayers) {
|
for (const Layer of this.gameMap.flatLayers) {
|
||||||
if (Layer.type == "tilelayer") {
|
if (Layer.type == "tilelayer") {
|
||||||
@ -1251,12 +1264,15 @@ ${escapedMessage}
|
|||||||
this.CurrentPlayer.moveUser(delta);
|
this.CurrentPlayer.moveUser(delta);
|
||||||
if (this.CurrentPlayer.isMoving()) {
|
if (this.CurrentPlayer.isMoving()) {
|
||||||
this.dirty = true;
|
this.dirty = true;
|
||||||
this.physics.enableUpdate();
|
if (!this.physicsEnabled) {
|
||||||
} else {
|
this.physics.enableUpdate();
|
||||||
|
this.physicsEnabled = true;
|
||||||
|
}
|
||||||
|
} else if (this.physicsEnabled) {
|
||||||
this.physics.disableUpdate();
|
this.physics.disableUpdate();
|
||||||
|
this.physicsEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Let's handle all events
|
// Let's handle all events
|
||||||
while (this.pendingEvents.length !== 0) {
|
while (this.pendingEvents.length !== 0) {
|
||||||
this.dirty = true;
|
this.dirty = true;
|
||||||
@ -1523,6 +1539,8 @@ ${escapedMessage}
|
|||||||
mediaManager.addTriggerCloseJitsiFrameButton('close-jisi',() => {
|
mediaManager.addTriggerCloseJitsiFrameButton('close-jisi',() => {
|
||||||
this.stopJitsi();
|
this.stopJitsi();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.onVisibilityChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
public stopJitsi(): void {
|
public stopJitsi(): void {
|
||||||
@ -1531,6 +1549,7 @@ ${escapedMessage}
|
|||||||
mediaManager.showGameOverlay();
|
mediaManager.showGameOverlay();
|
||||||
|
|
||||||
mediaManager.removeTriggerCloseJitsiFrameButton('close-jisi');
|
mediaManager.removeTriggerCloseJitsiFrameButton('close-jisi');
|
||||||
|
this.onVisibilityChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo: put this into an 'orchestrator' scene (EntryScene?)
|
//todo: put this into an 'orchestrator' scene (EntryScene?)
|
||||||
@ -1570,4 +1589,20 @@ ${escapedMessage}
|
|||||||
waScaleManager.zoomModifier *= zoomFactor;
|
waScaleManager.zoomModifier *= zoomFactor;
|
||||||
this.updateCameraOffset();
|
this.updateCameraOffset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private onVisibilityChange(): void {
|
||||||
|
// If the overlay is not displayed, we are in Jitsi. We don't need the webcam.
|
||||||
|
if (!mediaManager.isGameOverlayVisible()) {
|
||||||
|
mediaManager.blurCamera();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.visibilityState === 'visible') {
|
||||||
|
mediaManager.focusCamera();
|
||||||
|
} else {
|
||||||
|
if (this.simplePeer.getNbConnections() === 0) {
|
||||||
|
mediaManager.blurCamera();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import {HasMovedEvent} from "./GameManager";
|
import type {HasMovedEvent} from "./GameManager";
|
||||||
import {MAX_EXTRAPOLATION_TIME} from "../../Enum/EnvironmentVariable";
|
import {MAX_EXTRAPOLATION_TIME} from "../../Enum/EnvironmentVariable";
|
||||||
import {PositionInterface} from "../../Connexion/ConnexionModels";
|
import type {PositionInterface} from "../../Connexion/ConnexionModels";
|
||||||
|
|
||||||
export class PlayerMovement {
|
export class PlayerMovement {
|
||||||
public constructor(private startPosition: PositionInterface, private startTick: number, private endPosition: HasMovedEvent, private endTick: number) {
|
public constructor(private startPosition: PositionInterface, private startTick: number, private endPosition: HasMovedEvent, private endTick: number) {
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
* This class is in charge of computing the position of all players.
|
* This class is in charge of computing the position of all players.
|
||||||
* Player movement is delayed by 200ms so position depends on ticks.
|
* Player movement is delayed by 200ms so position depends on ticks.
|
||||||
*/
|
*/
|
||||||
import {PlayerMovement} from "./PlayerMovement";
|
import type {PlayerMovement} from "./PlayerMovement";
|
||||||
import {HasMovedEvent} from "./GameManager";
|
import type {HasMovedEvent} from "./GameManager";
|
||||||
|
|
||||||
export class PlayersPositionInterpolator {
|
export class PlayersPositionInterpolator {
|
||||||
playerMovements: Map<number, PlayerMovement> = new Map<number, PlayerMovement>();
|
playerMovements: Map<number, PlayerMovement> = new Map<number, PlayerMovement>();
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*/
|
*/
|
||||||
import Sprite = Phaser.GameObjects.Sprite;
|
import Sprite = Phaser.GameObjects.Sprite;
|
||||||
import {OutlinePipeline} from "../Shaders/OutlinePipeline";
|
import {OutlinePipeline} from "../Shaders/OutlinePipeline";
|
||||||
import {GameScene} from "../Game/GameScene";
|
import type {GameScene} from "../Game/GameScene";
|
||||||
|
|
||||||
type EventCallback = (state: unknown, parameters: unknown) => void;
|
type EventCallback = (state: unknown, parameters: unknown) => void;
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import * as Phaser from 'phaser';
|
import * as Phaser from 'phaser';
|
||||||
import {Scene} from "phaser";
|
import {Scene} from "phaser";
|
||||||
import Sprite = Phaser.GameObjects.Sprite;
|
import Sprite = Phaser.GameObjects.Sprite;
|
||||||
import {ITiledMapObject} from "../../Map/ITiledMap";
|
import type {ITiledMapObject} from "../../Map/ITiledMap";
|
||||||
import {ItemFactoryInterface} from "../ItemFactoryInterface";
|
import type {ItemFactoryInterface} from "../ItemFactoryInterface";
|
||||||
import {GameScene} from "../../Game/GameScene";
|
import type {GameScene} from "../../Game/GameScene";
|
||||||
import {ActionableItem} from "../ActionableItem";
|
import {ActionableItem} from "../ActionableItem";
|
||||||
import * as tg from "generic-type-guard";
|
import * as tg from "generic-type-guard";
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
import type {GameScene} from "../Game/GameScene";
|
||||||
|
import type {ITiledMapObject} from "../Map/ITiledMap";
|
||||||
|
import type {ActionableItem} from "./ActionableItem";
|
||||||
import LoaderPlugin = Phaser.Loader.LoaderPlugin;
|
import LoaderPlugin = Phaser.Loader.LoaderPlugin;
|
||||||
import {GameScene} from "../Game/GameScene";
|
|
||||||
import {ITiledMapObject} from "../Map/ITiledMap";
|
|
||||||
import {ActionableItem} from "./ActionableItem";
|
|
||||||
|
|
||||||
export interface ItemFactoryInterface {
|
export interface ItemFactoryInterface {
|
||||||
preload: (loader: LoaderPlugin) => void;
|
preload: (loader: LoaderPlugin) => void;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
import {ResizableScene} from "./ResizableScene";
|
import {ResizableScene} from "./ResizableScene";
|
||||||
import {localUserStore} from "../../Connexion/LocalUserStore";
|
import {localUserStore} from "../../Connexion/LocalUserStore";
|
||||||
import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
import type {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
||||||
import {loadCustomTexture} from "../Entity/PlayerTexturesLoadingManager";
|
import {loadCustomTexture} from "../Entity/PlayerTexturesLoadingManager";
|
||||||
import {CharacterTexture} from "../../Connexion/LocalUser";
|
import type {CharacterTexture} from "../../Connexion/LocalUser";
|
||||||
|
|
||||||
export abstract class AbstractCharacterScene extends ResizableScene {
|
export abstract class AbstractCharacterScene extends ResizableScene {
|
||||||
|
|
||||||
@ -38,4 +38,4 @@ export abstract class AbstractCharacterScene extends ResizableScene {
|
|||||||
const localUser = localUserStore.getLocalUser();
|
const localUser = localUserStore.getLocalUser();
|
||||||
return localUser?.textures;
|
return localUser?.textures;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ import Container = Phaser.GameObjects.Container;
|
|||||||
import {gameManager} from "../Game/GameManager";
|
import {gameManager} from "../Game/GameManager";
|
||||||
import {localUserStore} from "../../Connexion/LocalUserStore";
|
import {localUserStore} from "../../Connexion/LocalUserStore";
|
||||||
import {addLoader} from "../Components/Loader";
|
import {addLoader} from "../Components/Loader";
|
||||||
import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
import type {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
||||||
import {AbstractCharacterScene} from "./AbstractCharacterScene";
|
import {AbstractCharacterScene} from "./AbstractCharacterScene";
|
||||||
import {areCharacterLayersValid} from "../../Connexion/LocalUser";
|
import {areCharacterLayersValid} from "../../Connexion/LocalUser";
|
||||||
import { MenuScene } from "../Menu/MenuScene";
|
import { MenuScene } from "../Menu/MenuScene";
|
||||||
|
@ -252,7 +252,6 @@ export class EnableCameraScene extends ResizableScene {
|
|||||||
|
|
||||||
update(time: number, delta: number): void {
|
update(time: number, delta: number): void {
|
||||||
this.soundMeterSprite.setVolume(this.soundMeter.getVolume());
|
this.soundMeterSprite.setVolume(this.soundMeter.getVolume());
|
||||||
mediaManager.updateScene();
|
|
||||||
|
|
||||||
this.centerXDomElement(this.enableCameraSceneElement, 300);
|
this.centerXDomElement(this.enableCameraSceneElement, 300);
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,4 @@
|
|||||||
import {gameManager} from "../Game/GameManager";
|
import { SelectCharacterScene } from "./SelectCharacterScene";
|
||||||
import {TextField} from "../Components/TextField";
|
|
||||||
import Image = Phaser.GameObjects.Image;
|
|
||||||
import Rectangle = Phaser.GameObjects.Rectangle;
|
|
||||||
import {EnableCameraSceneName} from "./EnableCameraScene";
|
|
||||||
import {CustomizeSceneName} from "./CustomizeScene";
|
|
||||||
import {localUserStore} from "../../Connexion/LocalUserStore";
|
|
||||||
import {loadAllDefaultModels} from "../Entity/PlayerTexturesLoadingManager";
|
|
||||||
import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
|
||||||
import {AbstractCharacterScene} from "./AbstractCharacterScene";
|
|
||||||
import {areCharacterLayersValid} from "../../Connexion/LocalUser";
|
|
||||||
import {touchScreenManager} from "../../Touch/TouchScreenManager";
|
|
||||||
import {PinchManager} from "../UserInput/PinchManager";
|
|
||||||
import {MenuScene} from "../Menu/MenuScene";
|
|
||||||
import { SelectCharacterScene, SelectCharacterSceneName } from "./SelectCharacterScene";
|
|
||||||
|
|
||||||
export class SelectCharacterMobileScene extends SelectCharacterScene {
|
export class SelectCharacterMobileScene extends SelectCharacterScene {
|
||||||
|
|
||||||
@ -20,7 +6,7 @@ export class SelectCharacterMobileScene extends SelectCharacterScene {
|
|||||||
super.create();
|
super.create();
|
||||||
this.selectedRectangle.destroy();
|
this.selectedRectangle.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected defineSetupPlayer(numero: number){
|
protected defineSetupPlayer(numero: number){
|
||||||
const deltaX = 30;
|
const deltaX = 30;
|
||||||
const deltaY = 2;
|
const deltaY = 2;
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
import {gameManager} from "../Game/GameManager";
|
import {gameManager} from "../Game/GameManager";
|
||||||
import Image = Phaser.GameObjects.Image;
|
|
||||||
import Rectangle = Phaser.GameObjects.Rectangle;
|
import Rectangle = Phaser.GameObjects.Rectangle;
|
||||||
import {EnableCameraSceneName} from "./EnableCameraScene";
|
import {EnableCameraSceneName} from "./EnableCameraScene";
|
||||||
import {CustomizeSceneName} from "./CustomizeScene";
|
import {CustomizeSceneName} from "./CustomizeScene";
|
||||||
import {localUserStore} from "../../Connexion/LocalUserStore";
|
import {localUserStore} from "../../Connexion/LocalUserStore";
|
||||||
import {loadAllDefaultModels} from "../Entity/PlayerTexturesLoadingManager";
|
import {loadAllDefaultModels} from "../Entity/PlayerTexturesLoadingManager";
|
||||||
import {addLoader} from "../Components/Loader";
|
import {addLoader} from "../Components/Loader";
|
||||||
import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
import type {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
|
||||||
import {AbstractCharacterScene} from "./AbstractCharacterScene";
|
import {AbstractCharacterScene} from "./AbstractCharacterScene";
|
||||||
import {areCharacterLayersValid} from "../../Connexion/LocalUser";
|
import {areCharacterLayersValid} from "../../Connexion/LocalUser";
|
||||||
import {touchScreenManager} from "../../Touch/TouchScreenManager";
|
import {touchScreenManager} from "../../Touch/TouchScreenManager";
|
||||||
import {PinchManager} from "../UserInput/PinchManager";
|
import {PinchManager} from "../UserInput/PinchManager";
|
||||||
import {MenuScene} from "../Menu/MenuScene";
|
import {MenuScene} from "../Menu/MenuScene";
|
||||||
import { SelectCharacterMobileScene } from "./SelectCharacterMobileScene";
|
|
||||||
|
|
||||||
//todo: put this constants in a dedicated file
|
//todo: put this constants in a dedicated file
|
||||||
export const SelectCharacterSceneName = "SelectCharacterScene";
|
export const SelectCharacterSceneName = "SelectCharacterScene";
|
||||||
|
@ -5,7 +5,7 @@ import { gameManager} from "../Game/GameManager";
|
|||||||
import { ResizableScene } from "./ResizableScene";
|
import { ResizableScene } from "./ResizableScene";
|
||||||
import { EnableCameraSceneName } from "./EnableCameraScene";
|
import { EnableCameraSceneName } from "./EnableCameraScene";
|
||||||
import { localUserStore } from "../../Connexion/LocalUserStore";
|
import { localUserStore } from "../../Connexion/LocalUserStore";
|
||||||
import { CompanionResourceDescriptionInterface } from "../Companion/CompanionTextures";
|
import type { CompanionResourceDescriptionInterface } from "../Companion/CompanionTextures";
|
||||||
import { getAllCompanionResources } from "../Companion/CompanionTexturesLoadingManager";
|
import { getAllCompanionResources } from "../Companion/CompanionTexturesLoadingManager";
|
||||||
import {touchScreenManager} from "../../Touch/TouchScreenManager";
|
import {touchScreenManager} from "../../Touch/TouchScreenManager";
|
||||||
import {PinchManager} from "../UserInput/PinchManager";
|
import {PinchManager} from "../UserInput/PinchManager";
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import {ITiledMap, ITiledMapLayer} from "./ITiledMap";
|
import type {ITiledMap, ITiledMapLayer} from "./ITiledMap";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flatten the grouped layers
|
* Flatten the grouped layers
|
||||||
*/
|
*/
|
||||||
export function flattenGroupLayersMap(map: ITiledMap) {
|
export function flattenGroupLayersMap(map: ITiledMap) {
|
||||||
let flatLayers: ITiledMapLayer[] = [];
|
const flatLayers: ITiledMapLayer[] = [];
|
||||||
flattenGroupLayers(map.layers, '', flatLayers);
|
flattenGroupLayers(map.layers, '', flatLayers);
|
||||||
return flatLayers;
|
return flatLayers;
|
||||||
}
|
}
|
||||||
|
@ -109,15 +109,18 @@ export class HelpCameraSettingsScene extends DirtyScene {
|
|||||||
|
|
||||||
public onResize(ev: UIEvent): void {
|
public onResize(ev: UIEvent): void {
|
||||||
super.onResize(ev);
|
super.onResize(ev);
|
||||||
const middleX = this.getMiddleX();
|
if (this.helpCameraSettingsOpened) {
|
||||||
const middleY = this.getMiddleY();
|
const middleX = this.getMiddleX();
|
||||||
this.tweens.add({
|
const middleY = this.getMiddleY();
|
||||||
targets: this.helpCameraSettingsElement,
|
this.tweens.add({
|
||||||
x: middleX,
|
targets: this.helpCameraSettingsElement,
|
||||||
y: middleY,
|
x: middleX,
|
||||||
duration: 1000,
|
y: middleY,
|
||||||
ease: 'Power3'
|
duration: 1000,
|
||||||
});
|
ease: 'Power3'
|
||||||
|
});
|
||||||
|
this.dirty = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getMiddleX() : number{
|
private getMiddleX() : number{
|
||||||
|
@ -9,6 +9,7 @@ import {connectionManager} from "../../Connexion/ConnectionManager";
|
|||||||
import {GameConnexionTypes} from "../../Url/UrlManager";
|
import {GameConnexionTypes} from "../../Url/UrlManager";
|
||||||
import {WarningContainer, warningContainerHtml, warningContainerKey} from "../Components/WarningContainer";
|
import {WarningContainer, warningContainerHtml, warningContainerKey} from "../Components/WarningContainer";
|
||||||
import {worldFullWarningStream} from "../../Connexion/WorldFullWarningStream";
|
import {worldFullWarningStream} from "../../Connexion/WorldFullWarningStream";
|
||||||
|
import {menuIconVisible} from "../../Stores/MenuStore";
|
||||||
|
|
||||||
export const MenuSceneName = 'MenuScene';
|
export const MenuSceneName = 'MenuScene';
|
||||||
const gameMenuKey = 'gameMenu';
|
const gameMenuKey = 'gameMenu';
|
||||||
@ -53,6 +54,7 @@ export class MenuScene extends Phaser.Scene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
create() {
|
create() {
|
||||||
|
menuIconVisible.set(true);
|
||||||
this.menuElement = this.add.dom(closedSideMenuX, 30).createFromCache(gameMenuKey);
|
this.menuElement = this.add.dom(closedSideMenuX, 30).createFromCache(gameMenuKey);
|
||||||
this.menuElement.setOrigin(0);
|
this.menuElement.setOrigin(0);
|
||||||
MenuScene.revealMenusAfterInit(this.menuElement, 'gameMenu');
|
MenuScene.revealMenusAfterInit(this.menuElement, 'gameMenu');
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {PlayerAnimationDirections} from "./Animation";
|
import {PlayerAnimationDirections} from "./Animation";
|
||||||
import {GameScene} from "../Game/GameScene";
|
import type {GameScene} from "../Game/GameScene";
|
||||||
import {UserInputEvent, UserInputManager} from "../UserInput/UserInputManager";
|
import {UserInputEvent, UserInputManager} from "../UserInput/UserInputManager";
|
||||||
import {Character} from "../Entity/Character";
|
import {Character} from "../Entity/Character";
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import ScaleManager = Phaser.Scale.ScaleManager;
|
|
||||||
|
|
||||||
interface Size {
|
interface Size {
|
||||||
width: number;
|
width: number;
|
||||||
@ -13,8 +12,7 @@ export class HdpiManager {
|
|||||||
* @param minRecommendedGamePixelsNumber The minimum number of pixels we want to display "by default" to the user
|
* @param minRecommendedGamePixelsNumber The minimum number of pixels we want to display "by default" to the user
|
||||||
* @param absoluteMinPixelNumber The very minimum of game pixels to display. Below, we forbid zooming more
|
* @param absoluteMinPixelNumber The very minimum of game pixels to display. Below, we forbid zooming more
|
||||||
*/
|
*/
|
||||||
public constructor(private minRecommendedGamePixelsNumber: number, private absoluteMinPixelNumber: number) {
|
public constructor(private minRecommendedGamePixelsNumber: number, private absoluteMinPixelNumber: number) {}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the optimal size in "game pixels" based on the screen size in "real pixels".
|
* Returns the optimal size in "game pixels" based on the screen size in "real pixels".
|
||||||
@ -36,16 +34,12 @@ export class HdpiManager {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let i = 1;
|
const optimalZoomLevel = this.getOptimalZoomLevel(realPixelNumber);
|
||||||
|
|
||||||
while (realPixelNumber > this.minRecommendedGamePixelsNumber * i * i) {
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Has the canvas more pixels than the screen? This is forbidden
|
// Has the canvas more pixels than the screen? This is forbidden
|
||||||
if ((i - 1) * this._zoomModifier < 1) {
|
if (optimalZoomLevel * this._zoomModifier < 1) {
|
||||||
// Let's reset the zoom modifier (WARNING this is a SIDE EFFECT in a getter)
|
// Let's reset the zoom modifier (WARNING this is a SIDE EFFECT in a getter)
|
||||||
this._zoomModifier = 1 / (i - 1);
|
this._zoomModifier = 1 / optimalZoomLevel;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
game: {
|
game: {
|
||||||
@ -59,8 +53,8 @@ export class HdpiManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const gameWidth = Math.ceil(realPixelScreenSize.width / (i - 1) / this._zoomModifier);
|
const gameWidth = Math.ceil(realPixelScreenSize.width / optimalZoomLevel / this._zoomModifier);
|
||||||
const gameHeight = Math.ceil(realPixelScreenSize.height / (i - 1) / this._zoomModifier);
|
const gameHeight = Math.ceil(realPixelScreenSize.height / optimalZoomLevel / this._zoomModifier);
|
||||||
|
|
||||||
// Let's ensure we display a minimum of pixels, even if crazily zoomed in.
|
// Let's ensure we display a minimum of pixels, even if crazily zoomed in.
|
||||||
if (gameWidth * gameHeight < this.absoluteMinPixelNumber) {
|
if (gameWidth * gameHeight < this.absoluteMinPixelNumber) {
|
||||||
@ -68,7 +62,7 @@ export class HdpiManager {
|
|||||||
const minGameWidth = Math.sqrt(this.absoluteMinPixelNumber * realPixelScreenSize.width / realPixelScreenSize.height);
|
const minGameWidth = Math.sqrt(this.absoluteMinPixelNumber * realPixelScreenSize.width / realPixelScreenSize.height);
|
||||||
|
|
||||||
// Let's reset the zoom modifier (WARNING this is a SIDE EFFECT in a getter)
|
// Let's reset the zoom modifier (WARNING this is a SIDE EFFECT in a getter)
|
||||||
this._zoomModifier = realPixelScreenSize.width / minGameWidth / (i - 1);
|
this._zoomModifier = realPixelScreenSize.width / minGameWidth / optimalZoomLevel;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
game: {
|
game: {
|
||||||
@ -89,12 +83,24 @@ export class HdpiManager {
|
|||||||
height: gameHeight,
|
height: gameHeight,
|
||||||
},
|
},
|
||||||
real: {
|
real: {
|
||||||
width: Math.ceil(realPixelScreenSize.width / (i - 1)) * (i - 1),
|
width: Math.ceil(realPixelScreenSize.width / optimalZoomLevel) * optimalZoomLevel,
|
||||||
height: Math.ceil(realPixelScreenSize.height / (i - 1)) * (i - 1),
|
height: Math.ceil(realPixelScreenSize.height / optimalZoomLevel) * optimalZoomLevel,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We only accept integer but we make an exception for 1.5
|
||||||
|
*/
|
||||||
|
private getOptimalZoomLevel(realPixelNumber: number): number {
|
||||||
|
const result = Math.sqrt(realPixelNumber / this.minRecommendedGamePixelsNumber);
|
||||||
|
if (1.5 <= result && result < 2) {
|
||||||
|
return 1.5
|
||||||
|
} else {
|
||||||
|
return Math.floor(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public get zoomModifier(): number {
|
public get zoomModifier(): number {
|
||||||
return this._zoomModifier;
|
return this._zoomModifier;
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,21 @@
|
|||||||
import {HdpiManager} from "./HdpiManager";
|
import {HdpiManager} from "./HdpiManager";
|
||||||
import ScaleManager = Phaser.Scale.ScaleManager;
|
import ScaleManager = Phaser.Scale.ScaleManager;
|
||||||
import {coWebsiteManager} from "../../WebRtc/CoWebsiteManager";
|
import {coWebsiteManager} from "../../WebRtc/CoWebsiteManager";
|
||||||
|
import type {Game} from "../Game/Game";
|
||||||
|
|
||||||
|
|
||||||
class WaScaleManager {
|
class WaScaleManager {
|
||||||
private hdpiManager: HdpiManager;
|
private hdpiManager: HdpiManager;
|
||||||
private scaleManager!: ScaleManager;
|
private scaleManager!: ScaleManager;
|
||||||
|
private game!: Game;
|
||||||
|
|
||||||
public constructor(private minGamePixelsNumber: number, private absoluteMinPixelNumber: number) {
|
public constructor(private minGamePixelsNumber: number, private absoluteMinPixelNumber: number) {
|
||||||
this.hdpiManager = new HdpiManager(minGamePixelsNumber, absoluteMinPixelNumber);
|
this.hdpiManager = new HdpiManager(minGamePixelsNumber, absoluteMinPixelNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
public setScaleManager(scaleManager: ScaleManager) {
|
public setGame(game: Game): void {
|
||||||
this.scaleManager = scaleManager;
|
this.scaleManager = game.scale;
|
||||||
|
this.game = game;
|
||||||
}
|
}
|
||||||
|
|
||||||
public applyNewSize() {
|
public applyNewSize() {
|
||||||
@ -32,6 +35,8 @@ class WaScaleManager {
|
|||||||
const style = this.scaleManager.canvas.style;
|
const style = this.scaleManager.canvas.style;
|
||||||
style.width = Math.ceil(realSize.width / devicePixelRatio) + 'px';
|
style.width = Math.ceil(realSize.width / devicePixelRatio) + 'px';
|
||||||
style.height = Math.ceil(realSize.height / devicePixelRatio) + 'px';
|
style.height = Math.ceil(realSize.height / devicePixelRatio) + 'px';
|
||||||
|
|
||||||
|
this.game.markDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public get zoomModifier(): number {
|
public get zoomModifier(): number {
|
||||||
@ -42,6 +47,7 @@ class WaScaleManager {
|
|||||||
this.hdpiManager.zoomModifier = zoomModifier;
|
this.hdpiManager.zoomModifier = zoomModifier;
|
||||||
this.applyNewSize();
|
this.applyNewSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const waScaleManager = new WaScaleManager(640*480, 196*196);
|
export const waScaleManager = new WaScaleManager(640*480, 196*196);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Direction } from "../../types";
|
import type { Direction } from "../../types";
|
||||||
import {GameScene} from "../Game/GameScene";
|
import type {GameScene} from "../Game/GameScene";
|
||||||
import {touchScreenManager} from "../../Touch/TouchScreenManager";
|
import {touchScreenManager} from "../../Touch/TouchScreenManager";
|
||||||
import {MobileJoystick} from "../Components/MobileJoystick";
|
import {MobileJoystick} from "../Components/MobileJoystick";
|
||||||
|
|
||||||
@ -173,7 +173,7 @@ export class UserInputManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
destroy(): void {
|
destroy(): void {
|
||||||
this.joystick.destroy();
|
this.joystick?.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private initMouseWheel() {
|
private initMouseWheel() {
|
||||||
|
3
front/src/Stores/MenuStore.ts
Normal file
3
front/src/Stores/MenuStore.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { derived, writable, Writable } from "svelte/store";
|
||||||
|
|
||||||
|
export const menuIconVisible = writable(false);
|
@ -1,4 +1,4 @@
|
|||||||
import {Room} from "../Connexion/Room";
|
import type {Room} from "../Connexion/Room";
|
||||||
|
|
||||||
export enum GameConnexionTypes {
|
export enum GameConnexionTypes {
|
||||||
anonymous=1,
|
anonymous=1,
|
||||||
|
@ -32,7 +32,7 @@ class CoWebsiteManager {
|
|||||||
private resizing: boolean = false;
|
private resizing: boolean = false;
|
||||||
private cowebsiteMainDom: HTMLDivElement;
|
private cowebsiteMainDom: HTMLDivElement;
|
||||||
private cowebsiteAsideDom: HTMLDivElement;
|
private cowebsiteAsideDom: HTMLDivElement;
|
||||||
|
|
||||||
get width(): number {
|
get width(): number {
|
||||||
return this.cowebsiteDiv.clientWidth;
|
return this.cowebsiteDiv.clientWidth;
|
||||||
}
|
}
|
||||||
@ -137,14 +137,14 @@ class CoWebsiteManager {
|
|||||||
if (allowPolicy) {
|
if (allowPolicy) {
|
||||||
iframe.allow = allowPolicy;
|
iframe.allow = allowPolicy;
|
||||||
}
|
}
|
||||||
const onloadPromise = new Promise((resolve) => {
|
const onloadPromise = new Promise<void>((resolve) => {
|
||||||
iframe.onload = () => resolve();
|
iframe.onload = () => resolve();
|
||||||
});
|
});
|
||||||
if (allowApi) {
|
if (allowApi) {
|
||||||
iframeListener.registerIframe(iframe);
|
iframeListener.registerIframe(iframe);
|
||||||
}
|
}
|
||||||
this.cowebsiteMainDom.appendChild(iframe);
|
this.cowebsiteMainDom.appendChild(iframe);
|
||||||
const onTimeoutPromise = new Promise((resolve) => {
|
const onTimeoutPromise = new Promise<void>((resolve) => {
|
||||||
setTimeout(() => resolve(), 2000);
|
setTimeout(() => resolve(), 2000);
|
||||||
});
|
});
|
||||||
this.currentOperationPromise = this.currentOperationPromise.then(() =>Promise.race([onloadPromise, onTimeoutPromise])).then(() => {
|
this.currentOperationPromise = this.currentOperationPromise.then(() =>Promise.race([onloadPromise, onTimeoutPromise])).then(() => {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import {HtmlUtils} from "./HtmlUtils";
|
import {HtmlUtils} from "./HtmlUtils";
|
||||||
import {mediaManager, ReportCallback, ShowReportCallBack} from "./MediaManager";
|
import type {ShowReportCallBack} from "./MediaManager";
|
||||||
import {UserInputManager} from "../Phaser/UserInput/UserInputManager";
|
import type {UserInputManager} from "../Phaser/UserInput/UserInputManager";
|
||||||
import {connectionManager} from "../Connexion/ConnectionManager";
|
import {connectionManager} from "../Connexion/ConnectionManager";
|
||||||
import {GameConnexionTypes} from "../Url/UrlManager";
|
import {GameConnexionTypes} from "../Url/UrlManager";
|
||||||
import {iframeListener} from "../Api/IframeListener";
|
import {iframeListener} from "../Api/IframeListener";
|
||||||
|
@ -10,9 +10,10 @@ interface jitsiConfigInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const getDefaultConfig = () : jitsiConfigInterface => {
|
const getDefaultConfig = () : jitsiConfigInterface => {
|
||||||
|
const constraints = mediaManager.getConstraintRequestedByUser();
|
||||||
return {
|
return {
|
||||||
startWithAudioMuted: !mediaManager.constraintsMedia.audio,
|
startWithAudioMuted: !constraints.audio,
|
||||||
startWithVideoMuted: mediaManager.constraintsMedia.video === false,
|
startWithVideoMuted: constraints.video === false,
|
||||||
prejoinPageEnabled: false
|
prejoinPageEnabled: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,7 +72,7 @@ class JitsiFactory {
|
|||||||
private jitsiApi: any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
private jitsiApi: any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||||
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;
|
private jitsiScriptLoaded: boolean = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -136,32 +137,24 @@ class JitsiFactory {
|
|||||||
|
|
||||||
//restore previous config
|
//restore previous config
|
||||||
if(this.previousConfigMeet?.startWithAudioMuted){
|
if(this.previousConfigMeet?.startWithAudioMuted){
|
||||||
mediaManager.disableMicrophone();
|
await mediaManager.disableMicrophone();
|
||||||
}else{
|
}else{
|
||||||
mediaManager.enableMicrophone();
|
await mediaManager.enableMicrophone();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.previousConfigMeet?.startWithVideoMuted){
|
if(this.previousConfigMeet?.startWithVideoMuted){
|
||||||
mediaManager.disableCamera();
|
await mediaManager.disableCamera();
|
||||||
}else{
|
}else{
|
||||||
mediaManager.enableCamera();
|
await mediaManager.enableCamera();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private onAudioChange({muted}: {muted: boolean}): void {
|
private onAudioChange({muted}: {muted: boolean}): void {
|
||||||
if (muted && mediaManager.constraintsMedia.audio === true) {
|
this.previousConfigMeet.startWithAudioMuted = muted;
|
||||||
mediaManager.disableMicrophone();
|
|
||||||
} else if(!muted && mediaManager.constraintsMedia.audio === false) {
|
|
||||||
mediaManager.enableMicrophone();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private onVideoChange({muted}: {muted: boolean}): void {
|
private onVideoChange({muted}: {muted: boolean}): void {
|
||||||
if (muted && mediaManager.constraintsMedia.video !== false) {
|
this.previousConfigMeet.startWithVideoMuted = muted;
|
||||||
mediaManager.disableCamera();
|
|
||||||
} else if(!muted && mediaManager.constraintsMedia.video === false) {
|
|
||||||
mediaManager.enableCamera();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async loadJitsiScript(domain: string): Promise<void> {
|
private async loadJitsiScript(domain: string): Promise<void> {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { UserInputManager } from "../Phaser/UserInput/UserInputManager";
|
import type { UserInputManager } from "../Phaser/UserInput/UserInputManager";
|
||||||
import {HtmlUtils} from "./HtmlUtils";
|
import {HtmlUtils} from "./HtmlUtils";
|
||||||
|
|
||||||
export enum LayoutMode {
|
export enum LayoutMode {
|
||||||
@ -324,7 +324,7 @@ class LayoutManager {
|
|||||||
public addActionButton(id: string, text: string, callBack: Function, userInputManager: UserInputManager){
|
public addActionButton(id: string, text: string, callBack: Function, userInputManager: UserInputManager){
|
||||||
//delete previous element
|
//delete previous element
|
||||||
this.removeActionButton(id, userInputManager);
|
this.removeActionButton(id, userInputManager);
|
||||||
|
|
||||||
//create div and text html component
|
//create div and text html component
|
||||||
const p = document.createElement('p');
|
const p = document.createElement('p');
|
||||||
p.classList.add('action-body');
|
p.classList.add('action-body');
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import {DivImportance, layoutManager} from "./LayoutManager";
|
import {DivImportance, layoutManager} from "./LayoutManager";
|
||||||
import {HtmlUtils} from "./HtmlUtils";
|
import {HtmlUtils} from "./HtmlUtils";
|
||||||
import {discussionManager, SendMessageCallback} from "./DiscussionManager";
|
import {discussionManager, SendMessageCallback} from "./DiscussionManager";
|
||||||
import {UserInputManager} from "../Phaser/UserInput/UserInputManager";
|
import type {UserInputManager} from "../Phaser/UserInput/UserInputManager";
|
||||||
import {localUserStore} from "../Connexion/LocalUserStore";
|
import {localUserStore} from "../Connexion/LocalUserStore";
|
||||||
import {UserSimplePeerInterface} from "./SimplePeer";
|
import type {UserSimplePeerInterface} from "./SimplePeer";
|
||||||
import {SoundMeter} from "../Phaser/Components/SoundMeter";
|
import {SoundMeter} from "../Phaser/Components/SoundMeter";
|
||||||
|
import {DISABLE_NOTIFICATIONS} from "../Enum/EnvironmentVariable";
|
||||||
|
|
||||||
declare const navigator:any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
declare const navigator:any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ const audioConstraint: boolean|MediaTrackConstraints = {
|
|||||||
//TODO: make these values configurable in the game settings menu and store them in localstorage
|
//TODO: make these values configurable in the game settings menu and store them in localstorage
|
||||||
autoGainControl: false,
|
autoGainControl: false,
|
||||||
echoCancellation: true,
|
echoCancellation: true,
|
||||||
noiseSuppression: false
|
noiseSuppression: true
|
||||||
};
|
};
|
||||||
|
|
||||||
export type UpdatedLocalStreamCallback = (media: MediaStream|null) => void;
|
export type UpdatedLocalStreamCallback = (media: MediaStream|null) => void;
|
||||||
@ -43,7 +44,8 @@ export class MediaManager {
|
|||||||
microphoneClose: HTMLImageElement;
|
microphoneClose: HTMLImageElement;
|
||||||
microphone: HTMLImageElement;
|
microphone: HTMLImageElement;
|
||||||
webrtcInAudio: HTMLAudioElement;
|
webrtcInAudio: HTMLAudioElement;
|
||||||
mySoundMeterElement: HTMLDivElement;
|
//FIX ME SOUNDMETER: check stalability of sound meter calculation
|
||||||
|
//mySoundMeterElement: HTMLDivElement;
|
||||||
private webrtcOutAudio: HTMLAudioElement;
|
private webrtcOutAudio: HTMLAudioElement;
|
||||||
constraintsMedia : MediaStreamConstraints = {
|
constraintsMedia : MediaStreamConstraints = {
|
||||||
audio: audioConstraint,
|
audio: audioConstraint,
|
||||||
@ -54,7 +56,7 @@ export class MediaManager {
|
|||||||
stopScreenSharingCallBacks : Set<StopScreenSharingCallback> = new Set<StopScreenSharingCallback>();
|
stopScreenSharingCallBacks : Set<StopScreenSharingCallback> = new Set<StopScreenSharingCallback>();
|
||||||
showReportModalCallBacks : Set<ShowReportCallBack> = new Set<ShowReportCallBack>();
|
showReportModalCallBacks : Set<ShowReportCallBack> = new Set<ShowReportCallBack>();
|
||||||
helpCameraSettingsCallBacks : Set<HelpCameraSettingsCallBack> = new Set<HelpCameraSettingsCallBack>();
|
helpCameraSettingsCallBacks : Set<HelpCameraSettingsCallBack> = new Set<HelpCameraSettingsCallBack>();
|
||||||
|
|
||||||
private microphoneBtn: HTMLDivElement;
|
private microphoneBtn: HTMLDivElement;
|
||||||
private cinemaBtn: HTMLDivElement;
|
private cinemaBtn: HTMLDivElement;
|
||||||
private monitorBtn: HTMLDivElement;
|
private monitorBtn: HTMLDivElement;
|
||||||
@ -62,18 +64,16 @@ export class MediaManager {
|
|||||||
private previousConstraint : MediaStreamConstraints;
|
private previousConstraint : MediaStreamConstraints;
|
||||||
private focused : boolean = true;
|
private focused : boolean = true;
|
||||||
|
|
||||||
private lastUpdateScene : Date = new Date();
|
|
||||||
private setTimeOutlastUpdateScene? : NodeJS.Timeout;
|
|
||||||
|
|
||||||
private hasCamera = true;
|
private hasCamera = true;
|
||||||
|
|
||||||
private triggerCloseJistiFrame : Map<String, Function> = new Map<String, Function>();
|
private triggerCloseJistiFrame : Map<String, Function> = new Map<String, Function>();
|
||||||
|
|
||||||
private userInputManager?: UserInputManager;
|
private userInputManager?: UserInputManager;
|
||||||
|
|
||||||
private mySoundMeter?: SoundMeter|null;
|
//FIX ME SOUNDMETER: check stalability of sound meter calculation
|
||||||
|
/*private mySoundMeter?: SoundMeter|null;
|
||||||
private soundMeters: Map<string, SoundMeter> = new Map<string, SoundMeter>();
|
private soundMeters: Map<string, SoundMeter> = new Map<string, SoundMeter>();
|
||||||
private soundMeterElements: Map<string, HTMLDivElement> = new Map<string, HTMLDivElement>();
|
private soundMeterElements: Map<string, HTMLDivElement> = new Map<string, HTMLDivElement>();*/
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
||||||
@ -132,17 +132,19 @@ export class MediaManager {
|
|||||||
this.previousConstraint = JSON.parse(JSON.stringify(this.constraintsMedia));
|
this.previousConstraint = JSON.parse(JSON.stringify(this.constraintsMedia));
|
||||||
this.pingCameraStatus();
|
this.pingCameraStatus();
|
||||||
|
|
||||||
this.checkActiveUser(); //todo: desactivated in case of bug
|
//FIX ME SOUNDMETER: check stalability of sound meter calculation
|
||||||
|
/*this.mySoundMeterElement = (HtmlUtils.getElementByIdOrFail('mySoundMeter'));
|
||||||
this.mySoundMeterElement = (HtmlUtils.getElementByIdOrFail('mySoundMeter'));
|
|
||||||
this.mySoundMeterElement.childNodes.forEach((value: ChildNode, index) => {
|
this.mySoundMeterElement.childNodes.forEach((value: ChildNode, index) => {
|
||||||
this.mySoundMeterElement.children.item(index)?.classList.remove('active');
|
this.mySoundMeterElement.children.item(index)?.classList.remove('active');
|
||||||
});
|
});*/
|
||||||
|
|
||||||
|
//Check of ask notification navigator permission
|
||||||
|
this.getNotification();
|
||||||
}
|
}
|
||||||
|
|
||||||
public updateScene(){
|
public updateScene(){
|
||||||
this.lastUpdateScene = new Date();
|
//FIX ME SOUNDMETER: check stalability of sound meter calculation
|
||||||
this.updateSoudMeter();
|
//this.updateSoudMeter();
|
||||||
}
|
}
|
||||||
|
|
||||||
public blurCamera() {
|
public blurCamera() {
|
||||||
@ -154,6 +156,13 @@ export class MediaManager {
|
|||||||
this.disableCamera();
|
this.disableCamera();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the constraint that the user wants (independently of the visibility / jitsi state...)
|
||||||
|
*/
|
||||||
|
public getConstraintRequestedByUser(): MediaStreamConstraints {
|
||||||
|
return this.previousConstraint ?? this.constraintsMedia;
|
||||||
|
}
|
||||||
|
|
||||||
public focusCamera() {
|
public focusCamera() {
|
||||||
if(this.focused){
|
if(this.focused){
|
||||||
return;
|
return;
|
||||||
@ -196,7 +205,7 @@ export class MediaManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public showGameOverlay(){
|
public showGameOverlay(): void {
|
||||||
const gameOverlay = HtmlUtils.getElementByIdOrFail('game-overlay');
|
const gameOverlay = HtmlUtils.getElementByIdOrFail('game-overlay');
|
||||||
gameOverlay.classList.add('active');
|
gameOverlay.classList.add('active');
|
||||||
|
|
||||||
@ -207,7 +216,7 @@ export class MediaManager {
|
|||||||
buttonCloseFrame.removeEventListener('click', functionTrigger);
|
buttonCloseFrame.removeEventListener('click', functionTrigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
public hideGameOverlay(){
|
public hideGameOverlay(): void {
|
||||||
const gameOverlay = HtmlUtils.getElementByIdOrFail('game-overlay');
|
const gameOverlay = HtmlUtils.getElementByIdOrFail('game-overlay');
|
||||||
gameOverlay.classList.remove('active');
|
gameOverlay.classList.remove('active');
|
||||||
|
|
||||||
@ -218,6 +227,11 @@ export class MediaManager {
|
|||||||
buttonCloseFrame.addEventListener('click', functionTrigger);
|
buttonCloseFrame.addEventListener('click', functionTrigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public isGameOverlayVisible(): boolean {
|
||||||
|
const gameOverlay = HtmlUtils.getElementByIdOrFail('game-overlay');
|
||||||
|
return gameOverlay.classList.contains('active');
|
||||||
|
}
|
||||||
|
|
||||||
public updateCameraQuality(value: number) {
|
public updateCameraQuality(value: number) {
|
||||||
this.enableCameraStyle();
|
this.enableCameraStyle();
|
||||||
const newVideoConstraint = JSON.parse(JSON.stringify(videoConstraint));
|
const newVideoConstraint = JSON.parse(JSON.stringify(videoConstraint));
|
||||||
@ -229,29 +243,32 @@ export class MediaManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public enableCamera() {
|
public async enableCamera() {
|
||||||
this.constraintsMedia.video = videoConstraint;
|
this.constraintsMedia.video = videoConstraint;
|
||||||
|
|
||||||
this.getCamera().then((stream: MediaStream) => {
|
try {
|
||||||
|
const stream = await this.getCamera()
|
||||||
//TODO show error message tooltip upper of camera button
|
//TODO show error message tooltip upper of camera button
|
||||||
//TODO message : please check camera permission of your navigator
|
//TODO message : please check camera permission of your navigator
|
||||||
if(stream.getVideoTracks().length === 0) {
|
if(stream.getVideoTracks().length === 0) {
|
||||||
throw Error('Video track is empty, please check camera permission of your navigator')
|
throw new Error('Video track is empty, please check camera permission of your navigator')
|
||||||
}
|
}
|
||||||
this.enableCameraStyle();
|
this.enableCameraStyle();
|
||||||
this.triggerUpdatedLocalStreamCallbacks(stream);
|
this.triggerUpdatedLocalStreamCallbacks(stream);
|
||||||
}).catch((err) => {
|
} catch(err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.disableCameraStyle();
|
this.disableCameraStyle();
|
||||||
|
this.stopCamera();
|
||||||
|
|
||||||
layoutManager.addInformation('warning', 'Camera access denied. Click here and check navigators permissions.', () => {
|
layoutManager.addInformation('warning', 'Camera access denied. Click here and check navigators permissions.', () => {
|
||||||
this.showHelpCameraSettingsCallBack();
|
this.showHelpCameraSettingsCallBack();
|
||||||
}, this.userInputManager);
|
}, this.userInputManager);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async disableCamera() {
|
public async disableCamera() {
|
||||||
this.disableCameraStyle();
|
this.disableCameraStyle();
|
||||||
|
this.stopCamera();
|
||||||
|
|
||||||
if (this.constraintsMedia.audio !== false) {
|
if (this.constraintsMedia.audio !== false) {
|
||||||
const stream = await this.getCamera();
|
const stream = await this.getCamera();
|
||||||
@ -261,25 +278,27 @@ export class MediaManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enableMicrophone() {
|
public async enableMicrophone() {
|
||||||
this.constraintsMedia.audio = audioConstraint;
|
this.constraintsMedia.audio = audioConstraint;
|
||||||
|
|
||||||
this.getCamera().then((stream) => {
|
try {
|
||||||
|
const stream = await this.getCamera();
|
||||||
|
|
||||||
//TODO show error message tooltip upper of camera button
|
//TODO show error message tooltip upper of camera button
|
||||||
//TODO message : please check microphone permission of your navigator
|
//TODO message : please check microphone permission of your navigator
|
||||||
if(stream.getAudioTracks().length === 0) {
|
if (stream.getAudioTracks().length === 0) {
|
||||||
throw Error('Audio track is empty, please check microphone permission of your navigator')
|
throw Error('Audio track is empty, please check microphone permission of your navigator')
|
||||||
}
|
}
|
||||||
this.enableMicrophoneStyle();
|
this.enableMicrophoneStyle();
|
||||||
this.triggerUpdatedLocalStreamCallbacks(stream);
|
this.triggerUpdatedLocalStreamCallbacks(stream);
|
||||||
}).catch((err) => {
|
} catch(err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.disableMicrophoneStyle();
|
this.disableMicrophoneStyle();
|
||||||
|
|
||||||
layoutManager.addInformation('warning', 'Microphone access denied. Click here and check navigators permissions.', () => {
|
layoutManager.addInformation('warning', 'Microphone access denied. Click here and check navigators permissions.', () => {
|
||||||
this.showHelpCameraSettingsCallBack();
|
this.showHelpCameraSettingsCallBack();
|
||||||
}, this.userInputManager);
|
}, this.userInputManager);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async disableMicrophone() {
|
public async disableMicrophone() {
|
||||||
@ -324,7 +343,6 @@ export class MediaManager {
|
|||||||
this.cinemaBtn.classList.add("disabled");
|
this.cinemaBtn.classList.add("disabled");
|
||||||
this.constraintsMedia.video = false;
|
this.constraintsMedia.video = false;
|
||||||
this.myCamVideo.srcObject = null;
|
this.myCamVideo.srcObject = null;
|
||||||
this.stopCamera();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private enableMicrophoneStyle(){
|
private enableMicrophoneStyle(){
|
||||||
@ -411,7 +429,7 @@ export class MediaManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _startScreenCapture() {
|
private _startScreenCapture() {
|
||||||
if (navigator.getDisplayMedia) {
|
if (navigator.getDisplayMedia) {
|
||||||
return navigator.getDisplayMedia({video: true});
|
return navigator.getDisplayMedia({video: true});
|
||||||
} else if (navigator.mediaDevices.getDisplayMedia) {
|
} else if (navigator.mediaDevices.getDisplayMedia) {
|
||||||
return navigator.mediaDevices.getDisplayMedia({video: true});
|
return navigator.mediaDevices.getDisplayMedia({video: true});
|
||||||
@ -435,6 +453,8 @@ export class MediaManager {
|
|||||||
return this.getLocalStream().catch((err) => {
|
return this.getLocalStream().catch((err) => {
|
||||||
console.info('Error get camera, trying with video option at null =>', err);
|
console.info('Error get camera, trying with video option at null =>', err);
|
||||||
this.disableCameraStyle();
|
this.disableCameraStyle();
|
||||||
|
this.stopCamera();
|
||||||
|
|
||||||
return this.getLocalStream().then((stream : MediaStream) => {
|
return this.getLocalStream().then((stream : MediaStream) => {
|
||||||
this.hasCamera = false;
|
this.hasCamera = false;
|
||||||
return stream;
|
return stream;
|
||||||
@ -457,12 +477,12 @@ export class MediaManager {
|
|||||||
this.localStream = stream;
|
this.localStream = stream;
|
||||||
this.myCamVideo.srcObject = this.localStream;
|
this.myCamVideo.srcObject = this.localStream;
|
||||||
|
|
||||||
//init sound meter
|
//FIX ME SOUNDMETER: check stalability of sound meter calculation
|
||||||
this.mySoundMeter = null;
|
/*this.mySoundMeter = null;
|
||||||
if(this.constraintsMedia.audio){
|
if(this.constraintsMedia.audio){
|
||||||
this.mySoundMeter = new SoundMeter();
|
this.mySoundMeter = new SoundMeter();
|
||||||
this.mySoundMeter.connectToSource(stream, new AudioContext());
|
this.mySoundMeter.connectToSource(stream, new AudioContext());
|
||||||
}
|
}*/
|
||||||
return stream;
|
return stream;
|
||||||
}).catch((err: Error) => {
|
}).catch((err: Error) => {
|
||||||
throw err;
|
throw err;
|
||||||
@ -489,7 +509,7 @@ export class MediaManager {
|
|||||||
track.stop();
|
track.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.mySoundMeter?.stop();
|
//this.mySoundMeter?.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
setCamera(id: string): Promise<MediaStream> {
|
setCamera(id: string): Promise<MediaStream> {
|
||||||
@ -546,7 +566,7 @@ export class MediaManager {
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
layoutManager.add(DivImportance.Normal, userId, html);
|
layoutManager.add(DivImportance.Normal, userId, html);
|
||||||
|
|
||||||
this.remoteVideo.set(userId, HtmlUtils.getElementByIdOrFail<HTMLVideoElement>(userId));
|
this.remoteVideo.set(userId, HtmlUtils.getElementByIdOrFail<HTMLVideoElement>(userId));
|
||||||
|
|
||||||
//permit to create participant in discussion part
|
//permit to create participant in discussion part
|
||||||
@ -564,7 +584,7 @@ export class MediaManager {
|
|||||||
showReportUser();
|
showReportUser();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addScreenSharingActiveVideo(userId: string, divImportance: DivImportance = DivImportance.Important){
|
addScreenSharingActiveVideo(userId: string, divImportance: DivImportance = DivImportance.Important){
|
||||||
|
|
||||||
userId = this.getScreenSharingId(userId);
|
userId = this.getScreenSharingId(userId);
|
||||||
@ -590,7 +610,7 @@ export class MediaManager {
|
|||||||
}
|
}
|
||||||
element.classList.add('active') //todo: why does a method 'disable' add a class 'active'?
|
element.classList.add('active') //todo: why does a method 'disable' add a class 'active'?
|
||||||
}
|
}
|
||||||
|
|
||||||
enabledMicrophoneByUserId(userId: number){
|
enabledMicrophoneByUserId(userId: number){
|
||||||
const element = document.getElementById(`microphone-${userId}`);
|
const element = document.getElementById(`microphone-${userId}`);
|
||||||
if(!element){
|
if(!element){
|
||||||
@ -598,7 +618,7 @@ export class MediaManager {
|
|||||||
}
|
}
|
||||||
element.classList.remove('active') //todo: why does a method 'enable' remove a class 'active'?
|
element.classList.remove('active') //todo: why does a method 'enable' remove a class 'active'?
|
||||||
}
|
}
|
||||||
|
|
||||||
disabledVideoByUserId(userId: number) {
|
disabledVideoByUserId(userId: number) {
|
||||||
let element = document.getElementById(`${userId}`);
|
let element = document.getElementById(`${userId}`);
|
||||||
if (element) {
|
if (element) {
|
||||||
@ -609,7 +629,7 @@ export class MediaManager {
|
|||||||
element.style.display = "block";
|
element.style.display = "block";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enabledVideoByUserId(userId: number){
|
enabledVideoByUserId(userId: number){
|
||||||
let element = document.getElementById(`${userId}`);
|
let element = document.getElementById(`${userId}`);
|
||||||
if(element){
|
if(element){
|
||||||
@ -632,11 +652,12 @@ export class MediaManager {
|
|||||||
}
|
}
|
||||||
remoteVideo.srcObject = stream;
|
remoteVideo.srcObject = stream;
|
||||||
|
|
||||||
|
//FIX ME SOUNDMETER: check stalability of sound meter calculation
|
||||||
//sound metter
|
//sound metter
|
||||||
const soundMeter = new SoundMeter();
|
/*const soundMeter = new SoundMeter();
|
||||||
soundMeter.connectToSource(stream, new AudioContext());
|
soundMeter.connectToSource(stream, new AudioContext());
|
||||||
this.soundMeters.set(userId, soundMeter);
|
this.soundMeters.set(userId, soundMeter);
|
||||||
this.soundMeterElements.set(userId, HtmlUtils.getElementByIdOrFail<HTMLImageElement>('soundMeter-'+userId));
|
this.soundMeterElements.set(userId, HtmlUtils.getElementByIdOrFail<HTMLImageElement>('soundMeter-'+userId));*/
|
||||||
}
|
}
|
||||||
addStreamRemoteScreenSharing(userId: string, stream : MediaStream){
|
addStreamRemoteScreenSharing(userId: string, stream : MediaStream){
|
||||||
// In the case of screen sharing (going both ways), we may need to create the HTML element if it does not exist yet
|
// In the case of screen sharing (going both ways), we may need to create the HTML element if it does not exist yet
|
||||||
@ -647,14 +668,15 @@ export class MediaManager {
|
|||||||
|
|
||||||
this.addStreamRemoteVideo(this.getScreenSharingId(userId), stream);
|
this.addStreamRemoteVideo(this.getScreenSharingId(userId), stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeActiveVideo(userId: string){
|
removeActiveVideo(userId: string){
|
||||||
layoutManager.remove(userId);
|
layoutManager.remove(userId);
|
||||||
this.remoteVideo.delete(userId);
|
this.remoteVideo.delete(userId);
|
||||||
|
|
||||||
this.soundMeters.get(userId)?.stop();
|
//FIX ME SOUNDMETER: check stalability of sound meter calculation
|
||||||
|
/*this.soundMeters.get(userId)?.stop();
|
||||||
this.soundMeters.delete(userId);
|
this.soundMeters.delete(userId);
|
||||||
this.soundMeterElements.delete(userId);
|
this.soundMeterElements.delete(userId);*/
|
||||||
|
|
||||||
//permit to remove user in discussion part
|
//permit to remove user in discussion part
|
||||||
this.removeParticipant(userId);
|
this.removeParticipant(userId);
|
||||||
@ -662,7 +684,7 @@ export class MediaManager {
|
|||||||
removeActiveScreenSharingVideo(userId: string) {
|
removeActiveScreenSharingVideo(userId: string) {
|
||||||
this.removeActiveVideo(this.getScreenSharingId(userId))
|
this.removeActiveVideo(this.getScreenSharingId(userId))
|
||||||
}
|
}
|
||||||
|
|
||||||
playWebrtcOutSound(): void {
|
playWebrtcOutSound(): void {
|
||||||
this.webrtcOutAudio.play();
|
this.webrtcOutAudio.play();
|
||||||
}
|
}
|
||||||
@ -708,7 +730,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
@ -776,22 +798,6 @@ export class MediaManager {
|
|||||||
this.userInputManager = userInputManager;
|
this.userInputManager = userInputManager;
|
||||||
discussionManager.setUserInputManager(userInputManager);
|
discussionManager.setUserInputManager(userInputManager);
|
||||||
}
|
}
|
||||||
//check if user is active
|
|
||||||
private checkActiveUser(){
|
|
||||||
if(this.setTimeOutlastUpdateScene){
|
|
||||||
clearTimeout(this.setTimeOutlastUpdateScene);
|
|
||||||
}
|
|
||||||
this.setTimeOutlastUpdateScene = setTimeout(() => {
|
|
||||||
const now = new Date();
|
|
||||||
//if last update is more of 10 sec
|
|
||||||
if( (now.getTime() - this.lastUpdateScene.getTime()) > 10000) {
|
|
||||||
this.blurCamera();
|
|
||||||
}else{
|
|
||||||
this.focusCamera();
|
|
||||||
}
|
|
||||||
this.checkActiveUser();
|
|
||||||
}, this.focused ? 10000 : 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
public setShowReportModalCallBacks(callback: ShowReportCallBack){
|
public setShowReportModalCallBacks(callback: ShowReportCallBack){
|
||||||
this.showReportModalCallBacks.add(callback);
|
this.showReportModalCallBacks.add(callback);
|
||||||
@ -807,11 +813,12 @@ export class MediaManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSoudMeter(){
|
//FIX ME SOUNDMETER: check stalability of sound meter calculation
|
||||||
|
/*updateSoudMeter(){
|
||||||
try{
|
try{
|
||||||
const volume = parseInt(((this.mySoundMeter ? this.mySoundMeter.getVolume() : 0) / 10).toFixed(0));
|
const volume = parseInt(((this.mySoundMeter ? this.mySoundMeter.getVolume() : 0) / 10).toFixed(0));
|
||||||
this.setVolumeSoundMeter(volume, this.mySoundMeterElement);
|
this.setVolumeSoundMeter(volume, this.mySoundMeterElement);
|
||||||
|
|
||||||
for(const indexUserId of this.soundMeters.keys()){
|
for(const indexUserId of this.soundMeters.keys()){
|
||||||
const soundMeter = this.soundMeters.get(indexUserId);
|
const soundMeter = this.soundMeters.get(indexUserId);
|
||||||
const soundMeterElement = this.soundMeterElements.get(indexUserId);
|
const soundMeterElement = this.soundMeterElements.get(indexUserId);
|
||||||
@ -824,7 +831,7 @@ export class MediaManager {
|
|||||||
}catch(err){
|
}catch(err){
|
||||||
//console.error(err);
|
//console.error(err);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
private setVolumeSoundMeter(volume: number, element: HTMLDivElement){
|
private setVolumeSoundMeter(volume: number, element: HTMLDivElement){
|
||||||
if(volume <= 0 && !element.classList.contains('active')){
|
if(volume <= 0 && !element.classList.contains('active')){
|
||||||
@ -847,6 +854,32 @@ export class MediaManager {
|
|||||||
elementChildre.classList.add('active');
|
elementChildre.classList.add('active');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getNotification(){
|
||||||
|
//Get notification
|
||||||
|
if (!DISABLE_NOTIFICATIONS && window.Notification && Notification.permission !== "granted") {
|
||||||
|
Notification.requestPermission().catch((err) => {
|
||||||
|
console.error(`Notification permission error`, err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public createNotification(userName: string){
|
||||||
|
if(this.focused){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (window.Notification && Notification.permission === "granted") {
|
||||||
|
const title = 'WorkAdventure';
|
||||||
|
const options = {
|
||||||
|
body: `Hi! ${userName} wants to discuss with you, don't be afraid!`,
|
||||||
|
icon: '/resources/logos/logo-WA-min.png',
|
||||||
|
image: '/resources/logos/logo-WA-min.png',
|
||||||
|
badge: '/resources/logos/logo-WA-min.png',
|
||||||
|
};
|
||||||
|
new Notification(title, options);
|
||||||
|
//new Notification(`Hi! ${userName} wants to discuss with you, don't be afraid!`);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mediaManager = new MediaManager();
|
export const mediaManager = new MediaManager();
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import * as SimplePeerNamespace from "simple-peer";
|
import type * as SimplePeerNamespace from "simple-peer";
|
||||||
import {mediaManager} from "./MediaManager";
|
import {mediaManager} from "./MediaManager";
|
||||||
import {STUN_SERVER, TURN_SERVER, TURN_USER, TURN_PASSWORD} from "../Enum/EnvironmentVariable";
|
import {STUN_SERVER, TURN_SERVER, TURN_USER, TURN_PASSWORD} from "../Enum/EnvironmentVariable";
|
||||||
import {RoomConnection} from "../Connexion/RoomConnection";
|
import type {RoomConnection} from "../Connexion/RoomConnection";
|
||||||
import {MESSAGE_TYPE_CONSTRAINT} from "./VideoPeer";
|
import {MESSAGE_TYPE_CONSTRAINT} from "./VideoPeer";
|
||||||
import {UserSimplePeerInterface} from "./SimplePeer";
|
import type {UserSimplePeerInterface} from "./SimplePeer";
|
||||||
|
|
||||||
const Peer: SimplePeerNamespace.SimplePeer = require('simple-peer');
|
const Peer: SimplePeerNamespace.SimplePeer = require('simple-peer');
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import {
|
import type {
|
||||||
WebRtcDisconnectMessageInterface,
|
WebRtcDisconnectMessageInterface,
|
||||||
WebRtcSignalReceivedMessageInterface,
|
WebRtcSignalReceivedMessageInterface,
|
||||||
} from "../Connexion/ConnexionModels";
|
} from "../Connexion/ConnexionModels";
|
||||||
@ -10,7 +10,7 @@ import {
|
|||||||
} from "./MediaManager";
|
} from "./MediaManager";
|
||||||
import {ScreenSharingPeer} from "./ScreenSharingPeer";
|
import {ScreenSharingPeer} from "./ScreenSharingPeer";
|
||||||
import {MESSAGE_TYPE_BLOCKED, MESSAGE_TYPE_CONSTRAINT, MESSAGE_TYPE_MESSAGE, VideoPeer} from "./VideoPeer";
|
import {MESSAGE_TYPE_BLOCKED, MESSAGE_TYPE_CONSTRAINT, MESSAGE_TYPE_MESSAGE, VideoPeer} from "./VideoPeer";
|
||||||
import {RoomConnection} from "../Connexion/RoomConnection";
|
import type {RoomConnection} from "../Connexion/RoomConnection";
|
||||||
import {connectionManager} from "../Connexion/ConnectionManager";
|
import {connectionManager} from "../Connexion/ConnectionManager";
|
||||||
import {GameConnexionTypes} from "../Url/UrlManager";
|
import {GameConnexionTypes} from "../Url/UrlManager";
|
||||||
import {blackListManager} from "./BlackListManager";
|
import {blackListManager} from "./BlackListManager";
|
||||||
@ -158,6 +158,11 @@ export class SimplePeer {
|
|||||||
this.sendLocalScreenSharingStreamToUser(user.userId);
|
this.sendLocalScreenSharingStreamToUser(user.userId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Create a notification for first user in circle discussion
|
||||||
|
if(this.PeerConnectionArray.size === 0){
|
||||||
|
mediaManager.createNotification(user.name??'');
|
||||||
|
}
|
||||||
this.PeerConnectionArray.set(user.userId, peer);
|
this.PeerConnectionArray.set(user.userId, peer);
|
||||||
|
|
||||||
for (const peerConnectionListener of this.peerConnectionListeners) {
|
for (const peerConnectionListener of this.peerConnectionListeners) {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import * as SimplePeerNamespace from "simple-peer";
|
import type * as SimplePeerNamespace from "simple-peer";
|
||||||
import {mediaManager} from "./MediaManager";
|
import {mediaManager} from "./MediaManager";
|
||||||
import {STUN_SERVER, TURN_PASSWORD, TURN_SERVER, TURN_USER} from "../Enum/EnvironmentVariable";
|
import {STUN_SERVER, TURN_PASSWORD, TURN_SERVER, TURN_USER} from "../Enum/EnvironmentVariable";
|
||||||
import {RoomConnection} from "../Connexion/RoomConnection";
|
import type {RoomConnection} from "../Connexion/RoomConnection";
|
||||||
import {blackListManager} from "./BlackListManager";
|
import {blackListManager} from "./BlackListManager";
|
||||||
import {Subscription} from "rxjs";
|
import type {Subscription} from "rxjs";
|
||||||
import {UserSimplePeerInterface} from "./SimplePeer";
|
import type {UserSimplePeerInterface} from "./SimplePeer";
|
||||||
|
|
||||||
const Peer: SimplePeerNamespace.SimplePeer = require('simple-peer');
|
const Peer: SimplePeerNamespace.SimplePeer = require('simple-peer');
|
||||||
|
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
import { ChatEvent } from "./Api/Events/ChatEvent";
|
import type { ChatEvent } from "./Api/Events/ChatEvent";
|
||||||
import { isIframeResponseEventWrapper } from "./Api/Events/IframeEvent";
|
import { isIframeResponseEventWrapper } from "./Api/Events/IframeEvent";
|
||||||
import { isUserInputChatEvent, UserInputChatEvent } from "./Api/Events/UserInputChatEvent";
|
import { isUserInputChatEvent, UserInputChatEvent } from "./Api/Events/UserInputChatEvent";
|
||||||
import { Subject } from "rxjs";
|
import { Subject } from "rxjs";
|
||||||
import { EnterLeaveEvent, isEnterLeaveEvent } from "./Api/Events/EnterLeaveEvent";
|
import { EnterLeaveEvent, isEnterLeaveEvent } from "./Api/Events/EnterLeaveEvent";
|
||||||
import { OpenPopupEvent } from "./Api/Events/OpenPopupEvent";
|
import type { OpenPopupEvent } from "./Api/Events/OpenPopupEvent";
|
||||||
import { isButtonClickedEvent } from "./Api/Events/ButtonClickedEvent";
|
import { isButtonClickedEvent } from "./Api/Events/ButtonClickedEvent";
|
||||||
import { ClosePopupEvent } from "./Api/Events/ClosePopupEvent";
|
import type { ClosePopupEvent } from "./Api/Events/ClosePopupEvent";
|
||||||
import { OpenTabEvent } from "./Api/Events/OpenTabEvent";
|
import type { OpenTabEvent } from "./Api/Events/OpenTabEvent";
|
||||||
import { GoToPageEvent } from "./Api/Events/GoToPageEvent";
|
import type { GoToPageEvent } from "./Api/Events/GoToPageEvent";
|
||||||
import { OpenCoWebSiteEvent } from "./Api/Events/OpenCoWebSiteEvent";
|
import type { OpenCoWebSiteEvent } from "./Api/Events/OpenCoWebSiteEvent";
|
||||||
import { LayerEvent } from "./Api/Events/LayerEvent";
|
import type { LayerEvent } from "./Api/Events/LayerEvent";
|
||||||
import { SetPropertyEvent } from "./Api/Events/setPropertyEvent";
|
import type { SetPropertyEvent } from "./Api/Events/setPropertyEvent";
|
||||||
|
|
||||||
interface WorkAdventureApi {
|
interface WorkAdventureApi {
|
||||||
sendChatMessage(message: string, author: string): void;
|
sendChatMessage(message: string, author: string): void;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import 'phaser';
|
import 'phaser';
|
||||||
import GameConfig = Phaser.Types.Core.GameConfig;
|
import GameConfig = Phaser.Types.Core.GameConfig;
|
||||||
import "../dist/resources/style/index.scss";
|
import "../style/index.scss";
|
||||||
|
|
||||||
import {DEBUG_MODE, isMobile} from "./Enum/EnvironmentVariable";
|
import {DEBUG_MODE, isMobile} from "./Enum/EnvironmentVariable";
|
||||||
import {LoginScene} from "./Phaser/Login/LoginScene";
|
import {LoginScene} from "./Phaser/Login/LoginScene";
|
||||||
@ -21,6 +21,8 @@ import { SelectCharacterMobileScene } from './Phaser/Login/SelectCharacterMobile
|
|||||||
import {HdpiManager} from "./Phaser/Services/HdpiManager";
|
import {HdpiManager} from "./Phaser/Services/HdpiManager";
|
||||||
import {waScaleManager} from "./Phaser/Services/WaScaleManager";
|
import {waScaleManager} from "./Phaser/Services/WaScaleManager";
|
||||||
import {Game} from "./Phaser/Game/Game";
|
import {Game} from "./Phaser/Game/Game";
|
||||||
|
import App from './Components/App.svelte';
|
||||||
|
import {HtmlUtils} from "./WebRtc/HtmlUtils";
|
||||||
|
|
||||||
const {width, height} = coWebsiteManager.getGameSize();
|
const {width, height} = coWebsiteManager.getGameSize();
|
||||||
|
|
||||||
@ -127,19 +129,12 @@ const config: GameConfig = {
|
|||||||
//const game = new Phaser.Game(config);
|
//const game = new Phaser.Game(config);
|
||||||
const game = new Game(config);
|
const game = new Game(config);
|
||||||
|
|
||||||
waScaleManager.setScaleManager(game.scale);
|
waScaleManager.setGame(game);
|
||||||
|
|
||||||
window.addEventListener('resize', function (event) {
|
window.addEventListener('resize', function (event) {
|
||||||
coWebsiteManager.resetStyle();
|
coWebsiteManager.resetStyle();
|
||||||
|
|
||||||
waScaleManager.applyNewSize();
|
waScaleManager.applyNewSize();
|
||||||
|
|
||||||
// Let's trigger the onResize method of any active scene that is a ResizableScene
|
|
||||||
for (const scene of game.scene.getScenes(true)) {
|
|
||||||
if (scene instanceof ResizableScene) {
|
|
||||||
scene.onResize(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
coWebsiteManager.onResize.subscribe(() => {
|
coWebsiteManager.onResize.subscribe(() => {
|
||||||
@ -147,3 +142,10 @@ coWebsiteManager.onResize.subscribe(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
iframeListener.init();
|
iframeListener.init();
|
||||||
|
|
||||||
|
const app = new App({
|
||||||
|
target: HtmlUtils.getElementByIdOrFail('svelte-overlay'),
|
||||||
|
props: { },
|
||||||
|
})
|
||||||
|
|
||||||
|
export default app
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import Phaser from "phaser";
|
import type Phaser from "phaser";
|
||||||
|
|
||||||
export type CursorKey = {
|
export type CursorKey = {
|
||||||
isDown: boolean
|
isDown: boolean
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
transition: transform 0.5s;
|
transition: transform 0.5s;
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
|
||||||
&.loading {
|
&.loading {
|
||||||
background-color: gray;
|
background-color: gray;
|
||||||
}
|
}
|
||||||
@ -15,7 +15,7 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
aside {
|
aside {
|
||||||
background: gray;
|
background: gray;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -32,7 +32,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
height: 25px;
|
height: 25px;
|
Before Width: | Height: | Size: 979 B After Width: | Height: | Size: 979 B |
Before Width: | Height: | Size: 937 B After Width: | Height: | Size: 937 B |
@ -1,9 +1,9 @@
|
|||||||
*{
|
*{
|
||||||
font-family: 'Open Sans', sans-serif;
|
font-family: 'Open Sans', sans-serif;
|
||||||
cursor: url('/resources/logos/cursor_normal.png'), auto;
|
cursor: url('./images/cursor_normal.png'), auto;
|
||||||
}
|
}
|
||||||
* a, button, select{
|
* a, button, select{
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
}
|
}
|
||||||
body{
|
body{
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -39,7 +39,7 @@ body .message-info.warning{
|
|||||||
position: relative;
|
position: relative;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
background-color: #00000099;
|
background-color: #00000099;
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
}
|
}
|
||||||
.video-container i{
|
.video-container i{
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -75,7 +75,7 @@ body .message-info.warning{
|
|||||||
|
|
||||||
.video-container button.report{
|
.video-container button.report{
|
||||||
display: block;
|
display: block;
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
background: none;
|
background: none;
|
||||||
background-color: rgba(0, 0, 0, 0);
|
background-color: rgba(0, 0, 0, 0);
|
||||||
border: none;
|
border: none;
|
||||||
@ -108,7 +108,7 @@ body .message-info.warning{
|
|||||||
left: 5px;
|
left: 5px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
width: 25px;
|
width: 25px;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
}
|
}
|
||||||
@ -118,7 +118,7 @@ body .message-info.warning{
|
|||||||
left: 36px;
|
left: 36px;
|
||||||
color: white;
|
color: white;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
}
|
}
|
||||||
.video-container img.active {
|
.video-container img.active {
|
||||||
display: block !important;
|
display: block !important;
|
||||||
@ -126,7 +126,7 @@ body .message-info.warning{
|
|||||||
|
|
||||||
.video-container video{
|
.video-container video{
|
||||||
height: 100%;
|
height: 100%;
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.video-container video:focus{
|
.video-container video:focus{
|
||||||
@ -206,7 +206,7 @@ video#myCamVideo{
|
|||||||
}
|
}
|
||||||
/*btn animation*/
|
/*btn animation*/
|
||||||
.btn-cam-action div{
|
.btn-cam-action div{
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
/*position: absolute;*/
|
/*position: absolute;*/
|
||||||
border: solid 0px black;
|
border: solid 0px black;
|
||||||
width: 44px;
|
width: 44px;
|
||||||
@ -260,7 +260,7 @@ video#myCamVideo{
|
|||||||
top: calc(48px - 37px);
|
top: calc(48px - 37px);
|
||||||
left: calc(48px - 41px);
|
left: calc(48px - 41px);
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Spinner */
|
/* Spinner */
|
||||||
@ -572,7 +572,7 @@ input[type=range]:focus::-ms-fill-upper {
|
|||||||
margin: 2%;
|
margin: 2%;
|
||||||
flex-basis: 96%;
|
flex-basis: 96%;
|
||||||
transition: margin-left 0.2s, margin-right 0.2s, margin-bottom 0.2s, margin-top 0.2s, flex-basis 0.2s;
|
transition: margin-left 0.2s, margin-right 0.2s, margin-bottom 0.2s, margin-top 0.2s, flex-basis 0.2s;
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
/*flex-shrink: 2;*/
|
/*flex-shrink: 2;*/
|
||||||
}
|
}
|
||||||
@ -590,7 +590,7 @@ input[type=range]:focus::-ms-fill-upper {
|
|||||||
.sidebar > div {
|
.sidebar > div {
|
||||||
margin: 2%;
|
margin: 2%;
|
||||||
transition: margin-left 0.2s, margin-right 0.2s, margin-bottom 0.2s, margin-top 0.2s, max-height 0.2s, max-width 0.2s;
|
transition: margin-left 0.2s, margin-right 0.2s, margin-bottom 0.2s, margin-top 0.2s, max-height 0.2s, max-width 0.2s;
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
border-radius: 15px 15px 15px 15px;
|
border-radius: 15px 15px 15px 15px;
|
||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
@ -600,7 +600,7 @@ input[type=range]:focus::-ms-fill-upper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sidebar > div video {
|
.sidebar > div video {
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Let's make sure videos are vertically centered if they need to be cropped */
|
/* Let's make sure videos are vertically centered if they need to be cropped */
|
||||||
@ -625,7 +625,7 @@ input[type=range]:focus::-ms-fill-upper {
|
|||||||
margin: 1%;
|
margin: 1%;
|
||||||
max-height: 96%;
|
max-height: 96%;
|
||||||
transition: margin-left 0.2s, margin-right 0.2s, margin-bottom 0.2s, margin-top 0.2s;
|
transition: margin-left 0.2s, margin-right 0.2s, margin-bottom 0.2s, margin-top 0.2s;
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-mode > div:hover {
|
.chat-mode > div:hover {
|
||||||
@ -715,7 +715,7 @@ input[type=range]:focus::-ms-fill-upper {
|
|||||||
margin-top: 6px;
|
margin-top: 6px;
|
||||||
width: 30px;
|
width: 30px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
transition: all .5s ease;
|
transition: all .5s ease;
|
||||||
transform: rotateY(0);
|
transform: rotateY(0);
|
||||||
@ -739,7 +739,7 @@ input[type=range]:focus::-ms-fill-upper {
|
|||||||
|
|
||||||
.main-console div.console:hover,
|
.main-console div.console:hover,
|
||||||
.message-container div.clear:hover {
|
.message-container div.clear:hover {
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
top: calc(100% + 5px);
|
top: calc(100% + 5px);
|
||||||
transform: scale(1.2) translateY(3px);
|
transform: scale(1.2) translateY(3px);
|
||||||
}
|
}
|
||||||
@ -772,7 +772,7 @@ input[type=range]:focus::-ms-fill-upper {
|
|||||||
transition: all .2s ease;
|
transition: all .2s ease;
|
||||||
}
|
}
|
||||||
.main-console .btn-action .btn:hover{
|
.main-console .btn-action .btn:hover{
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
background-color: #ffda01;
|
background-color: #ffda01;
|
||||||
color: black;
|
color: black;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
@ -787,7 +787,7 @@ input[type=range]:focus::-ms-fill-upper {
|
|||||||
|
|
||||||
.main-console .menu span {
|
.main-console .menu span {
|
||||||
margin: 20px;
|
margin: 20px;
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-console .menu span.active {
|
.main-console .menu span.active {
|
||||||
@ -821,10 +821,10 @@ input[type=range]:focus::-ms-fill-upper {
|
|||||||
}
|
}
|
||||||
.main-console section div.upload label img{
|
.main-console section div.upload label img{
|
||||||
height: 150px;
|
height: 150px;
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
}
|
}
|
||||||
.main-console section div.upload label img{
|
.main-console section div.upload label img{
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -917,7 +917,7 @@ div.modal-report-user{
|
|||||||
right: 0;
|
right: 0;
|
||||||
left: auto;
|
left: auto;
|
||||||
top: 0;
|
top: 0;
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
width: 15px;
|
width: 15px;
|
||||||
height: 15px;
|
height: 15px;
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
@ -936,7 +936,7 @@ div.modal-report-user{
|
|||||||
transition: all .2s ease;
|
transition: all .2s ease;
|
||||||
}
|
}
|
||||||
.modal-report-user button:hover{
|
.modal-report-user button:hover{
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
background-color: #ffda01;
|
background-color: #ffda01;
|
||||||
color: black;
|
color: black;
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
@ -979,7 +979,7 @@ div.modal-report-user{
|
|||||||
}
|
}
|
||||||
.discussion .active-btn{
|
.discussion .active-btn{
|
||||||
display: none;
|
display: none;
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
width: 50px;
|
width: 50px;
|
||||||
background-color: #2d2d2dba;
|
background-color: #2d2d2dba;
|
||||||
@ -1008,7 +1008,7 @@ div.modal-report-user{
|
|||||||
right: 10px;
|
right: 10px;
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
}
|
}
|
||||||
.discussion .close-btn img{
|
.discussion .close-btn img{
|
||||||
height: 15px;
|
height: 15px;
|
||||||
@ -1033,7 +1033,7 @@ div.modal-report-user{
|
|||||||
background-color: #ffffff69;
|
background-color: #ffffff69;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.discussion .participants .participant:hover{
|
.discussion .participants .participant:hover{
|
||||||
@ -1066,7 +1066,7 @@ div.modal-report-user{
|
|||||||
}
|
}
|
||||||
|
|
||||||
.discussion .participants .participant button.report-btn{
|
.discussion .participants .participant button.report-btn{
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background-color: #2d2d2dba;
|
background-color: #2d2d2dba;
|
||||||
right: 34px;
|
right: 34px;
|
||||||
@ -1176,7 +1176,7 @@ div.action.danger{
|
|||||||
animation-timing-function: ease-in-out;
|
animation-timing-function: ease-in-out;
|
||||||
}
|
}
|
||||||
div.action p.action-body{
|
div.action p.action-body{
|
||||||
cursor: url('/resources/logos/cursor_pointer.png'), pointer;
|
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background-color: #2d2d2dba;
|
background-color: #2d2d2dba;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
@ -1225,3 +1225,11 @@ div.action.danger p.action-body{
|
|||||||
50% {bottom: 30px;}
|
50% {bottom: 30px;}
|
||||||
100% {bottom: 40px;}
|
100% {bottom: 40px;}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#svelte-overlay {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import "jasmine";
|
import "jasmine";
|
||||||
import {Room} from "../../../src/Connexion/Room";
|
import {Room} from "../../../src/Connexion/Room";
|
||||||
import {flattenGroupLayersMap} from "../../../src/Phaser/Map/LayersFlattener";
|
import {flattenGroupLayersMap} from "../../../src/Phaser/Map/LayersFlattener";
|
||||||
import {ITiledMapLayer} from "../../../src/Phaser/Map/ITiledMap";
|
import type {ITiledMapLayer} from "../../../src/Phaser/Map/ITiledMap";
|
||||||
|
|
||||||
describe("Layers flattener", () => {
|
describe("Layers flattener", () => {
|
||||||
it("should iterate maps with no group", () => {
|
it("should iterate maps with no group", () => {
|
||||||
|
@ -50,6 +50,6 @@ describe("Test HdpiManager", () => {
|
|||||||
const result = hdpiManager.getOptimalGameSize({ width: 1280, height: 768 });
|
const result = hdpiManager.getOptimalGameSize({ width: 1280, height: 768 });
|
||||||
expect(result.game.width).toEqual(1280);
|
expect(result.game.width).toEqual(1280);
|
||||||
expect(result.game.height).toEqual(768);
|
expect(result.game.height).toEqual(768);
|
||||||
expect(hdpiManager.zoomModifier).toEqual(1);
|
expect(hdpiManager.zoomModifier).toEqual(2 / 3);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
9
front/tsconfig-for-jasmine.json
Normal file
9
front/tsconfig-for-jasmine.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"include": ["./src/**/*", "./tests/**/*"],
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "CommonJS",
|
||||||
|
"lib": ["es2015","dom"],
|
||||||
|
"types": ["svelte", "node"]
|
||||||
|
},
|
||||||
|
}
|
7
front/tsconfig-for-webpack.json
Normal file
7
front/tsconfig-for-webpack.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "es5",
|
||||||
|
"esModuleInterop": true
|
||||||
|
}
|
||||||
|
}
|
@ -1,16 +1,22 @@
|
|||||||
{
|
{
|
||||||
|
// "include": ["src/**/*", "webpack.config.ts"],
|
||||||
|
|
||||||
|
"extends": "@tsconfig/svelte/tsconfig.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "./dist/",
|
"outDir": "./dist/",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"module": "CommonJS",
|
//"module": "CommonJS",
|
||||||
"target": "ES2015",
|
"module": "ESNext",
|
||||||
|
"target": "ES2017",
|
||||||
"declaration": false,
|
"declaration": false,
|
||||||
"downlevelIteration": true,
|
"downlevelIteration": true,
|
||||||
"jsx": "react",
|
"jsx": "react",
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
|
|
||||||
|
"importsNotUsedAsValues": "error",
|
||||||
|
|
||||||
"strict": true, /* Enable all strict type-checking options. */
|
"strict": true, /* Enable all strict type-checking options. */
|
||||||
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||||
"strictNullChecks": true, /* Enable strict null checks. */
|
"strictNullChecks": true, /* Enable strict null checks. */
|
||||||
|
@ -1,88 +0,0 @@
|
|||||||
const path = require('path');
|
|
||||||
const webpack = require('webpack');
|
|
||||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
|
||||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
entry: {
|
|
||||||
'main': './src/index.ts',
|
|
||||||
'iframe_api': './src/iframe_api.ts'
|
|
||||||
},
|
|
||||||
devtool: 'inline-source-map',
|
|
||||||
devServer: {
|
|
||||||
contentBase: './dist',
|
|
||||||
host: '0.0.0.0',
|
|
||||||
sockPort: 80,
|
|
||||||
disableHostCheck: true,
|
|
||||||
historyApiFallback: {
|
|
||||||
rewrites: [
|
|
||||||
{ from: /^_\/.*$/, to: '/index.html' }
|
|
||||||
],
|
|
||||||
disableDotRule: true
|
|
||||||
},
|
|
||||||
},
|
|
||||||
module: {
|
|
||||||
rules: [
|
|
||||||
{
|
|
||||||
test: /\.tsx?$/,
|
|
||||||
use: 'ts-loader',
|
|
||||||
exclude: /node_modules/,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.scss$/,
|
|
||||||
use: [MiniCssExtractPlugin.loader, 'css-loader?url=false', 'sass-loader'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
resolve: {
|
|
||||||
extensions: [ '.tsx', '.ts', '.js' ],
|
|
||||||
},
|
|
||||||
output: {
|
|
||||||
filename: (pathData) => {
|
|
||||||
// Add a content hash only for the main bundle.
|
|
||||||
// We want the iframe_api.js file to keep its name as it will be referenced from outside iframes.
|
|
||||||
return pathData.chunk.name === 'main' ? 'js/[name].[contenthash].js': '[name].js';
|
|
||||||
},
|
|
||||||
path: path.resolve(__dirname, 'dist'),
|
|
||||||
publicPath: '/'
|
|
||||||
},
|
|
||||||
externals:[
|
|
||||||
require('webpack-require-http')
|
|
||||||
],
|
|
||||||
plugins: [
|
|
||||||
new MiniCssExtractPlugin({filename: 'style.[contenthash].css'}),
|
|
||||||
new HtmlWebpackPlugin(
|
|
||||||
{
|
|
||||||
template: './dist/index.tmpl.html.tmp',
|
|
||||||
minify: {
|
|
||||||
collapseWhitespace: true,
|
|
||||||
keepClosingSlash: true,
|
|
||||||
removeComments: false,
|
|
||||||
removeRedundantAttributes: true,
|
|
||||||
removeScriptTypeAttributes: true,
|
|
||||||
removeStyleLinkTypeAttributes: true,
|
|
||||||
useShortDoctype: true
|
|
||||||
},
|
|
||||||
chunks: ['main']
|
|
||||||
}
|
|
||||||
),
|
|
||||||
new webpack.ProvidePlugin({
|
|
||||||
Phaser: 'phaser'
|
|
||||||
}),
|
|
||||||
new webpack.EnvironmentPlugin({
|
|
||||||
'API_URL': null,
|
|
||||||
'PUSHER_URL': undefined,
|
|
||||||
'UPLOADER_URL': null,
|
|
||||||
'ADMIN_URL': null,
|
|
||||||
'DEBUG_MODE': null,
|
|
||||||
'STUN_SERVER': null,
|
|
||||||
'TURN_SERVER': null,
|
|
||||||
'TURN_USER': null,
|
|
||||||
'TURN_PASSWORD': null,
|
|
||||||
'JITSI_URL': null,
|
|
||||||
'JITSI_PRIVATE_MODE': null,
|
|
||||||
'START_ROOM_URL': null
|
|
||||||
})
|
|
||||||
],
|
|
||||||
|
|
||||||
};
|
|
174
front/webpack.config.ts
Normal file
174
front/webpack.config.ts
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
import type {Configuration} from "webpack";
|
||||||
|
import type WebpackDevServer from "webpack-dev-server";
|
||||||
|
import path from 'path';
|
||||||
|
import webpack from 'webpack';
|
||||||
|
import HtmlWebpackPlugin from 'html-webpack-plugin';
|
||||||
|
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
||||||
|
import sveltePreprocess from 'svelte-preprocess';
|
||||||
|
import ForkTsCheckerWebpackPlugin from "fork-ts-checker-webpack-plugin";
|
||||||
|
import NodePolyfillPlugin from 'node-polyfill-webpack-plugin';
|
||||||
|
|
||||||
|
const mode = process.env.NODE_ENV ?? 'development';
|
||||||
|
const isProduction = mode === 'production';
|
||||||
|
const isDevelopment = !isProduction;
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
entry: {
|
||||||
|
'main': './src/index.ts',
|
||||||
|
'iframe_api': './src/iframe_api.ts'
|
||||||
|
},
|
||||||
|
mode: mode,
|
||||||
|
devtool: isDevelopment ? 'inline-source-map' : 'source-map',
|
||||||
|
devServer: {
|
||||||
|
contentBase: './dist',
|
||||||
|
host: '0.0.0.0',
|
||||||
|
sockPort: 80,
|
||||||
|
disableHostCheck: true,
|
||||||
|
historyApiFallback: {
|
||||||
|
rewrites: [
|
||||||
|
{ from: /^_\/.*$/, to: '/index.html' }
|
||||||
|
],
|
||||||
|
disableDotRule: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.tsx?$/,
|
||||||
|
//use: 'ts-loader',
|
||||||
|
exclude: /node_modules/,
|
||||||
|
loader: 'ts-loader',
|
||||||
|
options: {
|
||||||
|
transpileOnly: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.scss$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
use: [
|
||||||
|
MiniCssExtractPlugin.loader, {
|
||||||
|
loader: 'css-loader',
|
||||||
|
options: {
|
||||||
|
//url: false,
|
||||||
|
sourceMap: true
|
||||||
|
}
|
||||||
|
}, 'sass-loader'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
use: [
|
||||||
|
MiniCssExtractPlugin.loader,
|
||||||
|
{
|
||||||
|
loader: 'css-loader',
|
||||||
|
options: {
|
||||||
|
//url: false,
|
||||||
|
sourceMap: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(html|svelte)$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
use: {
|
||||||
|
loader: 'svelte-loader',
|
||||||
|
options: {
|
||||||
|
compilerOptions: {
|
||||||
|
// Dev mode must be enabled for HMR to work!
|
||||||
|
dev: isDevelopment
|
||||||
|
},
|
||||||
|
emitCss: isProduction,
|
||||||
|
hotReload: isDevelopment,
|
||||||
|
hotOptions: {
|
||||||
|
// List of options and defaults: https://www.npmjs.com/package/svelte-loader-hot#usage
|
||||||
|
noPreserveState: false,
|
||||||
|
optimistic: true,
|
||||||
|
},
|
||||||
|
preprocess: sveltePreprocess({
|
||||||
|
scss: true,
|
||||||
|
sass: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Required to prevent errors from Svelte on Webpack 5+, omit on Webpack 4
|
||||||
|
// See: https://github.com/sveltejs/svelte-loader#usage
|
||||||
|
{
|
||||||
|
test: /node_modules\/svelte\/.*\.mjs$/,
|
||||||
|
resolve: {
|
||||||
|
fullySpecified: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(ttf|eot|svg|png|gif|jpg)$/,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
type: 'asset'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
svelte: path.resolve('node_modules', 'svelte')
|
||||||
|
},
|
||||||
|
extensions: [ '.tsx', '.ts', '.js', '.svelte' ],
|
||||||
|
mainFields: ['svelte', 'browser', 'module', 'main']
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
filename: (pathData) => {
|
||||||
|
// Add a content hash only for the main bundle.
|
||||||
|
// We want the iframe_api.js file to keep its name as it will be referenced from outside iframes.
|
||||||
|
return pathData.chunk?.name === 'main' ? 'js/[name].[contenthash].js': '[name].js';
|
||||||
|
},
|
||||||
|
path: path.resolve(__dirname, 'dist'),
|
||||||
|
publicPath: '/'
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new webpack.HotModuleReplacementPlugin(),
|
||||||
|
new ForkTsCheckerWebpackPlugin({
|
||||||
|
eslint: {
|
||||||
|
files: './src/**/*.ts'
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
new MiniCssExtractPlugin({filename: '[name].[contenthash].css'}),
|
||||||
|
new HtmlWebpackPlugin(
|
||||||
|
{
|
||||||
|
template: './dist/index.tmpl.html.tmp',
|
||||||
|
minify: {
|
||||||
|
collapseWhitespace: true,
|
||||||
|
keepClosingSlash: true,
|
||||||
|
removeComments: false,
|
||||||
|
removeRedundantAttributes: true,
|
||||||
|
removeScriptTypeAttributes: true,
|
||||||
|
removeStyleLinkTypeAttributes: true,
|
||||||
|
useShortDoctype: true
|
||||||
|
},
|
||||||
|
chunks: ['main']
|
||||||
|
}
|
||||||
|
),
|
||||||
|
new webpack.ProvidePlugin({
|
||||||
|
Phaser: 'phaser'
|
||||||
|
}),
|
||||||
|
new NodePolyfillPlugin(),
|
||||||
|
new webpack.EnvironmentPlugin({
|
||||||
|
'API_URL': null,
|
||||||
|
'SKIP_RENDER_OPTIMIZATIONS': false,
|
||||||
|
'DISABLE_NOTIFICATIONS': false,
|
||||||
|
'PUSHER_URL': undefined,
|
||||||
|
'UPLOADER_URL': null,
|
||||||
|
'ADMIN_URL': null,
|
||||||
|
'DEBUG_MODE': null,
|
||||||
|
'STUN_SERVER': null,
|
||||||
|
'TURN_SERVER': null,
|
||||||
|
'TURN_USER': null,
|
||||||
|
'TURN_PASSWORD': null,
|
||||||
|
'JITSI_URL': null,
|
||||||
|
'JITSI_PRIVATE_MODE': null,
|
||||||
|
'START_ROOM_URL': null,
|
||||||
|
'MAX_USERNAME_LENGTH': 8,
|
||||||
|
'MAX_PER_GROUP': 4
|
||||||
|
})
|
||||||
|
],
|
||||||
|
|
||||||
|
} as Configuration & WebpackDevServer.Configuration;
|
@ -1,7 +0,0 @@
|
|||||||
const merge = require('webpack-merge');
|
|
||||||
const common = require('./webpack.config.js');
|
|
||||||
|
|
||||||
module.exports = merge(common, {
|
|
||||||
mode: 'production',
|
|
||||||
devtool: 'source-map'
|
|
||||||
});
|
|
2684
front/yarn.lock
2684
front/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user