diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 8e97dc1..0e292fc 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -43,6 +43,7 @@ jobs:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
CI: true
- run: sed -i 's|""|"https://unpkg.com/@workadventure/scripting-api-extra@${{ env.release_tag }}/dist"|g' src/Features/default_assets_url.ts
+ - run: sed -i 's|http://workadventure.localhost|https://workadventu.re|g' src/Features/default_api_url.ts
- run: npm run build --if-present
- run: npm run test
- run: curl -s https://codecov.io/bash | bash
diff --git a/docs/images/logo_upload_configuration_properties.png b/docs/images/logo_upload_configuration_properties.png
new file mode 100644
index 0000000..35154f9
Binary files /dev/null and b/docs/images/logo_upload_configuration_properties.png differ
diff --git a/docs/images/logo_upload_configuration_tile.png b/docs/images/logo_upload_configuration_tile.png
new file mode 100644
index 0000000..74dea3d
Binary files /dev/null and b/docs/images/logo_upload_configuration_tile.png differ
diff --git a/docs/images/logo_upload_demo.gif b/docs/images/logo_upload_demo.gif
new file mode 100644
index 0000000..33fdf9a
Binary files /dev/null and b/docs/images/logo_upload_demo.gif differ
diff --git a/docs/images/logo_upload_embedded_website_object.png b/docs/images/logo_upload_embedded_website_object.png
new file mode 100644
index 0000000..2a93b12
Binary files /dev/null and b/docs/images/logo_upload_embedded_website_object.png differ
diff --git a/docs/images/logo_upload_embedded_website_properties.png b/docs/images/logo_upload_embedded_website_properties.png
new file mode 100644
index 0000000..66ed8a7
Binary files /dev/null and b/docs/images/logo_upload_embedded_website_properties.png differ
diff --git a/docs/images/logo_upload_layers.png b/docs/images/logo_upload_layers.png
new file mode 100644
index 0000000..9377cab
Binary files /dev/null and b/docs/images/logo_upload_layers.png differ
diff --git a/docs/images/logo_upload_objects.png b/docs/images/logo_upload_objects.png
new file mode 100644
index 0000000..52d13d2
Binary files /dev/null and b/docs/images/logo_upload_objects.png differ
diff --git a/docs/images/logo_upload_variable_object.png b/docs/images/logo_upload_variable_object.png
new file mode 100644
index 0000000..8c381a6
Binary files /dev/null and b/docs/images/logo_upload_variable_object.png differ
diff --git a/docs/images/logo_upload_variable_properties.png b/docs/images/logo_upload_variable_properties.png
new file mode 100644
index 0000000..33da7bd
Binary files /dev/null and b/docs/images/logo_upload_variable_properties.png differ
diff --git a/docs/logo-upload.md b/docs/logo-upload.md
new file mode 100644
index 0000000..30dd0b4
--- /dev/null
+++ b/docs/logo-upload.md
@@ -0,0 +1,111 @@
+{.section-title.accent.text-primary}
+# Logo upload
+
+{.alert.alert-info}
+**Important!** To use the "logo upload" feature, you need to [import the "Scripting API Extra" script in your map](about.md#importing-the-extended-features)
+
+The logo upload feature let you customize your maps in a simple way.
+By defining some objects and properties in Tiled you can have a logo appearing in your map. Combined with the local configuration feature,
+you will have the possibility to change your logo at any time just be heading in front of him and by uploading your brand-new logo file!
+
+To achieve this you will need to define 1 layer, 1 object layer and 2 objects in Tiled.
+
+
+
+ Logo upload demo
+
+
+Let's see how this can be done!
+
+## The variable
+
+{.alert.alert-info}
+You can read more about variables [here](https://workadventu.re/map-building/variables.md).
+
+First things first, let's create the variable that will hold the logo URL of the uploaded file.
+Fo this to happen, you need first to upload an image, right?
+
+That's why when creating the variable you will pass a `type: "upload"` to its properties, this will have the effect of displaying an upload button in the configuration panel.
+
+For the upload input to appear in the configuration panel you MUST move this variable object inside an object layer called `configuration`.
+
+
+
+ Variable object
+
+
+
+
+ Variable properties
+
+
+As you can see, besides defining the new `upload` type we can also pass optional properties that will restrict the width and height of you image.
+Specify the number of pixels in width as `imageWidth` value and the number of pixels in height as `imageHeight` value.
+
+## The embedded website
+
+{.alert.alert-info}
+You can read more about embedded websites [here](https://workadventu.re/map-building/website-in-map.md).
+
+
+
+ Embedded website object
+
+
+Create a rectangle object outside the `configuration` object layer (in `floorLayer` for example), this will be out iFrame zone that will be in charge of displaying the actual image.
+You have to set its properties to allow the iFrame to interact with external programs (`allowApi: true`) and set the `url` to use the value of the previously defined variable.
+
+
+
+ Embedded website properties
+
+
+Now, what we are trying to say with this mustache syntax *(it complicates things a bit, but it's actually simple)* is "If there is a URL inside the variable 'logoUrl', pick this URL, otherwise just display another default image": `{{#logoUrl}}{{{logoUrl}}}{{/logoUrl}}{{^logoUrl}}https://workadventu.re/favicon-32x32.png{{/logoUrl}}`.
+
+## The configuration layer
+
+{.alert.alert-info}
+You can read more about the local configuration layer [here](https://workadventu.re/map-building-extra/automatic-configuration.md#local-configuration-panel).
+
+We have the variable object that will hold the image URL, we have the zone to display it, now the final step is to define a zone to be able to upload some new images by configuring the variable value.
+
+We just draw a single tile in front of the logo in a dedicated layer. In its properties we specify the name of the variable to configure with `openConfig: logoUrl`.
+
+
+
+ Configuration tile
+
+
+{.alert.alert-info}
+The rest of the properties are not mandatory. You can restrict who can access to this configuration as well.
+
+
+
+ Configuration properties
+
+
+## Let's recap
+
+To recap, we created 2 objects. One must be in the `configuration` object layer in order to be configurable.
+
+
+
+ Map objects
+
+
+Then, apart from the layers we used to create for a map, we created a layer that will have one tile. This will be the zone in which you can walk to open the local configuration panel. We named this layer 'logoConfiguration'.
+
+
+
+ Map layers
+
+
+That's it! This feature will be integrated with all of our preset maps.
+
+
+
+ Logo upload demo
+
+
+If you want to integrate it yourself into your awesome custom map, now you can!
+You can find the full code of the map that tests the logo upload feature [here](https://github.com/workadventure/scripting-api-extra/blob/main/test/maps/configuration_logo.json).
diff --git a/docs/menu.php b/docs/menu.php
index 6d3bc8b..b8b4789 100644
--- a/docs/menu.php
+++ b/docs/menu.php
@@ -38,6 +38,11 @@
'url' => '/map-building-extra/automatic-configuration.md',
'markdown' => 'scripting_api_extra_doc.automatic-configuration',
'editUrl' => 'https://github.com/workadventure/scripting-api-extra/edit/main/docs/automatic-configuration.md',
+ ],[
+ 'title' => 'Logo upload',
+ 'url' => '/map-building-extra/logo-upload.md',
+ 'markdown' => 'scripting_api_extra_doc.logo-upload',
+ 'editUrl' => 'https://github.com/workadventure/scripting-api-extra/edit/main/docs/logo-upload.md',
],[
'title' => 'Properties reference',
'url' => '/map-building-extra/reference.md',
diff --git a/package-lock.json b/package-lock.json
index 01ce39b..4a4a5d6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2157,9 +2157,9 @@
"dev": true
},
"@workadventure/iframe-api-typings": {
- "version": "1.4.14",
- "resolved": "https://registry.npmjs.org/@workadventure/iframe-api-typings/-/iframe-api-typings-1.4.14.tgz",
- "integrity": "sha512-p9uoU1m6aZD7ut+TGorMRaSB9oxDblwhOYZQgPD2U55jVNmSI9ZAlpp+J4hAvUaIOSP71G2qB7M/FoeyCyX4yA==",
+ "version": "1.6.4",
+ "resolved": "https://registry.npmjs.org/@workadventure/iframe-api-typings/-/iframe-api-typings-1.6.4.tgz",
+ "integrity": "sha512-mz4jvsu/Gn6IuIY84+wYHxT53mf+PY5N/OcpxcE5R/YqxTGbWOW5dFywlDpjG8QWOzunVkYwDCCAPercihJRUg==",
"dev": true
},
"@workadventure/tiled-map-type-guard": {
diff --git a/package.json b/package.json
index db3287b..5a51d1c 100644
--- a/package.json
+++ b/package.json
@@ -60,7 +60,7 @@
"@types/mini-css-extract-plugin": "^2.2.0",
"@types/mustache": "^4.1.2",
"@types/webpack-dev-server": "^4.1.0",
- "@workadventure/iframe-api-typings": "^1.4.14",
+ "@workadventure/iframe-api-typings": "^1.6.4",
"copy-webpack-plugin": "^9.0.1",
"cross-env": "^7.0.3",
"css-loader": "^5.2.4",
diff --git a/src/Features/configuration.ts b/src/Features/configuration.ts
index d087895..e91e1a4 100644
--- a/src/Features/configuration.ts
+++ b/src/Features/configuration.ts
@@ -31,20 +31,15 @@ export async function initConfiguration(assetsUrl?: string | undefined): Promise
const properties = new Properties(layer.properties);
const openConfigVariables = properties.getString("openConfig");
if (openConfigVariables && layer.type === "tilelayer") {
- initLocalConfigurationPanel(openConfigVariables, properties);
+ initLocalConfigurationPanel(layer.name, openConfigVariables, properties);
}
}
}
}
-function initLocalConfigurationPanel(openConfigVariables: string, properties: Properties): void {
+function initLocalConfigurationPanel(layerName: string, openConfigVariables: string, properties: Properties): void {
let actionMessage: ActionMessage | undefined = undefined;
- const zoneName = properties.getString("zone");
- if (!zoneName) {
- throw new Error('Missing "zone" property');
- }
-
const tag = properties.getString("openConfigAdminTag");
let allowedByTag = true;
if (tag && !WA.player.tags.includes(tag)) {
@@ -67,7 +62,7 @@ function initLocalConfigurationPanel(openConfigVariables: string, properties: Pr
WA.nav.closeCoWebSite();
}
- WA.room.onEnterZone(zoneName, () => {
+ WA.room.onEnterLayer(layerName).subscribe(() => {
const openConfigTriggerValue = properties.getString("openConfigTrigger");
// Do not display conf panel if the user is not allowed by tag
@@ -80,7 +75,7 @@ function initLocalConfigurationPanel(openConfigVariables: string, properties: Pr
}
});
- WA.room.onLeaveZone(zoneName, () => {
+ WA.room.onLeaveLayer(layerName).subscribe(() => {
if (actionMessage) {
actionMessage.remove();
closeConfigurationPanel();
diff --git a/src/Features/default_api_url.ts b/src/Features/default_api_url.ts
new file mode 100644
index 0000000..6c9c83f
--- /dev/null
+++ b/src/Features/default_api_url.ts
@@ -0,0 +1,5 @@
+/**
+ * The base URL for the default API.
+ * This file is updated dynamically during the package build process.
+ */
+export const defaultApiUrl = "http://workadventure.localhost/api";
diff --git a/src/Features/properties_templates.ts b/src/Features/properties_templates.ts
index 12d0726..b88b86e 100644
--- a/src/Features/properties_templates.ts
+++ b/src/Features/properties_templates.ts
@@ -15,25 +15,51 @@ export async function initPropertiesTemplates(): Promise {
) {
continue;
}
+
const template = new TemplateValue(property.value, WA.state);
if (template.isPureString()) {
continue;
}
const newValue = template.getValue();
- setProperty(layerName, property.name, newValue);
+ setLayerProperty(layerName, property.name, newValue);
template.onChange((newValue) => {
- setProperty(layerName, property.name, newValue);
+ setLayerProperty(layerName, property.name, newValue);
});
}
+
+ // Parse the URL of the integrated websites (for example if mustache is used)
+ // Here we want to select the Tiled object layers with the type 'website' and the property 'url'
+ const promises = [];
+ if (layer.type === "objectgroup") {
+ for (const object of layer.objects) {
+ if (object.type === "website") {
+ for (const property of object.properties) {
+ if (property.name === "url") {
+ const template = new TemplateValue(property.value, WA.state);
+ if (template.isPureString()) {
+ continue;
+ }
+ const newValue = template.getValue();
+ promises.push(setWebsiteProperty(object.name, newValue));
+
+ template.onChange((newValue) => {
+ setWebsiteProperty(object.name, newValue);
+ });
+ }
+ }
+ }
+ }
+ }
+ await Promise.all(promises);
}
}
/**
- * Sets the property value on the map.
+ * Sets the property value of a layer on the map.
* Furthermore, if the property name is "visible", modify the visibility of the layer.
*/
-function setProperty(layerName: string, propertyName: string, value: string): void {
+function setLayerProperty(layerName: string, propertyName: string, value: string): void {
WA.room.setProperty(layerName, propertyName, value);
if (propertyName === "visible") {
if (value) {
@@ -43,3 +69,11 @@ function setProperty(layerName: string, propertyName: string, value: string): vo
}
}
}
+
+/**
+ * Sets the property value of an object of type 'website' on the map.
+ */
+async function setWebsiteProperty(objectName: string, value: string): Promise {
+ const website = await WA.room.website.get(objectName);
+ website.url = value;
+}
diff --git a/src/Iframes/Configuration/Components/Field.svelte b/src/Iframes/Configuration/Components/Field.svelte
index 24401af..f932439 100644
--- a/src/Iframes/Configuration/Components/Field.svelte
+++ b/src/Iframes/Configuration/Components/Field.svelte
@@ -1,7 +1,9 @@
@@ -49,6 +62,30 @@
{/each}
+{:else if type === 'upload' }
+