diff --git a/docs/maps/images/click_space_jitsi.png b/docs/maps/images/click_space_jitsi.png new file mode 100644 index 00000000..ec7d7198 Binary files /dev/null and b/docs/maps/images/click_space_jitsi.png differ diff --git a/docs/maps/images/click_space_open_website.png b/docs/maps/images/click_space_open_website.png new file mode 100644 index 00000000..09d0daa2 Binary files /dev/null and b/docs/maps/images/click_space_open_website.png differ diff --git a/docs/maps/images/open_website.png b/docs/maps/images/open_website.png new file mode 100644 index 00000000..75023a4e Binary files /dev/null and b/docs/maps/images/open_website.png differ diff --git a/docs/maps/images/open_website_policy.png b/docs/maps/images/open_website_policy.png new file mode 100644 index 00000000..d72e3472 Binary files /dev/null and b/docs/maps/images/open_website_policy.png differ diff --git a/docs/maps/images/youtube.jpg b/docs/maps/images/youtube.jpg new file mode 100644 index 00000000..3dc6c15b Binary files /dev/null and b/docs/maps/images/youtube.jpg differ diff --git a/docs/maps/meeting-rooms.md b/docs/maps/meeting-rooms.md new file mode 100644 index 00000000..97d1b96f --- /dev/null +++ b/docs/maps/meeting-rooms.md @@ -0,0 +1,81 @@ +{.section-title.accent.text-primary} +# Meeting rooms + +https://www.youtube.com/watch?v=cN9VMWHN0eo + +## Opening a Jitsi meet when walking on the map + +On your map, you can define special zones (meeting rooms) that will trigger the opening of a Jitsi meet. When a player will pass over these zones, a Jitsi meet will open (as an iframe on the right side of the screen) + +In order to create Jitsi meet zones: + +* You must create a specific layer. +* In layer properties, you MUST add a "`jitsiRoom`" property (of type "`string`"). The value of the property is the name of the room in Jitsi. Note: the name of the room will be "slugified" and prepended with the name of the instance of the map (so that different instances of the map have different rooms) + +## Triggering of the "Jitsi meet" action + +By default, Jitsi meet will open when a user enters the zone defined on the map. + +It is however possible to trigger Jitsi only on user action. You can do this with the `jitsiTrigger` property. + +If you set `jitsiTrigger: onaction`, when the user walks on the layer, an alert message will be displayed at the bottom of the screen: + +
+ +
Jitsi meet will only open if the user clicks Space
+
+ +If you set `jitsiTriggerMessage: your message action` you can edit alert message displayed. If is not defined, the default message displayed is 'Press on SPACE to enter in jitsi meet room'. + +## Customizing your "Jitsi meet" + +Your Jitsi meet experience can be customized using Jitsi specific config options. The `jitsiConfig` and `jitsiInterfaceConfig` properties can be used on the Jitsi layer to change the way Jitsi looks and behaves. Those 2 properties are accepting a JSON string. + +For instance, use `jitsiConfig: { "startWithAudioMuted": true }` to automatically mute the microphone when someone enters a room. Or use `jitsiInterfaceConfig: { "DEFAULT_BACKGROUND": "#77ee77" }` to change the background color of Jitsi. + +The `jitsiConfig` property will override the Jitsi [config.js](https://github.com/jitsi/jitsi-meet/blob/master/config.js) file + +The `jitsiInterfaceConfig` property will override the Jitsi [interface_config.js](https://github.com/jitsi/jitsi-meet/blob/master/interface_config.js) file + +
If your customizations are not working: + +
+ +## Granting moderator controls in Jitsi + +{.alert.alert-info} +Moderator controls are linked to member tags. You need a pro account to edit member tags. + +You can grant moderator rights to some of your members. Jitsi moderators can: + +* Publish a Jitsi meeting on Youtube Live (you will need a Youtube Live account) +* Record a meeting to Dropbox (you will need a Dropbox account) +* Mute someone +* Mute everybody expect one speaker +* Kick users out of the meeting + +In order to grant moderator rights to a given user, you can add a `jitsiRoomAdminTag` property to your Jitsi layer. For instance, if you write a property: + + jitsiRoomAdminTag: speaker + +then, any of your member with the `speaker` tag will be automatically granted moderator rights over this Jitsi instance. + +You can read more about [managing member tags in the admin documentation](/admin-guide/manage-members). + +## Using another Jitsi server + +WorkAdventure usually comes with a default Jitsi meet installation. If you are using the online version at `workadventu.re`, we are handling a Jitsi meet cluster for you. If you are running the self-hosted version of WorkAdventure, the administrator probably set up a Jitsi meet instance too. + +You have the possibility, in your map, to override the Jitsi meet instance that will be used by default. This can be useful for regulatory reasons. Maybe your company wants to keep control on the video streams and therefore, wants to self-host a Jitsi instance? Or maybe you want to use a very special configuration or very special version of Jitsi? + +Use the `jitsiUrl` property to in the Jitsi layer to specify the Jitsi instance that should be used. Beware, `jitsiUrl` takes in parameter a **domain name**, without the protocol. So you should use: +`jitsiUrl: meet.jit.si` +and not +`jitsiUrl: https://meet.jit.si` + +{.alert.alert-info} +When you use `jitsiUrl`, the targeted Jitsi instance must be public. You cannot use moderation features or the JWT +tokens authentication with maps configured using the `jitsiUrl` property. diff --git a/docs/maps/opening-a-website.md b/docs/maps/opening-a-website.md new file mode 100644 index 00000000..29ea8af1 --- /dev/null +++ b/docs/maps/opening-a-website.md @@ -0,0 +1,65 @@ +{.section-title.accent.text-primary} +# Opening a website when walking on the map + +https://www.youtube.com/watch?v=Me8cu5lLN3A + +## The openWebsite property + +On your map, you can define special zones. When a player will pass over these zones, a website will open (as an iframe +on the right side of the screen) + +In order to create a zone that opens websites: + +* You must create a specific layer. +* In layer properties, you MUST add a "`openWebsite`" property (of type "`string`"). The value of the property is the URL of the website to open (the URL must start with "https://") +* You may also use "`openWebsiteWidth`" property (of type "`number`" between 0 and 100) to control the width of the iframe. + +{.alert.alert-warning} +A website can explicitly forbid another website from loading it in an iFrame using +the [X-Frame-Options HTTP header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options). + +## Integrating a Youtube video + +A common use case is to use `openWebsite` to open a Youtube video. + +The global Youtube page cannot be embedded into an iFrame (it has the `X-Frame-Options` HTTP header). + +To embed a Youtube video, be sure to **use the "embed" link**. You can get this link be clicking "Share > Embed" in Youtube. + +
+ +
Find the URL of your video in the "embed Video" HTML snippet on Youtube
+
+ +
+ +
Put this URL in the "openWebsite" property
+
+ +### Triggering of the "open website" action + +By default, the iFrame will open when a user enters the zone defined on the map. + +It is however possible to trigger the iFrame only on user action. You can do this with the `openWebsiteTrigger` property. + +If you set `openWebsiteTrigger: onaction`, when the user walks on the layer, an alert message will be displayed at the bottom of the screen: + +
+ +
The iFrame will only open if the user clicks Space
+
+ +If you set `openWebsiteTriggerMessage: your message action` you can edit alert message displayed. If is not defined, the default message displayed is 'Press on SPACE to open the web site'. + +### Setting the iFrame "allow" attribute + +By default, iFrames have limited rights in browsers. For instance, they cannot put their content in fullscreen, they cannot start your webcam, etc... + +If you want to grant additional access rights to your iFrame, you should use the `openWebsitePolicy` property. The value of this property will be directly used for the [`allow` atttribute of your iFrame](https://developer.mozilla.org/en-US/docs/Web/HTTP/Feature_Policy/Using_Feature_Policy#the_iframe_allow_attribute). + +For instance, if you want an iFrame to be able to go in fullscreen, you will use the property `openWebsitePolicy: fullscreen` + +
+ +
The generated iFrame will have the allow attribute set to: <iframe allow="fullscreen">
+
diff --git a/docs/maps/special-zones.md b/docs/maps/special-zones.md new file mode 100644 index 00000000..fff4e730 --- /dev/null +++ b/docs/maps/special-zones.md @@ -0,0 +1,27 @@ +{.section-title.accent.text-primary} +# Other special zones + +## Making a "silent" zone + +https://www.youtube.com/watch?v=z7XLo06o-ow + +On your map, you can define special silent zones where nobody is allowed to talk. In these zones, users will not speak to each others, even if they are next to each others. + +In order to create a silent zone: + +* You must create a specific layer. +* In layer properties, you MUST add a boolean "`silent`" property. If the silent property is checked, the users are entering the silent zone when they walk on any tile of the layer. + +## Playing sounds or background music + +Your map can define special zones where a sound or background music will automatically be played. + +In order to create a zone that triggers sounds/music: + +* You must create a specific layer. +* In layer properties, you MUST add a "`playAudio`" property. The value of the property is a URL to an MP3 file that will be played. The URL can be relative to the URL of the map. +* You may use the boolean property "`audioLoop`" to make the sound loop (thanks captain obvious). +* If the "`audioVolume`" property is set, the audio player uses either the value of the property or the last volume set by the user - whichever is smaller. This property is a float from 0 to 1.0 + +{.alert.alert-info} +"`playAudioLoop`" is deprecated and should not be used anymore. diff --git a/docs/maps/using-typescript.md b/docs/maps/using-typescript.md new file mode 100644 index 00000000..3a4c4e07 --- /dev/null +++ b/docs/maps/using-typescript.md @@ -0,0 +1,173 @@ +# Using Typescript with the scripting API + +{.alert.alert-info} +The easiest way to get started with writing scripts in Typescript is to use the +[Github map starter kit repository](https://github.com/thecodingmachine/workadventure-map-starter-kit). It comes with +Typescript enabled. If you are **not** using the "map starter kit", this page explains how to add Typescript to your +own scripts. + +## The short story + +In this page, we will assume you already know Typescript and know how to set it up with Webpack. + +To work with the scripting API in Typescript, you will need the typings of the `WA` object. These typings can be downloaded from the `@workadventure/iframe-api-typings` package. + +```console +$ npm install --save-dev @workadventure/iframe-api-typings +``` + +Furthermore, you need to make the global `WA` object available. To do this, edit the entry point of your project (usually, it is a file called `index.ts` in the root directory). + +Add this line at the top of the file: + +**index.ts** +```typescript +/// +``` + +From there, you should be able to use Typescript in your project. + +## The long story + +Below is a step by step guide explaining how to set up Typescript + Webpack along your WorkAdventure map. + +In your map directory, start by adding a `package.json` file. This file will contain dependencies on Webpack, Typescript and the Workadventure typings: + +**package.json** +```json +{ + "devDependencies": { + "@workadventure/iframe-api-typings": "^1.2.1", + "eslint": "^7.24.0", + "html-webpack-plugin": "^5.3.1", + "ts-loader": "^8.1.0", + "ts-node": "^9.1.1", + "typescript": "^4.2.4", + "webpack": "^5.31.2", + "webpack-cli": "^4.6.0", + "webpack-dev-server": "^3.11.2", + "webpack-merge": "^5.7.3" + }, + "scripts": { + "start": "webpack serve --open", + "build": "webpack --config webpack.prod.js", + } +} +``` + +You can now install the dependencies: + + $ npm install + +We now need to add a Webpack configuration file (for development mode). This Webpack file will: + +* Start a local webserver that will be in charge of serving the map +* Compile Typescript into Javascript and serve it automatically + +**webpack.config.js** + + 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: { + // The test webserver serves static files from the root directory. + // It comes with CORS enabled (important for WorkAdventure to be able to load the map) + 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/, + }, + ], + }, + resolve: { + extensions: [ '.tsx', '.ts', '.js' ], + }, + output: { + filename: 'script.js', + path: path.resolve(__dirname, 'dist'), + publicPath: '/' + } + }; + +We need to configure Typescript, using a `tsconfig.json` file. + +**tsconfig.json** + + { + "compilerOptions": { + "outDir": "./dist/", + "sourceMap": true, + "moduleResolution": "node", + "module": "CommonJS", + "target": "ES2015", + "declaration": false, + "downlevelIteration": true, + "jsx": "react", + "allowJs": true, + "strict": true + } + } + +Create your entry point (the Typescript file at the root of your project). + +**src/index.ts** + + /// + + console.log('Hello world!'); + +The first comment line is important in order to get `WA` typings. + +Now, you can start Webpack in dev mode! + + npm run start + +This will automatically compile Typescript, and serve it (along the map) on your local webserver (so at `http://localhost:8080/script.js`). Please note that the `script.js` file is never written to the disk. So do not worry if you don't see it appearing, you need to "build" it to actually write it to the disk. + +Final step, you must reference the script inside your map, by adding a `script` property at the root of your map: + +
+ +
![]({{url('img/docs/script_property.png')}}) + +
The script property
+ +
+ +
+ +### Building the final script + +We now have a correct development setup. But we still need to be able to build the production script from Typescript files. We are not going to use the development server in production. To do this, we will add an additional `webpack.prod.js` file. + +**webpack.prod.js** + + const { merge } = require('webpack-merge'); + const common = require('./webpack.config.js'); + + module.exports = merge(common, { + mode: 'production', + devtool: 'source-map' + }); + +This file will simply switch the Webpack config file in "production" mode. You can simply run: + + $ npm run build + +and the `script.js` file will be generated in the `dist/` folder. Beware, you will need to move it at the root of map for it to be read by the map.