Merge branch 'develop' of github.com:thecodingmachine/workadventure into develop
This commit is contained in:
commit
1f11ab57f3
@ -570,6 +570,7 @@ export class GameRoom {
|
|||||||
mapUrl,
|
mapUrl,
|
||||||
authenticationMandatory: null,
|
authenticationMandatory: null,
|
||||||
group: null,
|
group: null,
|
||||||
|
showPoweredBy: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ When controls are disabled, the user cannot move anymore using keyboard input. T
|
|||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```javascript
|
```ts
|
||||||
WA.room.onEnterLayer('myZone').subscribe(() => {
|
WA.room.onEnterLayer('myZone').subscribe(() => {
|
||||||
WA.controls.disablePlayerControls();
|
WA.controls.disablePlayerControls();
|
||||||
WA.ui.openPopup("popupRectangle", 'This is an imporant message!', [{
|
WA.ui.openPopup("popupRectangle", 'This is an imporant message!', [{
|
||||||
@ -25,5 +25,28 @@ WA.room.onEnterLayer('myZone').subscribe(() => {
|
|||||||
popup.close();
|
popup.close();
|
||||||
}
|
}
|
||||||
}]);
|
}]);
|
||||||
})
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Disabling / restoring proximity meeting
|
||||||
|
|
||||||
|
```
|
||||||
|
WA.controls.disablePlayerProximityMeeting(): void
|
||||||
|
WA.controls.restorePlayerProximityMeeting(): void
|
||||||
|
```
|
||||||
|
|
||||||
|
These 2 methods can be used to completely disable player proximity meeting and to enable them again.
|
||||||
|
|
||||||
|
When proximity meeting are disabled, the user cannot speak with anyone.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
WA.room.onEnterLayer('myZone').subscribe(() => {
|
||||||
|
WA.controls.disablePlayerProximityMeeting();
|
||||||
|
});
|
||||||
|
|
||||||
|
WA.room.onLeaveLayer('myZone').subscribe(() => {
|
||||||
|
WA.controls.restorePlayerProximityMeeting();
|
||||||
|
});
|
||||||
```
|
```
|
||||||
|
@ -34,7 +34,7 @@ Please note that `openPopup` returns an object of the `Popup` class. Also, the c
|
|||||||
|
|
||||||
The `Popup` class that represents an open popup contains a single method: `close()`. This will obviously close the popup when called.
|
The `Popup` class that represents an open popup contains a single method: `close()`. This will obviously close the popup when called.
|
||||||
|
|
||||||
```javascript
|
```ts
|
||||||
class Popup {
|
class Popup {
|
||||||
/**
|
/**
|
||||||
* Closes the popup
|
* Closes the popup
|
||||||
@ -45,7 +45,7 @@ class Popup {
|
|||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```javascript
|
```ts
|
||||||
let helloWorldPopup;
|
let helloWorldPopup;
|
||||||
|
|
||||||
// Open the popup when we enter a given zone
|
// Open the popup when we enter a given zone
|
||||||
@ -91,7 +91,7 @@ Custom menu exist only until the map is unloaded, or you leave the iframe zone o
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
```javascript
|
```ts
|
||||||
const menu = WA.ui.registerMenuCommand('menu test',
|
const menu = WA.ui.registerMenuCommand('menu test',
|
||||||
{
|
{
|
||||||
callback: () => {
|
callback: () => {
|
||||||
@ -107,7 +107,7 @@ Please note that `registerMenuCommand` returns an object of the `Menu` class.
|
|||||||
|
|
||||||
The `Menu` class contains a single method: `remove(): void`. This will obviously remove the menu when called.
|
The `Menu` class contains a single method: `remove(): void`. This will obviously remove the menu when called.
|
||||||
|
|
||||||
```javascript
|
```ts
|
||||||
class Menu {
|
class Menu {
|
||||||
/**
|
/**
|
||||||
* Remove the menu
|
* Remove the menu
|
||||||
@ -120,7 +120,7 @@ class Menu {
|
|||||||
|
|
||||||
### Awaiting User Confirmation (with space bar)
|
### Awaiting User Confirmation (with space bar)
|
||||||
|
|
||||||
```
|
```ts
|
||||||
WA.ui.displayActionMessage({
|
WA.ui.displayActionMessage({
|
||||||
message: string,
|
message: string,
|
||||||
callback: () => void,
|
callback: () => void,
|
||||||
@ -136,7 +136,7 @@ Displays a message at the bottom of the screen (that will disappear when space b
|
|||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
```javascript
|
```ts
|
||||||
const triggerMessage = WA.ui.displayActionMessage({
|
const triggerMessage = WA.ui.displayActionMessage({
|
||||||
message: "press 'space' to confirm",
|
message: "press 'space' to confirm",
|
||||||
callback: () => {
|
callback: () => {
|
||||||
@ -154,7 +154,7 @@ Please note that `displayActionMessage` returns an object of the `ActionMessage`
|
|||||||
|
|
||||||
The `ActionMessage` class contains a single method: `remove(): Promise<void>`. This will obviously remove the message when called.
|
The `ActionMessage` class contains a single method: `remove(): Promise<void>`. This will obviously remove the message when called.
|
||||||
|
|
||||||
```javascript
|
```ts
|
||||||
class ActionMessage {
|
class ActionMessage {
|
||||||
/**
|
/**
|
||||||
* Hides the message
|
* Hides the message
|
||||||
@ -173,7 +173,7 @@ When clicking on other player's WOKA, the contextual menu (we call it ActionsMen
|
|||||||
|
|
||||||
To do that, we need to listen for the `onRemotePlayerClicked` stream and make use of the `remotePlayer` object that is passed by as a payload.
|
To do that, we need to listen for the `onRemotePlayerClicked` stream and make use of the `remotePlayer` object that is passed by as a payload.
|
||||||
|
|
||||||
```javascript
|
```ts
|
||||||
WA.ui.onRemotePlayerClicked.subscribe((remotePlayer) => {
|
WA.ui.onRemotePlayerClicked.subscribe((remotePlayer) => {
|
||||||
remotePlayer.addAction('Ask to tell a joke', () => {
|
remotePlayer.addAction('Ask to tell a joke', () => {
|
||||||
console.log('I am NOT telling you a joke!');
|
console.log('I am NOT telling you a joke!');
|
||||||
@ -182,7 +182,7 @@ WA.ui.onRemotePlayerClicked.subscribe((remotePlayer) => {
|
|||||||
```
|
```
|
||||||
|
|
||||||
`remotePlayer.addAction(actionName, callback)` returns an Action object, which can remove itself from ActionsMenu:
|
`remotePlayer.addAction(actionName, callback)` returns an Action object, which can remove itself from ActionsMenu:
|
||||||
```javascript
|
```ts
|
||||||
const action = remotePlayer.addAction('This will disappear!', () => {
|
const action = remotePlayer.addAction('This will disappear!', () => {
|
||||||
console.log('You managed to click me!');
|
console.log('You managed to click me!');
|
||||||
});
|
});
|
||||||
@ -193,3 +193,95 @@ setTimeout(
|
|||||||
1000,
|
1000,
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# Open fixed iframes
|
||||||
|
|
||||||
|
You can use the scripting API to display an iframe (so any HTML element) above the game. The iframe is positionned relative to the browser window (so unlike [embedded websites](website-in-map.md), the position of the iframe does not move when someone walks on the map).
|
||||||
|
|
||||||
|
<div class="col">
|
||||||
|
<img src="images/ui-website.png" class="figure-img img-fluid rounded" alt="" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
This functonnality creates an iframe positionned on the viewport.
|
||||||
|
|
||||||
|
## Display a UI website
|
||||||
|
|
||||||
|
```ts
|
||||||
|
WA.ui.website.open(website: CreateUIWebsiteEvent): Promise<UIWebsite>
|
||||||
|
|
||||||
|
interface CreateUIWebsiteEvent {
|
||||||
|
url: string, // Website URL
|
||||||
|
visible?: boolean, // The website is visible or not
|
||||||
|
allowApi?: boolean, // Allow scripting API on the website
|
||||||
|
allowPolicy?: string, // The list of feature policies allowed
|
||||||
|
position: {
|
||||||
|
vertical: "top"|"middle"|"bottom",,
|
||||||
|
horizontal: "left","middle","right",
|
||||||
|
},
|
||||||
|
size: { // Size on the UI (available units: px|em|%|cm|in|pc|pt|mm|ex|vw|vh|rem and others values auto|inherit)
|
||||||
|
height: string,
|
||||||
|
width: string,
|
||||||
|
},
|
||||||
|
margin?: { // Website margin (available units: px|em|%|cm|in|pc|pt|mm|ex|vw|vh|rem and others values auto|inherit)
|
||||||
|
top?: string,
|
||||||
|
bottom?: string,
|
||||||
|
left?: string,
|
||||||
|
right?: string,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UIWebsite {
|
||||||
|
readonly id: string, // Unique ID
|
||||||
|
url: string, // Website URL
|
||||||
|
visible: boolean, // The website is visible or not
|
||||||
|
readonly allowApi: boolean, // Allow scripting API on the website
|
||||||
|
readonly allowPolicy: string, // The list of feature policies allowed
|
||||||
|
position: {
|
||||||
|
vertical: string, // Vertical position (top, middle, bottom)
|
||||||
|
horizontal: string, // Horizontal position (left, middle, right)
|
||||||
|
},
|
||||||
|
size: { // Size on the UI (available units: px|em|%|cm|in|pc|pt|mm|ex|vw|vh|rem and others values auto|inherit)
|
||||||
|
height: string,
|
||||||
|
width: string,
|
||||||
|
},
|
||||||
|
margin?: { // Website margin (available units: px|em|%|cm|in|pc|pt|mm|ex|vw|vh|rem and others values auto|inherit)
|
||||||
|
top?: string,
|
||||||
|
bottom?: string,
|
||||||
|
left?: string,
|
||||||
|
right?: string,
|
||||||
|
},
|
||||||
|
close(): Promise<void>, // Close the current website instance
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You can open a website with the `WA.ui.website.open()` method. It returns an `Promise<UIWebsite>` instance.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const myWebsite = await WA.ui.website.open({
|
||||||
|
url: "https://wikipedia.org",
|
||||||
|
position: {
|
||||||
|
vertical: "middle",
|
||||||
|
horizontal: "middle",
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
height: "50vh",
|
||||||
|
width: "50vw",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
myWebsite.position.vertical = "top";
|
||||||
|
```
|
||||||
|
|
||||||
|
## Close a UI website
|
||||||
|
You can close a website with the close function on the `UIWebsite` object
|
||||||
|
|
||||||
|
```ts
|
||||||
|
myWebsite.close();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Get all UI websites
|
||||||
|
You can get all websites with the `WA.ui.website.getAll()` method. It returns an `Promise<UIWebsite[]>` instance.
|
||||||
|
|
||||||
|
```ts
|
||||||
|
WA.ui.website.getAll();
|
||||||
|
```
|
||||||
|
BIN
docs/maps/images/ui-website.png
Normal file
BIN
docs/maps/images/ui-website.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 454 KiB |
1
front/.gitignore
vendored
1
front/.gitignore
vendored
@ -5,3 +5,4 @@ dist/
|
|||||||
*.sh
|
*.sh
|
||||||
!templater.sh
|
!templater.sh
|
||||||
/public/iframe_api.js
|
/public/iframe_api.js
|
||||||
|
/public/es.js
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
"lint-staged": "^12.3.7",
|
"lint-staged": "^12.3.7",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"prettier": "^2.3.1",
|
"prettier": "^2.3.1",
|
||||||
"prettier-plugin-svelte": "^2.5.0",
|
"prettier-plugin-svelte": "^2.7.0",
|
||||||
"sass": "^1.49.7",
|
"sass": "^1.49.7",
|
||||||
"svelte": "^3.46.3",
|
"svelte": "^3.46.3",
|
||||||
"svelte-check": "^2.1.0",
|
"svelte-check": "^2.1.0",
|
||||||
|
@ -40,6 +40,7 @@ import { isAddActionsMenuKeyToRemotePlayerEvent } from "./AddActionsMenuKeyToRem
|
|||||||
import type { ActionsMenuActionClickedEvent } from "./ActionsMenuActionClickedEvent";
|
import type { ActionsMenuActionClickedEvent } from "./ActionsMenuActionClickedEvent";
|
||||||
import { isRemoveActionsMenuKeyFromRemotePlayerEvent } from "./RemoveActionsMenuKeyFromRemotePlayerEvent";
|
import { isRemoveActionsMenuKeyFromRemotePlayerEvent } from "./RemoveActionsMenuKeyFromRemotePlayerEvent";
|
||||||
import { isGetPropertyEvent } from "./GetPropertyEvent";
|
import { isGetPropertyEvent } from "./GetPropertyEvent";
|
||||||
|
import { isCreateUIWebsiteEvent, isModifyUIWebsiteEvent, isUIWebsite } from "./ui/UIWebsite";
|
||||||
|
|
||||||
export interface TypedMessageEvent<T> extends MessageEvent {
|
export interface TypedMessageEvent<T> extends MessageEvent {
|
||||||
data: T;
|
data: T;
|
||||||
@ -97,6 +98,14 @@ export const isIframeEventWrapper = z.union([
|
|||||||
type: z.literal("restorePlayerControls"),
|
type: z.literal("restorePlayerControls"),
|
||||||
data: z.undefined(),
|
data: z.undefined(),
|
||||||
}),
|
}),
|
||||||
|
z.object({
|
||||||
|
type: z.literal("disablePlayerProximityMeeting"),
|
||||||
|
data: z.undefined(),
|
||||||
|
}),
|
||||||
|
z.object({
|
||||||
|
type: z.literal("restorePlayerProximityMeeting"),
|
||||||
|
data: z.undefined(),
|
||||||
|
}),
|
||||||
z.object({
|
z.object({
|
||||||
type: z.literal("displayBubble"),
|
type: z.literal("displayBubble"),
|
||||||
data: z.undefined(),
|
data: z.undefined(),
|
||||||
@ -153,6 +162,10 @@ export const isIframeEventWrapper = z.union([
|
|||||||
type: z.literal("modifyEmbeddedWebsite"),
|
type: z.literal("modifyEmbeddedWebsite"),
|
||||||
data: isEmbeddedWebsiteEvent,
|
data: isEmbeddedWebsiteEvent,
|
||||||
}),
|
}),
|
||||||
|
z.object({
|
||||||
|
type: z.literal("modifyUIWebsite"),
|
||||||
|
data: isModifyUIWebsiteEvent,
|
||||||
|
}),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export type IframeEvent = z.infer<typeof isIframeEventWrapper>;
|
export type IframeEvent = z.infer<typeof isIframeEventWrapper>;
|
||||||
@ -266,6 +279,18 @@ export const iframeQueryMapTypeGuards = {
|
|||||||
query: isMovePlayerToEventConfig,
|
query: isMovePlayerToEventConfig,
|
||||||
answer: isMovePlayerToEventAnswer,
|
answer: isMovePlayerToEventAnswer,
|
||||||
},
|
},
|
||||||
|
openUIWebsite: {
|
||||||
|
query: isCreateUIWebsiteEvent,
|
||||||
|
answer: isUIWebsite,
|
||||||
|
},
|
||||||
|
closeUIWebsite: {
|
||||||
|
query: z.string(),
|
||||||
|
answer: z.undefined(),
|
||||||
|
},
|
||||||
|
getUIWebsites: {
|
||||||
|
query: z.undefined(),
|
||||||
|
answer: z.array(isUIWebsite),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
type IframeQueryMapTypeGuardsType = typeof iframeQueryMapTypeGuards;
|
type IframeQueryMapTypeGuardsType = typeof iframeQueryMapTypeGuards;
|
||||||
|
75
front/src/Api/Events/ui/UIWebsite.ts
Normal file
75
front/src/Api/Events/ui/UIWebsite.ts
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
const regexUnit = /-*\d+(px|em|%|cm|in|pc|pt|mm|ex|vw|vh|rem)|auto|inherit/;
|
||||||
|
|
||||||
|
// Parse the string to check if is a valid CSS unit (px,%,vw,vh...)
|
||||||
|
export const isUIWebsiteCSSValue = z.string().regex(regexUnit);
|
||||||
|
|
||||||
|
export type UIWebsiteCSSValue = z.infer<typeof isUIWebsiteCSSValue>;
|
||||||
|
|
||||||
|
export const isUIWebsiteMargin = z.object({
|
||||||
|
top: isUIWebsiteCSSValue.optional(),
|
||||||
|
bottom: isUIWebsiteCSSValue.optional(),
|
||||||
|
left: isUIWebsiteCSSValue.optional(),
|
||||||
|
right: isUIWebsiteCSSValue.optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type UIWebsiteMargin = z.infer<typeof isUIWebsiteMargin>;
|
||||||
|
|
||||||
|
export const isViewportPositionVertical = z.enum(["top", "middle", "bottom"]);
|
||||||
|
|
||||||
|
export type ViewportPositionVertical = z.infer<typeof isViewportPositionVertical>;
|
||||||
|
|
||||||
|
export const isViewportPositionHorizontal = z.enum(["left", "middle", "right"]);
|
||||||
|
|
||||||
|
export type ViewportPositionHorizontal = z.infer<typeof isViewportPositionHorizontal>;
|
||||||
|
|
||||||
|
export const isUIWebsitePosition = z.object({
|
||||||
|
vertical: isViewportPositionVertical,
|
||||||
|
horizontal: isViewportPositionHorizontal,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type UIWebsitePosition = z.infer<typeof isUIWebsitePosition>;
|
||||||
|
|
||||||
|
export const isUIWebsiteSize = z.object({
|
||||||
|
height: isUIWebsiteCSSValue,
|
||||||
|
width: isUIWebsiteCSSValue,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type UIWebsiteSize = z.infer<typeof isUIWebsiteSize>;
|
||||||
|
|
||||||
|
export const isCreateUIWebsiteEvent = z.object({
|
||||||
|
url: z.string(),
|
||||||
|
visible: z.optional(z.boolean()),
|
||||||
|
allowApi: z.optional(z.boolean()),
|
||||||
|
allowPolicy: z.optional(z.string()),
|
||||||
|
position: isUIWebsitePosition,
|
||||||
|
size: isUIWebsiteSize,
|
||||||
|
margin: isUIWebsiteMargin.optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type CreateUIWebsiteEvent = z.infer<typeof isCreateUIWebsiteEvent>;
|
||||||
|
|
||||||
|
export const isModifyUIWebsiteEvent = z.object({
|
||||||
|
id: z.string(),
|
||||||
|
url: z.string().optional(),
|
||||||
|
visible: z.boolean().optional(),
|
||||||
|
position: isUIWebsitePosition.optional(),
|
||||||
|
size: isUIWebsiteSize.optional(),
|
||||||
|
margin: isUIWebsiteMargin.optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type ModifyUIWebsiteEvent = z.infer<typeof isModifyUIWebsiteEvent>;
|
||||||
|
|
||||||
|
export const isUIWebsite = z.object({
|
||||||
|
id: z.string(),
|
||||||
|
url: z.string(),
|
||||||
|
visible: z.boolean(),
|
||||||
|
allowApi: z.boolean(),
|
||||||
|
allowPolicy: z.string(),
|
||||||
|
position: isUIWebsitePosition,
|
||||||
|
size: isUIWebsiteSize,
|
||||||
|
margin: isUIWebsiteMargin.optional(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type UIWebsite = z.infer<typeof isUIWebsite>;
|
@ -35,6 +35,7 @@ import type { RemotePlayerClickedEvent } from "./Events/RemotePlayerClickedEvent
|
|||||||
import { AddActionsMenuKeyToRemotePlayerEvent } from "./Events/AddActionsMenuKeyToRemotePlayerEvent";
|
import { AddActionsMenuKeyToRemotePlayerEvent } from "./Events/AddActionsMenuKeyToRemotePlayerEvent";
|
||||||
import type { ActionsMenuActionClickedEvent } from "./Events/ActionsMenuActionClickedEvent";
|
import type { ActionsMenuActionClickedEvent } from "./Events/ActionsMenuActionClickedEvent";
|
||||||
import { RemoveActionsMenuKeyFromRemotePlayerEvent } from "./Events/RemoveActionsMenuKeyFromRemotePlayerEvent";
|
import { RemoveActionsMenuKeyFromRemotePlayerEvent } from "./Events/RemoveActionsMenuKeyFromRemotePlayerEvent";
|
||||||
|
import { ModifyUIWebsiteEvent } from "./Events/ui/UIWebsite";
|
||||||
|
|
||||||
type AnswererCallback<T extends keyof IframeQueryMap> = (
|
type AnswererCallback<T extends keyof IframeQueryMap> = (
|
||||||
query: IframeQueryMap[T]["query"],
|
query: IframeQueryMap[T]["query"],
|
||||||
@ -58,6 +59,15 @@ class IframeListener {
|
|||||||
private readonly _disablePlayerControlStream: Subject<void> = new Subject();
|
private readonly _disablePlayerControlStream: Subject<void> = new Subject();
|
||||||
public readonly disablePlayerControlStream = this._disablePlayerControlStream.asObservable();
|
public readonly disablePlayerControlStream = this._disablePlayerControlStream.asObservable();
|
||||||
|
|
||||||
|
private readonly _enablePlayerControlStream: Subject<void> = new Subject();
|
||||||
|
public readonly enablePlayerControlStream = this._enablePlayerControlStream.asObservable();
|
||||||
|
|
||||||
|
private readonly _disablePlayerProximityMeetingStream: Subject<void> = new Subject();
|
||||||
|
public readonly disablePlayerProximityMeetingStream = this._disablePlayerProximityMeetingStream.asObservable();
|
||||||
|
|
||||||
|
private readonly _enablePlayerProximityMeetingStream: Subject<void> = new Subject();
|
||||||
|
public readonly enablePlayerProximityMeetingStream = this._enablePlayerProximityMeetingStream.asObservable();
|
||||||
|
|
||||||
private readonly _cameraSetStream: Subject<CameraSetEvent> = new Subject();
|
private readonly _cameraSetStream: Subject<CameraSetEvent> = new Subject();
|
||||||
public readonly cameraSetStream = this._cameraSetStream.asObservable();
|
public readonly cameraSetStream = this._cameraSetStream.asObservable();
|
||||||
|
|
||||||
@ -73,9 +83,6 @@ class IframeListener {
|
|||||||
public readonly removeActionsMenuKeyFromRemotePlayerEvent =
|
public readonly removeActionsMenuKeyFromRemotePlayerEvent =
|
||||||
this._removeActionsMenuKeyFromRemotePlayerEvent.asObservable();
|
this._removeActionsMenuKeyFromRemotePlayerEvent.asObservable();
|
||||||
|
|
||||||
private readonly _enablePlayerControlStream: Subject<void> = new Subject();
|
|
||||||
public readonly enablePlayerControlStream = this._enablePlayerControlStream.asObservable();
|
|
||||||
|
|
||||||
private readonly _closePopupStream: Subject<ClosePopupEvent> = new Subject();
|
private readonly _closePopupStream: Subject<ClosePopupEvent> = new Subject();
|
||||||
public readonly closePopupStream = this._closePopupStream.asObservable();
|
public readonly closePopupStream = this._closePopupStream.asObservable();
|
||||||
|
|
||||||
@ -115,6 +122,9 @@ class IframeListener {
|
|||||||
private readonly _modifyEmbeddedWebsiteStream: Subject<ModifyEmbeddedWebsiteEvent> = new Subject();
|
private readonly _modifyEmbeddedWebsiteStream: Subject<ModifyEmbeddedWebsiteEvent> = new Subject();
|
||||||
public readonly modifyEmbeddedWebsiteStream = this._modifyEmbeddedWebsiteStream.asObservable();
|
public readonly modifyEmbeddedWebsiteStream = this._modifyEmbeddedWebsiteStream.asObservable();
|
||||||
|
|
||||||
|
private readonly _modifyUIWebsiteStream: Subject<ModifyUIWebsiteEvent> = new Subject();
|
||||||
|
public readonly modifyUIWebsiteStream = this._modifyUIWebsiteStream.asObservable();
|
||||||
|
|
||||||
private readonly iframes = new Set<HTMLIFrameElement>();
|
private readonly iframes = new Set<HTMLIFrameElement>();
|
||||||
private readonly iframeCloseCallbacks = new Map<HTMLIFrameElement, (() => void)[]>();
|
private readonly iframeCloseCallbacks = new Map<HTMLIFrameElement, (() => void)[]>();
|
||||||
private readonly scripts = new Map<string, HTMLIFrameElement>();
|
private readonly scripts = new Map<string, HTMLIFrameElement>();
|
||||||
@ -263,6 +273,10 @@ class IframeListener {
|
|||||||
this._disablePlayerControlStream.next();
|
this._disablePlayerControlStream.next();
|
||||||
} else if (iframeEvent.type === "restorePlayerControls") {
|
} else if (iframeEvent.type === "restorePlayerControls") {
|
||||||
this._enablePlayerControlStream.next();
|
this._enablePlayerControlStream.next();
|
||||||
|
} else if (iframeEvent.type === "disablePlayerProximityMeeting") {
|
||||||
|
this._disablePlayerProximityMeetingStream.next();
|
||||||
|
} else if (iframeEvent.type === "restorePlayerProximityMeeting") {
|
||||||
|
this._enablePlayerProximityMeetingStream.next();
|
||||||
} else if (iframeEvent.type === "displayBubble") {
|
} else if (iframeEvent.type === "displayBubble") {
|
||||||
this._displayBubbleStream.next();
|
this._displayBubbleStream.next();
|
||||||
} else if (iframeEvent.type === "removeBubble") {
|
} else if (iframeEvent.type === "removeBubble") {
|
||||||
@ -279,6 +293,8 @@ class IframeListener {
|
|||||||
this._setTilesStream.next(iframeEvent.data);
|
this._setTilesStream.next(iframeEvent.data);
|
||||||
} else if (iframeEvent.type == "modifyEmbeddedWebsite") {
|
} else if (iframeEvent.type == "modifyEmbeddedWebsite") {
|
||||||
this._modifyEmbeddedWebsiteStream.next(iframeEvent.data);
|
this._modifyEmbeddedWebsiteStream.next(iframeEvent.data);
|
||||||
|
} else if (iframeEvent.type == "modifyUIWebsite") {
|
||||||
|
this._modifyUIWebsiteStream.next(iframeEvent.data);
|
||||||
} else if (iframeEvent.type == "registerMenu") {
|
} else if (iframeEvent.type == "registerMenu") {
|
||||||
const dataName = iframeEvent.data.name;
|
const dataName = iframeEvent.data.name;
|
||||||
this.iframeCloseCallbacks.get(iframe)?.push(() => {
|
this.iframeCloseCallbacks.get(iframe)?.push(() => {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { requestedCameraState, requestedMicrophoneState, silentStore } from "../../Stores/MediaStore";
|
import { requestedCameraState, requestedMicrophoneState, silentStore } from "../../Stores/MediaStore";
|
||||||
import { get } from "svelte/store";
|
import { get } from "svelte/store";
|
||||||
import { WorkAdventureDesktopApi } from "@wa-preload-app";
|
import { WorkAdventureDesktopApi } from "../../Interfaces/DesktopAppInterfaces";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
|
338
front/src/Api/iframe/Ui/UIWebsite.ts
Normal file
338
front/src/Api/iframe/Ui/UIWebsite.ts
Normal file
@ -0,0 +1,338 @@
|
|||||||
|
import {
|
||||||
|
CreateUIWebsiteEvent,
|
||||||
|
UIWebsiteCSSValue,
|
||||||
|
UIWebsiteMargin,
|
||||||
|
UIWebsitePosition,
|
||||||
|
UIWebsiteSize,
|
||||||
|
ViewportPositionHorizontal,
|
||||||
|
ViewportPositionVertical,
|
||||||
|
UIWebsite as UIWebsiteCore,
|
||||||
|
} from "../../Events/ui/UIWebsite";
|
||||||
|
import { IframeApiContribution, queryWorkadventure, sendToWorkadventure } from "../IframeApiContribution";
|
||||||
|
|
||||||
|
class UIWebsitePositionInternal {
|
||||||
|
private readonly website: UIWebsite;
|
||||||
|
private _vertical: ViewportPositionVertical;
|
||||||
|
private _horizontal: ViewportPositionHorizontal;
|
||||||
|
|
||||||
|
constructor(uiWebsite: UIWebsite, position: UIWebsitePosition) {
|
||||||
|
this.website = uiWebsite;
|
||||||
|
this._vertical = position.vertical;
|
||||||
|
this._horizontal = position.horizontal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get vertical() {
|
||||||
|
return this._vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set vertical(vertical: ViewportPositionVertical) {
|
||||||
|
this._vertical = vertical;
|
||||||
|
sendToWorkadventure({
|
||||||
|
type: "modifyUIWebsite",
|
||||||
|
data: {
|
||||||
|
id: this.website.id,
|
||||||
|
position: {
|
||||||
|
vertical: this._vertical,
|
||||||
|
horizontal: this._horizontal,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public get horizontal() {
|
||||||
|
return this._horizontal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set horizontal(horizontal: ViewportPositionHorizontal) {
|
||||||
|
this._horizontal = horizontal;
|
||||||
|
sendToWorkadventure({
|
||||||
|
type: "modifyUIWebsite",
|
||||||
|
data: {
|
||||||
|
id: this.website.id,
|
||||||
|
position: {
|
||||||
|
vertical: this._vertical,
|
||||||
|
horizontal: this._horizontal,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UIWebsiteSizeInternal {
|
||||||
|
private readonly website: UIWebsite;
|
||||||
|
private _height: UIWebsiteCSSValue;
|
||||||
|
private _width: UIWebsiteCSSValue;
|
||||||
|
|
||||||
|
constructor(uiWebsite: UIWebsite, size: UIWebsiteSize) {
|
||||||
|
this.website = uiWebsite;
|
||||||
|
this._height = size.height;
|
||||||
|
this._width = size.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get height() {
|
||||||
|
return this._height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set height(height: UIWebsiteCSSValue) {
|
||||||
|
this._height = height;
|
||||||
|
sendToWorkadventure({
|
||||||
|
type: "modifyUIWebsite",
|
||||||
|
data: {
|
||||||
|
id: this.website.id,
|
||||||
|
size: {
|
||||||
|
height: this._height,
|
||||||
|
width: this._width,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public get width() {
|
||||||
|
return this._height;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set width(width: UIWebsiteCSSValue) {
|
||||||
|
this._width = width;
|
||||||
|
sendToWorkadventure({
|
||||||
|
type: "modifyUIWebsite",
|
||||||
|
data: {
|
||||||
|
id: this.website.id,
|
||||||
|
size: {
|
||||||
|
height: this._height,
|
||||||
|
width: this._width,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UIWebsiteMarginInternal {
|
||||||
|
private readonly website: UIWebsite;
|
||||||
|
private _top?: UIWebsiteCSSValue;
|
||||||
|
private _bottom?: UIWebsiteCSSValue;
|
||||||
|
private _left?: UIWebsiteCSSValue;
|
||||||
|
private _right?: UIWebsiteCSSValue;
|
||||||
|
|
||||||
|
constructor(uiWebsite: UIWebsite, margin: UIWebsiteMargin) {
|
||||||
|
this.website = uiWebsite;
|
||||||
|
this._top = margin.top;
|
||||||
|
this._bottom = margin.bottom;
|
||||||
|
this._left = margin.left;
|
||||||
|
this._right = margin.right;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get top() {
|
||||||
|
return this._top;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set top(top: UIWebsiteCSSValue | undefined) {
|
||||||
|
this._top = top;
|
||||||
|
sendToWorkadventure({
|
||||||
|
type: "modifyUIWebsite",
|
||||||
|
data: {
|
||||||
|
id: this.website.id,
|
||||||
|
margin: {
|
||||||
|
top: this._top,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public get bottom() {
|
||||||
|
return this._bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set bottom(bottom: UIWebsiteCSSValue | undefined) {
|
||||||
|
this._bottom = bottom;
|
||||||
|
sendToWorkadventure({
|
||||||
|
type: "modifyUIWebsite",
|
||||||
|
data: {
|
||||||
|
id: this.website.id,
|
||||||
|
margin: {
|
||||||
|
bottom: this._bottom,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public get left() {
|
||||||
|
return this._left;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set left(left: UIWebsiteCSSValue | undefined) {
|
||||||
|
this._left = left;
|
||||||
|
sendToWorkadventure({
|
||||||
|
type: "modifyUIWebsite",
|
||||||
|
data: {
|
||||||
|
id: this.website.id,
|
||||||
|
margin: {
|
||||||
|
left: this._left,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public get right() {
|
||||||
|
return this._right;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set right(right: UIWebsiteCSSValue | undefined) {
|
||||||
|
this._right = right;
|
||||||
|
sendToWorkadventure({
|
||||||
|
type: "modifyUIWebsite",
|
||||||
|
data: {
|
||||||
|
id: this.website.id,
|
||||||
|
margin: {
|
||||||
|
right: this._right,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class UIWebsite {
|
||||||
|
public readonly id: string;
|
||||||
|
private _url: string;
|
||||||
|
private _visible: boolean;
|
||||||
|
private readonly _allowPolicy: string;
|
||||||
|
private readonly _allowApi: boolean;
|
||||||
|
private _position: UIWebsitePositionInternal;
|
||||||
|
private _size: UIWebsiteSizeInternal;
|
||||||
|
private _margin: UIWebsiteMarginInternal;
|
||||||
|
|
||||||
|
constructor(config: UIWebsiteCore) {
|
||||||
|
this.id = config.id;
|
||||||
|
this._url = config.url;
|
||||||
|
this._visible = config.visible ?? true;
|
||||||
|
this._allowPolicy = config.allowPolicy ?? "";
|
||||||
|
this._allowApi = config.allowApi ?? false;
|
||||||
|
this._position = new UIWebsitePositionInternal(this, config.position);
|
||||||
|
this._size = new UIWebsiteSizeInternal(this, config.size);
|
||||||
|
this._margin = new UIWebsiteMarginInternal(this, config.margin ?? {});
|
||||||
|
}
|
||||||
|
|
||||||
|
public get url() {
|
||||||
|
return this._url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set url(url: string) {
|
||||||
|
this._url = url;
|
||||||
|
sendToWorkadventure({
|
||||||
|
type: "modifyUIWebsite",
|
||||||
|
data: {
|
||||||
|
id: this.id,
|
||||||
|
url: this._url,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public get visible() {
|
||||||
|
return this._visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set visible(visible: boolean) {
|
||||||
|
this._visible = visible;
|
||||||
|
sendToWorkadventure({
|
||||||
|
type: "modifyUIWebsite",
|
||||||
|
data: {
|
||||||
|
id: this.id,
|
||||||
|
visible: this._visible,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public get allowPolicy() {
|
||||||
|
return this._allowPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get allowApi() {
|
||||||
|
return this._allowApi;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get position() {
|
||||||
|
return this._position;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set position(position: UIWebsitePosition) {
|
||||||
|
this._position = new UIWebsitePositionInternal(this, position);
|
||||||
|
sendToWorkadventure({
|
||||||
|
type: "modifyUIWebsite",
|
||||||
|
data: {
|
||||||
|
id: this.id,
|
||||||
|
position: {
|
||||||
|
vertical: this._position.vertical,
|
||||||
|
horizontal: this._position.horizontal,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public get size() {
|
||||||
|
return this._size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set size(size: UIWebsiteSize) {
|
||||||
|
this._size = new UIWebsiteSizeInternal(this, size);
|
||||||
|
sendToWorkadventure({
|
||||||
|
type: "modifyUIWebsite",
|
||||||
|
data: {
|
||||||
|
id: this.id,
|
||||||
|
size: {
|
||||||
|
height: this._size.height,
|
||||||
|
width: this._size.width,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public get margin() {
|
||||||
|
return this._margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set margin(margin: UIWebsiteMargin) {
|
||||||
|
this._margin = new UIWebsiteMarginInternal(this, margin);
|
||||||
|
sendToWorkadventure({
|
||||||
|
type: "modifyUIWebsite",
|
||||||
|
data: {
|
||||||
|
id: this.id,
|
||||||
|
margin: {
|
||||||
|
top: this._margin.top,
|
||||||
|
bottom: this._margin.bottom,
|
||||||
|
left: this._margin.left,
|
||||||
|
right: this._margin.right,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
return queryWorkadventure({
|
||||||
|
type: "closeUIWebsite",
|
||||||
|
data: this.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class UIWebsiteCommands extends IframeApiContribution<UIWebsiteCommands> {
|
||||||
|
callbacks = [];
|
||||||
|
|
||||||
|
async open(createUIWebsite: CreateUIWebsiteEvent): Promise<UIWebsite> {
|
||||||
|
const result = await queryWorkadventure({
|
||||||
|
type: "openUIWebsite",
|
||||||
|
data: createUIWebsite,
|
||||||
|
});
|
||||||
|
|
||||||
|
return new UIWebsite(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getAll(): Promise<UIWebsite[]> {
|
||||||
|
const result = await queryWorkadventure({
|
||||||
|
type: "getUIWebsites",
|
||||||
|
data: undefined,
|
||||||
|
});
|
||||||
|
|
||||||
|
return result.map((current) => new UIWebsite(current));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new UIWebsiteCommands();
|
@ -10,6 +10,14 @@ export class WorkadventureControlsCommands extends IframeApiContribution<Workadv
|
|||||||
restorePlayerControls(): void {
|
restorePlayerControls(): void {
|
||||||
sendToWorkadventure({ type: "restorePlayerControls", data: undefined });
|
sendToWorkadventure({ type: "restorePlayerControls", data: undefined });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disablePlayerProximityMeeting(): void {
|
||||||
|
sendToWorkadventure({ type: "disablePlayerProximityMeeting", data: undefined });
|
||||||
|
}
|
||||||
|
|
||||||
|
restorePlayerProximityMeeting(): void {
|
||||||
|
sendToWorkadventure({ type: "restorePlayerProximityMeeting", data: undefined });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new WorkadventureControlsCommands();
|
export default new WorkadventureControlsCommands();
|
||||||
|
@ -14,6 +14,8 @@ import {
|
|||||||
isActionsMenuActionClickedEvent,
|
isActionsMenuActionClickedEvent,
|
||||||
} from "../Events/ActionsMenuActionClickedEvent";
|
} from "../Events/ActionsMenuActionClickedEvent";
|
||||||
import { Observable, Subject } from "rxjs";
|
import { Observable, Subject } from "rxjs";
|
||||||
|
import type { UIWebsiteCommands } from "./Ui/UIWebsite";
|
||||||
|
import website from "./Ui/UIWebsite";
|
||||||
|
|
||||||
let popupId = 0;
|
let popupId = 0;
|
||||||
const popups: Map<number, Popup> = new Map<number, Popup>();
|
const popups: Map<number, Popup> = new Map<number, Popup>();
|
||||||
@ -290,6 +292,10 @@ export class WorkAdventureUiCommands extends IframeApiContribution<WorkAdventure
|
|||||||
actionMessages.set(actionMessage.uuid, actionMessage);
|
actionMessages.set(actionMessage.uuid, actionMessage);
|
||||||
return actionMessage;
|
return actionMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get website(): UIWebsiteCommands {
|
||||||
|
return website;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new WorkAdventureUiCommands();
|
export default new WorkAdventureUiCommands();
|
||||||
|
@ -63,7 +63,7 @@
|
|||||||
<section class="action">
|
<section class="action">
|
||||||
<button type="submit" class="nes-btn is-primary loginSceneFormSubmit">{$LL.login.continue()}</button>
|
<button type="submit" class="nes-btn is-primary loginSceneFormSubmit">{$LL.login.continue()}</button>
|
||||||
</section>
|
</section>
|
||||||
{#if logo !== logoImg}
|
{#if logo !== logoImg && gameManager.currentStartedRoom.showPoweredBy !== false}
|
||||||
<section class="text-center powered-by">
|
<section class="text-center powered-by">
|
||||||
<img src={poweredByWorkAdventureImg} alt="Powered by WorkAdventure" />
|
<img src={poweredByWorkAdventureImg} alt="Powered by WorkAdventure" />
|
||||||
</section>
|
</section>
|
||||||
|
@ -39,6 +39,8 @@
|
|||||||
import ActionsMenu from "./ActionsMenu/ActionsMenu.svelte";
|
import ActionsMenu from "./ActionsMenu/ActionsMenu.svelte";
|
||||||
import Lazy from "./Lazy.svelte";
|
import Lazy from "./Lazy.svelte";
|
||||||
import { showDesktopCapturerSourcePicker } from "../Stores/ScreenSharingStore";
|
import { showDesktopCapturerSourcePicker } from "../Stores/ScreenSharingStore";
|
||||||
|
import UiWebsiteContainer from "./UI/Website/UIWebsiteContainer.svelte";
|
||||||
|
import { uiWebsitesStore } from "../Stores/UIWebsiteStore";
|
||||||
|
|
||||||
let mainLayout: HTMLDivElement;
|
let mainLayout: HTMLDivElement;
|
||||||
|
|
||||||
@ -128,6 +130,10 @@
|
|||||||
{#if hasEmbedScreen}
|
{#if hasEmbedScreen}
|
||||||
<EmbedScreensContainer />
|
<EmbedScreensContainer />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
{#if $uiWebsitesStore}
|
||||||
|
<UiWebsiteContainer />
|
||||||
|
{/if}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="main-layout-baseline">
|
<section id="main-layout-baseline">
|
||||||
|
@ -11,14 +11,17 @@
|
|||||||
import reload from "../images/reload.png";
|
import reload from "../images/reload.png";
|
||||||
let errorScreen = get(errorScreenStore);
|
let errorScreen = get(errorScreenStore);
|
||||||
|
|
||||||
|
import error from "./images/error.png";
|
||||||
|
let errorLogo = errorScreen?.image ?? error;
|
||||||
|
|
||||||
function click() {
|
function click() {
|
||||||
if (errorScreen.type === "unauthorized") void connectionManager.logout();
|
if (errorScreen?.type === "unauthorized") void connectionManager.logout();
|
||||||
else window.location.reload();
|
else window.location.reload();
|
||||||
}
|
}
|
||||||
let details = errorScreen.details;
|
let details = errorScreen?.details ?? "";
|
||||||
let timeVar = errorScreen.timeToRetry ?? 0;
|
let timeVar = errorScreen?.timeToRetry ?? 0;
|
||||||
|
|
||||||
if (errorScreen.type === "retry") {
|
if (errorScreen?.type === "retry") {
|
||||||
let interval = setInterval(() => {
|
let interval = setInterval(() => {
|
||||||
if (timeVar <= 1000) click();
|
if (timeVar <= 1000) click();
|
||||||
timeVar -= 1000;
|
timeVar -= 1000;
|
||||||
@ -29,24 +32,29 @@
|
|||||||
$: detailsStylized = (details ?? "").replace("{time}", `${timeVar / 1000}`);
|
$: detailsStylized = (details ?? "").replace("{time}", `${timeVar / 1000}`);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<main class="errorScreen" transition:fly={{ y: -200, duration: 500 }}>
|
{#if $errorScreenStore}
|
||||||
<div style="width: 90%;">
|
<main class="errorScreen" transition:fly={{ y: -200, duration: 500 }}>
|
||||||
<img src={logo} alt="WorkAdventure" class="logo" />
|
<div style="width: 90%;">
|
||||||
<div><img src={$errorScreenStore.image} alt="" class="icon" /></div>
|
<img src={logo} alt="WorkAdventure" class="logo" />
|
||||||
{#if $errorScreenStore.type !== "retry"}<h2>{$errorScreenStore.title}</h2>{/if}
|
<div><img src={errorLogo} alt="Error logo" class="icon" /></div>
|
||||||
<p>{$errorScreenStore.subtitle}</p>
|
{#if $errorScreenStore.type !== "retry"}<h2>{$errorScreenStore.title}</h2>{/if}
|
||||||
{#if $errorScreenStore.type !== "retry"}<p class="code">Code : {$errorScreenStore.code}</p>{/if}
|
{#if $errorScreenStore.subtitle}<p>{$errorScreenStore.subtitle}</p>{/if}
|
||||||
<p class="details">
|
{#if $errorScreenStore.type !== "retry"}<p class="code">Code : {$errorScreenStore.code}</p>{/if}
|
||||||
{detailsStylized}{#if $errorScreenStore.type === "retry"}<div class="loading" />{/if}
|
<p class="details">
|
||||||
</p>
|
{detailsStylized}
|
||||||
{#if ($errorScreenStore.type === "retry" && $errorScreenStore.canRetryManual) || $errorScreenStore.type === "unauthorized"}
|
{#if $errorScreenStore.type === "retry" || $errorScreenStore.type === "reconnecting"}
|
||||||
<button type="button" class="nes-btn is-primary button" on:click={click}>
|
<div class="loading" />
|
||||||
{#if $errorScreenStore.type === "retry"}<img src={reload} alt="" class="reload" />{/if}
|
{/if}
|
||||||
{$errorScreenStore.buttonTitle}
|
</p>
|
||||||
</button>
|
{#if ($errorScreenStore.type === "retry" && $errorScreenStore.canRetryManual) || $errorScreenStore.type === "unauthorized"}
|
||||||
{/if}
|
<button type="button" class="nes-btn is-primary button" on:click={click}>
|
||||||
</div>
|
{#if $errorScreenStore.type === "retry"}<img src={reload} alt="" class="reload" />{/if}
|
||||||
</main>
|
{$errorScreenStore.buttonTitle}
|
||||||
|
</button>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
main.errorScreen {
|
main.errorScreen {
|
||||||
|
21
front/src/Components/UI/Website/UIWebsiteContainer.svelte
Normal file
21
front/src/Components/UI/Website/UIWebsiteContainer.svelte
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { uiWebsitesStore } from "../../../Stores/UIWebsiteStore";
|
||||||
|
import UiWebsiteLayer from "./UIWebsiteLayer.svelte";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div id="ui-website-container">
|
||||||
|
{#each $uiWebsitesStore.reverse() as uiWebsite (uiWebsite.id)}
|
||||||
|
<UiWebsiteLayer {uiWebsite} />
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
#ui-website-container {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 180;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
</style>
|
66
front/src/Components/UI/Website/UIWebsiteLayer.svelte
Normal file
66
front/src/Components/UI/Website/UIWebsiteLayer.svelte
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { onDestroy, onMount } from "svelte";
|
||||||
|
import { UIWebsite } from "../../../Api/Events/ui/UIWebsite";
|
||||||
|
import { iframeListener } from "../../../Api/IframeListener";
|
||||||
|
|
||||||
|
export let uiWebsite: UIWebsite;
|
||||||
|
|
||||||
|
let main: HTMLDivElement;
|
||||||
|
const iframe = document.createElement("iframe");
|
||||||
|
|
||||||
|
$: {
|
||||||
|
iframe.id = `ui-website-${uiWebsite.id}`;
|
||||||
|
iframe.src = uiWebsite.url;
|
||||||
|
iframe.title = uiWebsite.url;
|
||||||
|
iframe.style.border = "0";
|
||||||
|
iframe.allow = uiWebsite.allowPolicy ?? "";
|
||||||
|
iframe.style.height = uiWebsite.size.height;
|
||||||
|
iframe.style.width = uiWebsite.size.width;
|
||||||
|
iframe.style.visibility = uiWebsite.visible ? "visible" : "hidden";
|
||||||
|
iframe.style.margin = uiWebsite.margin
|
||||||
|
? `${uiWebsite.margin.top ? uiWebsite.margin.top : "O"} ${
|
||||||
|
uiWebsite.margin.right ? uiWebsite.margin.right : "O"
|
||||||
|
} ${uiWebsite.margin.bottom ? uiWebsite.margin.bottom : "O"} ${
|
||||||
|
uiWebsite.margin.left ? uiWebsite.margin.left : "O"
|
||||||
|
}`
|
||||||
|
: "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
main.appendChild(iframe);
|
||||||
|
|
||||||
|
if (uiWebsite.allowApi) {
|
||||||
|
iframeListener.registerIframe(iframe);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
if (uiWebsite.allowApi) {
|
||||||
|
iframeListener.unregisterIframe(iframe);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
bind:this={main}
|
||||||
|
class="layer"
|
||||||
|
style:justify-content={uiWebsite.position.horizontal === "middle"
|
||||||
|
? "center"
|
||||||
|
: uiWebsite.position.horizontal === "right"
|
||||||
|
? "end"
|
||||||
|
: "start"}
|
||||||
|
style:align-items={uiWebsite.position.vertical === "middle"
|
||||||
|
? "center"
|
||||||
|
: uiWebsite.position.vertical === "bottom"
|
||||||
|
? "end"
|
||||||
|
: "top"}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.layer {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
</style>
|
BIN
front/src/Components/UI/images/error.png
Normal file
BIN
front/src/Components/UI/images/error.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.3 KiB |
@ -5,7 +5,7 @@
|
|||||||
showDesktopCapturerSourcePicker,
|
showDesktopCapturerSourcePicker,
|
||||||
} from "../../Stores/ScreenSharingStore";
|
} from "../../Stores/ScreenSharingStore";
|
||||||
import { onDestroy, onMount } from "svelte";
|
import { onDestroy, onMount } from "svelte";
|
||||||
import type { DesktopCapturerSource } from "@wa-preload-app";
|
import type { DesktopCapturerSource } from "../../Interfaces/DesktopAppInterfaces";
|
||||||
|
|
||||||
let desktopCapturerSources: DesktopCapturerSource[] = [];
|
let desktopCapturerSources: DesktopCapturerSource[] = [];
|
||||||
let interval: ReturnType<typeof setInterval>;
|
let interval: ReturnType<typeof setInterval>;
|
||||||
|
@ -296,7 +296,32 @@ class ConnectionManager {
|
|||||||
});
|
});
|
||||||
|
|
||||||
connection.connectionErrorStream.subscribe((event: CloseEvent) => {
|
connection.connectionErrorStream.subscribe((event: CloseEvent) => {
|
||||||
console.log("connectionErrorStream => An error occurred while connecting to socket server. Retrying");
|
console.info(
|
||||||
|
"An error occurred while connecting to socket server. Retrying => Event: ",
|
||||||
|
event.reason,
|
||||||
|
event.code,
|
||||||
|
event
|
||||||
|
);
|
||||||
|
|
||||||
|
//However, Chrome will rarely report any close code 1006 reasons to the Javascript side.
|
||||||
|
//This is likely due to client security rules in the WebSocket spec to prevent abusing WebSocket.
|
||||||
|
//(such as using it to scan for open ports on a destination server, or for generating lots of connections for a denial-of-service attack).
|
||||||
|
// more detail here: https://www.rfc-editor.org/rfc/rfc6455#section-7.4.1
|
||||||
|
if (event.code === 1006) {
|
||||||
|
//check cookies
|
||||||
|
const cookies = document.cookie.split(";");
|
||||||
|
for (const cookie of cookies) {
|
||||||
|
//check id cookie posthog exist
|
||||||
|
const numberIndexPh = cookie.indexOf("_posthog=");
|
||||||
|
if (numberIndexPh !== -1) {
|
||||||
|
//if exist, remove posthog cookie
|
||||||
|
document.cookie =
|
||||||
|
cookie.slice(0, numberIndexPh + 9) +
|
||||||
|
"; domain=.workadventu.re; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
reject(
|
reject(
|
||||||
new Error(
|
new Error(
|
||||||
"An error occurred while connecting to socket server. Retrying. Code: " +
|
"An error occurred while connecting to socket server. Retrying. Code: " +
|
||||||
|
@ -25,6 +25,7 @@ export class Room {
|
|||||||
private _canReport: boolean = false;
|
private _canReport: boolean = false;
|
||||||
private _loadingLogo: string | undefined;
|
private _loadingLogo: string | undefined;
|
||||||
private _loginSceneLogo: string | undefined;
|
private _loginSceneLogo: string | undefined;
|
||||||
|
private _showPoweredBy: boolean | undefined = true;
|
||||||
|
|
||||||
private constructor(private roomUrl: URL) {
|
private constructor(private roomUrl: URL) {
|
||||||
this.id = roomUrl.pathname;
|
this.id = roomUrl.pathname;
|
||||||
@ -120,6 +121,7 @@ export class Room {
|
|||||||
this._canReport = data.canReport ?? false;
|
this._canReport = data.canReport ?? false;
|
||||||
this._loadingLogo = data.loadingLogo ?? undefined;
|
this._loadingLogo = data.loadingLogo ?? undefined;
|
||||||
this._loginSceneLogo = data.loginSceneLogo ?? undefined;
|
this._loginSceneLogo = data.loginSceneLogo ?? undefined;
|
||||||
|
this._showPoweredBy = data.showPoweredBy ?? true;
|
||||||
return new MapDetail(data.mapUrl);
|
return new MapDetail(data.mapUrl);
|
||||||
} else {
|
} else {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
@ -213,4 +215,8 @@ export class Room {
|
|||||||
get loginSceneLogo(): string | undefined {
|
get loginSceneLogo(): string | undefined {
|
||||||
return this._loginSceneLogo;
|
return this._loginSceneLogo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get showPoweredBy(): boolean | undefined {
|
||||||
|
return this._showPoweredBy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
21
front/src/Interfaces/DesktopAppInterfaces.ts
Normal file
21
front/src/Interfaces/DesktopAppInterfaces.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// copy of Electron.SourcesOptions to avoid Electron dependency in front
|
||||||
|
export interface SourcesOptions {
|
||||||
|
types: string[];
|
||||||
|
thumbnailSize?: { height: number; width: number };
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DesktopCapturerSource {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
thumbnailURL: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type WorkAdventureDesktopApi = {
|
||||||
|
desktop: boolean;
|
||||||
|
isDevelopment: () => Promise<boolean>;
|
||||||
|
getVersion: () => Promise<string>;
|
||||||
|
notify: (txt: string) => void;
|
||||||
|
onMuteToggle: (callback: () => void) => void;
|
||||||
|
onCameraToggle: (callback: () => void) => void;
|
||||||
|
getDesktopCapturerSources: (options: SourcesOptions) => Promise<DesktopCapturerSource[]>;
|
||||||
|
};
|
@ -54,7 +54,7 @@ export class Loader {
|
|||||||
.catch((e) => console.warn("Could not load logo: ", logoResource, e));
|
.catch((e) => console.warn("Could not load logo: ", logoResource, e));
|
||||||
|
|
||||||
let poweredByLogoPromise: CancelablePromise<Texture> | undefined;
|
let poweredByLogoPromise: CancelablePromise<Texture> | undefined;
|
||||||
if (gameManager.currentStartedRoom.loadingLogo) {
|
if (gameManager.currentStartedRoom.loadingLogo && gameManager.currentStartedRoom.showPoweredBy !== false) {
|
||||||
poweredByLogoPromise = this.superLoad.image(
|
poweredByLogoPromise = this.superLoad.image(
|
||||||
"poweredByLogo",
|
"poweredByLogo",
|
||||||
"static/images/Powered_By_WorkAdventure_Small.png"
|
"static/images/Powered_By_WorkAdventure_Small.png"
|
||||||
|
@ -4,5 +4,6 @@ export const DEPTH_TILE_INDEX = 0;
|
|||||||
//Note: Player characters use their y coordinate as their depth to simulate a perspective.
|
//Note: Player characters use their y coordinate as their depth to simulate a perspective.
|
||||||
//See the Character class.
|
//See the Character class.
|
||||||
export const DEPTH_OVERLAY_INDEX = 10000;
|
export const DEPTH_OVERLAY_INDEX = 10000;
|
||||||
|
export const DEPTH_BUBBLE_CHAT_SPRITE = 99999;
|
||||||
export const DEPTH_INGAME_TEXT_INDEX = 100000;
|
export const DEPTH_INGAME_TEXT_INDEX = 100000;
|
||||||
export const DEPTH_UI_INDEX = 1000000;
|
export const DEPTH_UI_INDEX = 1000000;
|
||||||
|
@ -76,6 +76,7 @@ import { contactPageStore } from "../../Stores/MenuStore";
|
|||||||
import type { WasCameraUpdatedEvent } from "../../Api/Events/WasCameraUpdatedEvent";
|
import type { WasCameraUpdatedEvent } from "../../Api/Events/WasCameraUpdatedEvent";
|
||||||
import { audioManagerFileStore } from "../../Stores/AudioManagerStore";
|
import { audioManagerFileStore } from "../../Stores/AudioManagerStore";
|
||||||
import { currentPlayerGroupLockStateStore } from "../../Stores/CurrentPlayerGroupStore";
|
import { currentPlayerGroupLockStateStore } from "../../Stores/CurrentPlayerGroupStore";
|
||||||
|
import { errorScreenStore } from "../../Stores/ErrorScreenStore";
|
||||||
|
|
||||||
import EVENT_TYPE = Phaser.Scenes.Events;
|
import EVENT_TYPE = Phaser.Scenes.Events;
|
||||||
import Texture = Phaser.Textures.Texture;
|
import Texture = Phaser.Textures.Texture;
|
||||||
@ -90,8 +91,8 @@ import FILE_LOAD_ERROR = Phaser.Loader.Events.FILE_LOAD_ERROR;
|
|||||||
import { MapStore } from "../../Stores/Utils/MapStore";
|
import { MapStore } from "../../Stores/Utils/MapStore";
|
||||||
import { followUsersColorStore } from "../../Stores/FollowStore";
|
import { followUsersColorStore } from "../../Stores/FollowStore";
|
||||||
import { GameSceneUserInputHandler } from "../UserInput/GameSceneUserInputHandler";
|
import { GameSceneUserInputHandler } from "../UserInput/GameSceneUserInputHandler";
|
||||||
import { locale } from "../../i18n/i18n-svelte";
|
|
||||||
import { i18nJson } from "../../i18n/locales";
|
import { i18nJson } from "../../i18n/locales";
|
||||||
|
import LL, { locale } from "../../i18n/i18n-svelte";
|
||||||
import { availabilityStatusStore, localVolumeStore } from "../../Stores/MediaStore";
|
import { availabilityStatusStore, localVolumeStore } from "../../Stores/MediaStore";
|
||||||
import { StringUtils } from "../../Utils/StringUtils";
|
import { StringUtils } from "../../Utils/StringUtils";
|
||||||
import { startLayerNamesStore } from "../../Stores/StartLayerNamesStore";
|
import { startLayerNamesStore } from "../../Stores/StartLayerNamesStore";
|
||||||
@ -101,7 +102,9 @@ import type { CoWebsite } from "../../WebRtc/CoWebsite/CoWesbite";
|
|||||||
import CancelablePromise from "cancelable-promise";
|
import CancelablePromise from "cancelable-promise";
|
||||||
import { Deferred } from "ts-deferred";
|
import { Deferred } from "ts-deferred";
|
||||||
import { SuperLoaderPlugin } from "../Services/SuperLoaderPlugin";
|
import { SuperLoaderPlugin } from "../Services/SuperLoaderPlugin";
|
||||||
import { PlayerDetailsUpdatedMessage } from "../../Messages/ts-proto-generated/protos/messages";
|
import { DEPTH_BUBBLE_CHAT_SPRITE } from "./DepthIndexes";
|
||||||
|
import { ErrorScreenMessage, PlayerDetailsUpdatedMessage } from "../../Messages/ts-proto-generated/protos/messages";
|
||||||
|
import { uiWebsiteManager } from "./UI/UIWebsiteManager";
|
||||||
export interface GameSceneInitInterface {
|
export interface GameSceneInitInterface {
|
||||||
initPosition: PointInterface | null;
|
initPosition: PointInterface | null;
|
||||||
reconnecting: boolean;
|
reconnecting: boolean;
|
||||||
@ -613,14 +616,30 @@ export class GameScene extends DirtyScene {
|
|||||||
if (this.isReconnecting) {
|
if (this.isReconnecting) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.scene.sleep();
|
this.scene.sleep();
|
||||||
this.scene.launch(ReconnectingSceneName);
|
errorScreenStore.setError(
|
||||||
|
ErrorScreenMessage.fromPartial({
|
||||||
|
type: "reconnecting",
|
||||||
|
code: "CONNECTION_LOST",
|
||||||
|
title: get(LL).warning.connectionLostTitle(),
|
||||||
|
details: get(LL).warning.connectionLostSubtitle(),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
//this.scene.launch(ReconnectingSceneName);
|
||||||
}, 0);
|
}, 0);
|
||||||
} else if (this.connection === undefined) {
|
} else if (this.connection === undefined) {
|
||||||
// Let's wait 1 second before printing the "connecting" screen to avoid blinking
|
// Let's wait 1 second before printing the "connecting" screen to avoid blinking
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (this.connection === undefined) {
|
if (this.connection === undefined) {
|
||||||
this.scene.sleep();
|
this.scene.sleep();
|
||||||
this.scene.launch(ReconnectingSceneName);
|
errorScreenStore.setError(
|
||||||
|
ErrorScreenMessage.fromPartial({
|
||||||
|
type: "reconnecting",
|
||||||
|
code: "CONNECTION_LOST",
|
||||||
|
title: get(LL).warning.connectionLostTitle(),
|
||||||
|
details: get(LL).warning.connectionLostSubtitle(),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
//this.scene.launch(ReconnectingSceneName);
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
@ -904,7 +923,9 @@ export class GameScene extends DirtyScene {
|
|||||||
// Analyze tags to find if we are admin. If yes, show console.
|
// Analyze tags to find if we are admin. If yes, show console.
|
||||||
|
|
||||||
if (this.scene.isSleeping()) {
|
if (this.scene.isSleeping()) {
|
||||||
this.scene.stop(ReconnectingSceneName);
|
const error = get(errorScreenStore);
|
||||||
|
if (error && error?.type === "reconnecting") errorScreenStore.delete();
|
||||||
|
//this.scene.stop(ReconnectingSceneName);
|
||||||
}
|
}
|
||||||
|
|
||||||
//init user position and play trigger to check layers properties
|
//init user position and play trigger to check layers properties
|
||||||
@ -1111,6 +1132,24 @@ export class GameScene extends DirtyScene {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.iframeSubscriptionList.push(
|
||||||
|
iframeListener.enablePlayerControlStream.subscribe(() => {
|
||||||
|
this.userInputManager.restoreControls();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
this.iframeSubscriptionList.push(
|
||||||
|
iframeListener.disablePlayerProximityMeetingStream.subscribe(() => {
|
||||||
|
this.disableMediaBehaviors();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
this.iframeSubscriptionList.push(
|
||||||
|
iframeListener.enablePlayerProximityMeetingStream.subscribe(() => {
|
||||||
|
this.enableMediaBehaviors();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
this.iframeSubscriptionList.push(
|
this.iframeSubscriptionList.push(
|
||||||
iframeListener.cameraSetStream.subscribe((cameraSetEvent) => {
|
iframeListener.cameraSetStream.subscribe((cameraSetEvent) => {
|
||||||
const duration = cameraSetEvent.smooth ? 1000 : 0;
|
const duration = cameraSetEvent.smooth ? 1000 : 0;
|
||||||
@ -1198,11 +1237,6 @@ export class GameScene extends DirtyScene {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
this.iframeSubscriptionList.push(
|
|
||||||
iframeListener.enablePlayerControlStream.subscribe(() => {
|
|
||||||
this.userInputManager.restoreControls();
|
|
||||||
})
|
|
||||||
);
|
|
||||||
this.iframeSubscriptionList.push(
|
this.iframeSubscriptionList.push(
|
||||||
iframeListener.loadPageStream.subscribe((url: string) => {
|
iframeListener.loadPageStream.subscribe((url: string) => {
|
||||||
this.loadNextGameFromExitUrl(url)
|
this.loadNextGameFromExitUrl(url)
|
||||||
@ -1225,7 +1259,7 @@ export class GameScene extends DirtyScene {
|
|||||||
this.CurrentPlayer.y,
|
this.CurrentPlayer.y,
|
||||||
"circleSprite-white"
|
"circleSprite-white"
|
||||||
);
|
);
|
||||||
scriptedBubbleSprite.setDisplayOrigin(48, 48);
|
scriptedBubbleSprite.setDisplayOrigin(48, 48).setDepth(DEPTH_BUBBLE_CHAT_SPRITE);
|
||||||
this.add.existing(scriptedBubbleSprite);
|
this.add.existing(scriptedBubbleSprite);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@ -1313,6 +1347,17 @@ export class GameScene extends DirtyScene {
|
|||||||
data.propertyValue = this.gameMap.getLayerProperty(data.layerName, data.propertyName);
|
data.propertyValue = this.gameMap.getLayerProperty(data.layerName, data.propertyName);
|
||||||
return data;
|
return data;
|
||||||
});
|
});
|
||||||
|
iframeListener.registerAnswerer("openUIWebsite", (websiteConfig) => {
|
||||||
|
return uiWebsiteManager.open(websiteConfig);
|
||||||
|
});
|
||||||
|
|
||||||
|
iframeListener.registerAnswerer("getUIWebsites", () => {
|
||||||
|
return uiWebsiteManager.getAll();
|
||||||
|
});
|
||||||
|
|
||||||
|
iframeListener.registerAnswerer("closeUIWebsite", (websiteId) => {
|
||||||
|
return uiWebsiteManager.close(websiteId);
|
||||||
|
});
|
||||||
|
|
||||||
iframeListener.registerAnswerer("getMapData", () => {
|
iframeListener.registerAnswerer("getMapData", () => {
|
||||||
return {
|
return {
|
||||||
@ -1610,6 +1655,9 @@ export class GameScene extends DirtyScene {
|
|||||||
iframeListener.unregisterAnswerer("getCoWebsites");
|
iframeListener.unregisterAnswerer("getCoWebsites");
|
||||||
iframeListener.unregisterAnswerer("setPlayerOutline");
|
iframeListener.unregisterAnswerer("setPlayerOutline");
|
||||||
iframeListener.unregisterAnswerer("setVariable");
|
iframeListener.unregisterAnswerer("setVariable");
|
||||||
|
iframeListener.unregisterAnswerer("openUIWebsite");
|
||||||
|
iframeListener.unregisterAnswerer("getUIWebsites");
|
||||||
|
iframeListener.unregisterAnswerer("closeUIWebsite");
|
||||||
this.sharedVariablesManager?.close();
|
this.sharedVariablesManager?.close();
|
||||||
this.embeddedWebsiteManager?.close();
|
this.embeddedWebsiteManager?.close();
|
||||||
|
|
||||||
@ -2079,7 +2127,7 @@ export class GameScene extends DirtyScene {
|
|||||||
? "circleSprite-red"
|
? "circleSprite-red"
|
||||||
: "circleSprite-white"
|
: "circleSprite-white"
|
||||||
);
|
);
|
||||||
sprite.setDisplayOrigin(48, 48);
|
sprite.setDisplayOrigin(48, 48).setDepth(DEPTH_BUBBLE_CHAT_SPRITE);
|
||||||
this.add.existing(sprite);
|
this.add.existing(sprite);
|
||||||
this.groups.set(groupPositionMessage.groupId, sprite);
|
this.groups.set(groupPositionMessage.groupId, sprite);
|
||||||
if (this.currentPlayerGroupId === groupPositionMessage.groupId) {
|
if (this.currentPlayerGroupId === groupPositionMessage.groupId) {
|
||||||
|
94
front/src/Phaser/Game/UI/UIWebsiteManager.ts
Normal file
94
front/src/Phaser/Game/UI/UIWebsiteManager.ts
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import { get } from "svelte/store";
|
||||||
|
import { CreateUIWebsiteEvent, ModifyUIWebsiteEvent, UIWebsite } from "../../../Api/Events/ui/UIWebsite";
|
||||||
|
import { iframeListener } from "../../../Api/IframeListener";
|
||||||
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
import { uiWebsitesStore } from "../../../Stores/UIWebsiteStore";
|
||||||
|
|
||||||
|
class UIWebsiteManager {
|
||||||
|
constructor() {
|
||||||
|
iframeListener.modifyUIWebsiteStream.subscribe((websiteEvent: ModifyUIWebsiteEvent) => {
|
||||||
|
const website = get(uiWebsitesStore).find((currentWebsite) => currentWebsite.id === websiteEvent.id);
|
||||||
|
if (!website) {
|
||||||
|
throw new Error(`Could not find ui website with the id "${websiteEvent.id}" in your map`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (websiteEvent.url) {
|
||||||
|
website.url = websiteEvent.url;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (websiteEvent.visible !== undefined) {
|
||||||
|
website.visible = websiteEvent.visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (websiteEvent.position) {
|
||||||
|
if (websiteEvent.position.horizontal) {
|
||||||
|
website.position.horizontal = websiteEvent.position.horizontal;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (websiteEvent.position.vertical) {
|
||||||
|
website.position.vertical = websiteEvent.position.vertical;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (websiteEvent.size) {
|
||||||
|
if (websiteEvent.size.height) {
|
||||||
|
website.size.height = websiteEvent.size.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (websiteEvent.size.width) {
|
||||||
|
website.size.width = websiteEvent.size.width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (websiteEvent.margin) {
|
||||||
|
website.margin = {};
|
||||||
|
|
||||||
|
if (websiteEvent.margin.top !== undefined) {
|
||||||
|
website.margin.top = websiteEvent.margin.top;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (websiteEvent.margin.bottom !== undefined) {
|
||||||
|
website.margin.bottom = websiteEvent.margin.bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (websiteEvent.margin.left !== undefined) {
|
||||||
|
website.margin.left = websiteEvent.margin.left;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (websiteEvent.margin.right !== undefined) {
|
||||||
|
website.margin.right = websiteEvent.margin.right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public open(websiteConfig: CreateUIWebsiteEvent): UIWebsite {
|
||||||
|
const newWebsite: UIWebsite = {
|
||||||
|
...websiteConfig,
|
||||||
|
id: uuidv4(),
|
||||||
|
visible: websiteConfig.visible ?? true,
|
||||||
|
allowPolicy: websiteConfig.allowPolicy ?? "",
|
||||||
|
allowApi: websiteConfig.allowApi ?? false,
|
||||||
|
};
|
||||||
|
|
||||||
|
uiWebsitesStore.add(newWebsite);
|
||||||
|
|
||||||
|
return newWebsite;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getAll(): UIWebsite[] {
|
||||||
|
return get(uiWebsitesStore);
|
||||||
|
}
|
||||||
|
|
||||||
|
public close(websiteId: string) {
|
||||||
|
const uiWebsite = get(uiWebsitesStore).find((currentWebsite) => currentWebsite.id === websiteId);
|
||||||
|
|
||||||
|
if (!uiWebsite) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uiWebsitesStore.remove(uiWebsite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const uiWebsiteManager = new UIWebsiteManager();
|
@ -94,6 +94,7 @@ export class CustomizeScene extends AbstractCharacterScene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public create(): void {
|
public create(): void {
|
||||||
|
this.selectedLayers = [0, 0, 0, 0, 0, 0];
|
||||||
this.tryLoadLastUsedWokaLayers();
|
this.tryLoadLastUsedWokaLayers();
|
||||||
waScaleManager.zoomModifier = 1;
|
waScaleManager.zoomModifier = 1;
|
||||||
this.createSlotBackgroundTextures();
|
this.createSlotBackgroundTextures();
|
||||||
@ -154,11 +155,10 @@ export class CustomizeScene extends AbstractCharacterScene {
|
|||||||
try {
|
try {
|
||||||
const savedWokaLayers = gameManager.getCharacterLayers();
|
const savedWokaLayers = gameManager.getCharacterLayers();
|
||||||
if (savedWokaLayers && savedWokaLayers.length !== 0) {
|
if (savedWokaLayers && savedWokaLayers.length !== 0) {
|
||||||
this.selectedLayers = [];
|
|
||||||
for (let i = 0; i < savedWokaLayers.length; i += 1) {
|
for (let i = 0; i < savedWokaLayers.length; i += 1) {
|
||||||
this.selectedLayers.push(
|
const index = this.layers[i].findIndex((item) => item.id === gameManager.getCharacterLayers()[i]);
|
||||||
this.layers[i].findIndex((item) => item.id === gameManager.getCharacterLayers()[i])
|
// set first item as default if not found
|
||||||
);
|
this.selectedLayers[i] = index !== -1 ? index : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
|
@ -5,13 +5,16 @@ import { ErrorScreenMessage } from "../Messages/ts-proto-generated/protos/messag
|
|||||||
* A store that contains one error of type WAError to be displayed.
|
* A store that contains one error of type WAError to be displayed.
|
||||||
*/
|
*/
|
||||||
function createErrorScreenStore() {
|
function createErrorScreenStore() {
|
||||||
const { subscribe, set } = writable<ErrorScreenMessage>(undefined);
|
const { subscribe, set } = writable<ErrorScreenMessage | undefined>(undefined);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
subscribe,
|
subscribe,
|
||||||
setError: (e: ErrorScreenMessage): void => {
|
setError: (e: ErrorScreenMessage): void => {
|
||||||
set(e);
|
set(e);
|
||||||
},
|
},
|
||||||
|
delete: () => {
|
||||||
|
set(undefined);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import { derived, Readable, readable, writable } from "svelte/store";
|
|||||||
import { peerStore } from "./PeerStore";
|
import { peerStore } from "./PeerStore";
|
||||||
import type { LocalStreamStoreValue } from "./MediaStore";
|
import type { LocalStreamStoreValue } from "./MediaStore";
|
||||||
import { myCameraVisibilityStore } from "./MyCameraStoreVisibility";
|
import { myCameraVisibilityStore } from "./MyCameraStoreVisibility";
|
||||||
import type { DesktopCapturerSource } from "@wa-preload-app";
|
import type { DesktopCapturerSource } from "../Interfaces/DesktopAppInterfaces";
|
||||||
|
|
||||||
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
front/src/Stores/UIWebsiteStore.ts
Normal file
20
front/src/Stores/UIWebsiteStore.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { writable } from "svelte/store";
|
||||||
|
import { UIWebsite } from "../Api/Events/ui/UIWebsite";
|
||||||
|
|
||||||
|
function createUIWebsiteStore() {
|
||||||
|
const { subscribe, update, set } = writable(Array<UIWebsite>());
|
||||||
|
|
||||||
|
set(Array<UIWebsite>());
|
||||||
|
|
||||||
|
return {
|
||||||
|
subscribe,
|
||||||
|
add: (uiWebsite: UIWebsite) => {
|
||||||
|
update((currentArray) => [...currentArray, uiWebsite]);
|
||||||
|
},
|
||||||
|
remove: (uiWebsite: UIWebsite) => {
|
||||||
|
update((currentArray) => currentArray.filter((currentWebsite) => currentWebsite.id !== uiWebsite.id));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const uiWebsitesStore = createUIWebsiteStore();
|
@ -238,6 +238,7 @@ class CoWebsiteManager {
|
|||||||
|
|
||||||
const iframe = coWebsite.getIframe();
|
const iframe = coWebsite.getIframe();
|
||||||
if (iframe) {
|
if (iframe) {
|
||||||
|
this.activateMainLoaderAnimation();
|
||||||
iframe.style.display = "none";
|
iframe.style.display = "none";
|
||||||
}
|
}
|
||||||
this.resizing = true;
|
this.resizing = true;
|
||||||
@ -258,6 +259,7 @@ class CoWebsiteManager {
|
|||||||
const iframe = coWebsite.getIframe();
|
const iframe = coWebsite.getIframe();
|
||||||
if (iframe) {
|
if (iframe) {
|
||||||
iframe.style.display = "flex";
|
iframe.style.display = "flex";
|
||||||
|
this.desactivateMainLoaderAnimation();
|
||||||
}
|
}
|
||||||
this.resizing = false;
|
this.resizing = false;
|
||||||
});
|
});
|
||||||
@ -273,6 +275,7 @@ class CoWebsiteManager {
|
|||||||
|
|
||||||
const iframe = coWebsite.getIframe();
|
const iframe = coWebsite.getIframe();
|
||||||
if (iframe) {
|
if (iframe) {
|
||||||
|
this.activateMainLoaderAnimation();
|
||||||
iframe.style.display = "none";
|
iframe.style.display = "none";
|
||||||
}
|
}
|
||||||
this.resizing = true;
|
this.resizing = true;
|
||||||
@ -296,6 +299,7 @@ class CoWebsiteManager {
|
|||||||
const iframe = coWebsite.getIframe();
|
const iframe = coWebsite.getIframe();
|
||||||
if (iframe) {
|
if (iframe) {
|
||||||
iframe.style.display = "flex";
|
iframe.style.display = "flex";
|
||||||
|
this.desactivateMainLoaderAnimation();
|
||||||
}
|
}
|
||||||
this.resizing = false;
|
this.resizing = false;
|
||||||
});
|
});
|
||||||
@ -309,9 +313,7 @@ class CoWebsiteManager {
|
|||||||
|
|
||||||
if (this.cowebsiteDom.classList.contains("closing")) {
|
if (this.cowebsiteDom.classList.contains("closing")) {
|
||||||
this.cowebsiteDom.classList.remove("closing");
|
this.cowebsiteDom.classList.remove("closing");
|
||||||
if (this.loaderAnimationInterval.interval) {
|
this.desactivateMainLoaderAnimation();
|
||||||
clearInterval(this.loaderAnimationInterval.interval);
|
|
||||||
}
|
|
||||||
this.loaderAnimationInterval.trails = undefined;
|
this.loaderAnimationInterval.trails = undefined;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -353,7 +355,10 @@ class CoWebsiteManager {
|
|||||||
this.fire();
|
this.fire();
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadMain(openingWidth?: number): void {
|
private activateMainLoaderAnimation() {
|
||||||
|
this.desactivateMainLoaderAnimation();
|
||||||
|
|
||||||
|
this.cowebsiteLoaderDom.style.display = "block";
|
||||||
this.loaderAnimationInterval.interval = setInterval(() => {
|
this.loaderAnimationInterval.interval = setInterval(() => {
|
||||||
if (!this.loaderAnimationInterval.trails) {
|
if (!this.loaderAnimationInterval.trails) {
|
||||||
this.loaderAnimationInterval.trails = [0, 1, 2];
|
this.loaderAnimationInterval.trails = [0, 1, 2];
|
||||||
@ -361,7 +366,6 @@ class CoWebsiteManager {
|
|||||||
|
|
||||||
for (let trail = 1; trail < this.loaderAnimationInterval.trails.length + 1; trail++) {
|
for (let trail = 1; trail < this.loaderAnimationInterval.trails.length + 1; trail++) {
|
||||||
for (let state = 0; state < 4; state++) {
|
for (let state = 0; state < 4; state++) {
|
||||||
// const newState = this.loaderAnimationInterval.frames + trail -1;
|
|
||||||
const stateDom = this.cowebsiteLoaderDom.querySelector(
|
const stateDom = this.cowebsiteLoaderDom.querySelector(
|
||||||
`#trail-${trail}-state-${state}`
|
`#trail-${trail}-state-${state}`
|
||||||
) as SVGPolygonElement;
|
) as SVGPolygonElement;
|
||||||
@ -382,6 +386,17 @@ class CoWebsiteManager {
|
|||||||
trail === 3 ? 0 : trail + 1
|
trail === 3 ? 0 : trail + 1
|
||||||
);
|
);
|
||||||
}, 200);
|
}, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
private desactivateMainLoaderAnimation() {
|
||||||
|
if (this.loaderAnimationInterval.interval) {
|
||||||
|
this.cowebsiteLoaderDom.style.display = "none";
|
||||||
|
clearInterval(this.loaderAnimationInterval.interval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private loadMain(openingWidth?: number): void {
|
||||||
|
this.activateMainLoaderAnimation();
|
||||||
|
|
||||||
if (!this.verticalMode && openingWidth) {
|
if (!this.verticalMode && openingWidth) {
|
||||||
let newWidth = 50;
|
let newWidth = 50;
|
||||||
@ -623,6 +638,8 @@ class CoWebsiteManager {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.fire();
|
this.fire();
|
||||||
}, animationTime);
|
}, animationTime);
|
||||||
|
|
||||||
|
this.desactivateMainLoaderAnimation();
|
||||||
} else if (
|
} else if (
|
||||||
!highlightedEmbed &&
|
!highlightedEmbed &&
|
||||||
this.getCoWebsites().find((searchCoWebsite) => searchCoWebsite.getId() === coWebsite.getId())
|
this.getCoWebsites().find((searchCoWebsite) => searchCoWebsite.getId() === coWebsite.getId())
|
||||||
|
@ -14,6 +14,8 @@ const warning: NonNullable<Translation["warning"]> = {
|
|||||||
},
|
},
|
||||||
importantMessage: "Wichtige Nachricht",
|
importantMessage: "Wichtige Nachricht",
|
||||||
connectionLost: "Verbindungen unterbrochen. Wiederverbinden...",
|
connectionLost: "Verbindungen unterbrochen. Wiederverbinden...",
|
||||||
|
connectionLostTitle: "Verbindungen unterbrochen",
|
||||||
|
connectionLostSubtitle: "Wiederverbinden",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default warning;
|
export default warning;
|
||||||
|
@ -13,6 +13,8 @@ const warning: BaseTranslation = {
|
|||||||
},
|
},
|
||||||
importantMessage: "Important message",
|
importantMessage: "Important message",
|
||||||
connectionLost: "Connection lost. Reconnecting...",
|
connectionLost: "Connection lost. Reconnecting...",
|
||||||
|
connectionLostTitle: "Connection lost",
|
||||||
|
connectionLostSubtitle: "Reconnecting",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default warning;
|
export default warning;
|
||||||
|
@ -71,6 +71,7 @@
|
|||||||
|
|
||||||
&-loader {
|
&-loader {
|
||||||
width: 20%;
|
width: 20%;
|
||||||
|
display: none;
|
||||||
|
|
||||||
#smoke {
|
#smoke {
|
||||||
@for $i from 1 through 3 {
|
@for $i from 1 through 3 {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
// "include": ["src/**/*"],
|
// "include": ["src/**/*"],
|
||||||
|
|
||||||
"extends": "@tsconfig/svelte/tsconfig.json",
|
"extends": "@tsconfig/svelte/tsconfig.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"outDir": "./dist/",
|
"outDir": "./dist/",
|
||||||
@ -14,23 +13,17 @@
|
|||||||
"jsx": "react",
|
"jsx": "react",
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
|
|
||||||
"importsNotUsedAsValues": "remove",
|
"importsNotUsedAsValues": "remove",
|
||||||
|
"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. */
|
"strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||||
"strictFunctionTypes": true, /* Enable strict checking of function types. */
|
"strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
|
||||||
"strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
|
"strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||||
"strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
"noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||||
"noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
"alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||||
"alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
"noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||||
|
"noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||||
"noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
|
||||||
"noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
|
||||||
"paths": {
|
|
||||||
"@wa-preload-app": ["../desktop/electron/src/preload-app/types.ts"],
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules",
|
"node_modules",
|
||||||
|
@ -2244,10 +2244,10 @@ prelude-ls@^1.2.1:
|
|||||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
|
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
|
||||||
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
|
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
|
||||||
|
|
||||||
prettier-plugin-svelte@^2.5.0:
|
prettier-plugin-svelte@^2.7.0:
|
||||||
version "2.5.0"
|
version "2.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/prettier-plugin-svelte/-/prettier-plugin-svelte-2.5.0.tgz#7922534729f7febe59b4c56c3f5360539f0d8ab1"
|
resolved "https://registry.yarnpkg.com/prettier-plugin-svelte/-/prettier-plugin-svelte-2.7.0.tgz#ecfa4fe824238a4466a3497df1a96d15cf43cabb"
|
||||||
integrity sha512-+iHY2uGChOngrgKielJUnqo74gIL/EO5oeWm8MftFWjEi213lq9QYTOwm1pv4lI1nA61tdgf80CF2i5zMcu1kw==
|
integrity sha512-fQhhZICprZot2IqEyoiUYLTRdumULGRvw0o4dzl5jt0jfzVWdGqeYW27QTWAeXhoupEZJULmNoH3ueJwUWFLIA==
|
||||||
|
|
||||||
prettier@^2.0.2:
|
prettier@^2.0.2:
|
||||||
version "2.5.1"
|
version "2.5.1"
|
||||||
|
5
maps/tests/UIWebsite/index.html
Normal file
5
maps/tests/UIWebsite/index.html
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<html>
|
||||||
|
<body style="background-color: white;">
|
||||||
|
This is test page
|
||||||
|
</body>
|
||||||
|
</html>
|
48
maps/tests/UIWebsite/script.js
Normal file
48
maps/tests/UIWebsite/script.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
WA.onInit().then(() => {
|
||||||
|
initListeners();
|
||||||
|
});
|
||||||
|
|
||||||
|
function initListeners() {
|
||||||
|
let first_website = undefined;
|
||||||
|
let second_website = undefined;
|
||||||
|
|
||||||
|
WA.room.onEnterLayer('first_website').subscribe(async () => {
|
||||||
|
first_website = await WA.ui.website.open({
|
||||||
|
url: "http://maps.workadventure.localhost/tests/UIWebsite/index.html",
|
||||||
|
position: {
|
||||||
|
vertical: "middle",
|
||||||
|
horizontal: "middle",
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
height: "50vh",
|
||||||
|
width: "50vw",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
WA.room.onLeaveLayer('first_website').subscribe(() => {
|
||||||
|
if (first_website) {
|
||||||
|
first_website.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
WA.room.onEnterLayer('second_website').subscribe(async () => {
|
||||||
|
second_website = await WA.ui.website.open({
|
||||||
|
url: "https://www.wikipedia.org/",
|
||||||
|
position: {
|
||||||
|
vertical: "top",
|
||||||
|
horizontal: "right",
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
height: "20vh",
|
||||||
|
width: "50vw",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
WA.room.onLeaveLayer('second_website').subscribe(() => {
|
||||||
|
if (second_website) {
|
||||||
|
second_website.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
679
maps/tests/UIWebsite/uiwebsite.json
Normal file
679
maps/tests/UIWebsite/uiwebsite.json
Normal file
@ -0,0 +1,679 @@
|
|||||||
|
{ "compressionlevel":-1,
|
||||||
|
"height":10,
|
||||||
|
"infinite":false,
|
||||||
|
"layers":[
|
||||||
|
{
|
||||||
|
"data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
|
||||||
|
"height":10,
|
||||||
|
"id":1,
|
||||||
|
"name":"floor",
|
||||||
|
"opacity":1,
|
||||||
|
"type":"tilelayer",
|
||||||
|
"visible":true,
|
||||||
|
"width":10,
|
||||||
|
"x":0,
|
||||||
|
"y":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
12, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
"height":10,
|
||||||
|
"id":2,
|
||||||
|
"name":"start",
|
||||||
|
"opacity":1,
|
||||||
|
"type":"tilelayer",
|
||||||
|
"visible":true,
|
||||||
|
"width":10,
|
||||||
|
"x":0,
|
||||||
|
"y":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data":[0, 0, 0, 0, 0, 23, 23, 23, 23, 23,
|
||||||
|
0, 0, 0, 0, 0, 23, 23, 23, 23, 23,
|
||||||
|
0, 0, 0, 0, 0, 23, 23, 23, 23, 23,
|
||||||
|
0, 0, 0, 0, 0, 23, 23, 23, 23, 23,
|
||||||
|
0, 0, 0, 0, 0, 23, 23, 23, 23, 23,
|
||||||
|
0, 0, 0, 0, 0, 23, 23, 23, 23, 23,
|
||||||
|
0, 0, 0, 0, 0, 23, 23, 23, 23, 23,
|
||||||
|
0, 0, 0, 0, 0, 23, 23, 23, 23, 23,
|
||||||
|
0, 0, 0, 0, 0, 23, 23, 23, 23, 23,
|
||||||
|
0, 0, 0, 0, 0, 23, 23, 23, 23, 23],
|
||||||
|
"height":10,
|
||||||
|
"id":5,
|
||||||
|
"name":"first_website",
|
||||||
|
"opacity":1,
|
||||||
|
"type":"tilelayer",
|
||||||
|
"visible":true,
|
||||||
|
"width":10,
|
||||||
|
"x":0,
|
||||||
|
"y":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 12, 12, 12, 12, 12,
|
||||||
|
0, 0, 0, 0, 0, 12, 12, 12, 12, 12,
|
||||||
|
0, 0, 0, 0, 0, 12, 12, 12, 12, 12,
|
||||||
|
0, 0, 0, 0, 0, 12, 12, 12, 12, 12,
|
||||||
|
0, 0, 0, 0, 0, 12, 12, 12, 12, 12],
|
||||||
|
"height":10,
|
||||||
|
"id":7,
|
||||||
|
"name":"second_website",
|
||||||
|
"opacity":1,
|
||||||
|
"type":"tilelayer",
|
||||||
|
"visible":true,
|
||||||
|
"width":10,
|
||||||
|
"x":0,
|
||||||
|
"y":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"draworder":"topdown",
|
||||||
|
"id":3,
|
||||||
|
"name":"floorLayer",
|
||||||
|
"objects":[
|
||||||
|
{
|
||||||
|
"height":116.924156284309,
|
||||||
|
"id":1,
|
||||||
|
"name":"Tests",
|
||||||
|
"rotation":0,
|
||||||
|
"text":
|
||||||
|
{
|
||||||
|
"fontfamily":"Sans Serif",
|
||||||
|
"pixelsize":8,
|
||||||
|
"text":"Test 1:\nMove on the white carpet to display a UIWebsite.\n\nTest 2:\nMove on the blue carpet to display an other UIWebsite above the first.",
|
||||||
|
"wrap":true
|
||||||
|
},
|
||||||
|
"type":"",
|
||||||
|
"visible":true,
|
||||||
|
"width":158.381128664136,
|
||||||
|
"x":1.64026713939023,
|
||||||
|
"y":201.037039933902
|
||||||
|
}],
|
||||||
|
"opacity":1,
|
||||||
|
"type":"objectgroup",
|
||||||
|
"visible":true,
|
||||||
|
"x":0,
|
||||||
|
"y":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data":[0, 0, 0, 0, 0, 0, 0, 0, 82, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 8, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 19, 27, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 30, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
"height":10,
|
||||||
|
"id":8,
|
||||||
|
"name":"objects",
|
||||||
|
"opacity":1,
|
||||||
|
"type":"tilelayer",
|
||||||
|
"visible":true,
|
||||||
|
"width":10,
|
||||||
|
"x":0,
|
||||||
|
"y":0
|
||||||
|
}],
|
||||||
|
"nextlayerid":9,
|
||||||
|
"nextobjectid":3,
|
||||||
|
"orientation":"orthogonal",
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"script",
|
||||||
|
"type":"string",
|
||||||
|
"value":"script.js"
|
||||||
|
}],
|
||||||
|
"renderorder":"right-down",
|
||||||
|
"tiledversion":"1.8.4",
|
||||||
|
"tileheight":32,
|
||||||
|
"tilesets":[
|
||||||
|
{
|
||||||
|
"columns":11,
|
||||||
|
"firstgid":1,
|
||||||
|
"image":"..\/tileset1.png",
|
||||||
|
"imageheight":352,
|
||||||
|
"imagewidth":352,
|
||||||
|
"margin":0,
|
||||||
|
"name":"tileset1",
|
||||||
|
"spacing":0,
|
||||||
|
"tilecount":121,
|
||||||
|
"tileheight":32,
|
||||||
|
"tiles":[
|
||||||
|
{
|
||||||
|
"id":1,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":2,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":3,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":4,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":5,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":6,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":7,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":8,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":9,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":10,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"id":12,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":16,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":17,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":18,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":19,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":20,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":21,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":23,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":24,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":25,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"id":26,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":27,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":28,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":29,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":30,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":31,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":32,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":34,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":35,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":42,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"id":43,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":45,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":46,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":59,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":60,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":70,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":71,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":80,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":81,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":89,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"id":91,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":93,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":94,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":95,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":96,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":97,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":100,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":102,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":103,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":104,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"id":105,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":106,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":107,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":108,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":114,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":115,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"collides",
|
||||||
|
"type":"bool",
|
||||||
|
"value":true
|
||||||
|
}]
|
||||||
|
}],
|
||||||
|
"tilewidth":32
|
||||||
|
}],
|
||||||
|
"tilewidth":32,
|
||||||
|
"type":"map",
|
||||||
|
"version":"1.8",
|
||||||
|
"width":10
|
||||||
|
}
|
@ -363,6 +363,14 @@
|
|||||||
<a href="#" class="testLink" data-testmap="Modules/without_modules.json" target="_blank">Testing scripts with modules mode disabled</a>
|
<a href="#" class="testLink" data-testmap="Modules/without_modules.json" target="_blank">Testing scripts with modules mode disabled</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<input type="radio" name="test-uiwebsite"> Success <input type="radio" name="test-uiwebsite"> Failure <input type="radio" name="test-uiwebsite" checked> Pending
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="#" class="testLink" data-testmap="UIWebsite/uiwebsite.json" target="_blank">Testing UIWebsites</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<h2>CoWebsite</h2>
|
<h2>CoWebsite</h2>
|
||||||
<table class="table">
|
<table class="table">
|
||||||
|
@ -49,6 +49,10 @@ export const isMapDetailsData = z.object({
|
|||||||
description: "The URL of the image to be used on the LoginScene",
|
description: "The URL of the image to be used on the LoginScene",
|
||||||
example: "https://example.com/logo_login.png",
|
example: "https://example.com/logo_login.png",
|
||||||
}),
|
}),
|
||||||
|
showPoweredBy: extendApi(z.boolean(), {
|
||||||
|
description: "The URL of the image to be used on the name scene",
|
||||||
|
example: "https://example.com/logo_login.png",
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type MapDetailsData = z.infer<typeof isMapDetailsData>;
|
export type MapDetailsData = z.infer<typeof isMapDetailsData>;
|
||||||
|
@ -49,6 +49,7 @@ class LocalAdmin implements AdminInterface {
|
|||||||
iframeAuthentication: null,
|
iframeAuthentication: null,
|
||||||
loadingLogo: null,
|
loadingLogo: null,
|
||||||
loginSceneLogo: null,
|
loginSceneLogo: null,
|
||||||
|
showPoweredBy: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user