mirror of
https://github.com/MatomoCamp/workadventure-map.git
synced 2024-09-19 16:03:45 +02:00
Merge pull request #4 from GRL78/customize_iframe
Possibility to configure the map
This commit is contained in:
commit
963a0a99e9
41 changed files with 4858 additions and 4694 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1 +1,3 @@
|
|||
/node_modules/
|
||||
/dist/
|
||||
/yarn.lock
|
||||
|
|
|
@ -25,4 +25,4 @@ terms of use, available online in the following link:
|
|||
|
||||
The terms described in the above link have precedence over the terms described
|
||||
in the present document. In case of disagreement, the Freepik Terms of Use
|
||||
will prevail.
|
||||
will prevail.
|
||||
|
|
BIN
image/mini-config-2-rooms.png
Normal file
BIN
image/mini-config-2-rooms.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
BIN
image/mini-config-3-rooms.png
Normal file
BIN
image/mini-config-3-rooms.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
BIN
image/mini-config-4-rooms.png
Normal file
BIN
image/mini-config-4-rooms.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 34 KiB |
BIN
image/mini-config-5-rooms.png
Normal file
BIN
image/mini-config-5-rooms.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 31 KiB |
1173
map.json
1173
map.json
File diff suppressed because one or more lines are too long
3599
package-lock.json
generated
3599
package-lock.json
generated
File diff suppressed because it is too large
Load diff
30
package.json
30
package.json
|
@ -4,9 +4,24 @@
|
|||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@workadventure/iframe-api-typings": "^1.2.1",
|
||||
"@tsconfig/svelte": "^1.0.10",
|
||||
"@types/mini-css-extract-plugin": "^1.4.3",
|
||||
"@types/webpack-dev-server": "^3.11.4",
|
||||
"@workadventure/iframe-api-typings": "^1.4.12",
|
||||
"cross-env": "^7.0.3",
|
||||
"css-loader": "^5.2.4",
|
||||
"eslint": "^7.24.0",
|
||||
"fork-ts-checker-webpack-plugin": "^6.2.9",
|
||||
"html-webpack-plugin": "^5.3.1",
|
||||
"mini-css-extract-plugin": "^1.6.0",
|
||||
"node-polyfill-webpack-plugin": "^1.1.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"sass": "^1.32.12",
|
||||
"sass-loader": "^11.1.0",
|
||||
"svelte": "^3.38.2",
|
||||
"svelte-check": "^2.1.0",
|
||||
"svelte-loader": "^3.1.1",
|
||||
"svelte-preprocess": "^4.7.3",
|
||||
"ts-loader": "^8.1.0",
|
||||
"ts-node": "^9.1.1",
|
||||
"typescript": "^4.2.4",
|
||||
|
@ -16,10 +31,17 @@
|
|||
"webpack-merge": "^5.7.3"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "webpack serve --open",
|
||||
"build": "webpack --config webpack.prod.js",
|
||||
"start": "run-p serve svelte-check-watch",
|
||||
"serve": "cross-env TS_NODE_PROJECT=\"tsconfig-for-webpack.json\" webpack serve --open",
|
||||
"build": "cross-env TS_NODE_PROJECT=\"tsconfig-for-webpack.json\" NODE_ENV=production webpack",
|
||||
"test": "ts-node node_modules/jasmine/bin/jasmine --config=jasmine.json",
|
||||
"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",
|
||||
"svelte-check-watch": "svelte-check --fail-on-warnings --fail-on-hints --compiler-warnings \"a11y-no-onchange:ignore,a11y-autofocus:ignore,a11y-media-has-caption:ignore\" --watch",
|
||||
"svelte-check": "svelte-check --fail-on-warnings --fail-on-hints --compiler-warnings \"a11y-no-onchange:ignore,a11y-autofocus:ignore,a11y-media-has-caption:ignore\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@fontsource/press-start-2p": "^4.5.0",
|
||||
"nes.css": "^2.3.0"
|
||||
}
|
||||
}
|
||||
|
|
59
src/Components/App.svelte
Normal file
59
src/Components/App.svelte
Normal file
|
@ -0,0 +1,59 @@
|
|||
<script lang="ts">
|
||||
import ChooseSpace from "./ChooseSpace.svelte";
|
||||
import Miniature from "./Miniature.svelte";
|
||||
import type { SvelteComponent } from "svelte";
|
||||
import type { WorkAdventureApi } from "@workadventure/iframe-api-typings";
|
||||
import { ConferenceStore } from "../Stores/ConferenceStore";
|
||||
import { MeetingRoomStore } from "../Stores/MeetingRoomStore";
|
||||
import { OpenCoWebsiteStore } from "../Stores/OpenCoWebsiteStore";
|
||||
import { ExitStore } from "../Stores/ExitStore";
|
||||
import { StartStore } from "../Stores/StartStore";
|
||||
|
||||
|
||||
export let WA: WorkAdventureApi;
|
||||
let selected: { id: number, label: string, component: typeof SvelteComponent };
|
||||
|
||||
function saveMetadata() {
|
||||
WA.state.conference = $ConferenceStore;
|
||||
WA.state.meetingRooms = $MeetingRoomStore;
|
||||
WA.state.receptionWebsite = $OpenCoWebsiteStore;
|
||||
WA.state.exits = $ExitStore;
|
||||
WA.state.starts = $StartStore;
|
||||
}
|
||||
|
||||
function cancel() {
|
||||
WA.nav.closeCoWebSite();
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="main-app">
|
||||
<h1>Configure the room</h1>
|
||||
<Miniature/>
|
||||
<ChooseSpace bind:selected={selected} />
|
||||
|
||||
{#if selected}
|
||||
<svelte:component this="{selected.component}" />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="main-app-btn">
|
||||
<button class="nes-btn" type="button" on:click={cancel}>Cancel</button>
|
||||
<button class="nes-btn is-primary" type="button" on:click={saveMetadata}>Save</button>
|
||||
</div>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
div.main-app {
|
||||
h1 {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 25px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
div.main-app-btn {
|
||||
margin-top: 10px;
|
||||
text-align: right;
|
||||
font-size: 25px;
|
||||
}
|
||||
</style>
|
26
src/Components/ChooseSpace.svelte
Normal file
26
src/Components/ChooseSpace.svelte
Normal file
|
@ -0,0 +1,26 @@
|
|||
<script lang="ts">
|
||||
import ReceptionSpace from "./SpacesComponents/ReceptionSpace.svelte"
|
||||
import AmphiSpace from "./SpacesComponents/AmphiSpace.svelte"
|
||||
import MeetingRoomSpace from "./SpacesComponents/MeetingRoomSpace.svelte"
|
||||
import ExitStartSpace from "./SpacesComponents/ExitStartSpace.svelte"
|
||||
|
||||
const spaces = [
|
||||
{ id: 1, label: "Amphi", component: AmphiSpace },
|
||||
{ id: 2, label: "Reception", component: ReceptionSpace },
|
||||
{ id: 3, label: "Meeting Room", component: MeetingRoomSpace },
|
||||
{ id: 4, label: "Exit/Start", component: ExitStartSpace }
|
||||
]
|
||||
|
||||
export let selected = spaces[0];
|
||||
|
||||
</script>
|
||||
|
||||
<div class="select nes-select">
|
||||
<select bind:value={selected}>
|
||||
{#each spaces as space}
|
||||
<option value="{space}">
|
||||
{space.label}
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
9
src/Components/Configs/ExitConfig.ts
Normal file
9
src/Components/Configs/ExitConfig.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
/**
|
||||
* Declare and export the exitConfig interface
|
||||
*/
|
||||
|
||||
export interface ExitConfig {
|
||||
nameSpace : string,
|
||||
active: boolean,
|
||||
url : string,
|
||||
}
|
12
src/Components/Configs/JitsiConfig.ts
Normal file
12
src/Components/Configs/JitsiConfig.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
/**
|
||||
* Declare and export the jitsiConfig interface
|
||||
*/
|
||||
|
||||
export interface JitsiConfig {
|
||||
nameSpace : string,
|
||||
roomName: string,
|
||||
url : string,
|
||||
audioMute : boolean,
|
||||
videoMute : boolean,
|
||||
adminTags : string[],
|
||||
}
|
12
src/Components/Configs/OpenCoWebSiteConfig.ts
Normal file
12
src/Components/Configs/OpenCoWebSiteConfig.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
/**
|
||||
* Declare and export the openCoWebSiteConfig interface
|
||||
*/
|
||||
|
||||
export interface OpenCoWebSiteConfig {
|
||||
nameSpace : string,
|
||||
url : string,
|
||||
active : number,
|
||||
onaction : boolean,
|
||||
messageTrigger : string,
|
||||
fullscreen : boolean,
|
||||
}
|
11
src/Components/Configs/YoutubeConfig.ts
Normal file
11
src/Components/Configs/YoutubeConfig.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
/**
|
||||
* Declare and export the youtubeConfig interface
|
||||
*/
|
||||
|
||||
export interface YoutubeConfig {
|
||||
nameSpace : string,
|
||||
channelID : string,
|
||||
fullscreen : boolean,
|
||||
autoplay: boolean,
|
||||
pictureInPicture : boolean
|
||||
}
|
87
src/Components/Miniature.svelte
Normal file
87
src/Components/Miniature.svelte
Normal file
|
@ -0,0 +1,87 @@
|
|||
<script lang="ts">
|
||||
import { MeetingRoomStore } from "../Stores/MeetingRoomStore";
|
||||
|
||||
</script>
|
||||
|
||||
<div class="img-miniature">
|
||||
{#if $MeetingRoomStore.nbRooms === 5}
|
||||
<img src="../../image/mini-config-5-rooms.png" alt="Miniature Configuration with 5 rooms"/>
|
||||
{/if}
|
||||
{#if $MeetingRoomStore.nbRooms === 4}
|
||||
<img src="../../image/mini-config-4-rooms.png" alt="Miniature Configuration with 4 rooms"/>
|
||||
{/if}
|
||||
{#if $MeetingRoomStore.nbRooms === 3}
|
||||
<img src="../../image/mini-config-3-rooms.png" alt="Miniature Configuration with 3 rooms"/>
|
||||
{/if}
|
||||
{#if $MeetingRoomStore.nbRooms === 2}
|
||||
<img src="../../image/mini-config-2-rooms.png" alt="Miniature Configuration with 2 rooms"/>
|
||||
{/if}
|
||||
|
||||
<section class="show-space-Amphi">Amphi</section>
|
||||
<section class="show-space-MeetingRoom">Meeting Rooms</section>
|
||||
<section class="show-space-Reception">Reception</section>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
div.img-miniature {
|
||||
position: relative;
|
||||
width: 630px;
|
||||
height: 500px;
|
||||
|
||||
text-align: center;
|
||||
margin-bottom: 25px;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
section {
|
||||
position: absolute;
|
||||
border: #006bb3 2px solid;
|
||||
font-size: 25px;
|
||||
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&.show-space-Amphi {
|
||||
width: 370px;
|
||||
height: 325px;
|
||||
top: 175px;
|
||||
left: 0;
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(45deg, rgb(255, 255, 255, .5) 1%, rgb(0, 107, 179, .5) 1%, rgb(0, 107, 179, .5) 49%, rgb(255, 255, 255, .5) 49%, rgb(255, 255, 255, .5) 51%, rgb(0, 107, 179, .5) 51%, rgb(0, 107, 179, .5) 99%, rgb(255, 255, 255, .5) 99%);
|
||||
background-size: 6px 6px;
|
||||
}
|
||||
}
|
||||
|
||||
&.show-space-Reception {
|
||||
width: 152px;
|
||||
height: 203px;
|
||||
top: 297px;
|
||||
left: 478px;
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(45deg, rgb(255, 255, 255, .5) 1%, rgb(0, 107, 179, .5) 1%, rgb(0, 107, 179, .5) 49%, rgb(255, 255, 255, .5) 49%, rgb(255, 255, 255, .5) 51%, rgb(0, 107, 179, .5) 51%, rgb(0, 107, 179, .5) 99%, rgb(255, 255, 255, .5) 99%);
|
||||
background-size: 6px 6px;
|
||||
}
|
||||
}
|
||||
|
||||
&.show-space-MeetingRoom {
|
||||
width: 630px;
|
||||
height: 150px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
&:hover {
|
||||
background: linear-gradient(45deg, rgb(255, 255, 255, .5) 1%, rgb(0, 107, 179, .5) 1%, rgb(0, 107, 179, .5) 49%, rgb(255, 255, 255, .5) 49%, rgb(255, 255, 255, .5) 51%, rgb(0, 107, 179, .5) 51%, rgb(0, 107, 179, .5) 99%, rgb(255, 255, 255, .5) 99%);
|
||||
background-size: 6px 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
29
src/Components/PropertiesComponents/ExitComponent.svelte
Normal file
29
src/Components/PropertiesComponents/ExitComponent.svelte
Normal file
|
@ -0,0 +1,29 @@
|
|||
<script lang="ts">
|
||||
import { ExitStore } from "../../Stores/ExitStore";
|
||||
import { get } from "svelte/store";
|
||||
|
||||
export let exitNameSpace: string;
|
||||
|
||||
let exitConfig = get(ExitStore).find(e => e.nameSpace == exitNameSpace);
|
||||
let exitActive = exitConfig ? exitConfig.active : false;
|
||||
let exitUrl = exitConfig ? exitConfig.url : '';
|
||||
|
||||
function changeExit() {
|
||||
ExitStore.addExit({nameSpace: exitNameSpace, active: exitActive, url: exitUrl});
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="nes-container with-title">
|
||||
<p class="title">{exitNameSpace}</p>
|
||||
<section on:change={changeExit}>
|
||||
<label>
|
||||
<input type="checkbox" class="nes-checkbox" bind:checked={exitActive}>
|
||||
<span>Enable</span>
|
||||
</label>
|
||||
<label class={!exitActive ? "disabled" : ""}>
|
||||
URL of the next map :
|
||||
<input type="text" class="nes-input" bind:value={exitUrl} disabled="{!exitActive}">
|
||||
</label>
|
||||
</section>
|
||||
</div>
|
48
src/Components/PropertiesComponents/JitsiComponent.svelte
Normal file
48
src/Components/PropertiesComponents/JitsiComponent.svelte
Normal file
|
@ -0,0 +1,48 @@
|
|||
<script lang="ts">
|
||||
import type { JitsiConfig } from "../Configs/JitsiConfig";
|
||||
|
||||
export let jitsi: JitsiConfig;
|
||||
let showMore: boolean = false;
|
||||
|
||||
</script>
|
||||
|
||||
<div class="nes-container with-title">
|
||||
<p class="title">Jitsi</p>
|
||||
<h2>{ jitsi.roomName }</h2>
|
||||
|
||||
<section>
|
||||
<label>
|
||||
Name of the jitsi room :
|
||||
<input type="text" class="nes-input" bind:value={jitsi.roomName}>
|
||||
</label>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<label>
|
||||
<input type="checkbox" class="nes-checkbox" bind:checked={jitsi.audioMute}>
|
||||
<span>Start with audio mute</span>
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" class="nes-checkbox" bind:checked={jitsi.videoMute}>
|
||||
<span>Start with video mute</span>
|
||||
</label>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<p>You need to have the '{jitsi.adminTags}' tag to be moderator of this jitsi.</p>
|
||||
</section>
|
||||
|
||||
<label class="right">
|
||||
<input type="checkbox" class="nes-checkbox" bind:checked={showMore}>
|
||||
<span> More options</span>
|
||||
</label>
|
||||
{#if showMore}
|
||||
<section>
|
||||
<label>
|
||||
Url of the jitsi server :
|
||||
<input type="text" class="nes-input" bind:value={jitsi.url}>
|
||||
</label>
|
||||
<p>(If empty the jitsi room will use the default jitsi server of your workadventure version)</p>
|
||||
</section>
|
||||
{/if}
|
||||
</div>
|
|
@ -0,0 +1,42 @@
|
|||
<script lang="ts">
|
||||
import type { OpenCoWebSiteConfig } from "../Configs/OpenCoWebSiteConfig";
|
||||
|
||||
export let openCoWebSite: OpenCoWebSiteConfig
|
||||
|
||||
</script>
|
||||
|
||||
<div class="nes-container with-title">
|
||||
<p class="title">OpenCoWebSite</p>
|
||||
<section class="centered">
|
||||
<p>Do you want an OpenCoWebSite in your reception ?</p>
|
||||
<label>
|
||||
<input type="radio" class="nes-radio" bind:group={openCoWebSite.active} value={1}>
|
||||
<span>Yes</span>
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" class="nes-radio" bind:group={openCoWebSite.active} value={0}>
|
||||
<span>No</span>
|
||||
</label>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<label class={!openCoWebSite.active ? "disabled" : ""}>
|
||||
URL :
|
||||
<input type="text" class="nes-input" bind:value={openCoWebSite.url} disabled={!openCoWebSite.active}>
|
||||
</label>
|
||||
<label class={!openCoWebSite.active ? "disabled" : ""}>
|
||||
<input type="checkbox" class="nes-checkbox" bind:checked={openCoWebSite.fullscreen} disabled={!openCoWebSite.active}>
|
||||
<span>Fullscreen</span>
|
||||
</label>
|
||||
</section>
|
||||
<section>
|
||||
<label class={!openCoWebSite.active ? "disabled" : ""}>
|
||||
<input type="checkbox" class="nes-checkbox" bind:checked={openCoWebSite.onaction} disabled={!openCoWebSite.active}>
|
||||
<span>Trigger by action</span>
|
||||
</label>
|
||||
<label class={!openCoWebSite.active || !openCoWebSite.onaction ? "disabled" : ""}>
|
||||
Message trigger :
|
||||
<input type="text" class="nes-input" bind:value={openCoWebSite.messageTrigger} disabled={!openCoWebSite.active || !openCoWebSite.onaction}>
|
||||
</label>
|
||||
</section>
|
||||
</div>
|
26
src/Components/PropertiesComponents/StartComponent.svelte
Normal file
26
src/Components/PropertiesComponents/StartComponent.svelte
Normal file
|
@ -0,0 +1,26 @@
|
|||
<script lang="ts">
|
||||
import { ExitStore } from "../../Stores/ExitStore";
|
||||
import { StartStore } from "../../Stores/StartStore";
|
||||
|
||||
let starts: string[] = [];
|
||||
|
||||
function changeStart(): void {
|
||||
StartStore.set(starts);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="nes-container with-title">
|
||||
<p class="title">Start</p>
|
||||
<p>Choose the entry point of your map. Use #[entry_point] at the end of the url of the map to enter by this entry point.</p>
|
||||
<p>Default entry will always be 'south'. (even if disable as entry point.)</p>
|
||||
<form on:change={() => changeStart()}>
|
||||
{#each $ExitStore as exit}
|
||||
{#if exit.active }
|
||||
<label class="chooseStart">
|
||||
<input type="checkbox" class="nes-checkbox" bind:group={starts} value="{exit.nameSpace}">
|
||||
<span>{exit.nameSpace}</span>
|
||||
</label>
|
||||
{/if}
|
||||
{/each}
|
||||
</form>
|
||||
</div>
|
30
src/Components/PropertiesComponents/YoutubeComponent.svelte
Normal file
30
src/Components/PropertiesComponents/YoutubeComponent.svelte
Normal file
|
@ -0,0 +1,30 @@
|
|||
<script lang="ts">
|
||||
import type { YoutubeConfig } from "../Configs/YoutubeConfig";
|
||||
|
||||
export let youtube: YoutubeConfig;
|
||||
|
||||
</script>
|
||||
|
||||
<div class="nes-container with-title">
|
||||
<p class="title">Youtube</p>
|
||||
<section>
|
||||
<label>
|
||||
URL Live Stream:
|
||||
<input type="text" class="nes-input" bind:value={youtube.channelID}>
|
||||
</label>
|
||||
</section>
|
||||
<section>
|
||||
<label>
|
||||
<input type="checkbox" class="nes-checkbox" bind:checked={youtube.fullscreen}>
|
||||
<span>Fullscreen</span>
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" class="nes-checkbox" bind:checked={youtube.autoplay}>
|
||||
<span>Autoplay</span>
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" class="nes-checkbox" bind:checked={youtube.pictureInPicture}>
|
||||
<span>Picture-in-picture</span>
|
||||
</label>
|
||||
</section>
|
||||
</div>
|
22
src/Components/SpacesComponents/AmphiSpace.svelte
Normal file
22
src/Components/SpacesComponents/AmphiSpace.svelte
Normal file
|
@ -0,0 +1,22 @@
|
|||
<script lang="ts">
|
||||
import JitsiComponent from "../PropertiesComponents/JitsiComponent.svelte";
|
||||
import YoutubeComponent from "../PropertiesComponents/YoutubeComponent.svelte";
|
||||
import { ConferenceStore } from "../../Stores/ConferenceStore";
|
||||
</script>
|
||||
|
||||
<div class="spaceComponent">
|
||||
<h2>Properties of the amphi</h2>
|
||||
<label>
|
||||
<input type="radio" class="nes-radio" bind:group={$ConferenceStore.typeConference} value={1}>
|
||||
<span>Little conference (50 peoples or less)</span>
|
||||
</label>
|
||||
<label>
|
||||
<input type="radio" class="nes-radio" bind:group={$ConferenceStore.typeConference} value={2}>
|
||||
<span>Big conference (more than 50 peoples)</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<JitsiComponent jitsi={$ConferenceStore.jitsi} />
|
||||
{#if $ConferenceStore.typeConference === 2}
|
||||
<YoutubeComponent youtube={$ConferenceStore.youtube} />
|
||||
{/if}
|
19
src/Components/SpacesComponents/ExitStartSpace.svelte
Normal file
19
src/Components/SpacesComponents/ExitStartSpace.svelte
Normal file
|
@ -0,0 +1,19 @@
|
|||
<script lang="ts">
|
||||
import StartComponent from "../PropertiesComponents/StartComponent.svelte";
|
||||
import ExitComponent from "../PropertiesComponents/ExitComponent.svelte";
|
||||
import { MeetingRoomStore } from "../../Stores/MeetingRoomStore";
|
||||
|
||||
</script>
|
||||
|
||||
<div class="spaceComponent">
|
||||
<h2>Properties of the exits and start</h2>
|
||||
</div>
|
||||
|
||||
{#if $MeetingRoomStore.nbRooms === 2}
|
||||
<ExitComponent exitNameSpace="north"/>
|
||||
{/if}
|
||||
<ExitComponent exitNameSpace="east"/>
|
||||
<ExitComponent exitNameSpace="south"/>
|
||||
<ExitComponent exitNameSpace="west"/>
|
||||
|
||||
<StartComponent/>
|
48
src/Components/SpacesComponents/MeetingRoomSpace.svelte
Normal file
48
src/Components/SpacesComponents/MeetingRoomSpace.svelte
Normal file
|
@ -0,0 +1,48 @@
|
|||
<script lang="ts">
|
||||
import JitsiComponent from "../PropertiesComponents/JitsiComponent.svelte"
|
||||
import { MeetingRoomStore } from "../../Stores/MeetingRoomStore";
|
||||
import { get } from "svelte/store";
|
||||
|
||||
const meetingRooms = [
|
||||
{ id: 1, label : "5 little rooms", nbRooms: 5},
|
||||
{ id: 2, label: "1 big room and 3 little ones", nbRooms: 4 },
|
||||
{ id: 3, label: "2 big rooms and 1 little", nbRooms: 3 },
|
||||
{ id: 4, label: "2 big rooms and north exit", nbRooms: 2 }
|
||||
]
|
||||
|
||||
let selectedMeetingRoom = meetingRooms.find(c => c.nbRooms === get(MeetingRoomStore).nbRooms);
|
||||
|
||||
function onChangeNBRooms() {
|
||||
if (selectedMeetingRoom === undefined) {
|
||||
throw Error("You MUST select a meeting rooms configuration !");
|
||||
}
|
||||
MeetingRoomStore.setNbRooms(selectedMeetingRoom.nbRooms);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="spaceComponent">
|
||||
<h2>Properties of the meeting rooms</h2>
|
||||
</div>
|
||||
|
||||
<div on:change={onChangeNBRooms} class="nes-select">
|
||||
<select bind:value={selectedMeetingRoom}>
|
||||
{#each meetingRooms as meetingRoom}
|
||||
<option value="{meetingRoom}">
|
||||
{meetingRoom.label}
|
||||
</option>
|
||||
{/each}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<p class="text">The list of the meeting rooms is displayed form left to right. (The room on top of the list is the leftest room in the map.)</p>
|
||||
{#each Array($MeetingRoomStore.nbRooms) as _, i}
|
||||
<JitsiComponent jitsi={$MeetingRoomStore.jitsis[i]} />
|
||||
{/each}
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
p.text {
|
||||
margin: 15px;
|
||||
}
|
||||
</style>
|
10
src/Components/SpacesComponents/ReceptionSpace.svelte
Normal file
10
src/Components/SpacesComponents/ReceptionSpace.svelte
Normal file
|
@ -0,0 +1,10 @@
|
|||
<script lang="ts">
|
||||
import OpenCoWebSiteComponent from "../PropertiesComponents/OpenCoWebSiteComponent.svelte";
|
||||
import { OpenCoWebsiteStore } from "../../Stores/OpenCoWebsiteStore";
|
||||
|
||||
</script>
|
||||
|
||||
<div class="spaceComponent">
|
||||
<h2>Properties of the reception</h2>
|
||||
</div>
|
||||
<OpenCoWebSiteComponent openCoWebSite={$OpenCoWebsiteStore}/>
|
36
src/Stores/ConferenceStore.ts
Normal file
36
src/Stores/ConferenceStore.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
import { writable } from "svelte/store";
|
||||
import type { JitsiConfig } from "../Components/Configs/JitsiConfig";
|
||||
import type { YoutubeConfig } from "../Components/Configs/YoutubeConfig";
|
||||
|
||||
/**
|
||||
* A store that contains the type of conference wanted and the configuration of the jitsi and the youtube
|
||||
* TypeConference :
|
||||
* - 1 : Little conference, only jitsi
|
||||
* - 2 : Big conference, jitsi on stage and youtube for audience
|
||||
*/
|
||||
|
||||
export interface TypeConference {
|
||||
typeConference : number,
|
||||
jitsi : JitsiConfig,
|
||||
youtube : YoutubeConfig;
|
||||
}
|
||||
|
||||
export const ConferenceStore = writable<TypeConference>(
|
||||
{
|
||||
typeConference: 1,
|
||||
jitsi : {
|
||||
nameSpace: 'jitsiAmphi/jitsiStage',
|
||||
roomName : "Amphi",
|
||||
url : '',
|
||||
audioMute : false,
|
||||
videoMute : false,
|
||||
adminTags : ["expert"],
|
||||
},
|
||||
youtube : {
|
||||
nameSpace : 'jitsiAmphi/jitsiYoutube',
|
||||
channelID : '',
|
||||
fullscreen : false,
|
||||
autoplay : true,
|
||||
pictureInPicture: false,
|
||||
}
|
||||
});
|
56
src/Stores/ExitStore.ts
Normal file
56
src/Stores/ExitStore.ts
Normal file
|
@ -0,0 +1,56 @@
|
|||
import { writable } from "svelte/store";
|
||||
import type { ExitConfig } from "../Components/Configs/ExitConfig";
|
||||
/**
|
||||
* A store that contains an array of the exit on the map
|
||||
*/
|
||||
|
||||
function createExitStore() {
|
||||
const { subscribe, update } = writable<ExitConfig[]>(
|
||||
[
|
||||
{
|
||||
nameSpace: 'north',
|
||||
active: false,
|
||||
url: '',
|
||||
},
|
||||
{
|
||||
nameSpace: 'east',
|
||||
active: false,
|
||||
url: '',
|
||||
},
|
||||
{
|
||||
nameSpace: 'south',
|
||||
active: true,
|
||||
url: '',
|
||||
},
|
||||
{
|
||||
nameSpace: 'west',
|
||||
active: false,
|
||||
url: '',
|
||||
}
|
||||
]);
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
addExit: (newExit: ExitConfig): void => {
|
||||
update((configs: ExitConfig[]) => {
|
||||
let found = false;
|
||||
for (let config of configs) {
|
||||
if (config.nameSpace === newExit.nameSpace) {
|
||||
config.url = newExit.url;
|
||||
config.active = newExit.active;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
configs.push(newExit);
|
||||
}
|
||||
|
||||
return configs;
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const ExitStore = createExitStore();
|
81
src/Stores/MeetingRoomStore.ts
Normal file
81
src/Stores/MeetingRoomStore.ts
Normal file
|
@ -0,0 +1,81 @@
|
|||
import { writable } from "svelte/store";
|
||||
import type { JitsiConfig } from "../Components/Configs/JitsiConfig";
|
||||
|
||||
|
||||
/**
|
||||
* A store that contains the number of meeting rooms wanted and the configuration of every jitsi of the meeting room.
|
||||
*/
|
||||
|
||||
export interface MeetingRooms {
|
||||
nbRooms : number,
|
||||
jitsis : JitsiConfig[],
|
||||
}
|
||||
|
||||
const defaultMeetingRooms = {
|
||||
nbRooms : 5,
|
||||
jitsis : [
|
||||
{
|
||||
nameSpace : "meetingRoom/meetingroom-1/bottom",
|
||||
roomName : "meetingroom-1",
|
||||
url : '',
|
||||
audioMute : false,
|
||||
videoMute : false,
|
||||
adminTags : ["expert"],
|
||||
},
|
||||
{
|
||||
nameSpace : "meetingRoom/meetingroom-2/bottom",
|
||||
roomName : "meetingroom-2",
|
||||
url : '',
|
||||
audioMute : false,
|
||||
videoMute : false,
|
||||
adminTags : ["expert"],
|
||||
},
|
||||
{
|
||||
nameSpace : "meetingRoom/meetingroom-3/bottom",
|
||||
roomName : "meetingroom-3",
|
||||
url : '',
|
||||
audioMute : false,
|
||||
videoMute : false,
|
||||
adminTags : ["expert"],
|
||||
},
|
||||
{
|
||||
nameSpace : "meetingRoom/meetingroom-4/bottom",
|
||||
roomName : "meetingroom-4",
|
||||
url : '',
|
||||
audioMute : false,
|
||||
videoMute : false,
|
||||
adminTags : ["expert"],
|
||||
},
|
||||
{
|
||||
nameSpace : "meetingRoom/meetingroom-5/bottom",
|
||||
roomName : "meetingroom-5",
|
||||
url : '',
|
||||
audioMute : false,
|
||||
videoMute : false,
|
||||
adminTags : ["expert"],
|
||||
},
|
||||
]
|
||||
};
|
||||
|
||||
function createMeetingRoomStore() {
|
||||
const {subscribe, update, set} = writable<MeetingRooms>(defaultMeetingRooms);
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
set: (value: MeetingRooms|undefined): void => {
|
||||
if (value === undefined) {
|
||||
set(defaultMeetingRooms);
|
||||
} else {
|
||||
set(value);
|
||||
}
|
||||
},
|
||||
setNbRooms: (nb : number): void => {
|
||||
update((meetingRoom : MeetingRooms) => {
|
||||
meetingRoom.nbRooms = nb;
|
||||
return meetingRoom;
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export const MeetingRoomStore = createMeetingRoomStore();
|
16
src/Stores/OpenCoWebsiteStore.ts
Normal file
16
src/Stores/OpenCoWebsiteStore.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { writable } from "svelte/store";
|
||||
import type { OpenCoWebSiteConfig } from "../Components/Configs/OpenCoWebSiteConfig";
|
||||
|
||||
/**
|
||||
* A store that contains an array of the configuration of the OpenCoWebSite of the map
|
||||
*/
|
||||
|
||||
export const OpenCoWebsiteStore = writable<OpenCoWebSiteConfig>(
|
||||
{
|
||||
nameSpace: "reception",
|
||||
url: '',
|
||||
active: 0,
|
||||
onaction : false,
|
||||
messageTrigger: '',
|
||||
fullscreen : false,
|
||||
});
|
7
src/Stores/StartStore.ts
Normal file
7
src/Stores/StartStore.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { writable } from "svelte/store";
|
||||
|
||||
/**
|
||||
* A store that contains the name of the start layer on the map
|
||||
*/
|
||||
|
||||
export const StartStore = writable<string[]>();
|
18
src/Stores/VariableMapper.ts
Normal file
18
src/Stores/VariableMapper.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import type {Readable} from "svelte/store";
|
||||
|
||||
/**
|
||||
* A function that maps a WorkAdventure variable to a Svelte store
|
||||
*
|
||||
* The store is initialized with the value of the variable.
|
||||
*/
|
||||
export function mapVariableToStore(variableName: string, store: Readable<unknown>&{set(this: void, value: unknown): void;}) {
|
||||
store.set(WA.state.loadVariable(variableName));
|
||||
|
||||
store.subscribe((value) => {
|
||||
WA.state.saveVariable(variableName, value);
|
||||
});
|
||||
|
||||
WA.state.onVariableChange(variableName).subscribe((value: unknown) => {
|
||||
store.set(value);
|
||||
});
|
||||
}
|
18
src/iframe.html
Normal file
18
src/iframe.html
Normal file
|
@ -0,0 +1,18 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport"
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
|
||||
<title>WorkAdventure</title>
|
||||
|
||||
<script src="https://play.workadventu.re/iframe_api.js"></script>
|
||||
<link rel="stylesheet" href="./node_modules/nes.css/css/nes.min.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
19
src/iframe.ts
Normal file
19
src/iframe.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
/// <reference path="../node_modules/@workadventure/iframe-api-typings/iframe_api.d.ts" />
|
||||
|
||||
import App from "./Components/App.svelte";
|
||||
import "../style/style.scss";
|
||||
import {mapVariableToStore} from "./Stores/VariableMapper";
|
||||
import {MeetingRoomStore} from "./Stores/MeetingRoomStore";
|
||||
|
||||
WA.onInit().then(() => {
|
||||
//mapVariableToStore('meetingRooms', MeetingRoomStore);
|
||||
});
|
||||
|
||||
const app = new App({
|
||||
target: document.body,
|
||||
props: {
|
||||
WA: WA,
|
||||
}
|
||||
});
|
||||
|
||||
export default app;
|
273
src/index.ts
273
src/index.ts
|
@ -2,6 +2,275 @@
|
|||
|
||||
// You can write your WorkAdventure script here, if any.
|
||||
// The "WA" global object is available from anywhere.
|
||||
import type { TypeConference } from "./Stores/ConferenceStore";
|
||||
import {get} from "svelte/store";
|
||||
import type {MeetingRooms} from "./Stores/MeetingRoomStore";
|
||||
import {OpenCoWebsiteStore} from "./Stores/OpenCoWebsiteStore";
|
||||
import {ExitStore} from "./Stores/ExitStore";
|
||||
import {StartStore} from "./Stores/StartStore";
|
||||
import type {JitsiConfig} from "./Components/Configs/JitsiConfig";
|
||||
import type {OpenCoWebSiteConfig} from "./Components/Configs/OpenCoWebSiteConfig";
|
||||
import type {ExitConfig} from "./Components/Configs/ExitConfig";
|
||||
import type {YoutubeConfig} from "./Components/Configs/YoutubeConfig";
|
||||
|
||||
console.log('Script started successfully');
|
||||
WA.openCoWebSite('https://workadventu.re');
|
||||
WA.ui.registerMenuCommand('Configure the room', () => {
|
||||
WA.nav.openCoWebSite("../iframe.html", true);
|
||||
});
|
||||
/*Start by hiding the following layer :
|
||||
- Open/North
|
||||
- Open/East
|
||||
- Open/West
|
||||
- Close/South
|
||||
- meetingroom-6
|
||||
- meetingroom-7
|
||||
*/
|
||||
WA.room.hideLayer('Open/North');
|
||||
WA.room.hideLayer('Open/East');
|
||||
WA.room.hideLayer('Open/West');
|
||||
WA.room.hideLayer('Close/South');
|
||||
WA.room.hideLayer('meetingroom-6');
|
||||
WA.room.hideLayer('meetingroom-7');
|
||||
|
||||
WA.onInit().then(() => {
|
||||
applyMetadata();
|
||||
});
|
||||
|
||||
function applyMetadata() {
|
||||
deleteJitsi();
|
||||
applyConference();
|
||||
applyMeetingRooms();
|
||||
applyOpenCoWebSite();
|
||||
applyExit();
|
||||
applyStart();
|
||||
}
|
||||
|
||||
function applyConference() {
|
||||
const conference = WA.state.conference as TypeConference|undefined;
|
||||
if (conference === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (conference.typeConference === 1) {
|
||||
applyJitsiConfig(conference.jitsi);
|
||||
applyJitsiConfig(conference.jitsi, "jitsiAmphi/jitsiBetween");
|
||||
applyJitsiConfig(conference.jitsi, "jitsiAmphi/jitsiYoutube");
|
||||
} else if (conference.typeConference === 2) {
|
||||
applyJitsiConfig(conference.jitsi);
|
||||
applyYoutubeConfig(conference.youtube);
|
||||
}
|
||||
}
|
||||
|
||||
WA.state.onVariableChange("conference").subscribe(applyConference);
|
||||
|
||||
function applyMeetingRooms() {
|
||||
const meetingRooms = WA.state.meetingRooms as MeetingRooms|undefined;
|
||||
if (meetingRooms === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (meetingRooms.nbRooms === 2) {
|
||||
for (let i = 0; i < meetingRooms.nbRooms; i++) {
|
||||
applyJitsiConfig(meetingRooms.jitsis[i], "meetingRoom/meetingroom-" + (i + 6) + "/bottom");
|
||||
WA.room.showLayer("meetingroom-" + (i + 6));
|
||||
}
|
||||
|
||||
WA.room.hideLayer("meetingroom-1");
|
||||
WA.room.hideLayer("meetingroom-2");
|
||||
WA.room.hideLayer("meetingroom-3");
|
||||
WA.room.hideLayer("meetingroom-4");
|
||||
WA.room.hideLayer("meetingroom-5");
|
||||
}
|
||||
if (meetingRooms.nbRooms === 3) {
|
||||
applyJitsiConfig(meetingRooms.jitsis[0], "meetingRoom/meetingroom-6/bottom");
|
||||
applyJitsiConfig(meetingRooms.jitsis[1]);
|
||||
applyJitsiConfig(meetingRooms.jitsis[2], "meetingRoom/meetingroom-7/bottom");
|
||||
|
||||
WA.room.showLayer("meetingroom-3");
|
||||
WA.room.showLayer("meetingroom-6");
|
||||
WA.room.showLayer("meetingroom-7");
|
||||
|
||||
WA.room.hideLayer("meetingroom-1");
|
||||
WA.room.hideLayer("meetingroom-2");
|
||||
WA.room.hideLayer("meetingroom-4");
|
||||
WA.room.hideLayer("meetingroom-5");
|
||||
}
|
||||
if (meetingRooms.nbRooms === 4) {
|
||||
applyJitsiConfig(meetingRooms.jitsis[0], "meetingRoom/meetingRoom/meetingroom-6/bottom");
|
||||
WA.room.showLayer("meetingroom-6");
|
||||
|
||||
WA.room.hideLayer("meetingroom-1");
|
||||
WA.room.hideLayer("meetingroom-2");
|
||||
WA.room.hideLayer("meetingroom-7");
|
||||
|
||||
for (let i = 1; i < meetingRooms.nbRooms; i++) {
|
||||
applyJitsiConfig(meetingRooms.jitsis[i]);
|
||||
WA.room.showLayer("meetingroom-" + (i + 2));
|
||||
}
|
||||
}
|
||||
if (meetingRooms.nbRooms === 5) {
|
||||
for (let jitsi of meetingRooms.jitsis) {
|
||||
applyJitsiConfig(jitsi);
|
||||
}
|
||||
WA.room.hideLayer("meetingroom-6");
|
||||
WA.room.hideLayer("meetingroom-7");
|
||||
|
||||
WA.room.showLayer("meetingroom-1");
|
||||
WA.room.showLayer("meetingroom-2");
|
||||
WA.room.showLayer("meetingroom-3");
|
||||
WA.room.showLayer("meetingroom-4");
|
||||
WA.room.showLayer("meetingroom-5");
|
||||
}
|
||||
}
|
||||
|
||||
WA.state.onVariableChange("meetingRooms").subscribe(applyMeetingRooms);
|
||||
|
||||
|
||||
function applyJitsiConfig(jitsiConfig: JitsiConfig, name?: string) {
|
||||
WA.room.setProperty(name ? name : jitsiConfig.nameSpace, "jitsiRoom", jitsiConfig.roomName);
|
||||
if (jitsiConfig.url !== '') {
|
||||
WA.room.setProperty(name ? name : jitsiConfig.nameSpace, "jitsiUrl", jitsiConfig.url);
|
||||
}
|
||||
let jitsiConfigFormat = `{ \"startWithAudioMuted\": ${jitsiConfig.audioMute}, \"startWithVideoMuted\": ${jitsiConfig.videoMute} } `;
|
||||
WA.room.setProperty(name ? name : jitsiConfig.nameSpace, "jitsiConfig", jitsiConfigFormat);
|
||||
}
|
||||
|
||||
function applyYoutubeConfig(youtubeConfig: YoutubeConfig) {
|
||||
WA.room.setProperty(youtubeConfig.nameSpace, "OpenCoWebSite", "https://www.youtube.com/embed/live_stream?channel=" + youtubeConfig.channelID);
|
||||
let youtubeConfigFormat = `${youtubeConfig.fullscreen ? 'fullscreen' : ''}; ${youtubeConfig.autoplay ? 'autoplay' : ''}; ${youtubeConfig.pictureInPicture ? 'picture-in-picture' : ''}`;
|
||||
WA.room.setProperty(youtubeConfig.nameSpace, "OpenCoWebSitePolicy", youtubeConfigFormat);
|
||||
}
|
||||
|
||||
function applyOpenCoWebSite() {
|
||||
const receptionWebsite = WA.state.receptionWebsite as OpenCoWebSiteConfig|undefined;
|
||||
if (receptionWebsite === undefined) {
|
||||
return;
|
||||
}
|
||||
if (receptionWebsite.active) {
|
||||
WA.room.setProperty(receptionWebsite.nameSpace, 'OpenCoWebSite', receptionWebsite.url);
|
||||
let OpenCoWebSiteConfigFormat = `${receptionWebsite.fullscreen ? 'fullscreen' : undefined}`;
|
||||
WA.room.setProperty(receptionWebsite.nameSpace, 'OpenCoWebSitePolicy', OpenCoWebSiteConfigFormat);
|
||||
if (receptionWebsite.onaction) {
|
||||
WA.room.setProperty(receptionWebsite.nameSpace, 'OpenCoWebSiteTrigger', 'onaction');
|
||||
WA.room.setProperty(receptionWebsite.nameSpace, 'OpenCoWebSiteTriggerMessage', receptionWebsite.messageTrigger);
|
||||
}
|
||||
} else {
|
||||
WA.room.setProperty(receptionWebsite.nameSpace, "OpenCoWebSite", undefined);
|
||||
}
|
||||
}
|
||||
|
||||
WA.state.onVariableChange("receptionWebsite").subscribe(applyOpenCoWebSite);
|
||||
|
||||
function applyExit() {
|
||||
const exits = WA.state.exits as ExitConfig[]|undefined;
|
||||
if (exits === undefined) {
|
||||
return;
|
||||
}
|
||||
for (let exit of exits) {
|
||||
if (exit.nameSpace === "north") {
|
||||
if (exit.active) {
|
||||
WA.room.showLayer("Open/North");
|
||||
WA.room.hideLayer("Close/North");
|
||||
WA.room.setProperty("Exit/Open/North/bottom", "exitUrl", exit.url);
|
||||
} else {
|
||||
WA.room.hideLayer("Open/North");
|
||||
WA.room.showLayer("Close/North");
|
||||
WA.room.setProperty("Exit/Open/North/bottom", "exitUrl", undefined);
|
||||
}
|
||||
}
|
||||
if (exit.nameSpace === "south") {
|
||||
if (exit.active) {
|
||||
WA.room.showLayer("Open/South");
|
||||
WA.room.hideLayer("Close/South");
|
||||
WA.room.setProperty("Exit/Open/South/bottom", "exitUrl", exit.url);
|
||||
} else {
|
||||
WA.room.hideLayer("Open/South");
|
||||
WA.room.showLayer("Close/South");
|
||||
WA.room.setProperty("Exit/Open/South/bottom", "exitUrl", undefined);
|
||||
}
|
||||
}
|
||||
if (exit.nameSpace === "east") {
|
||||
if (exit.active) {
|
||||
WA.room.showLayer("Open/East");
|
||||
WA.room.hideLayer("Close/East");
|
||||
WA.room.setProperty("Exit/Open/East/bottom", "exitUrl", exit.url);
|
||||
} else {
|
||||
WA.room.hideLayer("Open/East");
|
||||
WA.room.showLayer("Close/East");
|
||||
WA.room.setProperty("Exit/Open/East/bottom", "exitUrl", undefined);
|
||||
}
|
||||
}
|
||||
if (exit.nameSpace === "west") {
|
||||
if (exit.active) {
|
||||
WA.room.showLayer("Open/West");
|
||||
WA.room.hideLayer("Close/West");
|
||||
WA.room.setProperty("Exit/Open/West/bottom", "exitUrl", exit.url);
|
||||
} else {
|
||||
WA.room.hideLayer("Open/West");
|
||||
WA.room.showLayer("Close/West");
|
||||
WA.room.setProperty("Exit/Open/West/bottom", "exitUrl", undefined);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WA.state.onVariableChange("exits").subscribe(applyExit);
|
||||
|
||||
|
||||
|
||||
function applyStart() {
|
||||
const starts = WA.state.starts as string[]|undefined;
|
||||
if (starts === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let start of starts) {
|
||||
if (start == "north") {
|
||||
WA.room.setTiles([
|
||||
{x: 22, y: 1, tile: start, layer: 'start'},
|
||||
{x: 22, y: 2, tile: start, layer: 'start'},
|
||||
{x: 23, y: 1, tile: start, layer: 'start'},
|
||||
{x: 23, y: 2, tile: start, layer: 'start'}
|
||||
]);
|
||||
} else if (start == "east") {
|
||||
WA.room.setTiles([
|
||||
{x: 43, y: 16, tile: start, layer: 'start'},
|
||||
{x: 43, y: 17, tile: start, layer: 'start'},
|
||||
{x: 44, y: 16, tile: start, layer: 'start'},
|
||||
{x: 44, y: 17, tile: start, layer: 'start'}
|
||||
]);
|
||||
} else if (start == "south") {
|
||||
WA.room.setTiles([
|
||||
{x: 30, y: 34, tile: start, layer: 'start'},
|
||||
{x: 30, y: 35, tile: start, layer: 'start'},
|
||||
{x: 31, y: 34, tile: start, layer: 'start'},
|
||||
{x: 31, y: 35, tile: start, layer: 'start'}
|
||||
]);
|
||||
} else if (start == "west") {
|
||||
WA.room.setTiles([
|
||||
{x: 1, y: 11, tile: start, layer: 'start'},
|
||||
{x: 1, y: 12, tile: start, layer: 'start'},
|
||||
{x: 2, y: 11, tile: start, layer: 'start'},
|
||||
{x: 2, y: 12, tile: start, layer: 'start'}
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WA.state.onVariableChange("starts").subscribe(applyStart);
|
||||
|
||||
function deleteJitsi() {
|
||||
WA.room.setProperty("jitsiAmphi/jitsiStage", "jitsiRoom", undefined);
|
||||
WA.room.setProperty("jitsiAmphi/jitsiBetween", "jitsiRoom", undefined);
|
||||
WA.room.setProperty("jitsiAmphi/jitsiYoutube", "jitsiRoom", undefined);
|
||||
|
||||
WA.room.setProperty("meetingRoom/meetingroom-1/bottom", "jitsiRoom", undefined);
|
||||
WA.room.setProperty("meetingRoom/meetingroom-2/bottom", "jitsiRoom", undefined);
|
||||
WA.room.setProperty("meetingRoom/meetingroom-3/bottom", "jitsiRoom", undefined);
|
||||
WA.room.setProperty("meetingRoom/meetingroom-4/bottom", "jitsiRoom", undefined);
|
||||
WA.room.setProperty("meetingRoom/meetingroom-5/bottom", "jitsiRoom", undefined);
|
||||
WA.room.setProperty("meetingRoom/meetingroom-6/bottom", "jitsiRoom", undefined);
|
||||
WA.room.setProperty("meetingRoom/meetingroom-7/bottom", "jitsiRoom", undefined);
|
||||
}
|
||||
|
||||
|
||||
export {}
|
||||
|
|
57
style/style.scss
Normal file
57
style/style.scss
Normal file
|
@ -0,0 +1,57 @@
|
|||
@import "~@fontsource/press-start-2p/index.css";
|
||||
|
||||
*{
|
||||
font-family: "Press Start 2P";
|
||||
}
|
||||
|
||||
div.main-app div {
|
||||
max-width: 98%;
|
||||
}
|
||||
|
||||
div.nes-select {
|
||||
max-width: 700px;
|
||||
width: 90%;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
|
||||
.spaceComponent {
|
||||
text-align: center;
|
||||
h2 {
|
||||
margin: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
div.nes-container.with-title {
|
||||
margin-top: 25px;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
padding-top: 15px;
|
||||
|
||||
p.title {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
section {
|
||||
margin-top: 20px;
|
||||
|
||||
label.disabled {
|
||||
color: gray;
|
||||
|
||||
input {
|
||||
background-color: lightgray;
|
||||
color: gray;
|
||||
}
|
||||
}
|
||||
|
||||
&.centered {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
7
tsconfig-for-webpack.json
Normal file
7
tsconfig-for-webpack.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"esModuleInterop": true
|
||||
}
|
||||
}
|
|
@ -1,14 +1,18 @@
|
|||
{
|
||||
"extends": "@tsconfig/svelte/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist/",
|
||||
"sourceMap": true,
|
||||
"moduleResolution": "node",
|
||||
"module": "CommonJS",
|
||||
"target": "ES2015",
|
||||
"module": "ESNext",
|
||||
"target": "ES2017",
|
||||
"declaration": false,
|
||||
"downlevelIteration": true,
|
||||
"jsx": "react",
|
||||
"allowJs": true,
|
||||
"esModuleInterop": true,
|
||||
|
||||
"importsNotUsedAsValues": "error",
|
||||
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
|
||||
module.exports = {
|
||||
mode: 'development',
|
||||
entry: './src/index.ts',
|
||||
devtool: 'inline-source-map',
|
||||
devServer: {
|
||||
contentBase: '.',
|
||||
//host: '0.0.0.0',
|
||||
host: 'localhost',
|
||||
//sockPort: 80,
|
||||
disableHostCheck: true,
|
||||
headers: {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
|
||||
"Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
|
||||
}
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
extensions: [ '.tsx', '.ts', '.js' ],
|
||||
},
|
||||
output: {
|
||||
filename: 'script.js',
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
publicPath: '/'
|
||||
},
|
||||
/*externals:[
|
||||
require('webpack-require-http')
|
||||
],*/
|
||||
plugins: [
|
||||
/*new webpack.ProvidePlugin({
|
||||
WA: ['@workadventure/iframe-api-typings', 'window.WA']
|
||||
}),*/
|
||||
/*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
|
||||
})*/
|
||||
],
|
||||
|
||||
};
|
176
webpack.config.ts
Normal file
176
webpack.config.ts
Normal file
|
@ -0,0 +1,176 @@
|
|||
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': './src/iframe.ts'
|
||||
},
|
||||
mode: mode,
|
||||
//devtool: isDevelopment ? 'inline-source-map' : 'source-map',
|
||||
//devtool: isDevelopment ? 'eval' : 'source-map',
|
||||
devServer: {
|
||||
port: 3000,
|
||||
contentBase: '.',
|
||||
host: 'localhost',
|
||||
disableHostCheck: true,
|
||||
headers: {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
|
||||
"Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
|
||||
}
|
||||
},
|
||||
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: /\.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,
|
||||
}),
|
||||
onwarn: function (warning: { code: string }, handleWarning: (warning: { code: string }) => void) {
|
||||
// See https://github.com/sveltejs/svelte/issues/4946#issuecomment-662168782
|
||||
|
||||
/*if (warning.code === 'a11y-no-onchange') { return }
|
||||
if (warning.code === 'a11y-autofocus') { return }
|
||||
if (warning.code === 'a11y-media-has-caption') { return }*/
|
||||
|
||||
// process as usual
|
||||
handleWarning(warning);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 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: /\.(eot|svg|png|gif|jpg)$/,
|
||||
exclude: /node_modules/,
|
||||
type: 'asset'
|
||||
},
|
||||
{
|
||||
test: /\.(woff(2)?|ttf)$/,
|
||||
type: 'asset',
|
||||
generator: {
|
||||
filename: 'fonts/[name][ext]'
|
||||
}
|
||||
|
||||
}
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
svelte: path.resolve('node_modules', 'svelte')
|
||||
},
|
||||
extensions: [ '.tsx', '.ts', '.js', '.svelte' ],
|
||||
mainFields: ['svelte', 'browser', 'module', 'main', 'iframe']
|
||||
},
|
||||
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].js': '[name].[contenthash].js';
|
||||
return pathData.chunk?.name === 'main' ? 'js/[name].js': 'js/[name].[contenthash].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: './src/iframe.html',
|
||||
filename: 'iframe.html',
|
||||
minify: {
|
||||
collapseWhitespace: true,
|
||||
keepClosingSlash: true,
|
||||
removeComments: false,
|
||||
removeRedundantAttributes: true,
|
||||
removeScriptTypeAttributes: true,
|
||||
removeStyleLinkTypeAttributes: true,
|
||||
useShortDoctype: true
|
||||
},
|
||||
chunks: ['iframe']
|
||||
}
|
||||
),
|
||||
new webpack.ProvidePlugin({
|
||||
Phaser: 'phaser'
|
||||
}),
|
||||
new NodePolyfillPlugin()
|
||||
],
|
||||
|
||||
} 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'
|
||||
});
|
Loading…
Reference in a new issue