Merge branch 'develop' of github.com:thecodingmachine/workadventure
This commit is contained in:
commit
6783598244
@ -83,7 +83,8 @@
|
||||
"SECRET_JITSI_KEY": env.SECRET_JITSI_KEY,
|
||||
"TURN_SERVER": "turn:coturn.workadventu.re:443,turns:coturn.workadventu.re:443",
|
||||
"JITSI_PRIVATE_MODE": if env.SECRET_JITSI_KEY != '' then "true" else "false",
|
||||
"START_ROOM_URL": "/_/global/maps-"+url+"/starter/map.json"
|
||||
"START_ROOM_URL": "/_/global/maps-"+url+"/starter/map.json",
|
||||
"ICON_URL": "//icon-"+url,
|
||||
}
|
||||
},
|
||||
"uploader": {
|
||||
@ -109,7 +110,15 @@
|
||||
"redis": {
|
||||
"image": "redis:6",
|
||||
"ports": [6379]
|
||||
}
|
||||
},
|
||||
"iconserver": {
|
||||
"image": "matthiasluedtke/iconserver:v3.13.0",
|
||||
"host": {
|
||||
"url": "icon-"+url,
|
||||
"containerPort": 8080,
|
||||
},
|
||||
"ports": [8080]
|
||||
},
|
||||
},
|
||||
"config": {
|
||||
k8sextension(k8sConf)::
|
||||
@ -210,6 +219,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
iconserver+: {
|
||||
ingress+: {
|
||||
spec+: {
|
||||
tls+: [{
|
||||
hosts: ["icon-"+url],
|
||||
secretName: "certificate-tls"
|
||||
}]
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,17 +52,17 @@ WA.nav.goToRoom("/_/global/<path to global map>.json#start-layer-2")
|
||||
### Opening/closing web page in Co-Websites
|
||||
|
||||
```
|
||||
WA.nav.openCoWebSite(url: string, allowApi: boolean = false, allowPolicy: string = "", position: number = 0): Promise<CoWebsite>
|
||||
WA.nav.openCoWebSite(url: string, allowApi: boolean = false, allowPolicy: string = "", position: number, closable: boolean, lazy: boolean): Promise<CoWebsite>
|
||||
```
|
||||
|
||||
Opens the webpage at "url" in an iFrame (on the right side of the screen) or close that iFrame. `allowApi` allows the webpage to use the "IFrame API" and execute script (it is equivalent to putting the `openWebsiteAllowApi` property in the map). `allowPolicy` grants additional access rights to the iFrame. The `allowPolicy` parameter is turned into an [`allow` feature policy in the iFrame](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-allow), position in whitch slot the web page will be open.
|
||||
You can have only 5 co-wbesites open simultaneously.
|
||||
Opens the webpage at "url" in an iFrame (on the right side of the screen) or close that iFrame. `allowApi` allows the webpage to use the "IFrame API" and execute script (it is equivalent to putting the `openWebsiteAllowApi` property in the map). `allowPolicy` grants additional access rights to the iFrame. The `allowPolicy` parameter is turned into an [`allow` feature policy in the iFrame](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#attr-allow), position in whitch slot the web page will be open, closable allow to close the webpage also you need to close it by the api and lazy
|
||||
it's to add the cowebsite but don't load it.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
const coWebsite = await WA.nav.openCoWebSite('https://www.wikipedia.org/');
|
||||
const coWebsiteWorkAdventure = await WA.nav.openCoWebSite('https://workadventu.re/', true, "", 1);
|
||||
const coWebsiteWorkAdventure = await WA.nav.openCoWebSite('https://workadventu.re/', true, "", 1, true, true);
|
||||
// ...
|
||||
coWebsite.close();
|
||||
```
|
||||
|
4
front/dist/.gitignore
vendored
4
front/dist/.gitignore
vendored
@ -1,4 +1,6 @@
|
||||
index.html
|
||||
index.tmpl.html.tmp
|
||||
/js/
|
||||
/fonts/
|
||||
style.*.css
|
||||
!env-config.template.js
|
||||
*.png
|
||||
|
27
front/dist/env-config.template.js
vendored
Normal file
27
front/dist/env-config.template.js
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
window.env = {
|
||||
SKIP_RENDER_OPTIMIZATIONS: '${SKIP_RENDER_OPTIMIZATIONS}',
|
||||
DISABLE_NOTIFICATIONS: '${DISABLE_NOTIFICATIONS}',
|
||||
PUSHER_URL: '${PUSHER_URL}',
|
||||
UPLOADER_URL: '${UPLOADER_URL}',
|
||||
ADMIN_URL: '${ADMIN_URL}',
|
||||
CONTACT_URL: '${CONTACT_URL}',
|
||||
PROFILE_URL: '${PROFILE_URL}',
|
||||
ICON_URL: '${ICON_URL}',
|
||||
DEBUG_MODE: '${DEBUG_MODE}',
|
||||
STUN_SERVER: '${STUN_SERVER}',
|
||||
TURN_SERVER: '${TURN_SERVER}',
|
||||
TURN_USER: '${TURN_USER}',
|
||||
TURN_PASSWORD: '${TURN_PASSWORD}',
|
||||
JITSI_URL: '${JITSI_URL}',
|
||||
JITSI_PRIVATE_MODE: '${JITSI_PRIVATE_MODE}',
|
||||
START_ROOM_URL: '${START_ROOM_URL}',
|
||||
MAX_USERNAME_LENGTH: '${MAX_USERNAME_LENGTH}',
|
||||
MAX_PER_GROUP: '${MAX_PER_GROUP}',
|
||||
DISPLAY_TERMS_OF_USE: '${DISPLAY_TERMS_OF_USE}',
|
||||
POSTHOG_API_KEY: '${POSTHOG_API_KEY}',
|
||||
POSTHOG_URL: '${POSTHOG_URL}',
|
||||
NODE_ENV: '${NODE_ENV}',
|
||||
DISABLE_ANONYMOUS: '${DISABLE_ANONYMOUS}',
|
||||
OPID_LOGIN_SCREEN_PROVIDER: '${OPID_LOGIN_SCREEN_PROVIDER}',
|
||||
FALLBACK_LOCALE: '${FALLBACK_LOCALE}',
|
||||
};
|
68
front/dist/index.ejs
vendored
Normal file
68
front/dist/index.ejs
vendored
Normal file
File diff suppressed because one or more lines are too long
124
front/dist/index.tmpl.html
vendored
124
front/dist/index.tmpl.html
vendored
@ -1,124 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport"
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
|
||||
<!-- TRACK CODE -->
|
||||
<!-- END TRACK CODE -->
|
||||
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="static/images/favicons/apple-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="static/images/favicons/apple-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="static/images/favicons/apple-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="static/images/favicons/apple-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="static/images/favicons/apple-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="static/images/favicons/apple-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="static/images/favicons/apple-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="static/images/favicons/apple-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="static/images/favicons/apple-icon-180x180.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="static/images/favicons/android-icon-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="static/images/favicons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="static/images/favicons/favicon-96x96.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="static/images/favicons/favicon-16x16.png">
|
||||
<link rel="manifest" href="static/images/favicons/manifest.json">
|
||||
<meta name="msapplication-TileColor" content="#000000">
|
||||
<meta name="msapplication-TileImage" content="static/images/favicons/ms-icon-144x144.png">
|
||||
<meta name="theme-color" content="#000000">
|
||||
|
||||
<base href="/">
|
||||
|
||||
<title>Partey</title>
|
||||
</head>
|
||||
<body id="body" style="margin: 0; background-color: #000">
|
||||
<div class="main-container" id="main-container">
|
||||
<!-- Create the editor container -->
|
||||
<div id="game" class="game">
|
||||
<div id="cowebsite-container">
|
||||
<div id="cowebsite-container-main">
|
||||
<div id="cowebsite-slot-1">
|
||||
<div class="actions">
|
||||
<button type="button" class="nes-btn is-primary expand">></button>
|
||||
<button type="button" class="nes-btn is-error close">×</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="cowebsite-container-sub">
|
||||
<div id="cowebsite-slot-2">
|
||||
<div class="overlay">
|
||||
<div class="actions">
|
||||
<button type="button" title="Close" class="nes-btn is-error close">×</button>
|
||||
</div>
|
||||
<div class="actions-move">
|
||||
<button type="button" title="Expand" class="nes-btn is-primary expand">></button>
|
||||
<button type="button" title="Hightlight" class="nes-btn is-secondary hightlight">Ξ</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="cowebsite-slot-3">
|
||||
<div class="overlay">
|
||||
<div class="actions">
|
||||
<button type="button" title="Close" class="nes-btn is-error close">×</button>
|
||||
</div>
|
||||
<div class="actions-move">
|
||||
<button type="button" title="Expand" class="nes-btn is-primary expand">></button>
|
||||
<button type="button" title="Hightlight" class="nes-btn is-secondary hightlight">Ξ</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="cowebsite-slot-4">
|
||||
<div class="overlay">
|
||||
<div class="actions">
|
||||
<button type="button" title="Close" class="nes-btn is-error close">×</button>
|
||||
</div>
|
||||
<div class="actions-move">
|
||||
<button type="button" title="Expand" class="nes-btn is-primary expand">></button>
|
||||
<button type="button" title="Hightlight" class="nes-btn is-secondary hightlight">Ξ</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="svelte-overlay"></div>
|
||||
<div id="game-overlay" class="game-overlay">
|
||||
<div id="main-section" class="main-section">
|
||||
</div>
|
||||
<aside id="sidebar" class="sidebar">
|
||||
</aside>
|
||||
<div id="chat-mode" class="chat-mode three-col" style="display: none;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="cowebsite" class="cowebsite hidden">
|
||||
<aside id="cowebsite-aside" class="noselect">
|
||||
<div id="cowebsite-aside-buttons">
|
||||
<button class="top-right-btn nes-btn is-error" id="cowebsite-close" alt="close all co-websites">
|
||||
×
|
||||
</button>
|
||||
<button class="top-right-btn nes-btn is-primary" id="cowebsite-fullscreen" alt="fullscreen mode">
|
||||
<img id="cowebsite-fullscreen-close" style="display: none;" src="resources/logos/fullscreen-exit.svg"/>
|
||||
<img id="cowebsite-fullscreen-open" src="resources/logos/fullscreen.svg"/>
|
||||
</button>
|
||||
</div>
|
||||
<div id="cowebsite-aside-holder">
|
||||
<img src="/static/images/menu.svg" alt="hold to resize"/>
|
||||
</div>
|
||||
<div id="cowebsite-sub-icons"></div>
|
||||
</aside>
|
||||
<main id="cowebsite-slot-0"></main>
|
||||
</div>
|
||||
<div id="cowebsite-buffer"></div>
|
||||
</div>
|
||||
|
||||
<div id="activeScreenSharing" class="active-screen-sharing active">
|
||||
</div>
|
||||
<audio id="report-message">
|
||||
<source src="/resources/objects/report-message.mp3" type="audio/mp3">
|
||||
</audio>
|
||||
|
||||
</body>
|
||||
</html>
|
1
front/dist/resources/logos/cowebsite-swipe.svg
vendored
Normal file
1
front/dist/resources/logos/cowebsite-swipe.svg
vendored
Normal file
@ -0,0 +1 @@
|
||||
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><defs><image width="12" height="14" id="img1" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAOAQMAAAAhc2+vAAAAAXNSR0IB2cksfwAAAAZQTFRFAAAA////pdmf3QAAAAJ0Uk5TAP9bkSK1AAAAJUlEQVR4nGNgOMDAoMDw/wMDCDgwMDQwQIAASBgE/j8ACRswAACLjwYPIknTggAAAABJRU5ErkJggg=="/><image width="12" height="12" id="img2" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMAgMAAAArG7R0AAAAAXNSR0IB2cksfwAAAAlQTFRFAAAA/////wAAzV63nAAAAAN0Uk5TAP8BHlUJOgAAACJJREFUeJxjYGAQYGBgYGEIDQ0F0xA+BwMDEi80NASqigEAOD8CVqGVgwsAAAAASUVORK5CYII="/></defs><style></style><use href="#img1" x="2" y="1" /><use href="#img2" x="2" y="2" /></svg>
|
After Width: | Height: | Size: 717 B |
@ -15,6 +15,7 @@
|
||||
"@typescript-eslint/eslint-plugin": "^5.6.0",
|
||||
"@typescript-eslint/parser": "^5.6.0",
|
||||
"css-loader": "^5.2.4",
|
||||
"css-minimizer-webpack-plugin": "^3.3.1",
|
||||
"eslint": "^8.4.1",
|
||||
"eslint-plugin-svelte3": "^3.2.1",
|
||||
"fork-ts-checker-webpack-plugin": "^6.5.0",
|
||||
|
@ -6,13 +6,14 @@ export const isOpenCoWebsiteEvent = new tg.IsInterface()
|
||||
allowApi: tg.isOptional(tg.isBoolean),
|
||||
allowPolicy: tg.isOptional(tg.isString),
|
||||
position: tg.isOptional(tg.isNumber),
|
||||
closable: tg.isOptional(tg.isBoolean),
|
||||
lazy: tg.isOptional(tg.isBoolean),
|
||||
})
|
||||
.get();
|
||||
|
||||
export const isCoWebsite = new tg.IsInterface()
|
||||
.withProperties({
|
||||
id: tg.isString,
|
||||
position: tg.isNumber,
|
||||
})
|
||||
.get();
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { IframeApiContribution, sendToWorkadventure, queryWorkadventure } from "./IframeApiContribution";
|
||||
|
||||
export class CoWebsite {
|
||||
constructor(private readonly id: string, public readonly position: number) {}
|
||||
constructor(private readonly id: string) {}
|
||||
|
||||
close() {
|
||||
return queryWorkadventure({
|
||||
@ -41,7 +41,14 @@ export class WorkadventureNavigationCommands extends IframeApiContribution<Worka
|
||||
});
|
||||
}
|
||||
|
||||
async openCoWebSite(url: string, allowApi?: boolean, allowPolicy?: string, position?: number): Promise<CoWebsite> {
|
||||
async openCoWebSite(
|
||||
url: string,
|
||||
allowApi?: boolean,
|
||||
allowPolicy?: string,
|
||||
position?: number,
|
||||
closable?: boolean,
|
||||
lazy?: boolean
|
||||
): Promise<CoWebsite> {
|
||||
const result = await queryWorkadventure({
|
||||
type: "openCoWebsite",
|
||||
data: {
|
||||
@ -49,9 +56,11 @@ export class WorkadventureNavigationCommands extends IframeApiContribution<Worka
|
||||
allowApi,
|
||||
allowPolicy,
|
||||
position,
|
||||
closable,
|
||||
lazy,
|
||||
},
|
||||
});
|
||||
return new CoWebsite(result.id, result.position);
|
||||
return new CoWebsite(result.id);
|
||||
}
|
||||
|
||||
async getCoWebSites(): Promise<CoWebsite[]> {
|
||||
@ -59,7 +68,7 @@ export class WorkadventureNavigationCommands extends IframeApiContribution<Worka
|
||||
type: "getCoWebsites",
|
||||
data: undefined,
|
||||
});
|
||||
return result.map((cowebsiteEvent) => new CoWebsite(cowebsiteEvent.id, cowebsiteEvent.position));
|
||||
return result.map((cowebsiteEvent) => new CoWebsite(cowebsiteEvent.id));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,166 +1,52 @@
|
||||
<script lang="typescript">
|
||||
import MenuIcon from "./Menu/MenuIcon.svelte";
|
||||
import { menuIconVisiblilityStore, menuVisiblilityStore } from "../Stores/MenuStore";
|
||||
import { emoteMenuStore } from "../Stores/EmoteStore";
|
||||
import { enableCameraSceneVisibilityStore } from "../Stores/MediaStore";
|
||||
import CameraControls from "./CameraControls.svelte";
|
||||
import MyCamera from "./MyCamera.svelte";
|
||||
import SelectCompanionScene from "./SelectCompanion/SelectCompanionScene.svelte";
|
||||
import { selectCompanionSceneVisibleStore } from "../Stores/SelectCompanionStore";
|
||||
import { selectCharacterSceneVisibleStore } from "../Stores/SelectCharacterStore";
|
||||
import SelectCharacterScene from "./selectCharacter/SelectCharacterScene.svelte";
|
||||
import { customCharacterSceneVisibleStore } from "../Stores/CustomCharacterStore";
|
||||
import { errorStore } from "../Stores/ErrorStore";
|
||||
import CustomCharacterScene from "./CustomCharacterScene/CustomCharacterScene.svelte";
|
||||
import LoginScene from "./Login/LoginScene.svelte";
|
||||
import Chat from "./Chat/Chat.svelte";
|
||||
import { loginSceneVisibleStore } from "../Stores/LoginSceneStore";
|
||||
import EnableCameraScene from "./EnableCamera/EnableCameraScene.svelte";
|
||||
import VisitCard from "./VisitCard/VisitCard.svelte";
|
||||
import { requestVisitCardsStore } from "../Stores/GameStore";
|
||||
|
||||
import type { Game } from "../Phaser/Game/Game";
|
||||
import { chatVisibilityStore } from "../Stores/ChatStore";
|
||||
import { helpCameraSettingsVisibleStore } from "../Stores/HelpCameraSettingsStore";
|
||||
import HelpCameraSettingsPopup from "./HelpCameraSettings/HelpCameraSettingsPopup.svelte";
|
||||
import { showLimitRoomModalStore, showShareLinkMapModalStore } from "../Stores/ModalStore";
|
||||
import LimitRoomModal from "./Modal/LimitRoomModal.svelte";
|
||||
import ShareLinkMapModal from "./Modal/ShareLinkMapModal.svelte";
|
||||
import AudioPlaying from "./UI/AudioPlaying.svelte";
|
||||
import { soundPlayingStore } from "../Stores/SoundPlayingStore";
|
||||
import { customCharacterSceneVisibleStore } from "../Stores/CustomCharacterStore";
|
||||
import { errorStore } from "../Stores/ErrorStore";
|
||||
import { loginSceneVisibleStore } from "../Stores/LoginSceneStore";
|
||||
import { enableCameraSceneVisibilityStore } from "../Stores/MediaStore";
|
||||
import { selectCharacterSceneVisibleStore } from "../Stores/SelectCharacterStore";
|
||||
import { selectCompanionSceneVisibleStore } from "../Stores/SelectCompanionStore";
|
||||
import Chat from "./Chat/Chat.svelte";
|
||||
import CustomCharacterScene from "./CustomCharacterScene/CustomCharacterScene.svelte";
|
||||
import EnableCameraScene from "./EnableCamera/EnableCameraScene.svelte";
|
||||
import LoginScene from "./Login/LoginScene.svelte";
|
||||
import MainLayout from "./MainLayout.svelte";
|
||||
import SelectCharacterScene from "./selectCharacter/SelectCharacterScene.svelte";
|
||||
import SelectCompanionScene from "./SelectCompanion/SelectCompanionScene.svelte";
|
||||
import ErrorDialog from "./UI/ErrorDialog.svelte";
|
||||
import Menu from "./Menu/Menu.svelte";
|
||||
import EmoteMenu from "./EmoteMenu/EmoteMenu.svelte";
|
||||
import VideoOverlay from "./Video/VideoOverlay.svelte";
|
||||
import { gameOverlayVisibilityStore } from "../Stores/GameOverlayStoreVisibility";
|
||||
import BanMessageContainer from "./TypeMessage/BanMessageContainer.svelte";
|
||||
import TextMessageContainer from "./TypeMessage/TextMessageContainer.svelte";
|
||||
import { banMessageStore } from "../Stores/TypeMessageStore/BanMessageStore";
|
||||
import { textMessageStore } from "../Stores/TypeMessageStore/TextMessageStore";
|
||||
import { warningContainerStore } from "../Stores/MenuStore";
|
||||
import WarningContainer from "./WarningContainer/WarningContainer.svelte";
|
||||
import { layoutManagerVisibilityStore } from "../Stores/LayoutManagerStore";
|
||||
import LayoutManager from "./LayoutManager/LayoutManager.svelte";
|
||||
import { audioManagerVisibilityStore } from "../Stores/AudioManagerStore";
|
||||
import AudioManager from "./AudioManager/AudioManager.svelte";
|
||||
import { showReportScreenStore, userReportEmpty } from "../Stores/ShowReportScreenStore";
|
||||
import ReportMenu from "./ReportMenu/ReportMenu.svelte";
|
||||
import { followStateStore } from "../Stores/FollowStore";
|
||||
import { peerStore } from "../Stores/PeerStore";
|
||||
import FollowMenu from "./FollowMenu/FollowMenu.svelte";
|
||||
|
||||
export let game: Game;
|
||||
</script>
|
||||
|
||||
<div>
|
||||
{#if $loginSceneVisibleStore}
|
||||
<div class="scrollable">
|
||||
<LoginScene {game} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $selectCharacterSceneVisibleStore}
|
||||
<div>
|
||||
<SelectCharacterScene {game} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $customCharacterSceneVisibleStore}
|
||||
<div>
|
||||
<CustomCharacterScene {game} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $selectCompanionSceneVisibleStore}
|
||||
<div>
|
||||
<SelectCompanionScene {game} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $enableCameraSceneVisibilityStore}
|
||||
<div class="scrollable">
|
||||
<EnableCameraScene {game} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $banMessageStore.length > 0}
|
||||
<div>
|
||||
<BanMessageContainer />
|
||||
</div>
|
||||
{:else if $textMessageStore.length > 0}
|
||||
<div>
|
||||
<TextMessageContainer />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $soundPlayingStore}
|
||||
<div>
|
||||
<AudioPlaying url={$soundPlayingStore} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $audioManagerVisibilityStore}
|
||||
<div>
|
||||
<AudioManager />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $layoutManagerVisibilityStore}
|
||||
<div>
|
||||
<LayoutManager />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $showReportScreenStore !== userReportEmpty}
|
||||
<div>
|
||||
<ReportMenu />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $followStateStore !== "off" || $peerStore.size > 0}
|
||||
<div>
|
||||
<FollowMenu />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $menuIconVisiblilityStore}
|
||||
<div>
|
||||
<MenuIcon />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $menuVisiblilityStore}
|
||||
<div>
|
||||
<Menu />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $emoteMenuStore}
|
||||
<div>
|
||||
<EmoteMenu />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $gameOverlayVisibilityStore}
|
||||
<div>
|
||||
<VideoOverlay />
|
||||
<MyCamera />
|
||||
<CameraControls />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $helpCameraSettingsVisibleStore}
|
||||
<div>
|
||||
<HelpCameraSettingsPopup />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $showLimitRoomModalStore}
|
||||
<div>
|
||||
<LimitRoomModal />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $showShareLinkMapModalStore}
|
||||
<div>
|
||||
<ShareLinkMapModal />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $requestVisitCardsStore}
|
||||
<VisitCard visitCardUrl={$requestVisitCardsStore} />
|
||||
{/if}
|
||||
{#if $errorStore.length > 0}
|
||||
<div>
|
||||
<ErrorDialog />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $errorStore.length > 0}
|
||||
<div>
|
||||
<ErrorDialog />
|
||||
</div>
|
||||
{:else if $loginSceneVisibleStore}
|
||||
<div class="scrollable">
|
||||
<LoginScene {game} />
|
||||
</div>
|
||||
{:else if $selectCharacterSceneVisibleStore}
|
||||
<div>
|
||||
<SelectCharacterScene {game} />
|
||||
</div>
|
||||
{:else if $customCharacterSceneVisibleStore}
|
||||
<div>
|
||||
<CustomCharacterScene {game} />
|
||||
</div>
|
||||
{:else if $selectCompanionSceneVisibleStore}
|
||||
<div>
|
||||
<SelectCompanionScene {game} />
|
||||
</div>
|
||||
{:else if $enableCameraSceneVisibilityStore}
|
||||
<div class="scrollable">
|
||||
<EnableCameraScene {game} />
|
||||
</div>
|
||||
{:else}
|
||||
<MainLayout />
|
||||
|
||||
{#if $chatVisibilityStore}
|
||||
<Chat />
|
||||
{/if}
|
||||
{#if $warningContainerStore}
|
||||
<WarningContainer />
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
@ -157,13 +157,16 @@
|
||||
|
||||
<style lang="scss">
|
||||
div.main-audio-manager.nes-container.is-rounded {
|
||||
position: relative;
|
||||
top: 0.5rem;
|
||||
position: absolute;
|
||||
top: 1%;
|
||||
max-height: clamp(150px, 10vh, 15vh); //replace @media for small screen
|
||||
width: clamp(200px, 15vw, 15vw);
|
||||
padding: 3px 3px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 550;
|
||||
|
||||
background-color: rgb(0, 0, 0, 0.5);
|
||||
display: grid;
|
||||
|
@ -9,10 +9,15 @@
|
||||
import microphoneCloseImg from "./images/microphone-close.svg";
|
||||
import layoutPresentationImg from "./images/layout-presentation.svg";
|
||||
import layoutChatImg from "./images/layout-chat.svg";
|
||||
import { layoutModeStore } from "../Stores/StreamableCollectionStore";
|
||||
import followImg from "./images/follow.svg";
|
||||
import { LayoutMode } from "../WebRtc/LayoutManager";
|
||||
import { peerStore } from "../Stores/PeerStore";
|
||||
import { onDestroy } from "svelte";
|
||||
import { embedScreenLayout } from "../Stores/EmbedScreensStore";
|
||||
import { followRoleStore, followStateStore, followUsersStore } from "../Stores/FollowStore";
|
||||
import { gameManager } from "../Phaser/Game/GameManager";
|
||||
|
||||
const gameScene = gameManager.getCurrentGameScene();
|
||||
|
||||
function screenSharingClick(): void {
|
||||
if (isSilent) return;
|
||||
@ -42,10 +47,26 @@
|
||||
}
|
||||
|
||||
function switchLayoutMode() {
|
||||
if ($layoutModeStore === LayoutMode.Presentation) {
|
||||
$layoutModeStore = LayoutMode.VideoChat;
|
||||
if ($embedScreenLayout === LayoutMode.Presentation) {
|
||||
$embedScreenLayout = LayoutMode.VideoChat;
|
||||
} else {
|
||||
$layoutModeStore = LayoutMode.Presentation;
|
||||
$embedScreenLayout = LayoutMode.Presentation;
|
||||
}
|
||||
}
|
||||
|
||||
function followClick() {
|
||||
switch ($followStateStore) {
|
||||
case "off":
|
||||
gameScene.connection?.emitFollowRequest();
|
||||
followRoleStore.set("leader");
|
||||
followStateStore.set("active");
|
||||
break;
|
||||
case "requesting":
|
||||
case "active":
|
||||
case "ending":
|
||||
gameScene.connection?.emitFollowAbort();
|
||||
followUsersStore.stopFollowing();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,41 +77,156 @@
|
||||
onDestroy(unsubscribeIsSilent);
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<div class="btn-cam-action">
|
||||
<div class="btn-layout nes-btn is-dark" on:click={switchLayoutMode} class:hide={$peerStore.size === 0}>
|
||||
{#if $layoutModeStore === LayoutMode.Presentation}
|
||||
<img src={layoutPresentationImg} style="padding: 2px" alt="Switch to mosaic mode" />
|
||||
{:else}
|
||||
<img src={layoutChatImg} style="padding: 2px" alt="Switch to presentation mode" />
|
||||
{/if}
|
||||
</div>
|
||||
<div
|
||||
class="btn-monitor nes-btn is-dark"
|
||||
on:click={screenSharingClick}
|
||||
class:hide={!$screenSharingAvailableStore || isSilent}
|
||||
class:enabled={$requestedScreenSharingState}
|
||||
>
|
||||
{#if $requestedScreenSharingState && !isSilent}
|
||||
<img src={monitorImg} alt="Start screen sharing" />
|
||||
{:else}
|
||||
<img src={monitorCloseImg} alt="Stop screen sharing" />
|
||||
{/if}
|
||||
</div>
|
||||
<div class="btn-video nes-btn is-dark" on:click={cameraClick} class:disabled={!$requestedCameraState ||
|
||||
isSilent}>
|
||||
{#if $requestedCameraState && !isSilent}
|
||||
<img src={cinemaImg} alt="Turn on webcam" />
|
||||
{:else}
|
||||
<img src={cinemaCloseImg} alt="Turn off webcam" />
|
||||
{/if}
|
||||
</div>
|
||||
<div class="btn-micro nes-btn is-dark" on:click={microphoneClick} class:disabled={!$requestedMicrophoneState || isSilent}>
|
||||
{#if $requestedMicrophoneState && !isSilent}
|
||||
<img src={microphoneImg} alt="Turn on microphone" />
|
||||
{:else}
|
||||
<img src={microphoneCloseImg} alt="Turn off microphone" />
|
||||
{/if}
|
||||
</div>
|
||||
<div class="btn-cam-action">
|
||||
<div class="btn-layout nes-btn is-dark" on:click={switchLayoutMode} class:hide={$peerStore.size === 0}>
|
||||
{#if $embedScreenLayout === LayoutMode.Presentation}
|
||||
<img class="noselect" src={layoutPresentationImg} style="padding: 2px" alt="Switch to mosaic mode" />
|
||||
{:else}
|
||||
<img class="noselect" src={layoutChatImg} style="padding: 2px" alt="Switch to presentation mode" />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="btn-follow nes-btn is-dark"
|
||||
class:hide={($peerStore.size === 0 && $followStateStore === "off") || isSilent}
|
||||
class:disabled={$followStateStore !== "off"}
|
||||
on:click={followClick}
|
||||
>
|
||||
<img class="noselect" src={followImg} alt="" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="btn-monitor nes-btn is-dark"
|
||||
on:click={screenSharingClick}
|
||||
class:hide={!$screenSharingAvailableStore || isSilent}
|
||||
class:enabled={$requestedScreenSharingState}
|
||||
>
|
||||
{#if $requestedScreenSharingState && !isSilent}
|
||||
<img class="noselect" src={monitorImg} alt="Start screen sharing" />
|
||||
{:else}
|
||||
<img class="noselect" src={monitorCloseImg} alt="Stop screen sharing" />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="btn-video nes-btn is-dark" on:click={cameraClick} class:disabled={!$requestedCameraState || isSilent}>
|
||||
{#if $requestedCameraState && !isSilent}
|
||||
<img class="noselect" src={cinemaImg} alt="Turn on webcam" />
|
||||
{:else}
|
||||
<img class="noselect" src={cinemaCloseImg} alt="Turn off webcam" />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="btn-micro nes-btn is-dark" on:click={microphoneClick} class:disabled={!$requestedMicrophoneState || isSilent}>
|
||||
{#if $requestedMicrophoneState && !isSilent}
|
||||
<img class="noselect" src={microphoneImg} alt="Turn on microphone" />
|
||||
{:else}
|
||||
<img class="noselect" src={microphoneCloseImg} alt="Turn off microphone" />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../../style/breakpoints.scss";
|
||||
|
||||
.btn-cam-action {
|
||||
pointer-events: all;
|
||||
position: absolute;
|
||||
display: inline-flex;
|
||||
bottom: 10px;
|
||||
right: 15px;
|
||||
width: 360px;
|
||||
height: 40px;
|
||||
text-align: center;
|
||||
align-content: center;
|
||||
justify-content: flex-end;
|
||||
z-index: 251;
|
||||
|
||||
&:hover {
|
||||
div.hide {
|
||||
transform: translateY(60px);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*btn animation*/
|
||||
.btn-cam-action div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
transform: translateY(15px);
|
||||
transition-timing-function: ease-in-out;
|
||||
transition: all 0.3s;
|
||||
margin: 0 4%;
|
||||
|
||||
&.hide {
|
||||
transform: translateY(60px);
|
||||
}
|
||||
}
|
||||
.btn-cam-action div.disabled {
|
||||
background: #d75555;
|
||||
}
|
||||
.btn-cam-action div.enabled {
|
||||
background: #73c973;
|
||||
}
|
||||
.btn-cam-action:hover div {
|
||||
transform: translateY(0);
|
||||
}
|
||||
.btn-cam-action div:hover {
|
||||
background: #407cf7;
|
||||
box-shadow: 4px 4px 48px #666;
|
||||
transition: 120ms;
|
||||
}
|
||||
.btn-micro {
|
||||
pointer-events: auto;
|
||||
}
|
||||
.btn-video {
|
||||
pointer-events: auto;
|
||||
transition: all 0.25s;
|
||||
}
|
||||
.btn-monitor {
|
||||
pointer-events: auto;
|
||||
}
|
||||
.btn-layout {
|
||||
pointer-events: auto;
|
||||
transition: all 0.15s;
|
||||
}
|
||||
.btn-cam-action div img {
|
||||
height: 22px;
|
||||
width: 30px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.btn-follow {
|
||||
pointer-events: auto;
|
||||
|
||||
img {
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: none) {
|
||||
/**
|
||||
* If we cannot hover over elements, let's display camera button in full.
|
||||
*/
|
||||
.btn-cam-action {
|
||||
div {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(sm) {
|
||||
.btn-cam-action {
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 40%;
|
||||
max-height: 40px;
|
||||
|
||||
div {
|
||||
width: 20%;
|
||||
max-height: 44px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -42,9 +42,8 @@
|
||||
|
||||
<svelte:window on:keydown={onKeyDown} on:click={onClick} />
|
||||
|
||||
<aside class="chatWindow nes-container is-rounded is-dark" transition:fly={{ x: -1000, duration: 500 }}
|
||||
bind:this={chatWindowElement}>
|
||||
<p class="close-icon" on:click={closeChat}>×</p>
|
||||
<aside class="chatWindow nes-container is-rounded is-dark" transition:fly={{ x: -1000, duration: 500 }} bind:this={chatWindowElement}>
|
||||
<p class="close-icon noselect" on:click={closeChat}>×</p>
|
||||
<section class="messagesList" bind:this={listDom}>
|
||||
<ul>
|
||||
<li><p class="system-text">{$LL.chat.intro()}</p></li>
|
||||
@ -78,7 +77,7 @@
|
||||
}
|
||||
|
||||
aside.chatWindow {
|
||||
z-index: 100;
|
||||
z-index: 1000;
|
||||
pointer-events: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
@ -83,6 +83,8 @@
|
||||
</form>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../../../style/breakpoints.scss";
|
||||
|
||||
form.customCharacterScene {
|
||||
font-family: "Press Start 2P";
|
||||
pointer-events: auto;
|
||||
@ -129,7 +131,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
@include media-breakpoint-up(md) {
|
||||
form.customCharacterScene button.customCharacterSceneButtonLeft {
|
||||
left: 5vw;
|
||||
}
|
||||
|
32
front/src/Components/EmbedScreens/CamerasContainer.svelte
Normal file
32
front/src/Components/EmbedScreens/CamerasContainer.svelte
Normal file
@ -0,0 +1,32 @@
|
||||
<script lang="typescript">
|
||||
import type { EmbedScreen } from "../../Stores/EmbedScreensStore";
|
||||
import { streamableCollectionStore } from "../../Stores/StreamableCollectionStore";
|
||||
import MediaBox from "../Video/MediaBox.svelte";
|
||||
|
||||
export let highlightedEmbedScreen: EmbedScreen | null;
|
||||
export let full = false;
|
||||
$: clickable = !full;
|
||||
</script>
|
||||
|
||||
<aside class="cameras-container" class:full>
|
||||
{#each [...$streamableCollectionStore.values()] as peer (peer.uniqueId)}
|
||||
{#if !highlightedEmbedScreen || highlightedEmbedScreen.type !== "streamable" || (highlightedEmbedScreen.type === "streamable" && highlightedEmbedScreen.embed !== peer)}
|
||||
<MediaBox streamable={peer} isClickable={clickable} />
|
||||
{/if}
|
||||
{/each}
|
||||
</aside>
|
||||
|
||||
<style lang="scss">
|
||||
.cameras-container {
|
||||
flex: 0 0 25%;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
&:first-child {
|
||||
margin-top: 2%;
|
||||
}
|
||||
|
||||
&.full {
|
||||
flex: 0 0 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
268
front/src/Components/EmbedScreens/CoWebsiteThumbnailSlot.svelte
Normal file
268
front/src/Components/EmbedScreens/CoWebsiteThumbnailSlot.svelte
Normal file
@ -0,0 +1,268 @@
|
||||
<script lang="typescript">
|
||||
import { onMount } from "svelte";
|
||||
|
||||
import { ICON_URL } from "../../Enum/EnvironmentVariable";
|
||||
import { coWebsitesNotAsleep, mainCoWebsite } from "../../Stores/CoWebsiteStore";
|
||||
import { highlightedEmbedScreen } from "../../Stores/EmbedScreensStore";
|
||||
import type { CoWebsite } from "../../WebRtc/CoWebsiteManager";
|
||||
import { coWebsiteManager } from "../../WebRtc/CoWebsiteManager";
|
||||
|
||||
export let index: number;
|
||||
export let coWebsite: CoWebsite;
|
||||
export let vertical: boolean;
|
||||
|
||||
let icon: HTMLImageElement;
|
||||
let iconLoaded = false;
|
||||
let state = coWebsite.state;
|
||||
|
||||
const coWebsiteUrl = coWebsite.iframe.src;
|
||||
const urlObject = new URL(coWebsiteUrl);
|
||||
|
||||
onMount(() => {
|
||||
iconLoaded = true;
|
||||
});
|
||||
|
||||
async function onClick() {
|
||||
if (vertical) {
|
||||
coWebsiteManager.goToMain(coWebsite);
|
||||
} else if ($mainCoWebsite) {
|
||||
if ($mainCoWebsite.iframe.id === coWebsite.iframe.id) {
|
||||
const coWebsites = $coWebsitesNotAsleep;
|
||||
const newMain = $highlightedEmbedScreen ?? coWebsites.length > 1 ? coWebsites[1] : undefined;
|
||||
if (newMain) {
|
||||
coWebsiteManager.goToMain(coWebsite);
|
||||
}
|
||||
} else {
|
||||
highlightedEmbedScreen.toggleHighlight({
|
||||
type: "cowebsite",
|
||||
embed: coWebsite,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if ($state === "asleep") {
|
||||
await coWebsiteManager.loadCoWebsite(coWebsite);
|
||||
}
|
||||
|
||||
coWebsiteManager.resizeAllIframes();
|
||||
}
|
||||
|
||||
function noDrag() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let isHighlight: boolean = false;
|
||||
let isMain: boolean = false;
|
||||
$: {
|
||||
isMain = $mainCoWebsite !== undefined && $mainCoWebsite.iframe === coWebsite.iframe;
|
||||
isHighlight =
|
||||
$highlightedEmbedScreen !== null &&
|
||||
$highlightedEmbedScreen.type === "cowebsite" &&
|
||||
$highlightedEmbedScreen.embed.iframe === coWebsite.iframe;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
id={"cowebsite-thumbnail-" + index}
|
||||
class="cowebsite-thumbnail nes-pointer"
|
||||
class:asleep={$state === "asleep"}
|
||||
class:loading={$state === "loading"}
|
||||
class:ready={$state === "ready"}
|
||||
class:displayed={isMain || isHighlight}
|
||||
class:vertical
|
||||
on:click={onClick}
|
||||
>
|
||||
<img
|
||||
class="cowebsite-icon noselect nes-pointer"
|
||||
class:hide={!iconLoaded}
|
||||
bind:this={icon}
|
||||
on:dragstart|preventDefault={noDrag}
|
||||
alt=""
|
||||
/>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
class="cowebsite-icon"
|
||||
class:hide={iconLoaded}
|
||||
style="margin: auto; background: rgba(0, 0, 0, 0) none repeat scroll 0% 0%; shape-rendering: auto;"
|
||||
viewBox="0 0 100 100"
|
||||
preserveAspectRatio="xMidYMid"
|
||||
>
|
||||
<rect x="19" y="19" width="20" height="20" fill="#14304c">
|
||||
<animate
|
||||
attributeName="fill"
|
||||
values="#365dff;#14304c;#14304c"
|
||||
keyTimes="0;0.125;1"
|
||||
dur="1s"
|
||||
repeatCount="indefinite"
|
||||
begin="0s"
|
||||
calcMode="discrete"
|
||||
/>
|
||||
</rect><rect x="40" y="19" width="20" height="20" fill="#14304c">
|
||||
<animate
|
||||
attributeName="fill"
|
||||
values="#365dff;#14304c;#14304c"
|
||||
keyTimes="0;0.125;1"
|
||||
dur="1s"
|
||||
repeatCount="indefinite"
|
||||
begin="0.125s"
|
||||
calcMode="discrete"
|
||||
/>
|
||||
</rect><rect x="61" y="19" width="20" height="20" fill="#14304c">
|
||||
<animate
|
||||
attributeName="fill"
|
||||
values="#365dff;#14304c;#14304c"
|
||||
keyTimes="0;0.125;1"
|
||||
dur="1s"
|
||||
repeatCount="indefinite"
|
||||
begin="0.25s"
|
||||
calcMode="discrete"
|
||||
/>
|
||||
</rect><rect x="19" y="40" width="20" height="20" fill="#14304c">
|
||||
<animate
|
||||
attributeName="fill"
|
||||
values="#365dff;#14304c;#14304c"
|
||||
keyTimes="0;0.125;1"
|
||||
dur="1s"
|
||||
repeatCount="indefinite"
|
||||
begin="0.875s"
|
||||
calcMode="discrete"
|
||||
/>
|
||||
</rect><rect x="61" y="40" width="20" height="20" fill="#14304c">
|
||||
<animate
|
||||
attributeName="fill"
|
||||
values="#365dff;#14304c;#14304c"
|
||||
keyTimes="0;0.125;1"
|
||||
dur="1s"
|
||||
repeatCount="indefinite"
|
||||
begin="0.375s"
|
||||
calcMode="discrete"
|
||||
/>
|
||||
</rect><rect x="19" y="61" width="20" height="20" fill="#14304c">
|
||||
<animate
|
||||
attributeName="fill"
|
||||
values="#365dff;#14304c;#14304c"
|
||||
keyTimes="0;0.125;1"
|
||||
dur="1s"
|
||||
repeatCount="indefinite"
|
||||
begin="0.75s"
|
||||
calcMode="discrete"
|
||||
/>
|
||||
</rect><rect x="40" y="61" width="20" height="20" fill="#14304c">
|
||||
<animate
|
||||
attributeName="fill"
|
||||
values="#365dff;#14304c;#14304c"
|
||||
keyTimes="0;0.125;1"
|
||||
dur="1s"
|
||||
repeatCount="indefinite"
|
||||
begin="0.625s"
|
||||
calcMode="discrete"
|
||||
/>
|
||||
</rect><rect x="61" y="61" width="20" height="20" fill="#14304c">
|
||||
<animate
|
||||
attributeName="fill"
|
||||
values="#365dff;#14304c;#14304c"
|
||||
keyTimes="0;0.125;1"
|
||||
dur="1s"
|
||||
repeatCount="indefinite"
|
||||
begin="0.5s"
|
||||
calcMode="discrete"
|
||||
/>
|
||||
</rect>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.cowebsite-thumbnail {
|
||||
position: relative;
|
||||
padding: 0;
|
||||
background-color: rgba(#000000, 0.6);
|
||||
margin: 12px;
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 58px;
|
||||
height: 58px;
|
||||
left: -8px;
|
||||
top: -8px;
|
||||
|
||||
margin: 4px;
|
||||
|
||||
border-style: solid;
|
||||
border-width: 4px;
|
||||
border-image-slice: 3;
|
||||
border-image-width: 3;
|
||||
border-image-repeat: stretch;
|
||||
border-image-source: url('data:image/svg+xml;utf8,<?xml version="1.0" encoding="UTF-8" ?><svg version="1.1" width="8" height="8" xmlns="http://www.w3.org/2000/svg"><path d="M3 1 h1 v1 h-1 z M4 1 h1 v1 h-1 z M2 2 h1 v1 h-1 z M5 2 h1 v1 h-1 z M1 3 h1 v1 h-1 z M6 3 h1 v1 h-1 z M1 4 h1 v1 h-1 z M6 4 h1 v1 h-1 z M2 5 h1 v1 h-1 z M5 5 h1 v1 h-1 z M3 6 h1 v1 h-1 z M4 6 h1 v1 h-1 z" fill="rgb(33,37,41)" /></svg>');
|
||||
border-image-outset: 1;
|
||||
}
|
||||
|
||||
&.vertical {
|
||||
margin: 7px;
|
||||
|
||||
&::before {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.cowebsite-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
&.displayed {
|
||||
&:not(.vertical) {
|
||||
animation: activeThumbnail 300ms ease-in 0s forwards;
|
||||
}
|
||||
}
|
||||
|
||||
&.asleep {
|
||||
filter: grayscale(100%);
|
||||
--webkit-filter: grayscale(100%);
|
||||
}
|
||||
|
||||
&.loading {
|
||||
animation: 2500ms ease-in-out 0s infinite alternate backgroundLoading;
|
||||
}
|
||||
|
||||
&.ready {
|
||||
&::before {
|
||||
border-image-source: url('data:image/svg+xml;utf8,<?xml version="1.0" encoding="UTF-8" ?><svg version="1.1" width="8" height="8" xmlns="http://www.w3.org/2000/svg"><path d="M3 1 h1 v1 h-1 z M4 1 h1 v1 h-1 z M2 2 h1 v1 h-1 z M5 2 h1 v1 h-1 z M1 3 h1 v1 h-1 z M6 3 h1 v1 h-1 z M1 4 h1 v1 h-1 z M6 4 h1 v1 h-1 z M2 5 h1 v1 h-1 z M5 5 h1 v1 h-1 z M3 6 h1 v1 h-1 z M4 6 h1 v1 h-1 z" fill="rgb(38, 74, 110)" /></svg>');
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes backgroundLoading {
|
||||
0% {
|
||||
background-color: rgba(#000000, 0.6);
|
||||
}
|
||||
|
||||
100% {
|
||||
background-color: #25598e;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes activeThumbnail {
|
||||
0% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateY(-15px);
|
||||
}
|
||||
}
|
||||
|
||||
.cowebsite-icon {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
object-fit: cover;
|
||||
|
||||
&.hide {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
42
front/src/Components/EmbedScreens/CoWebsitesContainer.svelte
Normal file
42
front/src/Components/EmbedScreens/CoWebsitesContainer.svelte
Normal file
@ -0,0 +1,42 @@
|
||||
<script lang="typescript">
|
||||
import { coWebsites } from "../../Stores/CoWebsiteStore";
|
||||
import CoWebsiteThumbnail from "./CoWebsiteThumbnailSlot.svelte";
|
||||
|
||||
export let vertical = false;
|
||||
</script>
|
||||
|
||||
{#if $coWebsites.length > 0}
|
||||
<div id="cowebsite-thumbnail-container" class:vertical>
|
||||
{#each [...$coWebsites.values()] as coWebsite, index (coWebsite.iframe.id)}
|
||||
<CoWebsiteThumbnail {index} {coWebsite} {vertical} />
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style lang="scss">
|
||||
#cowebsite-thumbnail-container {
|
||||
pointer-events: all;
|
||||
height: 100px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
position: absolute;
|
||||
bottom: 5px;
|
||||
left: 2%;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
|
||||
&.vertical {
|
||||
height: auto !important;
|
||||
width: auto !important;
|
||||
bottom: auto !important;
|
||||
left: auto !important;
|
||||
position: relative;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding-top: 4px;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,22 @@
|
||||
<script lang="typescript">
|
||||
import PresentationLayout from "./Layouts/PresentationLayout.svelte";
|
||||
import MozaicLayout from "./Layouts/MozaicLayout.svelte";
|
||||
import { LayoutMode } from "../../WebRtc/LayoutManager";
|
||||
import { embedScreenLayout } from "../../Stores/EmbedScreensStore";
|
||||
</script>
|
||||
|
||||
<div id="embedScreensContainer">
|
||||
{#if $embedScreenLayout === LayoutMode.Presentation}
|
||||
<PresentationLayout />
|
||||
{:else}
|
||||
<MozaicLayout />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
#embedScreensContainer {
|
||||
display: flex;
|
||||
padding-top: 2%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,61 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import { highlightedEmbedScreen } from "../../../Stores/EmbedScreensStore";
|
||||
import { streamableCollectionStore } from "../../../Stores/StreamableCollectionStore";
|
||||
import MediaBox from "../../Video/MediaBox.svelte";
|
||||
|
||||
let layoutDom: HTMLDivElement;
|
||||
|
||||
const resizeObserver = new ResizeObserver(() => {});
|
||||
|
||||
onMount(() => {
|
||||
resizeObserver.observe(layoutDom);
|
||||
highlightedEmbedScreen.removeHighlight();
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="mozaic-layout" bind:this={layoutDom}>
|
||||
<div
|
||||
class="media-container"
|
||||
class:full-width={$streamableCollectionStore.size === 1 || $streamableCollectionStore.size === 2}
|
||||
class:quarter={$streamableCollectionStore.size === 3 || $streamableCollectionStore.size === 4}
|
||||
>
|
||||
{#each [...$streamableCollectionStore.values()] as peer (peer.uniqueId)}
|
||||
<MediaBox
|
||||
streamable={peer}
|
||||
mozaicFullWidth={$streamableCollectionStore.size === 1 || $streamableCollectionStore.size === 2}
|
||||
mozaicQuarter={$streamableCollectionStore.size === 3 || $streamableCollectionStore.size === 4}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
#mozaic-layout {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
|
||||
.media-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: 33.3% 33.3% 33.3%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
|
||||
&.full-width {
|
||||
grid-template-columns: 100%;
|
||||
grid-template-rows: 50% 50%;
|
||||
}
|
||||
|
||||
&.quarter {
|
||||
grid-template-columns: 50% 50%;
|
||||
grid-template-rows: 50% 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,143 @@
|
||||
<script lang="ts">
|
||||
import { highlightedEmbedScreen } from "../../../Stores/EmbedScreensStore";
|
||||
import CamerasContainer from "../CamerasContainer.svelte";
|
||||
import MediaBox from "../../Video/MediaBox.svelte";
|
||||
import { coWebsiteManager } from "../../../WebRtc/CoWebsiteManager";
|
||||
import { afterUpdate, onMount } from "svelte";
|
||||
import { isMediaBreakpointDown, isMediaBreakpointUp } from "../../../Utils/BreakpointsUtils";
|
||||
import { peerStore } from "../../../Stores/PeerStore";
|
||||
|
||||
function closeCoWebsite() {
|
||||
if ($highlightedEmbedScreen?.type === "cowebsite") {
|
||||
if ($highlightedEmbedScreen.embed.closable) {
|
||||
coWebsiteManager.closeCoWebsite($highlightedEmbedScreen.embed).catch(() => {
|
||||
console.error("Error during co-website highlighted closing");
|
||||
});
|
||||
} else {
|
||||
coWebsiteManager.unloadCoWebsite($highlightedEmbedScreen.embed).catch(() => {
|
||||
console.error("Error during co-website highlighted unloading");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
afterUpdate(() => {
|
||||
if ($highlightedEmbedScreen) {
|
||||
coWebsiteManager.resizeAllIframes();
|
||||
}
|
||||
});
|
||||
|
||||
let layoutDom: HTMLDivElement;
|
||||
|
||||
let displayCoWebsiteContainer = isMediaBreakpointDown("lg");
|
||||
let displayFullMedias = isMediaBreakpointUp("sm");
|
||||
|
||||
const resizeObserver = new ResizeObserver(() => {
|
||||
displayCoWebsiteContainer = isMediaBreakpointDown("lg");
|
||||
displayFullMedias = isMediaBreakpointUp("sm");
|
||||
|
||||
if (!displayCoWebsiteContainer && $highlightedEmbedScreen && $highlightedEmbedScreen.type === "cowebsite") {
|
||||
highlightedEmbedScreen.removeHighlight();
|
||||
}
|
||||
|
||||
if (displayFullMedias) {
|
||||
highlightedEmbedScreen.removeHighlight();
|
||||
}
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
resizeObserver.observe(layoutDom);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="presentation-layout" bind:this={layoutDom} class:full-medias={displayFullMedias}>
|
||||
{#if displayFullMedias}
|
||||
<div id="full-medias">
|
||||
<CamerasContainer full={true} highlightedEmbedScreen={$highlightedEmbedScreen} />
|
||||
</div>
|
||||
{:else}
|
||||
<div id="embed-left-block" class:full={$peerStore.size === 0}>
|
||||
<div id="main-embed-screen">
|
||||
{#if $highlightedEmbedScreen}
|
||||
{#if $highlightedEmbedScreen.type === "streamable"}
|
||||
{#key $highlightedEmbedScreen.embed.uniqueId}
|
||||
<MediaBox
|
||||
isHightlighted={true}
|
||||
isClickable={true}
|
||||
streamable={$highlightedEmbedScreen.embed}
|
||||
/>
|
||||
{/key}
|
||||
{:else if $highlightedEmbedScreen.type === "cowebsite"}
|
||||
{#key $highlightedEmbedScreen.embed.iframe.id}
|
||||
<div
|
||||
id={"cowebsite-slot-" + $highlightedEmbedScreen.embed.iframe.id}
|
||||
class="highlighted-cowebsite nes-container is-rounded"
|
||||
>
|
||||
<div class="actions">
|
||||
<button type="button" class="nes-btn is-error close" on:click={closeCoWebsite}
|
||||
>×</button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
{/key}
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if $peerStore.size > 0}
|
||||
<CamerasContainer highlightedEmbedScreen={$highlightedEmbedScreen} />
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
#presentation-layout {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
||||
&.full-medias {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
#embed-left-block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 0 0 75%;
|
||||
height: 100%;
|
||||
width: 75%;
|
||||
|
||||
&.full {
|
||||
flex: 0 0 98% !important;
|
||||
width: 98% !important;
|
||||
}
|
||||
}
|
||||
|
||||
#main-embed-screen {
|
||||
height: 100%;
|
||||
margin-bottom: 3%;
|
||||
|
||||
.highlighted-cowebsite {
|
||||
height: 100% !important;
|
||||
width: 96%;
|
||||
background-color: rgba(#000000, 0.6);
|
||||
margin: 0 !important;
|
||||
|
||||
.actions {
|
||||
z-index: 200;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: end;
|
||||
gap: 2%;
|
||||
|
||||
button {
|
||||
pointer-events: all;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -3,8 +3,8 @@
|
||||
import { emoteStore, emoteMenuStore } from "../../Stores/EmoteStore";
|
||||
import { onDestroy, onMount } from "svelte";
|
||||
import { EmojiButton } from "@joeattardi/emoji-button";
|
||||
import { isMobile } from "../../Enum/EnvironmentVariable";
|
||||
import LL from "../../i18n/i18n-svelte";
|
||||
import { isMediaBreakpointUp } from "../../Utils/BreakpointsUtils";
|
||||
|
||||
let emojiContainer: HTMLElement;
|
||||
let picker: EmojiButton;
|
||||
@ -20,7 +20,7 @@
|
||||
"--secondary-text-color": "whitesmoke",
|
||||
"--category-button-color": "whitesmoke",
|
||||
},
|
||||
emojisPerRow: isMobile() ? 6 : 8,
|
||||
emojisPerRow: isMediaBreakpointUp("md") ? 6 : 8,
|
||||
autoFocusSearch: false,
|
||||
style: "native",
|
||||
showPreview: false,
|
||||
@ -86,6 +86,8 @@
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
z-index: 300;
|
||||
}
|
||||
|
||||
.emote-menu {
|
||||
|
@ -127,6 +127,8 @@
|
||||
</form>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../../../style/breakpoints.scss";
|
||||
|
||||
.enableCameraScene {
|
||||
pointer-events: auto;
|
||||
margin: 20px auto 0;
|
||||
@ -214,7 +216,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
@include media-breakpoint-up(md) {
|
||||
.enableCameraScene h2 {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
32
front/src/Components/FollowMenu/FollowButton.svelte
Normal file
32
front/src/Components/FollowMenu/FollowButton.svelte
Normal file
@ -0,0 +1,32 @@
|
||||
<script lang="typescript">
|
||||
import followImg from "../images/follow.svg";
|
||||
|
||||
export let hidden: Boolean;
|
||||
|
||||
let cancelButton = false;
|
||||
</script>
|
||||
|
||||
<div class="btn-follow" class:hide={hidden} class:cancel={cancelButton}>
|
||||
<img src={followImg} alt="" />
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.btn-follow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: solid 0px black;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
background: #666;
|
||||
box-shadow: 2px 2px 24px #444;
|
||||
border-radius: 48px;
|
||||
transform: translateY(15px);
|
||||
transition-timing-function: ease-in-out;
|
||||
margin: 0 4%;
|
||||
|
||||
img {
|
||||
filter: brightness(0) invert(1);
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,9 +1,5 @@
|
||||
<!--
|
||||
vim: ft=typescript
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { gameManager } from "../../Phaser/Game/GameManager";
|
||||
import followImg from "../images/follow.svg";
|
||||
import { followStateStore, followRoleStore, followUsersStore } from "../../Stores/FollowStore";
|
||||
import LL from "../../i18n/i18n-svelte";
|
||||
|
||||
@ -14,10 +10,6 @@ vim: ft=typescript
|
||||
return user ? user.PlayerValue : "";
|
||||
}
|
||||
|
||||
function sendFollowRequest() {
|
||||
gameScene.CurrentPlayer.sendFollowRequest();
|
||||
}
|
||||
|
||||
function acceptFollowRequest() {
|
||||
gameScene.CurrentPlayer.startFollowing();
|
||||
}
|
||||
@ -83,7 +75,7 @@ vim: ft=typescript
|
||||
|
||||
{#if $followStateStore === "active" || $followStateStore === "ending"}
|
||||
<div class="interact-status nes-container is-rounded">
|
||||
<section class="interact-status">
|
||||
<section>
|
||||
{#if $followRoleStore === "follower"}
|
||||
<p>{$LL.follow.interactStatus.following({ leader: name($followUsersStore[0]) })}</p>
|
||||
{:else if $followUsersStore.length === 0}
|
||||
@ -109,48 +101,27 @@ vim: ft=typescript
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if $followStateStore === "off"}
|
||||
<button
|
||||
type="button"
|
||||
class="nes-btn is-primary follow-menu-button"
|
||||
on:click|preventDefault={sendFollowRequest}
|
||||
title="Ask others to follow"><img class="background-img" src={followImg} alt="" /></button
|
||||
>
|
||||
{/if}
|
||||
|
||||
{#if $followStateStore === "active" || $followStateStore === "ending"}
|
||||
{#if $followRoleStore === "follower"}
|
||||
<button
|
||||
type="button"
|
||||
class="nes-btn is-error follow-menu-button"
|
||||
on:click|preventDefault={reset}
|
||||
title="Stop following"><img class="background-img" src={followImg} alt="" /></button
|
||||
>
|
||||
{:else}
|
||||
<button
|
||||
type="button"
|
||||
class="nes-btn is-error follow-menu-button"
|
||||
on:click|preventDefault={reset}
|
||||
title="Stop leading the way"><img class="background-img" src={followImg} alt="" /></button
|
||||
>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<style lang="scss">
|
||||
@import "../../../style/breakpoints.scss";
|
||||
|
||||
.nes-container {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
div.interact-status {
|
||||
.interact-status {
|
||||
background-color: #333333;
|
||||
color: whitesmoke;
|
||||
|
||||
position: relative;
|
||||
height: 2.7em;
|
||||
position: absolute;
|
||||
max-height: 2.7em;
|
||||
width: 40vw;
|
||||
top: 87vh;
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
z-index: 400;
|
||||
}
|
||||
|
||||
div.interact-menu {
|
||||
@ -158,10 +129,14 @@ vim: ft=typescript
|
||||
background-color: #333333;
|
||||
color: whitesmoke;
|
||||
|
||||
position: relative;
|
||||
position: absolute;
|
||||
width: 60vw;
|
||||
top: 60vh;
|
||||
margin: auto;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
z-index: 150;
|
||||
|
||||
section.interact-menu-title {
|
||||
margin-bottom: 20px;
|
||||
@ -189,23 +164,16 @@ vim: ft=typescript
|
||||
}
|
||||
}
|
||||
|
||||
.follow-menu-button {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
div.interact-status {
|
||||
width: 100vw;
|
||||
@include media-breakpoint-up(md) {
|
||||
.interact-status {
|
||||
width: 90vw;
|
||||
top: 78vh;
|
||||
font-size: 0.75em;
|
||||
}
|
||||
|
||||
div.interact-menu {
|
||||
height: 21vh;
|
||||
width: 100vw;
|
||||
max-height: 21vh;
|
||||
width: 90vw;
|
||||
font-size: 0.75em;
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
<form
|
||||
class="helpCameraSettings nes-container"
|
||||
on:submit|preventDefault={close}
|
||||
transition:fly={{ y: -900, duration: 500 }}
|
||||
transition:fly={{ y: -50, duration: 500 }}
|
||||
>
|
||||
<section>
|
||||
<h2>{$LL.camera.help.title()}</h2>
|
||||
@ -55,9 +55,12 @@
|
||||
background: #eceeee;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 10vh;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin-top: 4%;
|
||||
max-height: 80vh;
|
||||
max-width: 80vw;
|
||||
z-index: 600;
|
||||
overflow: auto;
|
||||
text-align: center;
|
||||
|
||||
|
@ -35,9 +35,11 @@
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 40px;
|
||||
margin: 0 auto;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
padding: 0;
|
||||
width: clamp(200px, 20vw, 20vw);
|
||||
z-index: 155;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -45,6 +47,10 @@
|
||||
animation: moveMessage 0.5s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-timing-function: ease-in-out;
|
||||
|
||||
div {
|
||||
margin-bottom: 5%;
|
||||
}
|
||||
}
|
||||
|
||||
div.nes-container {
|
170
front/src/Components/MainLayout.svelte
Normal file
170
front/src/Components/MainLayout.svelte
Normal file
@ -0,0 +1,170 @@
|
||||
<script lang="typescript">
|
||||
import { onMount } from "svelte";
|
||||
import { audioManagerVisibilityStore } from "../Stores/AudioManagerStore";
|
||||
import { embedScreenLayout, hasEmbedScreen } from "../Stores/EmbedScreensStore";
|
||||
import { emoteMenuStore } from "../Stores/EmoteStore";
|
||||
import { myCameraVisibilityStore } from "../Stores/MyCameraStoreVisibility";
|
||||
import { requestVisitCardsStore } from "../Stores/GameStore";
|
||||
import { helpCameraSettingsVisibleStore } from "../Stores/HelpCameraSettingsStore";
|
||||
import { layoutManagerActionVisibilityStore } from "../Stores/LayoutManagerStore";
|
||||
import { menuIconVisiblilityStore, menuVisiblilityStore, warningContainerStore } from "../Stores/MenuStore";
|
||||
import { showReportScreenStore, userReportEmpty } from "../Stores/ShowReportScreenStore";
|
||||
import AudioManager from "./AudioManager/AudioManager.svelte";
|
||||
import CameraControls from "./CameraControls.svelte";
|
||||
import EmbedScreensContainer from "./EmbedScreens/EmbedScreensContainer.svelte";
|
||||
import EmoteMenu from "./EmoteMenu/EmoteMenu.svelte";
|
||||
import HelpCameraSettingsPopup from "./HelpCameraSettings/HelpCameraSettingsPopup.svelte";
|
||||
import LayoutActionManager from "./LayoutActionManager/LayoutActionManager.svelte";
|
||||
import Menu from "./Menu/Menu.svelte";
|
||||
import MenuIcon from "./Menu/MenuIcon.svelte";
|
||||
import MyCamera from "./MyCamera.svelte";
|
||||
import ReportMenu from "./ReportMenu/ReportMenu.svelte";
|
||||
import VisitCard from "./VisitCard/VisitCard.svelte";
|
||||
import WarningContainer from "./WarningContainer/WarningContainer.svelte";
|
||||
import { isMediaBreakpointDown, isMediaBreakpointUp } from "../Utils/BreakpointsUtils";
|
||||
import CoWebsitesContainer from "./EmbedScreens/CoWebsitesContainer.svelte";
|
||||
import FollowMenu from "./FollowMenu/FollowMenu.svelte";
|
||||
import { followStateStore } from "../Stores/FollowStore";
|
||||
import { peerStore } from "../Stores/PeerStore";
|
||||
import { banMessageStore } from "../Stores/TypeMessageStore/BanMessageStore";
|
||||
import BanMessageContainer from "./TypeMessage/BanMessageContainer.svelte";
|
||||
import { textMessageStore } from "../Stores/TypeMessageStore/TextMessageStore";
|
||||
import TextMessageContainer from "./TypeMessage/TextMessageContainer.svelte";
|
||||
import { soundPlayingStore } from "../Stores/SoundPlayingStore";
|
||||
import AudioPlaying from "./UI/AudioPlaying.svelte";
|
||||
import { showLimitRoomModalStore, showShareLinkMapModalStore } from "../Stores/ModalStore";
|
||||
import LimitRoomModal from "./Modal/LimitRoomModal.svelte";
|
||||
import ShareLinkMapModal from "./Modal/ShareLinkMapModal.svelte";
|
||||
import { LayoutMode } from "../WebRtc/LayoutManager";
|
||||
|
||||
let mainLayout: HTMLDivElement;
|
||||
|
||||
let displayCoWebsiteContainerMd = isMediaBreakpointUp("md");
|
||||
let displayCoWebsiteContainerLg = isMediaBreakpointDown("lg");
|
||||
|
||||
const resizeObserver = new ResizeObserver(() => {
|
||||
displayCoWebsiteContainerMd = isMediaBreakpointUp("md");
|
||||
displayCoWebsiteContainerLg = isMediaBreakpointDown("lg");
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
resizeObserver.observe(mainLayout);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div id="main-layout" bind:this={mainLayout}>
|
||||
<aside id="main-layout-left-aside">
|
||||
{#if $menuIconVisiblilityStore}
|
||||
<MenuIcon />
|
||||
{/if}
|
||||
|
||||
{#if $embedScreenLayout === LayoutMode.VideoChat || displayCoWebsiteContainerMd}
|
||||
<CoWebsitesContainer vertical={true} />
|
||||
{/if}
|
||||
</aside>
|
||||
|
||||
<section id="main-layout-main">
|
||||
{#if $menuVisiblilityStore}
|
||||
<Menu />
|
||||
{/if}
|
||||
|
||||
{#if $banMessageStore.length > 0}
|
||||
<BanMessageContainer />
|
||||
{:else if $textMessageStore.length > 0}
|
||||
<TextMessageContainer />
|
||||
{/if}
|
||||
|
||||
{#if $soundPlayingStore}
|
||||
<AudioPlaying url={$soundPlayingStore} />
|
||||
{/if}
|
||||
|
||||
{#if $warningContainerStore}
|
||||
<WarningContainer />
|
||||
{/if}
|
||||
|
||||
{#if $showReportScreenStore !== userReportEmpty}
|
||||
<ReportMenu />
|
||||
{/if}
|
||||
|
||||
{#if $helpCameraSettingsVisibleStore}
|
||||
<HelpCameraSettingsPopup />
|
||||
{/if}
|
||||
|
||||
{#if $audioManagerVisibilityStore}
|
||||
<AudioManager />
|
||||
{/if}
|
||||
|
||||
{#if $showLimitRoomModalStore}
|
||||
<LimitRoomModal />
|
||||
{/if}
|
||||
|
||||
{#if $showShareLinkMapModalStore}
|
||||
<ShareLinkMapModal />
|
||||
{/if}
|
||||
|
||||
{#if $followStateStore !== "off" || $peerStore.size > 0}
|
||||
<FollowMenu />
|
||||
{/if}
|
||||
|
||||
{#if $requestVisitCardsStore}
|
||||
<VisitCard visitCardUrl={$requestVisitCardsStore} />
|
||||
{/if}
|
||||
|
||||
{#if $emoteMenuStore}
|
||||
<EmoteMenu />
|
||||
{/if}
|
||||
|
||||
{#if hasEmbedScreen}
|
||||
<EmbedScreensContainer />
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
<section id="main-layout-baseline">
|
||||
{#if displayCoWebsiteContainerLg}
|
||||
<CoWebsitesContainer />
|
||||
{/if}
|
||||
|
||||
{#if $layoutManagerActionVisibilityStore}
|
||||
<LayoutActionManager />
|
||||
{/if}
|
||||
|
||||
{#if $myCameraVisibilityStore}
|
||||
<MyCamera />
|
||||
<CameraControls />
|
||||
{/if}
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../../style/breakpoints.scss";
|
||||
|
||||
#main-layout {
|
||||
display: grid;
|
||||
grid-template-columns: 120px calc(100% - 120px);
|
||||
grid-template-rows: 80% 20%;
|
||||
|
||||
&-left-aside {
|
||||
min-width: 80px;
|
||||
}
|
||||
|
||||
&-baseline {
|
||||
grid-column: 1/3;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
#main-layout {
|
||||
grid-template-columns: 15% 85%;
|
||||
|
||||
&-left-aside {
|
||||
min-width: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(sm) {
|
||||
#main-layout {
|
||||
grid-template-columns: 20% 80%;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -100,6 +100,8 @@
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../../../style/breakpoints.scss";
|
||||
|
||||
.string-HTML {
|
||||
white-space: pre-line;
|
||||
}
|
||||
@ -126,7 +128,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px), only screen and (max-height: 800px) {
|
||||
@include media-breakpoint-up(md) {
|
||||
div.about-room-main {
|
||||
section.container-overflow {
|
||||
height: calc(100% - 120px);
|
||||
|
@ -67,6 +67,8 @@
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../../../style/breakpoints.scss";
|
||||
|
||||
div.global-message-main {
|
||||
height: calc(100% - 50px);
|
||||
display: grid;
|
||||
@ -109,7 +111,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px), only screen and (max-height: 800px) {
|
||||
@include media-breakpoint-up(md) {
|
||||
.global-message-content {
|
||||
height: calc(100% - 5px);
|
||||
}
|
||||
|
@ -36,6 +36,8 @@
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../../../style/breakpoints.scss";
|
||||
|
||||
div.guest-main {
|
||||
height: calc(100% - 56px);
|
||||
|
||||
@ -57,7 +59,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 900px), only screen and (max-height: 600px) {
|
||||
@include media-breakpoint-up(md) {
|
||||
div.guest-main {
|
||||
section.share-url.not-mobile {
|
||||
display: none;
|
||||
|
@ -129,6 +129,8 @@
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../../../style/breakpoints.scss";
|
||||
|
||||
.nes-container {
|
||||
padding: 5px;
|
||||
}
|
||||
@ -140,11 +142,15 @@
|
||||
pointer-events: auto;
|
||||
height: 80%;
|
||||
width: 75%;
|
||||
top: 10%;
|
||||
top: 4%;
|
||||
|
||||
position: relative;
|
||||
z-index: 80;
|
||||
margin: auto;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
|
||||
position: absolute;
|
||||
z-index: 900;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: var(--size-first-columns-grid) calc(100% - var(--size-first-columns-grid));
|
||||
@ -177,12 +183,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
@include media-breakpoint-up(md) {
|
||||
div.menu-container-main {
|
||||
--size-first-columns-grid: 120px;
|
||||
height: 70%;
|
||||
top: 55px;
|
||||
width: 100%;
|
||||
width: 95%;
|
||||
font-size: 0.5em;
|
||||
|
||||
div.menu-nav-sidebar {
|
||||
|
@ -14,6 +14,7 @@
|
||||
function showMenu() {
|
||||
menuVisiblilityStore.set(!get(menuVisiblilityStore));
|
||||
}
|
||||
|
||||
function showChat() {
|
||||
chatVisibilityStore.set(true);
|
||||
}
|
||||
@ -21,68 +22,104 @@
|
||||
function register() {
|
||||
window.open(`${ADMIN_URL}/second-step-register`, "_self");
|
||||
}
|
||||
|
||||
function showInvite() {
|
||||
showShareLinkMapModalStore.set(true);
|
||||
}
|
||||
|
||||
function noDrag() {
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window />
|
||||
|
||||
<main class="menuIcon">
|
||||
<main class="menuIcon noselect">
|
||||
{#if $limitMapStore}
|
||||
<span class="nes-btn is-dark">
|
||||
<img
|
||||
src={logoInvite}
|
||||
alt={$LL.menu.icon.open.invite()}
|
||||
class="nes-pointer"
|
||||
on:click|preventDefault={showInvite}
|
||||
/>
|
||||
</span>
|
||||
|
||||
<span class="nes-btn is-dark">
|
||||
<img
|
||||
src={logoRegister}
|
||||
alt={$LL.menu.icon.open.register()}
|
||||
class="nes-pointer"
|
||||
on:click|preventDefault={register}
|
||||
/>
|
||||
</span>
|
||||
<span class="nes-btn is-dark">
|
||||
<img
|
||||
src={logoInvite}
|
||||
alt={$LL.menu.icon.open.invite()}
|
||||
class="nes-pointer"
|
||||
draggable="false"
|
||||
on:dragstart|preventDefault={noDrag}
|
||||
on:click|preventDefault={showInvite}
|
||||
/>
|
||||
</span>
|
||||
<span class="nes-btn is-dark">
|
||||
<img
|
||||
src={logoRegister}
|
||||
alt={$LL.menu.icon.open.register()}
|
||||
class="nes-pointer"
|
||||
draggable="false"
|
||||
on:dragstart|preventDefault={noDrag}
|
||||
on:click|preventDefault={register}
|
||||
/>
|
||||
</span>
|
||||
{:else}
|
||||
<span class="nes-btn is-dark">
|
||||
<img src={logoWA} alt={$LL.menu.icon.open.menu()} class="nes-pointer" on:click|preventDefault={showMenu} />
|
||||
</span>
|
||||
<span class="nes-btn is-dark">
|
||||
<img src={logoTalk} alt={$LL.menu.icon.open.chat()} class="nes-pointer" on:click|preventDefault={showChat} />
|
||||
</span>
|
||||
<span class="nes-btn is-dark">
|
||||
<img
|
||||
src={logoWA}
|
||||
alt={$LL.menu.icon.open.menu()}
|
||||
class="nes-pointer"
|
||||
draggable="false"
|
||||
on:dragstart|preventDefault={noDrag}
|
||||
on:click|preventDefault={showMenu}
|
||||
/>
|
||||
</span>
|
||||
<span class="nes-btn is-dark">
|
||||
<img
|
||||
src={logoTalk}
|
||||
alt={$LL.menu.icon.open.chat()}
|
||||
class="nes-pointer"
|
||||
draggable="false"
|
||||
on:dragstart|preventDefault={noDrag}
|
||||
on:click|preventDefault={showChat}
|
||||
/>
|
||||
</span>
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
<style lang="scss">
|
||||
.menuIcon {
|
||||
display: inline-grid;
|
||||
z-index: 90;
|
||||
position: relative;
|
||||
margin: 25px;
|
||||
img {
|
||||
pointer-events: auto;
|
||||
width: 24px;
|
||||
padding-top: 0;
|
||||
margin: 3px
|
||||
}
|
||||
}
|
||||
|
||||
.menuIcon img:hover{
|
||||
transform: scale(1.2);
|
||||
}
|
||||
@import "../../../style/breakpoints.scss";
|
||||
|
||||
@media only screen and (max-width: 800px),
|
||||
only screen and (max-height: 800px) {
|
||||
.menuIcon {
|
||||
margin: 6px;
|
||||
|
||||
img {
|
||||
width: 16px;
|
||||
}
|
||||
display: inline-grid;
|
||||
z-index: 90;
|
||||
position: relative;
|
||||
margin: 25px;
|
||||
img {
|
||||
pointer-events: auto;
|
||||
width: 24px;
|
||||
padding-top: 0;
|
||||
margin: 3px
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.menuIcon img:hover {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(sm) {
|
||||
.menuIcon {
|
||||
margin-top: 10%;
|
||||
img {
|
||||
pointer-events: auto;
|
||||
width: 60px;
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
.menuIcon img:hover {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
.menuIcon {
|
||||
img {
|
||||
width: 50px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -13,7 +13,6 @@
|
||||
import { EnableCameraScene, EnableCameraSceneName } from "../../Phaser/Login/EnableCameraScene";
|
||||
import { enableCameraSceneVisibilityStore } from "../../Stores/MediaStore";
|
||||
import btnProfileSubMenuCamera from "../images/btn-menu-profile-camera.svg";
|
||||
import btnProfileSubMenuIdentity from "../images/btn-menu-profile-identity.svg";
|
||||
import btnProfileSubMenuCompanion from "../images/btn-menu-profile-companion.svg";
|
||||
import Woka from "../Woka/Woka.svelte";
|
||||
import Companion from "../Companion/Companion.svelte";
|
||||
@ -104,6 +103,8 @@
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../../../style/breakpoints.scss";
|
||||
|
||||
div.customize-main {
|
||||
width: 100%;
|
||||
display: inline-flex;
|
||||
@ -163,7 +164,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
@include media-breakpoint-up(md) {
|
||||
div.customize-main.content section button {
|
||||
width: 130px;
|
||||
}
|
||||
|
@ -2,11 +2,11 @@
|
||||
import { localUserStore } from "../../Connexion/LocalUserStore";
|
||||
import { videoConstraintStore } from "../../Stores/MediaStore";
|
||||
import { HtmlUtils } from "../../WebRtc/HtmlUtils";
|
||||
import { isMobile } from "../../Enum/EnvironmentVariable";
|
||||
import { menuVisiblilityStore } from "../../Stores/MenuStore";
|
||||
import LL, { locale } from "../../i18n/i18n-svelte";
|
||||
import type { Locales } from "../../i18n/i18n-types";
|
||||
import { displayableLocales, setCurrentLocale } from "../../i18n/locales";
|
||||
import { isMediaBreakpointUp } from "../../Utils/BreakpointsUtils";
|
||||
|
||||
let fullscreen: boolean = localUserStore.getFullscreen();
|
||||
let notification: boolean = localUserStore.getNotification() === "granted";
|
||||
@ -85,6 +85,8 @@
|
||||
function closeMenu() {
|
||||
menuVisiblilityStore.set(false);
|
||||
}
|
||||
|
||||
const isMobile = isMediaBreakpointUp("md");
|
||||
</script>
|
||||
|
||||
<div class="settings-main" on:submit|preventDefault={saveSetting}>
|
||||
@ -93,22 +95,22 @@
|
||||
<div class="nes-select is-dark">
|
||||
<select bind:value={valueGame}>
|
||||
<option value={120}
|
||||
>{isMobile()
|
||||
>{isMobile
|
||||
? $LL.menu.settings.gameQuality.short.high()
|
||||
: $LL.menu.settings.gameQuality.long.high()}</option
|
||||
>
|
||||
<option value={60}
|
||||
>{isMobile()
|
||||
>{isMobile
|
||||
? $LL.menu.settings.gameQuality.short.medium()
|
||||
: $LL.menu.settings.gameQuality.long.medium()}</option
|
||||
>
|
||||
<option value={40}
|
||||
>{isMobile()
|
||||
>{isMobile
|
||||
? $LL.menu.settings.gameQuality.short.small()
|
||||
: $LL.menu.settings.gameQuality.long.small()}</option
|
||||
>
|
||||
<option value={20}
|
||||
>{isMobile()
|
||||
>{isMobile
|
||||
? $LL.menu.settings.gameQuality.short.minimum()
|
||||
: $LL.menu.settings.gameQuality.long.minimum()}</option
|
||||
>
|
||||
@ -120,22 +122,22 @@
|
||||
<div class="nes-select is-dark">
|
||||
<select bind:value={valueVideo}>
|
||||
<option value={30}
|
||||
>{isMobile()
|
||||
>{isMobile
|
||||
? $LL.menu.settings.videoQuality.short.high()
|
||||
: $LL.menu.settings.videoQuality.long.high()}</option
|
||||
>
|
||||
<option value={20}
|
||||
>{isMobile()
|
||||
>{isMobile
|
||||
? $LL.menu.settings.videoQuality.short.medium()
|
||||
: $LL.menu.settings.videoQuality.long.medium()}</option
|
||||
>
|
||||
<option value={10}
|
||||
>{isMobile()
|
||||
>{isMobile
|
||||
? $LL.menu.settings.videoQuality.short.small()
|
||||
: $LL.menu.settings.videoQuality.long.small()}</option
|
||||
>
|
||||
<option value={5}
|
||||
>{isMobile()
|
||||
>{isMobile
|
||||
? $LL.menu.settings.videoQuality.short.minimum()
|
||||
: $LL.menu.settings.videoQuality.long.minimum()}</option
|
||||
>
|
||||
@ -199,6 +201,8 @@
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../../../style/breakpoints.scss";
|
||||
|
||||
div.settings-main {
|
||||
height: calc(100% - 40px);
|
||||
overflow-y: auto;
|
||||
@ -236,7 +240,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px), only screen and (max-height: 800px) {
|
||||
@include media-breakpoint-up(md) {
|
||||
div.settings-main {
|
||||
section {
|
||||
padding: 0;
|
||||
|
@ -32,6 +32,7 @@
|
||||
max-width: 80vw;
|
||||
overflow: auto;
|
||||
text-align: center;
|
||||
z-index: 500;
|
||||
|
||||
h2 {
|
||||
font-family: "Press Start 2P";
|
||||
|
@ -75,6 +75,7 @@
|
||||
max-width: 80vw;
|
||||
overflow: auto;
|
||||
text-align: center;
|
||||
z-index: 450;
|
||||
|
||||
h2 {
|
||||
font-family: "Press Start 2P";
|
||||
|
@ -2,7 +2,7 @@
|
||||
import { obtainedMediaConstraintStore } from "../Stores/MediaStore";
|
||||
import { localStreamStore, isSilentStore } from "../Stores/MediaStore";
|
||||
import SoundMeterWidget from "./SoundMeterWidget.svelte";
|
||||
import { onDestroy } from "svelte";
|
||||
import { onDestroy, onMount } from "svelte";
|
||||
import { srcObject } from "./Video/utils";
|
||||
import LL from "../i18n/i18n-svelte";
|
||||
|
||||
@ -23,16 +23,75 @@
|
||||
isSilent = value;
|
||||
});
|
||||
|
||||
let cameraContainer: HTMLDivElement;
|
||||
|
||||
onMount(() => {
|
||||
cameraContainer.addEventListener("transitionend", () => {
|
||||
if (cameraContainer.classList.contains("hide")) {
|
||||
cameraContainer.style.visibility = "hidden";
|
||||
}
|
||||
});
|
||||
|
||||
cameraContainer.addEventListener("transitionstart", () => {
|
||||
if (!cameraContainer.classList.contains("hide")) {
|
||||
cameraContainer.style.visibility = "visible";
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
onDestroy(unsubscribeIsSilent);
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<div class="video-container nes-container is-rounded is-dark div-myCamVideo"
|
||||
class:hide={!$obtainedMediaConstraintStore.video || isSilent}>
|
||||
{#if $localStreamStore.type === "success" && $localStreamStore.stream}
|
||||
<video class="myCamVideo" use:srcObject={stream} autoplay muted playsinline />
|
||||
<SoundMeterWidget {stream} />
|
||||
{/if}
|
||||
</div>
|
||||
<div class="nes-container is-dark is-silent" class:hide={isSilent}>{$LL.camera.my.silentZone()}</div>
|
||||
<div
|
||||
class="nes-container is-rounded my-cam-video-container"
|
||||
class:hide={($localStreamStore.type !== "success" || !$obtainedMediaConstraintStore.video) && !isSilent}
|
||||
bind:this={cameraContainer}
|
||||
>
|
||||
{#if isSilent}
|
||||
<div class="is-silent">{$LL.camera.my.silentZone()}</div>
|
||||
{:else if $localStreamStore.type === "success" && $localStreamStore.stream}
|
||||
<video class="my-cam-video" use:srcObject={stream} autoplay muted playsinline />
|
||||
<SoundMeterWidget {stream} />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../../style/breakpoints.scss";
|
||||
|
||||
.my-cam-video-container {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
bottom: 30px;
|
||||
max-height: 20%;
|
||||
transition: transform 1000ms;
|
||||
padding: 0;
|
||||
background-color: rgba(#000000, 0.6);
|
||||
background-clip: content-box;
|
||||
overflow: hidden;
|
||||
line-height: 0;
|
||||
z-index: 250;
|
||||
|
||||
&.nes-container.is-rounded {
|
||||
border-image-outset: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.my-cam-video-container.hide {
|
||||
transform: translateX(200%);
|
||||
}
|
||||
|
||||
.my-cam-video {
|
||||
background-color: #00000099;
|
||||
max-height: 20vh;
|
||||
max-width: max(25vw, 150px);
|
||||
width: 100%;
|
||||
-webkit-transform: scaleX(-1);
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
|
||||
.is-silent {
|
||||
font-size: 2em;
|
||||
color: white;
|
||||
padding: 40px 20px;
|
||||
}
|
||||
</style>
|
||||
|
@ -108,12 +108,16 @@
|
||||
pointer-events: auto;
|
||||
background-color: #333333;
|
||||
color: whitesmoke;
|
||||
|
||||
position: relative;
|
||||
z-index: 650;
|
||||
position: absolute;
|
||||
height: 70vh;
|
||||
width: 50vw;
|
||||
top: 10vh;
|
||||
margin: auto;
|
||||
top: 4%;
|
||||
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
|
||||
section.report-menu-title {
|
||||
display: grid;
|
||||
@ -137,13 +141,4 @@
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
div.report-menu-main {
|
||||
top: 21vh;
|
||||
height: 60vh;
|
||||
width: 100vw;
|
||||
font-size: 0.5em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -47,6 +47,8 @@
|
||||
</form>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../../../style/breakpoints.scss";
|
||||
|
||||
form.selectCompanionScene {
|
||||
font-family: "Press Start 2P";
|
||||
pointer-events: auto;
|
||||
@ -85,7 +87,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
@include media-breakpoint-up(md) {
|
||||
form.selectCompanionScene button.selectCharacterButtonLeft {
|
||||
left: 5vw;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { fly, fade } from "svelte/transition";
|
||||
import { onMount } from "svelte";
|
||||
import { gameManager } from "../../Phaser/Game/GameManager";
|
||||
import type { Message } from "../../Stores/TypeMessageStore/MessageStore";
|
||||
import { banMessageStore } from "../../Stores/TypeMessageStore/BanMessageStore";
|
||||
import LL from "../../i18n/i18n-svelte";
|
||||
@ -13,6 +14,8 @@
|
||||
|
||||
onMount(() => {
|
||||
timeToRead();
|
||||
const gameScene = gameManager.getCurrentGameScene();
|
||||
gameScene.playSound("audio-report-message");
|
||||
});
|
||||
|
||||
function timeToRead() {
|
||||
@ -53,18 +56,19 @@
|
||||
on:click|preventDefault={closeBanMessage}>{nameButton}</button
|
||||
>
|
||||
</div>
|
||||
<!-- svelte-ignore a11y-media-has-caption -->
|
||||
<audio id="report-message" autoplay>
|
||||
<source src="/resources/objects/report-message.mp3" type="audio/mp3" />
|
||||
</audio>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
div.main-ban-message {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
top: 15vh;
|
||||
position: absolute;
|
||||
top: 4%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
z-index: 850;
|
||||
|
||||
height: 70vh;
|
||||
width: 60vw;
|
||||
|
@ -11,3 +11,9 @@
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.main-ban-message-container {
|
||||
z-index: 800;
|
||||
}
|
||||
</style>
|
||||
|
@ -42,14 +42,17 @@
|
||||
div.main-text-message {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: absolute;
|
||||
|
||||
max-height: 25vh;
|
||||
width: 80vw;
|
||||
max-height: 25%;
|
||||
width: 60%;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
margin-bottom: 16px;
|
||||
margin-top: 0;
|
||||
top: 6%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding-bottom: 0;
|
||||
z-index: 240;
|
||||
|
||||
pointer-events: auto;
|
||||
background-color: #333333;
|
||||
|
@ -15,7 +15,8 @@
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
div.main-text-message-container {
|
||||
.main-text-message-container {
|
||||
padding-top: 16px;
|
||||
z-index: 800;
|
||||
}
|
||||
</style>
|
||||
|
@ -37,6 +37,7 @@
|
||||
background-color: black;
|
||||
border-radius: 30px 0 0 30px;
|
||||
display: inline-flex;
|
||||
z-index: 750;
|
||||
|
||||
img {
|
||||
border-radius: 50%;
|
||||
|
@ -25,11 +25,17 @@
|
||||
<style lang="scss">
|
||||
div.error-div {
|
||||
pointer-events: auto;
|
||||
margin-top: 10vh;
|
||||
margin-top: 4%;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
left: 0;
|
||||
right: 0;
|
||||
position: absolute;
|
||||
width: max-content;
|
||||
max-width: 80vw;
|
||||
z-index: 230;
|
||||
height: auto !important;
|
||||
background-clip: padding-box;
|
||||
|
||||
.button-bar {
|
||||
text-align: center;
|
||||
|
@ -1,15 +1,33 @@
|
||||
<script lang="typescript">
|
||||
import { highlightedEmbedScreen } from "../../Stores/EmbedScreensStore";
|
||||
import type { EmbedScreen } from "../../Stores/EmbedScreensStore";
|
||||
import type { ScreenSharingLocalMedia } from "../../Stores/ScreenSharingStore";
|
||||
import { videoFocusStore } from "../../Stores/VideoFocusStore";
|
||||
import type { Streamable } from "../../Stores/StreamableCollectionStore";
|
||||
import { srcObject } from "./utils";
|
||||
|
||||
export let clickable = false;
|
||||
|
||||
export let peer: ScreenSharingLocalMedia;
|
||||
let stream = peer.stream;
|
||||
export let cssClass: string | undefined;
|
||||
let embedScreen: EmbedScreen;
|
||||
|
||||
if (stream) {
|
||||
embedScreen = {
|
||||
type: "streamable",
|
||||
embed: stream as unknown as Streamable,
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="video-container {cssClass ? cssClass : ''}" class:hide={!stream}>
|
||||
{#if stream}
|
||||
<video use:srcObject={stream} autoplay muted playsinline on:click={() => videoFocusStore.toggleFocus(peer)} />
|
||||
<video
|
||||
use:srcObject={stream}
|
||||
autoplay
|
||||
muted
|
||||
playsinline
|
||||
on:click={() => (clickable ? highlightedEmbedScreen.toggleHighlight(embedScreen) : null)}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
|
@ -7,14 +7,106 @@
|
||||
import type { Streamable } from "../../Stores/StreamableCollectionStore";
|
||||
|
||||
export let streamable: Streamable;
|
||||
export let isHightlighted = false;
|
||||
export let isClickable = false;
|
||||
export let mozaicFullWidth = false;
|
||||
export let mozaicQuarter = false;
|
||||
</script>
|
||||
|
||||
<div class="media-container">
|
||||
{#if streamable instanceof VideoPeer}
|
||||
<VideoMediaBox peer={streamable} />
|
||||
{:else if streamable instanceof ScreenSharingPeer}
|
||||
<ScreenSharingMediaBox peer={streamable} />
|
||||
{:else}
|
||||
<LocalStreamMediaBox peer={streamable} cssClass="" />
|
||||
{/if}
|
||||
<div
|
||||
class="media-container nes-container is-rounded {isHightlighted ? 'hightlighted' : ''}"
|
||||
class:clickable={isClickable}
|
||||
class:mozaic-full-width={mozaicFullWidth}
|
||||
class:mozaic-quarter={mozaicQuarter}
|
||||
>
|
||||
<div>
|
||||
{#if streamable instanceof VideoPeer}
|
||||
<VideoMediaBox peer={streamable} clickable={isClickable} />
|
||||
{:else if streamable instanceof ScreenSharingPeer}
|
||||
<ScreenSharingMediaBox peer={streamable} clickable={isClickable} />
|
||||
{:else}
|
||||
<LocalStreamMediaBox peer={streamable} clickable={isClickable} cssClass="" />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../../../style/breakpoints.scss";
|
||||
|
||||
.media-container {
|
||||
display: flex;
|
||||
margin-top: 4%;
|
||||
margin-bottom: 4%;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
transition: margin-left 0.2s, margin-right 0.2s, margin-bottom 0.2s, margin-top 0.2s, max-height 0.2s,
|
||||
max-width 0.2s;
|
||||
pointer-events: auto;
|
||||
|
||||
padding: 0;
|
||||
max-height: 85%;
|
||||
max-width: 85%;
|
||||
|
||||
&:hover {
|
||||
margin-top: 2%;
|
||||
margin-bottom: 2%;
|
||||
}
|
||||
|
||||
&.hightlighted {
|
||||
margin-top: 0% !important;
|
||||
margin-bottom: 0% !important;
|
||||
margin-left: 0% !important;
|
||||
|
||||
max-height: 100% !important;
|
||||
max-width: 96% !important;
|
||||
|
||||
&:hover {
|
||||
margin-top: 0% !important;
|
||||
margin-bottom: 0% !important;
|
||||
}
|
||||
}
|
||||
|
||||
&.mozaic-full-width {
|
||||
width: 95%;
|
||||
max-width: 95%;
|
||||
margin-left: 3%;
|
||||
margin-right: 3%;
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
|
||||
&:hover {
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
}
|
||||
}
|
||||
|
||||
&.mozaic-quarter {
|
||||
width: 95%;
|
||||
max-width: 95%;
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
|
||||
&:hover {
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
}
|
||||
}
|
||||
|
||||
&.nes-container.is-rounded {
|
||||
border-image-outset: 1;
|
||||
}
|
||||
|
||||
> div {
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-only(md) {
|
||||
.media-container {
|
||||
margin-top: 10%;
|
||||
margin-bottom: 10%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,26 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { streamableCollectionStore } from "../../Stores/StreamableCollectionStore";
|
||||
import { videoFocusStore } from "../../Stores/VideoFocusStore";
|
||||
import { afterUpdate } from "svelte";
|
||||
import { biggestAvailableAreaStore } from "../../Stores/BiggestAvailableAreaStore";
|
||||
import MediaBox from "./MediaBox.svelte";
|
||||
|
||||
afterUpdate(() => {
|
||||
biggestAvailableAreaStore.recompute();
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="main-section">
|
||||
{#if $videoFocusStore}
|
||||
{#key $videoFocusStore.uniqueId}
|
||||
<MediaBox streamable={$videoFocusStore} />
|
||||
{/key}
|
||||
{/if}
|
||||
</div>
|
||||
<aside class="sidebar">
|
||||
{#each [...$streamableCollectionStore.values()] as peer (peer.uniqueId)}
|
||||
{#if peer !== $videoFocusStore}
|
||||
<MediaBox streamable={peer} />
|
||||
{/if}
|
||||
{/each}
|
||||
</aside>
|
@ -1,12 +1,26 @@
|
||||
<script lang="ts">
|
||||
import { highlightedEmbedScreen } from "../../Stores/EmbedScreensStore";
|
||||
import type { EmbedScreen } from "../../Stores/EmbedScreensStore";
|
||||
import type { Streamable } from "../../Stores/StreamableCollectionStore";
|
||||
|
||||
import type { ScreenSharingPeer } from "../../WebRtc/ScreenSharingPeer";
|
||||
import { videoFocusStore } from "../../Stores/VideoFocusStore";
|
||||
import { getColorByString, srcObject } from "./utils";
|
||||
|
||||
export let clickable = false;
|
||||
|
||||
export let peer: ScreenSharingPeer;
|
||||
let streamStore = peer.streamStore;
|
||||
let name = peer.userName;
|
||||
let statusStore = peer.statusStore;
|
||||
|
||||
let embedScreen: EmbedScreen;
|
||||
|
||||
if (peer) {
|
||||
embedScreen = {
|
||||
type: "streamable",
|
||||
embed: peer as unknown as Streamable,
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="video-container">
|
||||
@ -20,7 +34,12 @@
|
||||
<i style="background-color: {getColorByString(name)};">{name}</i>
|
||||
{:else}
|
||||
<!-- svelte-ignore a11y-media-has-caption -->
|
||||
<video use:srcObject={$streamStore} autoplay playsinline on:click={() => videoFocusStore.toggleFocus(peer)} />
|
||||
<video
|
||||
use:srcObject={$streamStore}
|
||||
autoplay
|
||||
playsinline
|
||||
on:click={() => (clickable ? highlightedEmbedScreen.toggleHighlight(embedScreen) : null)}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
@ -4,11 +4,17 @@
|
||||
import microphoneCloseImg from "../images/microphone-close.svg";
|
||||
import reportImg from "./images/report.svg";
|
||||
import blockSignImg from "./images/blockSign.svg";
|
||||
import { videoFocusStore } from "../../Stores/VideoFocusStore";
|
||||
import { showReportScreenStore } from "../../Stores/ShowReportScreenStore";
|
||||
import { getColorByString, srcObject } from "./utils";
|
||||
import { highlightedEmbedScreen } from "../../Stores/EmbedScreensStore";
|
||||
import type { EmbedScreen } from "../../Stores/EmbedScreensStore";
|
||||
import type { Streamable } from "../../Stores/StreamableCollectionStore";
|
||||
|
||||
import Woka from "../Woka/Woka.svelte";
|
||||
import { onMount } from "svelte";
|
||||
import { isMediaBreakpointOnly } from "../../Utils/BreakpointsUtils";
|
||||
|
||||
export let clickable = false;
|
||||
|
||||
export let peer: VideoPeer;
|
||||
let streamStore = peer.streamStore;
|
||||
@ -19,9 +25,32 @@
|
||||
function openReport(peer: VideoPeer): void {
|
||||
showReportScreenStore.set({ userId: peer.userId, userName: peer.userName });
|
||||
}
|
||||
|
||||
let embedScreen: EmbedScreen;
|
||||
let videoContainer: HTMLDivElement;
|
||||
let minimized = isMediaBreakpointOnly("md");
|
||||
|
||||
if (peer) {
|
||||
embedScreen = {
|
||||
type: "streamable",
|
||||
embed: peer as unknown as Streamable,
|
||||
};
|
||||
}
|
||||
|
||||
function noDrag() {
|
||||
return false;
|
||||
}
|
||||
|
||||
const resizeObserver = new ResizeObserver(() => {
|
||||
minimized = isMediaBreakpointOnly("md");
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
resizeObserver.observe(videoContainer);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="video-container nes-container is-rounded is-dark">
|
||||
<div class="video-container" class:no-clikable={!clickable} bind:this={videoContainer}>
|
||||
{#if $statusStore === "connecting"}
|
||||
<div class="connecting-spinner" />
|
||||
{/if}
|
||||
@ -30,42 +59,64 @@
|
||||
{/if}
|
||||
<!-- {#if !$constraintStore || $constraintStore.video === false} -->
|
||||
<i
|
||||
class="container {!$constraintStore || $constraintStore.video === false ? '' : 'minimized'}"
|
||||
class="container"
|
||||
class:has-video={$constraintStore && $constraintStore.video === true}
|
||||
class:minimized={(!$constraintStore || $constraintStore.video !== true) && minimized}
|
||||
style="background-color: {getColorByString(name)};"
|
||||
>
|
||||
<span>{peer.userName}</span>
|
||||
<span style="noselect">{peer.userName}</span>
|
||||
<div class="woka-icon"><Woka userId={peer.userId} placeholderSrc={""} /></div>
|
||||
</i>
|
||||
<!-- {/if} -->
|
||||
{#if $constraintStore && $constraintStore.audio === false}
|
||||
<img src={microphoneCloseImg} class="active" alt="Muted" />
|
||||
<img
|
||||
src={microphoneCloseImg}
|
||||
class="active noselect"
|
||||
draggable="false"
|
||||
on:dragstart|preventDefault={noDrag}
|
||||
alt="Muted"
|
||||
/>
|
||||
{/if}
|
||||
<button class="report nes-button is-dark" on:click={() => openReport(peer)}>
|
||||
<img alt="Report this user" src={reportImg} />
|
||||
<span>Report/Block</span>
|
||||
<img alt="Report this user" draggable="false" on:dragstart|preventDefault={noDrag} src={reportImg} />
|
||||
<span class="noselect">Report/Block</span>
|
||||
</button>
|
||||
<!-- svelte-ignore a11y-media-has-caption -->
|
||||
<video use:srcObject={$streamStore} autoplay playsinline on:click={() => videoFocusStore.toggleFocus(peer)} />
|
||||
<img src={blockSignImg} class="block-logo" alt="Block" />
|
||||
<video
|
||||
class:no-video={!$constraintStore || $constraintStore.video === false}
|
||||
use:srcObject={$streamStore}
|
||||
autoplay
|
||||
playsinline
|
||||
on:click={() => (clickable ? highlightedEmbedScreen.toggleHighlight(embedScreen) : null)}
|
||||
/>
|
||||
<img src={blockSignImg} draggable="false" on:dragstart|preventDefault={noDrag} class="block-logo" alt="Block" />
|
||||
{#if $constraintStore && $constraintStore.audio !== false}
|
||||
<SoundMeterWidget stream={$streamStore} />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
<style lang="scss">
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.minimized {
|
||||
left: auto;
|
||||
transform: scale(0.5);
|
||||
opacity: 0.5;
|
||||
}
|
||||
&.has-video {
|
||||
left: auto;
|
||||
transform: scale(0.5);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.woka-icon {
|
||||
margin-right: 3px;
|
||||
&.minimized {
|
||||
transform: scale(0.5);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.woka-icon {
|
||||
margin-right: 3px;
|
||||
}
|
||||
}
|
||||
video.no-video {
|
||||
visibility: collapse;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,16 +1,16 @@
|
||||
<script lang="ts">
|
||||
import { LayoutMode } from "../../WebRtc/LayoutManager";
|
||||
import { layoutModeStore } from "../../Stores/StreamableCollectionStore";
|
||||
import PresentationLayout from "./PresentationLayout.svelte";
|
||||
import ChatLayout from "./ChatLayout.svelte";
|
||||
// import {LayoutMode} from "../../WebRtc/LayoutManager";
|
||||
// import {layoutModeStore} from "../../Stores/StreamableCollectionStore";
|
||||
// import PresentationLayout from "./PresentationLayout.svelte";
|
||||
// import ChatLayout from "./ChatLayout.svelte";
|
||||
</script>
|
||||
|
||||
<div class="video-overlay">
|
||||
{#if $layoutModeStore === LayoutMode.Presentation}
|
||||
<!-- {#if $layoutModeStore === LayoutMode.Presentation }
|
||||
<PresentationLayout />
|
||||
{:else}
|
||||
<ChatLayout />
|
||||
{/if}
|
||||
{/if} -->
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
|
@ -57,6 +57,7 @@
|
||||
height: 120px;
|
||||
margin: auto;
|
||||
animation: spin 2s linear infinite;
|
||||
z-index: 350;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
|
@ -27,18 +27,22 @@
|
||||
<style lang="scss">
|
||||
main.warningMain {
|
||||
pointer-events: auto;
|
||||
width: 100vw;
|
||||
width: 80%;
|
||||
background-color: #f9e81e;
|
||||
color: #14304c;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
|
||||
top: 4%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
transform: translate(-50%, 0);
|
||||
font-family: Lato;
|
||||
min-width: 300px;
|
||||
opacity: 0.9;
|
||||
z-index: 2;
|
||||
|
||||
z-index: 700;
|
||||
h2 {
|
||||
padding: 5px;
|
||||
}
|
||||
|
@ -22,10 +22,21 @@
|
||||
src = source ?? placeholderSrc;
|
||||
});
|
||||
|
||||
function noDrag() {
|
||||
return false;
|
||||
}
|
||||
|
||||
onDestroy(unsubscribe);
|
||||
</script>
|
||||
|
||||
<img {src} alt="" class="nes-pointer" style="--theme-width: {width}; --theme-height: {height}" />
|
||||
<img
|
||||
{src}
|
||||
alt=""
|
||||
class="nes-pointer noselect"
|
||||
style="--theme-width: {width}; --theme-height: {height}"
|
||||
draggable="false"
|
||||
on:dragstart|preventDefault={noDrag}
|
||||
/>
|
||||
|
||||
<style>
|
||||
img {
|
||||
|
@ -49,6 +49,8 @@
|
||||
</form>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../../../style/breakpoints.scss";
|
||||
|
||||
form.selectCharacterScene {
|
||||
font-family: "Press Start 2P";
|
||||
pointer-events: auto;
|
||||
@ -91,7 +93,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
@include media-breakpoint-up(md) {
|
||||
form.selectCharacterScene button.selectCharacterButtonLeft {
|
||||
left: 5vw;
|
||||
}
|
||||
|
@ -1,33 +1,46 @@
|
||||
const DEBUG_MODE: boolean = process.env.DEBUG_MODE == "true";
|
||||
const START_ROOM_URL: string =
|
||||
process.env.START_ROOM_URL || "/_/global/maps.workadventure.localhost/Floor1/floor1.json";
|
||||
const PUSHER_URL = process.env.PUSHER_URL || "//pusher.workadventure.localhost";
|
||||
export const ADMIN_URL = process.env.ADMIN_URL || "//workadventu.re";
|
||||
const UPLOADER_URL = process.env.UPLOADER_URL || "//uploader.workadventure.localhost";
|
||||
const ICON_URL = process.env.ICON_URL || "//icon.workadventure.localhost";
|
||||
const STUN_SERVER: string = process.env.STUN_SERVER || "stun:stun.l.google.com:19302";
|
||||
const TURN_SERVER: string = process.env.TURN_SERVER || "";
|
||||
const SKIP_RENDER_OPTIMIZATIONS: boolean = process.env.SKIP_RENDER_OPTIMIZATIONS == "true";
|
||||
const DISABLE_NOTIFICATIONS: boolean = process.env.DISABLE_NOTIFICATIONS == "true";
|
||||
const TURN_USER: string = process.env.TURN_USER || "";
|
||||
const TURN_PASSWORD: string = process.env.TURN_PASSWORD || "";
|
||||
const JITSI_URL: string | undefined = process.env.JITSI_URL === "" ? undefined : process.env.JITSI_URL;
|
||||
const JITSI_PRIVATE_MODE: boolean = process.env.JITSI_PRIVATE_MODE == "true";
|
||||
declare global {
|
||||
interface Window {
|
||||
env?: Record<string, string>;
|
||||
}
|
||||
}
|
||||
|
||||
const getEnv = (key: string): string | undefined => {
|
||||
if (global.window?.env) {
|
||||
return global.window.env[key];
|
||||
}
|
||||
if (global.process?.env) {
|
||||
return global.process.env[key];
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
const DEBUG_MODE: boolean = getEnv("DEBUG_MODE") == "true";
|
||||
const START_ROOM_URL: string = getEnv("START_ROOM_URL") || "/_/global/maps.workadventure.localhost/Floor1/floor1.json";
|
||||
const PUSHER_URL = getEnv("PUSHER_URL") || "//pusher.workadventure.localhost";
|
||||
export const ADMIN_URL = getEnv("ADMIN_URL") || "//workadventu.re";
|
||||
const UPLOADER_URL = getEnv("UPLOADER_URL") || "//uploader.workadventure.localhost";
|
||||
const ICON_URL = getEnv("ICON_URL") || "//icon.workadventure.localhost";
|
||||
const STUN_SERVER: string = getEnv("STUN_SERVER") || "stun:stun.l.google.com:19302";
|
||||
const TURN_SERVER: string = getEnv("TURN_SERVER") || "";
|
||||
const SKIP_RENDER_OPTIMIZATIONS: boolean = getEnv("SKIP_RENDER_OPTIMIZATIONS") == "true";
|
||||
const DISABLE_NOTIFICATIONS: boolean = getEnv("DISABLE_NOTIFICATIONS") == "true";
|
||||
const TURN_USER: string = getEnv("TURN_USER") || "";
|
||||
const TURN_PASSWORD: string = getEnv("TURN_PASSWORD") || "";
|
||||
const JITSI_URL: string | undefined = getEnv("JITSI_URL") === "" ? undefined : getEnv("JITSI_URL");
|
||||
const JITSI_PRIVATE_MODE: boolean = getEnv("JITSI_PRIVATE_MODE") == "true";
|
||||
const POSITION_DELAY = 200; // Wait 200ms between sending position events
|
||||
const MAX_EXTRAPOLATION_TIME = 100; // Extrapolate a maximum of 250ms if no new movement is sent by the player
|
||||
export const MAX_USERNAME_LENGTH = parseInt(process.env.MAX_USERNAME_LENGTH || "") || 8;
|
||||
export const MAX_PER_GROUP = parseInt(process.env.MAX_PER_GROUP || "4");
|
||||
export const DISPLAY_TERMS_OF_USE = process.env.DISPLAY_TERMS_OF_USE == "true";
|
||||
export const NODE_ENV = process.env.NODE_ENV || "development";
|
||||
export const CONTACT_URL = process.env.CONTACT_URL || undefined;
|
||||
export const PROFILE_URL = process.env.PROFILE_URL || undefined;
|
||||
export const POSTHOG_API_KEY: string = (process.env.POSTHOG_API_KEY as string) || "";
|
||||
export const POSTHOG_URL = process.env.POSTHOG_URL || undefined;
|
||||
export const DISABLE_ANONYMOUS: boolean = process.env.DISABLE_ANONYMOUS === "true";
|
||||
export const OPID_LOGIN_SCREEN_PROVIDER = process.env.OPID_LOGIN_SCREEN_PROVIDER;
|
||||
const FALLBACK_LOCALE = process.env.FALLBACK_LOCALE || undefined;
|
||||
|
||||
export const isMobile = (): boolean => window.innerWidth <= 800 || window.innerHeight <= 600;
|
||||
export const MAX_USERNAME_LENGTH = parseInt(getEnv("MAX_USERNAME_LENGTH") || "") || 8;
|
||||
export const MAX_PER_GROUP = parseInt(getEnv("MAX_PER_GROUP") || "4");
|
||||
export const DISPLAY_TERMS_OF_USE = getEnv("DISPLAY_TERMS_OF_USE") == "true";
|
||||
export const NODE_ENV = getEnv("NODE_ENV") || "development";
|
||||
export const CONTACT_URL = getEnv("CONTACT_URL") || undefined;
|
||||
export const PROFILE_URL = getEnv("PROFILE_URL") || undefined;
|
||||
export const POSTHOG_API_KEY: string = (getEnv("POSTHOG_API_KEY") as string) || "";
|
||||
export const POSTHOG_URL = getEnv("POSTHOG_URL") || undefined;
|
||||
export const DISABLE_ANONYMOUS: boolean = getEnv("DISABLE_ANONYMOUS") === "true";
|
||||
export const OPID_LOGIN_SCREEN_PROVIDER = getEnv("OPID_LOGIN_SCREEN_PROVIDER");
|
||||
const FALLBACK_LOCALE = getEnv("FALLBACK_LOCALE") || undefined;
|
||||
|
||||
export {
|
||||
DEBUG_MODE,
|
||||
|
@ -63,8 +63,6 @@ export class SoundMeter {
|
||||
//this.slow = 0.95 * that.slow + 0.05 * that.instant;
|
||||
//this.clip = clipcount / input.length;
|
||||
|
||||
//console.log('instant', this.instant, 'clip', this.clip);
|
||||
|
||||
return this.instant;
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,6 @@ export enum GameMapProperties {
|
||||
OPEN_WEBSITE = "openWebsite",
|
||||
OPEN_WEBSITE_ALLOW_API = "openWebsiteAllowApi",
|
||||
OPEN_WEBSITE_POLICY = "openWebsitePolicy",
|
||||
OPEN_WEBSITE_WIDTH = "openWebsiteWidth",
|
||||
OPEN_WEBSITE_POSITION = "openWebsitePosition",
|
||||
OPEN_WEBSITE_TRIGGER = "openWebsiteTrigger",
|
||||
OPEN_WEBSITE_TRIGGER_MESSAGE = "openWebsiteTriggerMessage",
|
||||
|
@ -2,33 +2,29 @@ import type { GameScene } from "./GameScene";
|
||||
import type { GameMap } from "./GameMap";
|
||||
import { scriptUtils } from "../../Api/ScriptUtils";
|
||||
import type { CoWebsite } from "../../WebRtc/CoWebsiteManager";
|
||||
import { coWebsiteManager, CoWebsiteState } from "../../WebRtc/CoWebsiteManager";
|
||||
import { coWebsiteManager } from "../../WebRtc/CoWebsiteManager";
|
||||
import { layoutManagerActionStore } from "../../Stores/LayoutManagerStore";
|
||||
import { localUserStore } from "../../Connexion/LocalUserStore";
|
||||
import { get } from "svelte/store";
|
||||
import { ON_ACTION_TRIGGER_BUTTON, ON_ACTION_TRIGGER_DISABLE } from "../../WebRtc/LayoutManager";
|
||||
import { ON_ACTION_TRIGGER_BUTTON } from "../../WebRtc/LayoutManager";
|
||||
import type { ITiledMapLayer } from "../Map/ITiledMap";
|
||||
import { GameMapProperties } from "./GameMapProperties";
|
||||
import { iframeListener } from "../../Api/IframeListener";
|
||||
import type { Subscription } from "rxjs";
|
||||
import { highlightedEmbedScreen } from "../../Stores/EmbedScreensStore";
|
||||
import { LL } from "../../i18n/i18n-svelte";
|
||||
|
||||
enum OpenCoWebsiteState {
|
||||
LOADING,
|
||||
ASLEEP,
|
||||
OPENED,
|
||||
MUST_BE_CLOSE,
|
||||
TRIGGER,
|
||||
}
|
||||
|
||||
interface OpenCoWebsite {
|
||||
coWebsite: CoWebsite | undefined;
|
||||
coWebsite: CoWebsite;
|
||||
state: OpenCoWebsiteState;
|
||||
}
|
||||
|
||||
export class GameMapPropertiesListener {
|
||||
private coWebsitesOpenByLayer = new Map<ITiledMapLayer, OpenCoWebsite>();
|
||||
private coWebsitesIframeListeners = new Map<ITiledMapLayer, Subscription>();
|
||||
private coWebsitesActionTriggerByLayer = new Map<ITiledMapLayer, string>();
|
||||
|
||||
constructor(private scene: GameScene, private gameMap: GameMap) {}
|
||||
|
||||
@ -69,10 +65,8 @@ export class GameMapPropertiesListener {
|
||||
let openWebsiteProperty: string | undefined;
|
||||
let allowApiProperty: boolean | undefined;
|
||||
let websitePolicyProperty: string | undefined;
|
||||
let websiteWidthProperty: number | undefined;
|
||||
let websitePositionProperty: number | undefined;
|
||||
let websiteTriggerProperty: string | undefined;
|
||||
let websiteTriggerMessageProperty: string | undefined;
|
||||
|
||||
layer.properties.forEach((property) => {
|
||||
switch (property.name) {
|
||||
@ -85,18 +79,12 @@ export class GameMapPropertiesListener {
|
||||
case GameMapProperties.OPEN_WEBSITE_POLICY:
|
||||
websitePolicyProperty = property.value as string | undefined;
|
||||
break;
|
||||
case GameMapProperties.OPEN_WEBSITE_WIDTH:
|
||||
websiteWidthProperty = property.value as number | undefined;
|
||||
break;
|
||||
case GameMapProperties.OPEN_WEBSITE_POSITION:
|
||||
websitePositionProperty = property.value as number | undefined;
|
||||
break;
|
||||
case GameMapProperties.OPEN_WEBSITE_TRIGGER:
|
||||
websiteTriggerProperty = property.value as string | undefined;
|
||||
break;
|
||||
case GameMapProperties.OPEN_WEBSITE_TRIGGER_MESSAGE:
|
||||
websiteTriggerMessageProperty = property.value as string | undefined;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
@ -110,27 +98,30 @@ export class GameMapPropertiesListener {
|
||||
return;
|
||||
}
|
||||
|
||||
const coWebsite = coWebsiteManager.addCoWebsite(
|
||||
openWebsiteProperty,
|
||||
this.scene.MapUrlFile,
|
||||
allowApiProperty,
|
||||
websitePolicyProperty,
|
||||
websitePositionProperty,
|
||||
false
|
||||
);
|
||||
|
||||
this.coWebsitesOpenByLayer.set(layer, {
|
||||
coWebsite: undefined,
|
||||
state: OpenCoWebsiteState.LOADING,
|
||||
coWebsite: coWebsite,
|
||||
state: OpenCoWebsiteState.ASLEEP,
|
||||
});
|
||||
|
||||
const openWebsiteFunction = () => {
|
||||
coWebsiteManager
|
||||
.loadCoWebsite(
|
||||
openWebsiteProperty as string,
|
||||
this.scene.MapUrlFile,
|
||||
allowApiProperty,
|
||||
websitePolicyProperty,
|
||||
websiteWidthProperty,
|
||||
websitePositionProperty
|
||||
)
|
||||
.loadCoWebsite(coWebsite)
|
||||
.then((coWebsite) => {
|
||||
const coWebsiteOpen = this.coWebsitesOpenByLayer.get(layer);
|
||||
if (coWebsiteOpen && coWebsiteOpen.state === OpenCoWebsiteState.MUST_BE_CLOSE) {
|
||||
coWebsiteManager.closeCoWebsite(coWebsite).catch((e) => console.error(e));
|
||||
coWebsiteManager.closeCoWebsite(coWebsite).catch(() => {
|
||||
console.error("Error during a co-website closing");
|
||||
});
|
||||
this.coWebsitesOpenByLayer.delete(layer);
|
||||
this.coWebsitesActionTriggerByLayer.delete(layer);
|
||||
} else {
|
||||
this.coWebsitesOpenByLayer.set(layer, {
|
||||
coWebsite,
|
||||
@ -138,57 +129,17 @@ export class GameMapPropertiesListener {
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((e) => console.error(e));
|
||||
.catch(() => {
|
||||
console.error("Error during loading a co-website: " + coWebsite.url);
|
||||
});
|
||||
|
||||
layoutManagerActionStore.removeAction(actionUuid);
|
||||
};
|
||||
|
||||
const createWebsiteTrigger = () => {
|
||||
if (!websiteTriggerMessageProperty) {
|
||||
websiteTriggerMessageProperty = get(LL).message.openWebsiteTrigger();
|
||||
}
|
||||
|
||||
this.coWebsitesOpenByLayer.set(layer, {
|
||||
coWebsite: undefined,
|
||||
state: OpenCoWebsiteState.TRIGGER,
|
||||
});
|
||||
|
||||
this.coWebsitesActionTriggerByLayer.set(layer, actionUuid);
|
||||
|
||||
layoutManagerActionStore.addAction({
|
||||
uuid: actionUuid,
|
||||
type: "message",
|
||||
message: websiteTriggerMessageProperty,
|
||||
callback: () => openWebsiteFunction(),
|
||||
userInputManager: this.scene.userInputManager,
|
||||
});
|
||||
};
|
||||
|
||||
this.coWebsitesIframeListeners.set(
|
||||
layer,
|
||||
iframeListener.unregisterIFrameStream.subscribe(() => {
|
||||
const coWebsiteOpen = this.coWebsitesOpenByLayer.get(layer);
|
||||
if (
|
||||
coWebsiteOpen?.coWebsite?.state == CoWebsiteState.CLOSED &&
|
||||
(!websiteTriggerProperty || websiteTriggerProperty !== ON_ACTION_TRIGGER_DISABLE)
|
||||
) {
|
||||
createWebsiteTrigger();
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
const forceTrigger = localUserStore.getForceCowebsiteTrigger();
|
||||
if (
|
||||
forceTrigger ||
|
||||
(websiteTriggerProperty && websiteTriggerProperty === ON_ACTION_TRIGGER_BUTTON)
|
||||
!localUserStore.getForceCowebsiteTrigger() &&
|
||||
websiteTriggerProperty !== ON_ACTION_TRIGGER_BUTTON
|
||||
) {
|
||||
createWebsiteTrigger();
|
||||
} else {
|
||||
this.coWebsitesOpenByLayer.set(layer, {
|
||||
coWebsite: undefined,
|
||||
state: OpenCoWebsiteState.LOADING,
|
||||
});
|
||||
|
||||
openWebsiteFunction();
|
||||
}
|
||||
});
|
||||
@ -223,29 +174,14 @@ export class GameMapPropertiesListener {
|
||||
return;
|
||||
}
|
||||
|
||||
const coWebsiteIframeListener = this.coWebsitesIframeListeners.get(layer);
|
||||
|
||||
if (coWebsiteIframeListener) {
|
||||
coWebsiteIframeListener.unsubscribe();
|
||||
this.coWebsitesIframeListeners.delete(layer);
|
||||
}
|
||||
|
||||
const coWebsiteOpen = this.coWebsitesOpenByLayer.get(layer);
|
||||
|
||||
if (!coWebsiteOpen) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (coWebsiteOpen.state === OpenCoWebsiteState.LOADING) {
|
||||
if (coWebsiteOpen.state === OpenCoWebsiteState.ASLEEP) {
|
||||
coWebsiteOpen.state = OpenCoWebsiteState.MUST_BE_CLOSE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
coWebsiteOpen.state !== OpenCoWebsiteState.OPENED &&
|
||||
coWebsiteOpen.state !== OpenCoWebsiteState.TRIGGER
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (coWebsiteOpen.coWebsite !== undefined) {
|
||||
@ -253,22 +189,6 @@ export class GameMapPropertiesListener {
|
||||
}
|
||||
|
||||
this.coWebsitesOpenByLayer.delete(layer);
|
||||
|
||||
const actionStore = get(layoutManagerActionStore);
|
||||
const actionTriggerUuid = this.coWebsitesActionTriggerByLayer.get(layer);
|
||||
|
||||
if (!actionTriggerUuid) {
|
||||
return;
|
||||
}
|
||||
|
||||
const action =
|
||||
actionStore && actionStore.length > 0
|
||||
? actionStore.find((action) => action.uuid === actionTriggerUuid)
|
||||
: undefined;
|
||||
|
||||
if (action) {
|
||||
layoutManagerActionStore.removeAction(actionTriggerUuid);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -255,7 +255,7 @@ export class GameScene extends DirtyScene {
|
||||
}
|
||||
this.load.audio("audio-webrtc-in", "/resources/objects/webrtc-in.mp3");
|
||||
this.load.audio("audio-webrtc-out", "/resources/objects/webrtc-out.mp3");
|
||||
//this.load.audio('audio-report-message', '/resources/objects/report-message.mp3');
|
||||
this.load.audio("audio-report-message", "/resources/objects/report-message.mp3");
|
||||
this.sound.pauseOnBlur = false;
|
||||
|
||||
this.load.on(FILE_LOAD_ERROR, (file: { src: string }) => {
|
||||
@ -650,13 +650,9 @@ export class GameScene extends DirtyScene {
|
||||
this.peerStoreUnsubscribe = peerStore.subscribe((peers) => {
|
||||
const newPeerNumber = peers.size;
|
||||
if (newPeerNumber > oldPeerNumber) {
|
||||
this.sound.play("audio-webrtc-in", {
|
||||
volume: 0.2,
|
||||
});
|
||||
this.playSound("audio-webrtc-in");
|
||||
} else if (newPeerNumber < oldPeerNumber) {
|
||||
this.sound.play("audio-webrtc-out", {
|
||||
volume: 0.2,
|
||||
});
|
||||
this.playSound("audio-webrtc-out");
|
||||
}
|
||||
oldPeerNumber = newPeerNumber;
|
||||
});
|
||||
@ -1296,21 +1292,21 @@ export class GameScene extends DirtyScene {
|
||||
throw new Error("Unknown query source");
|
||||
}
|
||||
|
||||
const coWebsite = await coWebsiteManager.loadCoWebsite(
|
||||
const coWebsite = coWebsiteManager.addCoWebsite(
|
||||
openCoWebsite.url,
|
||||
iframeListener.getBaseUrlFromSource(source),
|
||||
openCoWebsite.allowApi,
|
||||
openCoWebsite.allowPolicy,
|
||||
openCoWebsite.position
|
||||
openCoWebsite.position,
|
||||
openCoWebsite.closable ?? true
|
||||
);
|
||||
|
||||
if (!coWebsite) {
|
||||
throw new Error("Error on opening co-website");
|
||||
if (openCoWebsite.lazy !== undefined && !openCoWebsite.lazy) {
|
||||
await coWebsiteManager.loadCoWebsite(coWebsite);
|
||||
}
|
||||
|
||||
return {
|
||||
id: coWebsite.iframe.id,
|
||||
position: coWebsite.position,
|
||||
};
|
||||
});
|
||||
|
||||
@ -1320,7 +1316,6 @@ export class GameScene extends DirtyScene {
|
||||
return coWebsites.map((coWebsite: CoWebsite) => {
|
||||
return {
|
||||
id: coWebsite.iframe.id,
|
||||
position: coWebsite.position,
|
||||
};
|
||||
});
|
||||
});
|
||||
@ -1610,6 +1605,12 @@ export class GameScene extends DirtyScene {
|
||||
}
|
||||
}
|
||||
|
||||
public playSound(sound: string) {
|
||||
this.sound.play(sound, {
|
||||
volume: 0.2,
|
||||
});
|
||||
}
|
||||
|
||||
public cleanupClosingScene(): void {
|
||||
// stop playing audio, close any open website, stop any open Jitsi
|
||||
coWebsiteManager.closeCoWebsites().catch((e) => console.error(e));
|
||||
@ -1647,7 +1648,7 @@ export class GameScene extends DirtyScene {
|
||||
this.sharedVariablesManager?.close();
|
||||
this.embeddedWebsiteManager?.close();
|
||||
|
||||
mediaManager.hideGameOverlay();
|
||||
mediaManager.hideMyCamera();
|
||||
|
||||
for (const iframeEvents of this.iframeSubscriptionList) {
|
||||
iframeEvents.unsubscribe();
|
||||
@ -2156,6 +2157,17 @@ export class GameScene extends DirtyScene {
|
||||
biggestAvailableAreaStore.recompute();
|
||||
}
|
||||
|
||||
public enableMediaBehaviors() {
|
||||
const silent = this.gameMap.getCurrentProperties().get(GameMapProperties.SILENT);
|
||||
this.connection?.setSilent(!!silent);
|
||||
mediaManager.showMyCamera();
|
||||
}
|
||||
|
||||
public disableMediaBehaviors() {
|
||||
this.connection?.setSilent(true);
|
||||
mediaManager.hideMyCamera();
|
||||
}
|
||||
|
||||
public startJitsi(roomName: string, jwt?: string): void {
|
||||
const allProps = this.gameMap.getCurrentProperties();
|
||||
const jitsiConfig = this.safeParseJSONstring(
|
||||
@ -2167,71 +2179,26 @@ export class GameScene extends DirtyScene {
|
||||
GameMapProperties.JITSI_INTERFACE_CONFIG
|
||||
);
|
||||
const jitsiUrl = allProps.get(GameMapProperties.JITSI_URL) as string | undefined;
|
||||
const jitsiWidth = allProps.get(GameMapProperties.JITSI_WIDTH) as number | undefined;
|
||||
|
||||
const jitsiKeepCircle = allProps.get("jitsiKeepCircle") as boolean | false;
|
||||
|
||||
jitsiFactory
|
||||
.start(roomName, this.playerName, jwt, jitsiConfig, jitsiInterfaceConfig, jitsiUrl, jitsiWidth)
|
||||
.catch((e) => console.error(e));
|
||||
this.connection?.setSilent(true);
|
||||
mediaManager.hideGameOverlay();
|
||||
|
||||
if (jitsiKeepCircle) {
|
||||
const silent = this.gameMap.getCurrentProperties().get("silent");
|
||||
this.connection?.setSilent(!!silent);
|
||||
mediaManager.showGameOverlay();
|
||||
}
|
||||
|
||||
analyticsClient.enteredJitsi(roomName, this.room.id);
|
||||
|
||||
//permit to stop jitsi when user close iframe
|
||||
mediaManager.addTriggerCloseJitsiFrameButton("close-jitsi", () => {
|
||||
this.stopJitsi();
|
||||
jitsiFactory.start(roomName, this.playerName, jwt, jitsiConfig, jitsiInterfaceConfig, jitsiUrl).catch(() => {
|
||||
console.error("Cannot start a Jitsi co-website");
|
||||
});
|
||||
|
||||
if (allProps.get("jitsiKeepCircle") as boolean | false) {
|
||||
this.enableMediaBehaviors();
|
||||
} else {
|
||||
this.disableMediaBehaviors();
|
||||
}
|
||||
analyticsClient.enteredJitsi(roomName, this.room.id);
|
||||
}
|
||||
|
||||
public stopJitsi(): void {
|
||||
const silent = this.gameMap.getCurrentProperties().get(GameMapProperties.SILENT);
|
||||
this.connection?.setSilent(!!silent);
|
||||
jitsiFactory.stop();
|
||||
mediaManager.showGameOverlay();
|
||||
|
||||
const allProps = this.gameMap.getCurrentProperties();
|
||||
|
||||
if (allProps.get("jitsiRoom") === undefined) {
|
||||
layoutManagerActionStore.removeAction("jitsi");
|
||||
} else {
|
||||
const openJitsiRoomFunction = () => {
|
||||
const roomName = jitsiFactory.getRoomName(
|
||||
allProps.get(GameMapProperties.JITSI_ROOM) as string,
|
||||
this.instance
|
||||
);
|
||||
const jitsiUrl = allProps.get(GameMapProperties.JITSI_URL) as string | undefined;
|
||||
if (JITSI_PRIVATE_MODE && !jitsiUrl) {
|
||||
const adminTag = allProps.get(GameMapProperties.JITSI_ADMIN_ROOM_TAG) as string | undefined;
|
||||
|
||||
this.connection && this.connection.emitQueryJitsiJwtMessage(roomName, adminTag);
|
||||
} else {
|
||||
this.startJitsi(roomName, undefined);
|
||||
}
|
||||
layoutManagerActionStore.removeAction("jitsi");
|
||||
};
|
||||
|
||||
let message = allProps.get(GameMapProperties.JITSI_TRIGGER_MESSAGE);
|
||||
if (message === undefined) {
|
||||
message = "Press SPACE or touch here to enter Jitsi Meet room";
|
||||
}
|
||||
layoutManagerActionStore.addAction({
|
||||
uuid: "jitsi",
|
||||
type: "message",
|
||||
message: message,
|
||||
callback: () => openJitsiRoomFunction(),
|
||||
userInputManager: this.userInputManager,
|
||||
const coWebsite = coWebsiteManager.searchJitsi();
|
||||
if (coWebsite) {
|
||||
coWebsiteManager.closeCoWebsite(coWebsite).catch((e) => {
|
||||
console.error("Error during Jitsi co-website closing", e);
|
||||
});
|
||||
}
|
||||
|
||||
mediaManager.removeTriggerCloseJitsiFrameButton("close-jitsi");
|
||||
}
|
||||
|
||||
//todo: put this into an 'orchestrator' scene (EntryScene?)
|
||||
|
@ -11,10 +11,10 @@ import { areCharacterLayersValid } from "../../Connexion/LocalUser";
|
||||
import { SelectCharacterSceneName } from "./SelectCharacterScene";
|
||||
import { activeRowStore, customCharacterSceneVisibleStore } from "../../Stores/CustomCharacterStore";
|
||||
import { waScaleManager } from "../Services/WaScaleManager";
|
||||
import { isMobile } from "../../Enum/EnvironmentVariable";
|
||||
import { CustomizedCharacter } from "../Entity/CustomizedCharacter";
|
||||
import { get } from "svelte/store";
|
||||
import { analyticsClient } from "../../Administration/AnalyticsClient";
|
||||
import { isMediaBreakpointUp } from "../../Utils/BreakpointsUtils";
|
||||
|
||||
export const CustomizeSceneName = "CustomizeScene";
|
||||
|
||||
@ -67,12 +67,12 @@ export class CustomizeScene extends AbstractCharacterScene {
|
||||
customCharacterSceneVisibleStore.set(true);
|
||||
this.events.addListener("wake", () => {
|
||||
waScaleManager.saveZoom();
|
||||
waScaleManager.zoomModifier = isMobile() ? 3 : 1;
|
||||
waScaleManager.zoomModifier = isMediaBreakpointUp("md") ? 3 : 1;
|
||||
customCharacterSceneVisibleStore.set(true);
|
||||
});
|
||||
|
||||
waScaleManager.saveZoom();
|
||||
waScaleManager.zoomModifier = isMobile() ? 3 : 1;
|
||||
waScaleManager.zoomModifier = isMediaBreakpointUp("md") ? 3 : 1;
|
||||
|
||||
this.Rectangle = this.add.rectangle(
|
||||
this.cameras.main.worldView.x + this.cameras.main.width / 2,
|
||||
|
@ -12,8 +12,8 @@ import { touchScreenManager } from "../../Touch/TouchScreenManager";
|
||||
import { PinchManager } from "../UserInput/PinchManager";
|
||||
import { selectCharacterSceneVisibleStore } from "../../Stores/SelectCharacterStore";
|
||||
import { waScaleManager } from "../Services/WaScaleManager";
|
||||
import { isMobile } from "../../Enum/EnvironmentVariable";
|
||||
import { analyticsClient } from "../../Administration/AnalyticsClient";
|
||||
import { isMediaBreakpointUp } from "../../Utils/BreakpointsUtils";
|
||||
|
||||
//todo: put this constants in a dedicated file
|
||||
export const SelectCharacterSceneName = "SelectCharacterScene";
|
||||
@ -60,7 +60,7 @@ export class SelectCharacterScene extends AbstractCharacterScene {
|
||||
selectCharacterSceneVisibleStore.set(true);
|
||||
this.events.addListener("wake", () => {
|
||||
waScaleManager.saveZoom();
|
||||
waScaleManager.zoomModifier = isMobile() ? 2 : 1;
|
||||
waScaleManager.zoomModifier = isMediaBreakpointUp("md") ? 2 : 1;
|
||||
selectCharacterSceneVisibleStore.set(true);
|
||||
});
|
||||
|
||||
@ -69,7 +69,7 @@ export class SelectCharacterScene extends AbstractCharacterScene {
|
||||
}
|
||||
|
||||
waScaleManager.saveZoom();
|
||||
waScaleManager.zoomModifier = isMobile() ? 2 : 1;
|
||||
waScaleManager.zoomModifier = isMediaBreakpointUp("md") ? 2 : 1;
|
||||
|
||||
const rectangleXStart = this.game.renderer.width / 2 - (this.nbCharactersPerRow / 2) * 32 + 16;
|
||||
this.selectedRectangle = this.add.rectangle(rectangleXStart, 90, 32, 32).setStrokeStyle(2, 0xffffff);
|
||||
|
@ -9,7 +9,7 @@ import { touchScreenManager } from "../../Touch/TouchScreenManager";
|
||||
import { PinchManager } from "../UserInput/PinchManager";
|
||||
import { selectCompanionSceneVisibleStore } from "../../Stores/SelectCompanionStore";
|
||||
import { waScaleManager } from "../Services/WaScaleManager";
|
||||
import { isMobile } from "../../Enum/EnvironmentVariable";
|
||||
import { isMediaBreakpointUp } from "../../Utils/BreakpointsUtils";
|
||||
|
||||
export const SelectCompanionSceneName = "SelectCompanionScene";
|
||||
|
||||
@ -44,7 +44,7 @@ export class SelectCompanionScene extends ResizableScene {
|
||||
selectCompanionSceneVisibleStore.set(true);
|
||||
|
||||
waScaleManager.saveZoom();
|
||||
waScaleManager.zoomModifier = isMobile() ? 2 : 1;
|
||||
waScaleManager.zoomModifier = isMediaBreakpointUp("md") ? 2 : 1;
|
||||
|
||||
if (touchScreenManager.supportTouchScreen) {
|
||||
new PinchManager(this);
|
||||
|
@ -37,19 +37,17 @@ export class WaScaleManager {
|
||||
height: height * devicePixelRatio,
|
||||
});
|
||||
|
||||
if (gameSize.width == 0) {
|
||||
return;
|
||||
if (realSize.width !== 0 && gameSize.width !== 0 && devicePixelRatio !== 0) {
|
||||
this.actualZoom = realSize.width / gameSize.width / devicePixelRatio;
|
||||
}
|
||||
|
||||
this.actualZoom = realSize.width / gameSize.width / devicePixelRatio;
|
||||
|
||||
this.scaleManager.setZoom(realSize.width / gameSize.width / devicePixelRatio);
|
||||
this.scaleManager.setZoom(this.actualZoom);
|
||||
this.scaleManager.resize(gameSize.width, gameSize.height);
|
||||
|
||||
// Override bug in canvas resizing in Phaser. Let's resize the canvas ourselves
|
||||
const style = this.scaleManager.canvas.style;
|
||||
style.width = Math.ceil(realSize.width / devicePixelRatio) + "px";
|
||||
style.height = Math.ceil(realSize.height / devicePixelRatio) + "px";
|
||||
style.width = Math.ceil(realSize.width !== 0 ? realSize.width / devicePixelRatio : 0) + "px";
|
||||
style.height = Math.ceil(realSize.height !== 0 ? realSize.height / devicePixelRatio : 0) + "px";
|
||||
|
||||
// Resize the game element at the same size at the canvas
|
||||
const gameStyle = HtmlUtils.getElementByIdOrFail<HTMLDivElement>("game").style;
|
||||
|
@ -2,14 +2,14 @@ import { get, writable } from "svelte/store";
|
||||
import type { Box } from "../WebRtc/LayoutManager";
|
||||
import { HtmlUtils } from "../WebRtc/HtmlUtils";
|
||||
import { LayoutMode } from "../WebRtc/LayoutManager";
|
||||
import { layoutModeStore } from "./StreamableCollectionStore";
|
||||
import { embedScreenLayout } from "./EmbedScreensStore";
|
||||
|
||||
/**
|
||||
* Tries to find the biggest available box of remaining space (this is a space where we can center the character)
|
||||
*/
|
||||
function findBiggestAvailableArea(): Box {
|
||||
const game = HtmlUtils.querySelectorOrFail<HTMLCanvasElement>("#game canvas");
|
||||
if (get(layoutModeStore) === LayoutMode.VideoChat) {
|
||||
if (get(embedScreenLayout) === LayoutMode.VideoChat) {
|
||||
const children = document.querySelectorAll<HTMLDivElement>("div.chat-mode > div");
|
||||
const htmlChildren = Array.from(children.values());
|
||||
|
||||
|
51
front/src/Stores/CoWebsiteStore.ts
Normal file
51
front/src/Stores/CoWebsiteStore.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import { derived, get, writable } from "svelte/store";
|
||||
import type { CoWebsite } from "../WebRtc/CoWebsiteManager";
|
||||
|
||||
function createCoWebsiteStore() {
|
||||
const { subscribe, set, update } = writable(Array<CoWebsite>());
|
||||
|
||||
set(Array<CoWebsite>());
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
add: (coWebsite: CoWebsite, position?: number) => {
|
||||
coWebsite.state.subscribe((value) => {
|
||||
update((currentArray) => currentArray);
|
||||
});
|
||||
|
||||
if (position || position === 0) {
|
||||
update((currentArray) => {
|
||||
if (position === 0) {
|
||||
return [coWebsite, ...currentArray];
|
||||
} else if (currentArray.length > position) {
|
||||
const test = [...currentArray.splice(position, 0, coWebsite)];
|
||||
return [...currentArray.splice(position, 0, coWebsite)];
|
||||
}
|
||||
|
||||
return [...currentArray, coWebsite];
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
update((currentArray) => [...currentArray, coWebsite]);
|
||||
},
|
||||
remove: (coWebsite: CoWebsite) => {
|
||||
update((currentArray) => [
|
||||
...currentArray.filter((currentCoWebsite) => currentCoWebsite.iframe.id !== coWebsite.iframe.id),
|
||||
]);
|
||||
},
|
||||
empty: () => {
|
||||
set(Array<CoWebsite>());
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export const coWebsites = createCoWebsiteStore();
|
||||
|
||||
export const coWebsitesNotAsleep = derived([coWebsites], ([$coWebsites]) =>
|
||||
$coWebsites.filter((coWebsite) => get(coWebsite.state) !== "asleep")
|
||||
);
|
||||
|
||||
export const mainCoWebsite = derived([coWebsites], ([$coWebsites]) =>
|
||||
$coWebsites.find((coWebsite) => get(coWebsite.state) !== "asleep")
|
||||
);
|
51
front/src/Stores/EmbedScreensStore.ts
Normal file
51
front/src/Stores/EmbedScreensStore.ts
Normal file
@ -0,0 +1,51 @@
|
||||
import { derived, get, writable } from "svelte/store";
|
||||
import type { CoWebsite } from "../WebRtc/CoWebsiteManager";
|
||||
import { LayoutMode } from "../WebRtc/LayoutManager";
|
||||
import { coWebsites } from "./CoWebsiteStore";
|
||||
import { Streamable, streamableCollectionStore } from "./StreamableCollectionStore";
|
||||
|
||||
export type EmbedScreen =
|
||||
| {
|
||||
type: "streamable";
|
||||
embed: Streamable;
|
||||
}
|
||||
| {
|
||||
type: "cowebsite";
|
||||
embed: CoWebsite;
|
||||
};
|
||||
|
||||
function createHighlightedEmbedScreenStore() {
|
||||
const { subscribe, set, update } = writable<EmbedScreen | null>(null);
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
highlight: (embedScreen: EmbedScreen) => {
|
||||
set(embedScreen);
|
||||
},
|
||||
removeHighlight: () => {
|
||||
set(null);
|
||||
},
|
||||
toggleHighlight: (embedScreen: EmbedScreen) => {
|
||||
update((currentEmbedScreen) =>
|
||||
!currentEmbedScreen ||
|
||||
embedScreen.type !== currentEmbedScreen.type ||
|
||||
(embedScreen.type === "cowebsite" &&
|
||||
currentEmbedScreen.type === "cowebsite" &&
|
||||
embedScreen.embed.iframe.id !== currentEmbedScreen.embed.iframe.id) ||
|
||||
(embedScreen.type === "streamable" &&
|
||||
currentEmbedScreen.type === "streamable" &&
|
||||
embedScreen.embed.uniqueId !== currentEmbedScreen.embed.uniqueId)
|
||||
? embedScreen
|
||||
: null
|
||||
);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export const highlightedEmbedScreen = createHighlightedEmbedScreenStore();
|
||||
export const embedScreenLayout = writable<LayoutMode>(LayoutMode.Presentation);
|
||||
|
||||
export const hasEmbedScreen = derived(
|
||||
[streamableCollectionStore],
|
||||
($values) => get(streamableCollectionStore).size + get(coWebsites).length > 0
|
||||
);
|
@ -1,17 +0,0 @@
|
||||
import { writable } from "svelte/store";
|
||||
|
||||
/**
|
||||
* A store that contains whether the game overlay is shown or not.
|
||||
* Typically, the overlay is hidden when entering Jitsi meet.
|
||||
*/
|
||||
function createGameOverlayVisibilityStore() {
|
||||
const { subscribe, set, update } = writable(false);
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
showGameOverlay: () => set(true),
|
||||
hideGameOverlay: () => set(false),
|
||||
};
|
||||
}
|
||||
|
||||
export const gameOverlayVisibilityStore = createGameOverlayVisibilityStore();
|
@ -51,6 +51,6 @@ function createLayoutManagerAction() {
|
||||
|
||||
export const layoutManagerActionStore = createLayoutManagerAction();
|
||||
|
||||
export const layoutManagerVisibilityStore = derived(layoutManagerActionStore, ($layoutManagerActionStore) => {
|
||||
export const layoutManagerActionVisibilityStore = derived(layoutManagerActionStore, ($layoutManagerActionStore) => {
|
||||
return !!$layoutManagerActionStore.length;
|
||||
});
|
||||
|
@ -6,7 +6,7 @@ import { BrowserTooOldError } from "./Errors/BrowserTooOldError";
|
||||
import { errorStore } from "./ErrorStore";
|
||||
import { getNavigatorType, isIOS, NavigatorType } from "../WebRtc/DeviceUtils";
|
||||
import { WebviewOnOldIOS } from "./Errors/WebviewOnOldIOS";
|
||||
import { gameOverlayVisibilityStore } from "./GameOverlayStoreVisibility";
|
||||
import { myCameraVisibilityStore } from "./MyCameraStoreVisibility";
|
||||
import { peerStore } from "./PeerStore";
|
||||
import { privacyShutdownStore } from "./PrivacyShutdownStore";
|
||||
import { MediaStreamConstraintsError } from "./Errors/MediaStreamConstraintsError";
|
||||
@ -233,7 +233,7 @@ export const mediaStreamConstraintsStore = derived(
|
||||
[
|
||||
requestedCameraState,
|
||||
requestedMicrophoneState,
|
||||
gameOverlayVisibilityStore,
|
||||
myCameraVisibilityStore,
|
||||
enableCameraSceneVisibilityStore,
|
||||
videoConstraintStore,
|
||||
audioConstraintStore,
|
||||
@ -245,7 +245,7 @@ export const mediaStreamConstraintsStore = derived(
|
||||
[
|
||||
$requestedCameraState,
|
||||
$requestedMicrophoneState,
|
||||
$gameOverlayVisibilityStore,
|
||||
$myCameraVisibilityStore,
|
||||
$enableCameraSceneVisibilityStore,
|
||||
$videoConstraintStore,
|
||||
$audioConstraintStore,
|
||||
@ -283,7 +283,7 @@ export const mediaStreamConstraintsStore = derived(
|
||||
}
|
||||
|
||||
// Disable webcam and microphone when in a Jitsi
|
||||
if ($gameOverlayVisibilityStore === false) {
|
||||
if ($myCameraVisibilityStore === false) {
|
||||
currentVideoConstraint = false;
|
||||
currentAudioConstraint = false;
|
||||
}
|
||||
|
8
front/src/Stores/MyCameraStoreVisibility.ts
Normal file
8
front/src/Stores/MyCameraStoreVisibility.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { writable } from "svelte/store";
|
||||
|
||||
/**
|
||||
* A store that contains whether my camera & actions is shown or not.
|
||||
* Typically, the overlay is hidden when entering Jitsi meet.
|
||||
*/
|
||||
|
||||
export const myCameraVisibilityStore = writable(false);
|
@ -1,7 +1,7 @@
|
||||
import { derived, Readable, readable, writable } from "svelte/store";
|
||||
import { peerStore } from "./PeerStore";
|
||||
import type { LocalStreamStoreValue } from "./MediaStore";
|
||||
import { gameOverlayVisibilityStore } from "./GameOverlayStoreVisibility";
|
||||
import { myCameraVisibilityStore } from "./MyCameraStoreVisibility";
|
||||
|
||||
declare const navigator: any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
|
||||
@ -41,8 +41,8 @@ let previousComputedAudioConstraint: boolean | MediaTrackConstraints = false;
|
||||
* A store containing the media constraints we want to apply.
|
||||
*/
|
||||
export const screenSharingConstraintsStore = derived(
|
||||
[requestedScreenSharingState, gameOverlayVisibilityStore, peerStore],
|
||||
([$requestedScreenSharingState, $gameOverlayVisibilityStore, $peerStore], set) => {
|
||||
[requestedScreenSharingState, myCameraVisibilityStore, peerStore],
|
||||
([$requestedScreenSharingState, $myCameraVisibilityStore, $peerStore], set) => {
|
||||
let currentVideoConstraint: boolean | MediaTrackConstraints = true;
|
||||
let currentAudioConstraint: boolean | MediaTrackConstraints = false;
|
||||
|
||||
@ -53,7 +53,7 @@ export const screenSharingConstraintsStore = derived(
|
||||
}
|
||||
|
||||
// Disable screen sharing when in a Jitsi
|
||||
if (!$gameOverlayVisibilityStore) {
|
||||
if (!$myCameraVisibilityStore) {
|
||||
currentVideoConstraint = false;
|
||||
currentAudioConstraint = false;
|
||||
}
|
||||
|
@ -1,13 +1,10 @@
|
||||
import { derived, get, Readable, writable } from "svelte/store";
|
||||
import { derived, get, Readable } from "svelte/store";
|
||||
import { ScreenSharingLocalMedia, screenSharingLocalMedia } from "./ScreenSharingStore";
|
||||
import { peerStore, screenSharingStreamStore } from "./PeerStore";
|
||||
import type { RemotePeer } from "../WebRtc/SimplePeer";
|
||||
import { LayoutMode } from "../WebRtc/LayoutManager";
|
||||
|
||||
export type Streamable = RemotePeer | ScreenSharingLocalMedia;
|
||||
|
||||
export const layoutModeStore = writable<LayoutMode>(LayoutMode.Presentation);
|
||||
|
||||
/**
|
||||
* A store that contains everything that can produce a stream (so the peers + the local screen sharing stream)
|
||||
*/
|
||||
|
112
front/src/Utils/BreakpointsUtils.ts
Normal file
112
front/src/Utils/BreakpointsUtils.ts
Normal file
@ -0,0 +1,112 @@
|
||||
type InternalBreakpoint = {
|
||||
beforeBreakpoint: InternalBreakpoint | undefined;
|
||||
nextBreakpoint: InternalBreakpoint | undefined;
|
||||
pixels: number;
|
||||
};
|
||||
|
||||
function generateBreakpointsMap(): Map<string, InternalBreakpoint> {
|
||||
// If is changed don't forget to also change it on SASS.
|
||||
const breakpoints: { [key: string]: number } = {
|
||||
xs: 0,
|
||||
sm: 576,
|
||||
md: 768,
|
||||
lg: 992,
|
||||
xl: 1200,
|
||||
xxl: 1400,
|
||||
};
|
||||
|
||||
let beforeBreakpoint: InternalBreakpoint | undefined;
|
||||
let beforeBreakpointTag: string | undefined;
|
||||
const mapRender = new Map<string, InternalBreakpoint>();
|
||||
|
||||
for (const breakpoint in breakpoints) {
|
||||
const newBreakpoint = {
|
||||
beforeBreakpoint: beforeBreakpoint,
|
||||
nextBreakpoint: undefined,
|
||||
pixels: breakpoints[breakpoint],
|
||||
};
|
||||
|
||||
if (beforeBreakpointTag && beforeBreakpoint) {
|
||||
beforeBreakpoint.nextBreakpoint = newBreakpoint;
|
||||
mapRender.set(beforeBreakpointTag, beforeBreakpoint);
|
||||
}
|
||||
|
||||
mapRender.set(breakpoint, {
|
||||
beforeBreakpoint: beforeBreakpoint,
|
||||
nextBreakpoint: undefined,
|
||||
pixels: breakpoints[breakpoint],
|
||||
});
|
||||
|
||||
beforeBreakpointTag = breakpoint;
|
||||
beforeBreakpoint = newBreakpoint;
|
||||
}
|
||||
|
||||
return mapRender;
|
||||
}
|
||||
|
||||
const breakpoints = generateBreakpointsMap();
|
||||
|
||||
export type Breakpoint = "xs" | "sm" | "md" | "lg" | "xl" | "xxl";
|
||||
|
||||
export function isMediaBreakpointUp(breakpoint: Breakpoint): boolean {
|
||||
if (breakpoint === "xxl") {
|
||||
return true;
|
||||
}
|
||||
|
||||
const breakpointObject = breakpoints.get(breakpoint);
|
||||
|
||||
if (!breakpointObject) {
|
||||
throw new Error(`Unknown breakpoint: ${breakpoint}`);
|
||||
}
|
||||
|
||||
if (!breakpointObject.nextBreakpoint) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return breakpointObject.nextBreakpoint.pixels - 1 >= window.innerWidth;
|
||||
}
|
||||
|
||||
export function isMediaBreakpointDown(breakpoint: Breakpoint): boolean {
|
||||
if (breakpoint === "xs") {
|
||||
return true;
|
||||
}
|
||||
|
||||
const breakpointObject = breakpoints.get(breakpoint);
|
||||
|
||||
if (!breakpointObject) {
|
||||
throw new Error(`Unknown breakpoint: ${breakpoint}`);
|
||||
}
|
||||
|
||||
return breakpointObject.pixels <= window.innerWidth;
|
||||
}
|
||||
|
||||
export function isMediaBreakpointOnly(breakpoint: Breakpoint): boolean {
|
||||
const breakpointObject = breakpoints.get(breakpoint);
|
||||
|
||||
if (!breakpointObject) {
|
||||
throw new Error(`Unknown breakpoint: ${breakpoint}`);
|
||||
}
|
||||
|
||||
return (
|
||||
breakpointObject.pixels <= window.innerWidth &&
|
||||
(!breakpointObject.nextBreakpoint || breakpointObject.nextBreakpoint.pixels - 1 >= window.innerWidth)
|
||||
);
|
||||
}
|
||||
|
||||
export function isMediaBreakpointBetween(startBreakpoint: Breakpoint, endBreakpoint: Breakpoint): boolean {
|
||||
const startBreakpointObject = breakpoints.get(startBreakpoint);
|
||||
const endBreakpointObject = breakpoints.get(endBreakpoint);
|
||||
|
||||
if (!startBreakpointObject) {
|
||||
throw new Error(`Unknown start breakpoint: ${startBreakpointObject}`);
|
||||
}
|
||||
|
||||
if (!endBreakpointObject) {
|
||||
throw new Error(`Unknown end breakpoint: ${endBreakpointObject}`);
|
||||
}
|
||||
|
||||
return (
|
||||
startBreakpointObject.pixels <= innerWidth &&
|
||||
(!endBreakpointObject.nextBreakpoint || endBreakpointObject.nextBreakpoint.pixels - 1 >= window.innerWidth)
|
||||
);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -9,6 +9,11 @@ export class HtmlUtils {
|
||||
throw new Error("Cannot find HTML element with id '" + id + "'");
|
||||
}
|
||||
|
||||
public static getElementById<T extends HTMLElement>(id: string): T | undefined {
|
||||
const elem = document.getElementById(id);
|
||||
return HtmlUtils.isHtmlElement<T>(elem) ? elem : undefined;
|
||||
}
|
||||
|
||||
public static querySelectorOrFail<T extends HTMLElement>(selector: string): T {
|
||||
const elem = document.querySelector<T>(selector);
|
||||
if (HtmlUtils.isHtmlElement<T>(elem)) {
|
||||
|
@ -7,6 +7,7 @@ interface jitsiConfigInterface {
|
||||
startWithAudioMuted: boolean;
|
||||
startWithVideoMuted: boolean;
|
||||
prejoinPageEnabled: boolean;
|
||||
disableDeepLinking: boolean;
|
||||
}
|
||||
|
||||
interface JitsiOptions {
|
||||
@ -40,6 +41,7 @@ const getDefaultConfig = (): jitsiConfigInterface => {
|
||||
startWithAudioMuted: !get(requestedMicrophoneState),
|
||||
startWithVideoMuted: !get(requestedCameraState),
|
||||
prejoinPageEnabled: false,
|
||||
disableDeepLinking: false,
|
||||
};
|
||||
};
|
||||
|
||||
@ -135,64 +137,112 @@ class JitsiFactory {
|
||||
return slugify(instance.replace("/", "-") + "-" + roomName);
|
||||
}
|
||||
|
||||
public start(
|
||||
public async start(
|
||||
roomName: string,
|
||||
playerName: string,
|
||||
jwt?: string,
|
||||
config?: object,
|
||||
interfaceConfig?: object,
|
||||
jitsiUrl?: string,
|
||||
jitsiWidth?: number
|
||||
): Promise<CoWebsite> {
|
||||
return coWebsiteManager.addCoWebsite(
|
||||
async (cowebsiteDiv) => {
|
||||
// Jitsi meet external API maintains some data in local storage
|
||||
// which is sent via the appData URL parameter when joining a
|
||||
// conference. Problem is that this data grows indefinitely. Thus
|
||||
// after some time the URLs get so huge that loading the iframe
|
||||
// becomes slow and eventually breaks completely. Thus lets just
|
||||
// clear jitsi local storage before starting a new conference.
|
||||
window.localStorage.removeItem("jitsiLocalStorage");
|
||||
jitsiUrl?: string
|
||||
) {
|
||||
const coWebsite = coWebsiteManager.searchJitsi();
|
||||
|
||||
const domain = jitsiUrl || JITSI_URL;
|
||||
if (domain === undefined) {
|
||||
throw new Error("Missing JITSI_URL environment variable or jitsiUrl parameter in the map.");
|
||||
}
|
||||
await this.loadJitsiScript(domain);
|
||||
if (coWebsite) {
|
||||
await coWebsiteManager.closeCoWebsite(coWebsite);
|
||||
}
|
||||
|
||||
const options: JitsiOptions = {
|
||||
roomName: roomName,
|
||||
jwt: jwt,
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
parentNode: cowebsiteDiv,
|
||||
configOverwrite: mergeConfig(config),
|
||||
interfaceConfigOverwrite: { ...defaultInterfaceConfig, ...interfaceConfig },
|
||||
};
|
||||
if (!options.jwt) {
|
||||
delete options.jwt;
|
||||
}
|
||||
// Jitsi meet external API maintains some data in local storage
|
||||
// which is sent via the appData URL parameter when joining a
|
||||
// conference. Problem is that this data grows indefinitely. Thus
|
||||
// after some time the URLs get so huge that loading the iframe
|
||||
// becomes slow and eventually breaks completely. Thus lets just
|
||||
// clear jitsi local storage before starting a new conference.
|
||||
window.localStorage.removeItem("jitsiLocalStorage");
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const doResolve = (): void => {
|
||||
const iframe = cowebsiteDiv.querySelector<HTMLIFrameElement>('[id*="jitsi" i]');
|
||||
if (iframe === null) {
|
||||
throw new Error("Could not find Jitsi Iframe");
|
||||
}
|
||||
resolve(iframe);
|
||||
};
|
||||
options.onload = () => doResolve(); //we want for the iframe to be loaded before triggering animations.
|
||||
setTimeout(() => doResolve(), 2000); //failsafe in case the iframe is deleted before loading or too long to load
|
||||
this.jitsiApi = new window.JitsiMeetExternalAPI(domain, options);
|
||||
this.jitsiApi.executeCommand("displayName", playerName);
|
||||
const domain = jitsiUrl || JITSI_URL;
|
||||
if (domain === undefined) {
|
||||
throw new Error("Missing JITSI_URL environment variable or jitsiUrl parameter in the map.");
|
||||
}
|
||||
await this.loadJitsiScript(domain);
|
||||
|
||||
this.jitsiApi.addListener("audioMuteStatusChanged", this.audioCallback);
|
||||
this.jitsiApi.addListener("videoMuteStatusChanged", this.videoCallback);
|
||||
const options: JitsiOptions = {
|
||||
roomName: roomName,
|
||||
jwt: jwt,
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
parentNode: coWebsiteManager.getCoWebsiteBuffer(),
|
||||
configOverwrite: mergeConfig(config),
|
||||
interfaceConfigOverwrite: { ...defaultInterfaceConfig, ...interfaceConfig },
|
||||
};
|
||||
|
||||
if (!options.jwt) {
|
||||
delete options.jwt;
|
||||
}
|
||||
|
||||
const doResolve = (): void => {
|
||||
const iframe = coWebsiteManager.getCoWebsiteBuffer().querySelector<HTMLIFrameElement>('[id*="jitsi" i]');
|
||||
if (iframe && this.jitsiApi) {
|
||||
const coWebsite = coWebsiteManager.addCoWebsiteFromIframe(iframe, false, undefined, 0, false, true);
|
||||
|
||||
this.jitsiApi.addListener("videoConferenceLeft", () => {
|
||||
this.closeOrUnload(coWebsite);
|
||||
});
|
||||
},
|
||||
jitsiWidth,
|
||||
0
|
||||
);
|
||||
|
||||
this.jitsiApi.addListener("readyToClose", () => {
|
||||
this.closeOrUnload(coWebsite);
|
||||
});
|
||||
}
|
||||
|
||||
coWebsiteManager.resizeAllIframes();
|
||||
};
|
||||
|
||||
this.jitsiApi = undefined;
|
||||
|
||||
options.onload = () => doResolve(); //we want for the iframe to be loaded before triggering animations.
|
||||
setTimeout(() => doResolve(), 2000); //failsafe in case the iframe is deleted before loading or too long to load
|
||||
this.jitsiApi = new window.JitsiMeetExternalAPI(domain, options);
|
||||
this.jitsiApi.executeCommand("displayName", playerName);
|
||||
|
||||
this.jitsiApi.addListener("audioMuteStatusChanged", this.audioCallback);
|
||||
this.jitsiApi.addListener("videoMuteStatusChanged", this.videoCallback);
|
||||
}
|
||||
|
||||
private closeOrUnload = function (coWebsite: CoWebsite) {
|
||||
if (coWebsite.closable) {
|
||||
coWebsiteManager.closeCoWebsite(coWebsite).catch(() => {
|
||||
console.error("Error during closing a Jitsi Meet");
|
||||
});
|
||||
} else {
|
||||
coWebsiteManager.unloadCoWebsite(coWebsite).catch(() => {
|
||||
console.error("Error during unloading a Jitsi Meet");
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
public restart() {
|
||||
if (!this.jitsiApi) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.jitsiApi.addListener("audioMuteStatusChanged", this.audioCallback);
|
||||
this.jitsiApi.addListener("videoMuteStatusChanged", this.videoCallback);
|
||||
|
||||
const coWebsite = coWebsiteManager.searchJitsi();
|
||||
console.log("jitsi api ", this.jitsiApi);
|
||||
console.log("iframe cowebsite", coWebsite?.iframe);
|
||||
|
||||
if (!coWebsite) {
|
||||
this.destroy();
|
||||
return;
|
||||
}
|
||||
|
||||
this.jitsiApi.addListener("videoConferenceLeft", () => {
|
||||
this.closeOrUnload(coWebsite);
|
||||
});
|
||||
|
||||
this.jitsiApi.addListener("readyToClose", () => {
|
||||
this.closeOrUnload(coWebsite);
|
||||
});
|
||||
}
|
||||
|
||||
public stop() {
|
||||
@ -200,14 +250,16 @@ class JitsiFactory {
|
||||
return;
|
||||
}
|
||||
|
||||
const jitsiCoWebsite = coWebsiteManager.searchJitsi();
|
||||
|
||||
if (jitsiCoWebsite) {
|
||||
coWebsiteManager.closeJitsi().catch((e) => console.error(e));
|
||||
}
|
||||
|
||||
this.jitsiApi.removeListener("audioMuteStatusChanged", this.audioCallback);
|
||||
this.jitsiApi.removeListener("videoMuteStatusChanged", this.videoCallback);
|
||||
}
|
||||
|
||||
public destroy() {
|
||||
if (!this.jitsiApi) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.stop();
|
||||
this.jitsiApi?.dispose();
|
||||
}
|
||||
|
||||
|
@ -7,8 +7,7 @@ import { helpCameraSettingsVisibleStore } from "../Stores/HelpCameraSettingsStor
|
||||
export type StartScreenSharingCallback = (media: MediaStream) => void;
|
||||
export type StopScreenSharingCallback = (media: MediaStream) => void;
|
||||
|
||||
import { cowebsiteCloseButtonId } from "./CoWebsiteManager";
|
||||
import { gameOverlayVisibilityStore } from "../Stores/GameOverlayStoreVisibility";
|
||||
import { myCameraVisibilityStore } from "../Stores/MyCameraStoreVisibility";
|
||||
import { layoutManagerActionStore } from "../Stores/LayoutManagerStore";
|
||||
import { MediaStreamConstraintsError } from "../Stores/Errors/MediaStreamConstraintsError";
|
||||
import { localUserStore } from "../Connexion/LocalUserStore";
|
||||
@ -20,8 +19,6 @@ export class MediaManager {
|
||||
startScreenSharingCallBacks: Set<StartScreenSharingCallback> = new Set<StartScreenSharingCallback>();
|
||||
stopScreenSharingCallBacks: Set<StopScreenSharingCallback> = new Set<StopScreenSharingCallback>();
|
||||
|
||||
private triggerCloseJistiFrame: Map<String, Function> = new Map<String, Function>();
|
||||
|
||||
private userInputManager?: UserInputManager;
|
||||
|
||||
constructor() {
|
||||
@ -73,36 +70,12 @@ export class MediaManager {
|
||||
});
|
||||
}
|
||||
|
||||
public showGameOverlay(): void {
|
||||
const gameOverlay = HtmlUtils.getElementByIdOrFail("game-overlay");
|
||||
gameOverlay.classList.add("active");
|
||||
|
||||
const buttonCloseFrame = HtmlUtils.getElementByIdOrFail(cowebsiteCloseButtonId);
|
||||
const functionTrigger = () => {
|
||||
this.triggerCloseJitsiFrameButton();
|
||||
};
|
||||
buttonCloseFrame.removeEventListener("click", () => {
|
||||
buttonCloseFrame.blur();
|
||||
functionTrigger();
|
||||
});
|
||||
|
||||
gameOverlayVisibilityStore.showGameOverlay();
|
||||
public showMyCamera(): void {
|
||||
myCameraVisibilityStore.set(true);
|
||||
}
|
||||
|
||||
public hideGameOverlay(): void {
|
||||
const gameOverlay = HtmlUtils.getElementByIdOrFail("game-overlay");
|
||||
gameOverlay.classList.remove("active");
|
||||
|
||||
const buttonCloseFrame = HtmlUtils.getElementByIdOrFail(cowebsiteCloseButtonId);
|
||||
const functionTrigger = () => {
|
||||
this.triggerCloseJitsiFrameButton();
|
||||
};
|
||||
buttonCloseFrame.addEventListener("click", () => {
|
||||
buttonCloseFrame.blur();
|
||||
functionTrigger();
|
||||
});
|
||||
|
||||
gameOverlayVisibilityStore.hideGameOverlay();
|
||||
public hideMyCamera(): void {
|
||||
myCameraVisibilityStore.set(false);
|
||||
}
|
||||
|
||||
private getScreenSharingId(userId: string): string {
|
||||
@ -179,20 +152,6 @@ export class MediaManager {
|
||||
return connectingSpinnerDiv;
|
||||
}
|
||||
|
||||
public addTriggerCloseJitsiFrameButton(id: String, Function: Function) {
|
||||
this.triggerCloseJistiFrame.set(id, Function);
|
||||
}
|
||||
|
||||
public removeTriggerCloseJitsiFrameButton(id: String) {
|
||||
this.triggerCloseJistiFrame.delete(id);
|
||||
}
|
||||
|
||||
private triggerCloseJitsiFrameButton(): void {
|
||||
for (const callback of this.triggerCloseJistiFrame.values()) {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
public setUserInputManager(userInputManager: UserInputManager) {
|
||||
this.userInputManager = userInputManager;
|
||||
}
|
||||
|
@ -3,9 +3,9 @@ import type { RoomConnection } from "../Connexion/RoomConnection";
|
||||
import { MESSAGE_TYPE_CONSTRAINT, PeerStatus } from "./VideoPeer";
|
||||
import type { UserSimplePeerInterface } from "./SimplePeer";
|
||||
import { Readable, readable } from "svelte/store";
|
||||
import { videoFocusStore } from "../Stores/VideoFocusStore";
|
||||
import { getIceServersConfig } from "../Components/Video/utils";
|
||||
import { isMobile } from "../Enum/EnvironmentVariable";
|
||||
import { highlightedEmbedScreen } from "../Stores/EmbedScreensStore";
|
||||
import { isMediaBreakpointUp } from "../Utils/BreakpointsUtils";
|
||||
|
||||
const Peer: SimplePeerNamespace.SimplePeer = require("simple-peer");
|
||||
|
||||
@ -43,7 +43,10 @@ export class ScreenSharingPeer extends Peer {
|
||||
|
||||
this.streamStore = readable<MediaStream | null>(null, (set) => {
|
||||
const onStream = (stream: MediaStream | null) => {
|
||||
videoFocusStore.focus(this);
|
||||
highlightedEmbedScreen.highlight({
|
||||
type: "streamable",
|
||||
embed: this,
|
||||
});
|
||||
set(stream);
|
||||
};
|
||||
const onData = (chunk: Buffer) => {
|
||||
@ -177,7 +180,13 @@ export class ScreenSharingPeer extends Peer {
|
||||
public stopPushingScreenSharingToRemoteUser(stream: MediaStream) {
|
||||
this.removeStream(stream);
|
||||
this.write(
|
||||
new Buffer(JSON.stringify({ type: MESSAGE_TYPE_CONSTRAINT, streamEnded: true, isMobile: isMobile() }))
|
||||
new Buffer(
|
||||
JSON.stringify({
|
||||
type: MESSAGE_TYPE_CONSTRAINT,
|
||||
streamEnded: true,
|
||||
isMobile: isMediaBreakpointUp("md"),
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ export class SimplePeer {
|
||||
}
|
||||
);
|
||||
|
||||
mediaManager.showGameOverlay();
|
||||
mediaManager.showMyCamera();
|
||||
|
||||
//receive message start
|
||||
this.Connection.webRtcStartMessageStream.subscribe((message: UserSimplePeerInterface) => {
|
||||
|
@ -9,7 +9,7 @@ import { localStreamStore, obtainedMediaConstraintStore, ObtainedMediaStreamCons
|
||||
import { playersStore } from "../Stores/PlayersStore";
|
||||
import { chatMessagesStore, newChatMessageSubject } from "../Stores/ChatStore";
|
||||
import { getIceServersConfig } from "../Components/Video/utils";
|
||||
import { isMobile } from "../Enum/EnvironmentVariable";
|
||||
import { isMediaBreakpointUp } from "../Utils/BreakpointsUtils";
|
||||
|
||||
const Peer: SimplePeerNamespace.SimplePeer = require("simple-peer");
|
||||
|
||||
@ -202,7 +202,7 @@ export class VideoPeer extends Peer {
|
||||
JSON.stringify({
|
||||
type: MESSAGE_TYPE_CONSTRAINT,
|
||||
...constraints,
|
||||
isMobile: isMobile(),
|
||||
isMobile: isMediaBreakpointUp("md"),
|
||||
})
|
||||
)
|
||||
);
|
||||
|
@ -11,7 +11,7 @@ const error: NonNullable<Translation["error"]> = {
|
||||
title: "Verbindungen zurückgewiesen",
|
||||
subTitle: "Du kannst diese Welt nicht betreten. Versuche es später noch einmal {error}.",
|
||||
details:
|
||||
"Für weitere Information kannst du die Administratoren kontaktieren oder melde dich bei uns unter: prty.bstly.de",
|
||||
"Für weitere Information kannst du die Administratoren kontaktieren oder melde dich bei uns unter: prty@bstly.de",
|
||||
},
|
||||
connectionRetry: {
|
||||
unableConnect:
|
||||
|
@ -4,15 +4,15 @@ import audio from "./audio";
|
||||
import camera from "./camera";
|
||||
import chat from "./chat";
|
||||
import companion from "./companion";
|
||||
import emoji from "./emoji";
|
||||
import error from "./error";
|
||||
import follow from "./follow";
|
||||
import login from "./login";
|
||||
import menu from "./menu";
|
||||
import message from "./message";
|
||||
import menu from "./menu";
|
||||
import report from "./report";
|
||||
import warning from "./warning";
|
||||
import woka from "./woka";
|
||||
import emoji from "./emoji";
|
||||
|
||||
const de_DE: Translation = {
|
||||
...en_US,
|
||||
|
@ -2,7 +2,7 @@ import "phaser";
|
||||
import GameConfig = Phaser.Types.Core.GameConfig;
|
||||
import "../style/index.scss";
|
||||
|
||||
import { DEBUG_MODE, isMobile } from "./Enum/EnvironmentVariable";
|
||||
import { DEBUG_MODE } from "./Enum/EnvironmentVariable";
|
||||
import { LoginScene } from "./Phaser/Login/LoginScene";
|
||||
import { ReconnectingScene } from "./Phaser/Reconnecting/ReconnectingScene";
|
||||
import { SelectCharacterScene } from "./Phaser/Login/SelectCharacterScene";
|
||||
@ -24,6 +24,7 @@ import App from "./Components/App.svelte";
|
||||
import { HtmlUtils } from "./WebRtc/HtmlUtils";
|
||||
import WebGLRenderer = Phaser.Renderer.WebGL.WebGLRenderer;
|
||||
import { analyticsClient } from "./Administration/AnalyticsClient";
|
||||
import { isMediaBreakpointUp } from "./Utils/BreakpointsUtils";
|
||||
|
||||
const { width, height } = coWebsiteManager.getGameSize();
|
||||
const valueGameQuality = localUserStore.getGameQualityValue();
|
||||
@ -90,7 +91,7 @@ const config: GameConfig = {
|
||||
scene: [
|
||||
EntryScene,
|
||||
LoginScene,
|
||||
isMobile() ? SelectCharacterMobileScene : SelectCharacterScene,
|
||||
isMediaBreakpointUp("md") ? SelectCharacterMobileScene : SelectCharacterScene,
|
||||
SelectCompanionScene,
|
||||
EnableCameraScene,
|
||||
ReconnectingScene,
|
||||
@ -136,7 +137,6 @@ const config: GameConfig = {
|
||||
},
|
||||
};
|
||||
|
||||
//const game = new Phaser.Game(config);
|
||||
const game = new Game(config);
|
||||
|
||||
waScaleManager.setGame(game);
|
||||
@ -156,7 +156,7 @@ coWebsiteManager.onResize.subscribe(() => {
|
||||
iframeListener.init();
|
||||
|
||||
const app = new App({
|
||||
target: HtmlUtils.getElementByIdOrFail("svelte-overlay"),
|
||||
target: HtmlUtils.getElementByIdOrFail("game-overlay"),
|
||||
props: {
|
||||
game: game,
|
||||
},
|
||||
|
@ -30,7 +30,7 @@ section.section-input-send-text {
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px), only screen and (max-height: 800px) {
|
||||
@include media-breakpoint-up(md) {
|
||||
section.section-input-send-text {
|
||||
--height-toolbar: 30%;
|
||||
|
||||
|
102
front/style/breakpoints.scss
Normal file
102
front/style/breakpoints.scss
Normal file
@ -0,0 +1,102 @@
|
||||
@use "sass:map";
|
||||
|
||||
// If you modify this breakpoints don't forget to change it also in TS utils.
|
||||
$grid-breakpoints: (
|
||||
xs: 0,
|
||||
sm: 576px,
|
||||
md: 768px,
|
||||
lg: 992px,
|
||||
xl: 1200px,
|
||||
xxl: 1400px
|
||||
);
|
||||
|
||||
@function get-upper-breakpoint($breakpoint) {
|
||||
@return map-get((
|
||||
xs: map.get($grid-breakpoints, "sm"),
|
||||
sm: map.get($grid-breakpoints, "md"),
|
||||
md: map.get($grid-breakpoints, "lg"),
|
||||
lg: map.get($grid-breakpoints, "xl"),
|
||||
xl: map.get($grid-breakpoints, "xxl"),
|
||||
xxl: null,
|
||||
), $breakpoint);
|
||||
}
|
||||
|
||||
@function get-under-breakpoint($breakpoint) {
|
||||
@return map-get((
|
||||
xs: null,
|
||||
sm: map.get($grid-breakpoints, "xs"),
|
||||
md: map.get($grid-breakpoints, "sm"),
|
||||
lg: map.get($grid-breakpoints, "md"),
|
||||
xl: map.get($grid-breakpoints, "lg"),
|
||||
xxl: map.get($grid-breakpoints, "xl"),
|
||||
), $breakpoint);
|
||||
}
|
||||
|
||||
@mixin media-breakpoint-up($upTo) {
|
||||
@if $upTo == 'xxl' {
|
||||
@media only screen {
|
||||
@content;
|
||||
}
|
||||
} @else {
|
||||
$value: get-upper-breakpoint($upTo);
|
||||
|
||||
@if $value != null {
|
||||
$value: $value - 1px;
|
||||
@media only screen and (max-width: $value) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin media-breakpoint-down($downFrom) {
|
||||
@if $downFrom == 'xs' {
|
||||
@media only screen {
|
||||
@content;
|
||||
}
|
||||
} @else {
|
||||
$value: map.get($grid-breakpoints, $downFrom);
|
||||
|
||||
@if $value != null {
|
||||
@media only screen and (min-width: $value) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin media-breakpoint-only($only) {
|
||||
$maxValue: get-upper-breakpoint($only);
|
||||
$minValue: map.get($grid-breakpoints, $only);
|
||||
|
||||
@if $minValue == null {
|
||||
|
||||
} @else if $maxValue != null {
|
||||
$maxValue: $maxValue - 1px;
|
||||
@media only screen and (min-width: $minValue) and (max-width: $maxValue) {
|
||||
@content;
|
||||
}
|
||||
} @else {
|
||||
@media only screen and (min-width: $minValue) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin media-breakpoint-between($start, $end) {
|
||||
$maxValue: get-upper-breakpoint($end);
|
||||
$minValue: map.get($grid-breakpoints, $start);
|
||||
|
||||
@if $minValue == null {
|
||||
|
||||
} @else if $maxValue != null {
|
||||
$maxValue: $maxValue - 1px;
|
||||
@media only screen and (min-width: $minValue) and (max-width: $maxValue) {
|
||||
@content;
|
||||
}
|
||||
} @else {
|
||||
@media only screen and (min-width: $minValue) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
@media (max-aspect-ratio: 1/1) {
|
||||
|
||||
#main-container {
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
|
||||
|
||||
#cowebsite {
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
|
||||
&.loading {
|
||||
transform: translateY(-90%);
|
||||
}
|
||||
&.hidden {
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
|
||||
main {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
aside {
|
||||
height: 50px;
|
||||
cursor: ns-resize;
|
||||
flex-direction: row-reverse;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
#cowebsite-aside-holder {
|
||||
pointer-events: none;
|
||||
height: 100%;
|
||||
|
||||
img {
|
||||
height: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
#cowebsite-sub-icons {
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 0;
|
||||
height: 100%;
|
||||
visibility: visible;
|
||||
|
||||
img {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
cursor: pointer !important;
|
||||
border-radius: 50%;
|
||||
background-color: whitesmoke;
|
||||
}
|
||||
|
||||
&>div {
|
||||
display: flex;
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
#cowebsite-aside-buttons {
|
||||
flex-direction: row-reverse;
|
||||
margin-left: auto;
|
||||
margin-bottom: 0;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
img {
|
||||
cursor: ns-resize;
|
||||
}
|
||||
|
||||
#cowebsite-fullscreen {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.top-right-btn {
|
||||
img {
|
||||
width: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width:960px) and (max-height:768px) {
|
||||
#cowebsite {
|
||||
|
||||
&-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
aside {
|
||||
#cowebsite-sub-icons {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 0;
|
||||
height: 100%;
|
||||
visibility: visible;
|
||||
|
||||
img {
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
cursor: pointer !important;
|
||||
border-radius: 50%;
|
||||
background-color: whitesmoke;
|
||||
}
|
||||
|
||||
&>div {
|
||||
display: flex;
|
||||
margin-top: 2px;
|
||||
margin-bottom: 2px;
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
cursor: ns-resize;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,220 +1,3 @@
|
||||
/* A potentially shared website could appear in an iframe in the cowebsite space. */
|
||||
|
||||
#cowebsite {
|
||||
position: fixed;
|
||||
z-index: 200;
|
||||
transition: transform 0.5s;
|
||||
background-color: whitesmoke;
|
||||
display: none;
|
||||
|
||||
&.loading {
|
||||
background-color: gray;
|
||||
}
|
||||
|
||||
main {
|
||||
iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 100vw;
|
||||
max-height: 100vh;
|
||||
}
|
||||
}
|
||||
|
||||
aside {
|
||||
background: gray;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
#cowebsite-aside-holder {
|
||||
background: gray;
|
||||
height: 20px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
|
||||
img {
|
||||
width: 80%;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
#cowebsite-aside-buttons {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: auto;
|
||||
flex: 1;
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
.top-right-btn{
|
||||
transform: scale(0.5);
|
||||
cursor: url('./images/cursor_pointer.png'), pointer;
|
||||
}
|
||||
|
||||
#cowebsite-sub-icons {
|
||||
display: flex;
|
||||
margin-top: auto;
|
||||
visibility: hidden;
|
||||
justify-content: end;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&-container {
|
||||
position: absolute;
|
||||
display: none;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
&-main {
|
||||
padding: 2% 5%;
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
&-sub {
|
||||
position: absolute !important;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
bottom: 23%;
|
||||
height: 20% !important;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&-slot-0 {
|
||||
z-index: 70 !important;
|
||||
background-color: whitesmoke;
|
||||
}
|
||||
|
||||
@for $i from 1 through 4 {
|
||||
&-slot-#{$i} {
|
||||
transition: transform 0.5s;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
display: none;
|
||||
background-color: #333333;
|
||||
|
||||
@if $i == 1 {
|
||||
width: 100%;
|
||||
} @else {
|
||||
width: 33%;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 50;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.actions-move {
|
||||
display: none;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
gap: 10%;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: rgba($color: #333333, $alpha: 0.6);
|
||||
|
||||
.actions-move {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
pointer-events: all !important;
|
||||
margin: 3% 2%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: end;
|
||||
position: relative;
|
||||
z-index: 50;
|
||||
|
||||
button {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin: 8px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-buffer {
|
||||
iframe {
|
||||
z-index: 45 !important;
|
||||
pointer-events: none !important;
|
||||
overflow: hidden;
|
||||
border: 0;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.main {
|
||||
pointer-events: all !important;
|
||||
z-index: 205 !important;
|
||||
}
|
||||
|
||||
.sub-main {
|
||||
pointer-events: all !important;
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
transform: scale(0.5, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
.pixel {
|
||||
visibility: hidden;
|
||||
height: 1px;
|
||||
width: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-aspect-ratio: 1/1) {
|
||||
#cowebsite {
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 50%;
|
||||
height: 100vh;
|
||||
display: none;
|
||||
|
||||
&.loading {
|
||||
transform: translateX(90%);
|
||||
}
|
||||
&.hidden {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
main {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
aside {
|
||||
width: 30px;
|
||||
|
||||
img {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
&-aside-holder {
|
||||
cursor: ew-resize;
|
||||
}
|
||||
}
|
||||
}
|
||||
@import "cowebsite/global";
|
||||
@import "cowebsite/short-screens";
|
||||
@import "cowebsite/wide-screens";
|
||||
|
126
front/style/cowebsite/_global.scss
Normal file
126
front/style/cowebsite/_global.scss
Normal file
@ -0,0 +1,126 @@
|
||||
#cowebsite {
|
||||
position: fixed;
|
||||
z-index: 820;
|
||||
transition: transform 0.5s;
|
||||
background-color: rgba(10, 9, 9, 0.8);
|
||||
display: none;
|
||||
|
||||
main {
|
||||
iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
max-width: 100vw;
|
||||
max-height: 100vh;
|
||||
}
|
||||
}
|
||||
|
||||
aside {
|
||||
background: gray;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
#cowebsite-aside-holder {
|
||||
background: gray;
|
||||
height: 20px;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
|
||||
img {
|
||||
width: 80%;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
#cowebsite-aside-buttons {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: auto;
|
||||
flex: 1;
|
||||
justify-content: start;
|
||||
|
||||
#cowebsite-swipe {
|
||||
display: none;
|
||||
img {
|
||||
transform: rotate(0deg) !important;
|
||||
transform: scale(0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.top-right-btn {
|
||||
transform: scale(0.5);
|
||||
}
|
||||
|
||||
#cowebsite-other-actions {
|
||||
display: flex;
|
||||
margin-top: auto;
|
||||
visibility: hidden;
|
||||
justify-content: end;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&-loader {
|
||||
width: 20%;
|
||||
|
||||
#smoke {
|
||||
@for $i from 1 through 3 {
|
||||
#trail-#{$i} {
|
||||
@for $y from 1 through 3 {
|
||||
#trail-#{$i}-state-#{$y} {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-slot-main {
|
||||
z-index: 70 !important;
|
||||
background-color: rgba(10, 9, 9, 0);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&-buffer {
|
||||
iframe {
|
||||
z-index: 45 !important;
|
||||
pointer-events: none !important;
|
||||
overflow: hidden;
|
||||
border: 0;
|
||||
position: absolute;
|
||||
|
||||
&.pixel {
|
||||
height: 1px !important;
|
||||
width: 1px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
pointer-events: all !important;
|
||||
z-index: 821 !important;
|
||||
}
|
||||
|
||||
.highlighted {
|
||||
pointer-events: all !important;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
transform: scale(0.5, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
.pixel {
|
||||
visibility: hidden;
|
||||
height: 1px;
|
||||
width: 1px;
|
||||
}
|
||||
}
|
84
front/style/cowebsite/_short-screens.scss
Normal file
84
front/style/cowebsite/_short-screens.scss
Normal file
@ -0,0 +1,84 @@
|
||||
@include media-breakpoint-up(md) {
|
||||
#main-container {
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
|
||||
#cowebsite {
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 50%;
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
|
||||
visibility: collapse;
|
||||
transform: translateY(-100%);
|
||||
|
||||
&.loading {
|
||||
visibility: visible;
|
||||
transform: translateY(0%);
|
||||
}
|
||||
|
||||
&.opened {
|
||||
visibility: visible;
|
||||
transform: translateY(0%);
|
||||
}
|
||||
|
||||
&.closing {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
&-loader {
|
||||
height: 20%;
|
||||
}
|
||||
|
||||
main {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
aside {
|
||||
height: 50px;
|
||||
flex-direction: row-reverse;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
#cowebsite-aside-holder {
|
||||
height: 100%;
|
||||
cursor: ns-resize;
|
||||
|
||||
img {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
#cowebsite-aside-buttons {
|
||||
flex-direction: row-reverse;
|
||||
margin-left: auto;
|
||||
margin-bottom: 0;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
#cowebsite-fullscreen {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
#cowebsite-other-actions {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 0;
|
||||
height: 100%;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.top-right-btn {
|
||||
img {
|
||||
width: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
41
front/style/cowebsite/_wide-screens.scss
Normal file
41
front/style/cowebsite/_wide-screens.scss
Normal file
@ -0,0 +1,41 @@
|
||||
@include media-breakpoint-down(lg) {
|
||||
#cowebsite {
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 50%;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
visibility: collapse;
|
||||
transform: translateX(100%);
|
||||
|
||||
&.loading {
|
||||
visibility: visible;
|
||||
transform: translateX(0%);
|
||||
}
|
||||
|
||||
&.opened {
|
||||
visibility: visible;
|
||||
transform: translateX(0%);
|
||||
}
|
||||
|
||||
&.closing {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
main {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
aside {
|
||||
width: 30px;
|
||||
|
||||
img {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
&-aside-holder {
|
||||
cursor: ew-resize;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +1,5 @@
|
||||
@import "~@fontsource/press-start-2p/index.css";
|
||||
|
||||
@font-face {
|
||||
font-family: "Twemoji Mozilla";
|
||||
src: url("./fonts/TwemojiMozilla.ttf") format('truetype');
|
||||
}
|
||||
|
||||
*{
|
||||
font-family: "Press Start 2P",monospace;
|
||||
}
|
||||
|
Binary file not shown.
@ -1,9 +1,9 @@
|
||||
@import "~nes.css/css/nes.min.css";
|
||||
@import "nes.custom.css";
|
||||
@import "quill.snow.css";
|
||||
@charset 'UTF-8';
|
||||
@import "breakpoints";
|
||||
@import "cowebsite.scss";
|
||||
@import "cowebsite-mobile.scss";
|
||||
@import "style";
|
||||
@import "mobile-style.scss";
|
||||
@import "fonts.scss";
|
||||
@import "style";
|
||||
@import "TextGlobalMessageSvelte-Style";
|
||||
|
@ -1,48 +0,0 @@
|
||||
@media (hover: none) {
|
||||
/**
|
||||
* If we cannot hover over elements, let's display camera button in full.
|
||||
*/
|
||||
.btn-cam-action {
|
||||
div {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 700px),
|
||||
screen and (max-height: 700px){
|
||||
video.myCamVideo {
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.div-myCamVideo.hide {
|
||||
right: -160px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 20%;
|
||||
min-width: 200px;
|
||||
position: absolute;
|
||||
display: block;
|
||||
right: 0;
|
||||
height: 80%;
|
||||
|
||||
&> div {
|
||||
min-width: 200px;
|
||||
max-height: 21vh;
|
||||
}
|
||||
|
||||
.video-container{
|
||||
min-width: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
.main-section {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
|
||||
& > div {
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
}
|
@ -32,14 +32,16 @@ body .message-info.warning{
|
||||
}
|
||||
|
||||
.video-container {
|
||||
position: relative;
|
||||
display: flex;
|
||||
transition: all 0.2s ease;
|
||||
height: 100%;
|
||||
|
||||
width: 100%;
|
||||
|
||||
video {
|
||||
height: fit-content;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
|
||||
&.mobile{
|
||||
width: 100%;
|
||||
@ -130,31 +132,6 @@ body .message-info.warning{
|
||||
}
|
||||
}
|
||||
|
||||
.video-container.div-myCamVideo{
|
||||
border: none;
|
||||
}
|
||||
|
||||
.div-myCamVideo {
|
||||
position: absolute !important;
|
||||
right: 15px;
|
||||
bottom: 30px;
|
||||
max-height: 20%;
|
||||
transition: right 350ms;
|
||||
}
|
||||
|
||||
.div-myCamVideo.hide {
|
||||
right: -20vw;
|
||||
}
|
||||
|
||||
video.myCamVideo{
|
||||
max-height: 20vh;
|
||||
width: 15vw;
|
||||
-webkit-transform: scaleX(-1);
|
||||
transform: scaleX(-1);
|
||||
/*width: 200px;*/
|
||||
/*height: 113px;*/
|
||||
}
|
||||
|
||||
.sound-progress{
|
||||
display: none;
|
||||
position: absolute;
|
||||
@ -191,89 +168,6 @@ video.myCamVideo{
|
||||
top: calc(50% - 20px);
|
||||
}
|
||||
|
||||
.btn-cam-action {
|
||||
pointer-events: all;
|
||||
position: absolute;
|
||||
display: inline-flex;
|
||||
bottom: 10px;
|
||||
right: 15px;
|
||||
width: 240px;
|
||||
height: 40px;
|
||||
text-align: center;
|
||||
align-content: center;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
justify-items: center;
|
||||
}
|
||||
/*btn animation*/
|
||||
.btn-cam-action div{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
transform: translateY(15px);
|
||||
transition-timing-function: ease-in-out;
|
||||
margin: 0 4%;
|
||||
}
|
||||
.btn-cam-action div.disabled {
|
||||
background: #d75555;
|
||||
}
|
||||
.btn-cam-action div.enabled {
|
||||
background: #73c973;
|
||||
}
|
||||
.btn-cam-action:hover div{
|
||||
transform: translateY(0);
|
||||
}
|
||||
.btn-cam-action div:hover{
|
||||
background: #407cf7;
|
||||
box-shadow: 4px 4px 48px #666;
|
||||
transition: 120ms;
|
||||
}
|
||||
.btn-micro{
|
||||
pointer-events: auto;
|
||||
transition: all .3s;
|
||||
/*right: 44px;*/
|
||||
}
|
||||
.btn-video{
|
||||
pointer-events: auto;
|
||||
transition: all .25s;
|
||||
/*right: 134px;*/
|
||||
}
|
||||
.btn-monitor{
|
||||
pointer-events: auto;
|
||||
transition: all .2s;
|
||||
/*right: 224px;*/
|
||||
}
|
||||
.btn-monitor.hide {
|
||||
transform: translateY(60px);
|
||||
}
|
||||
.btn-cam-action:hover .btn-monitor.hide{
|
||||
transform: translateY(60px);
|
||||
}
|
||||
.btn-layout{
|
||||
pointer-events: auto;
|
||||
transition: all .15s;
|
||||
}
|
||||
.btn-layout.hide {
|
||||
transform: translateY(60px);
|
||||
}
|
||||
.btn-cam-action:hover .btn-layout.hide{
|
||||
transform: translateY(60px);
|
||||
}
|
||||
.btn-copy{
|
||||
pointer-events: auto;
|
||||
transition: all .3s;
|
||||
right: 44px;
|
||||
opacity: 1;
|
||||
}
|
||||
.btn-cam-action div img{
|
||||
height: 22px;
|
||||
width: 30px;
|
||||
position: relative;
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
/* Spinner */
|
||||
.connecting-spinner {
|
||||
/*display: inline-block;*/
|
||||
@ -344,26 +238,6 @@ body {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
@media (min-aspect-ratio: 1/1) {
|
||||
.game-overlay {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.sidebar > div {
|
||||
max-height: 21%;
|
||||
}
|
||||
|
||||
.sidebar > div:hover {
|
||||
max-height: 25%;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#game {
|
||||
position: relative; /* Position relative is needed for the game-overlay. */
|
||||
|
||||
@ -461,89 +335,6 @@ input[type=range]:focus::-ms-fill-upper {
|
||||
background: #FFFFFF;
|
||||
}
|
||||
|
||||
|
||||
.game-overlay {
|
||||
display: none;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
/* TODO: DO WE NEED FLEX HERE???? WE WANT A SIDEBAR OF EXACTLY 25% (note: flex useful for direction!!!) */
|
||||
}
|
||||
|
||||
.game-overlay + div {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.game-overlay + div > div {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.game-overlay.active {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.game-overlay video {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.main-section {
|
||||
flex: 0 0 75%;
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
align-items: flex-start;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.main-section > div {
|
||||
margin: 2%;
|
||||
flex-basis: 96%;
|
||||
transition: margin-left 0.2s, margin-right 0.2s, margin-bottom 0.2s, margin-top 0.2s, flex-basis 0.2s;
|
||||
pointer-events: auto;
|
||||
/*flex-shrink: 2;*/
|
||||
}
|
||||
|
||||
.main-section > div:hover {
|
||||
margin: 0%;
|
||||
flex-basis: 100%;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
flex: 0 0 25%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.sidebar > div {
|
||||
margin: 2%;
|
||||
transition: margin-left 0.2s, margin-right 0.2s, margin-bottom 0.2s, margin-top 0.2s, max-height 0.2s, max-width 0.2s;
|
||||
pointer-events: auto;
|
||||
|
||||
video {
|
||||
max-height: 21vh;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar > div:hover {
|
||||
margin: 0%;
|
||||
}
|
||||
|
||||
|
||||
/* Let's make sure videos are vertically centered if they need to be cropped */
|
||||
.media-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.chat-mode {
|
||||
display: grid;
|
||||
width: 100%;
|
||||
|
||||
align-items: flex-start;
|
||||
|
||||
padding: 1%;
|
||||
}
|
||||
|
||||
.chat-mode > div {
|
||||
margin: 1%;
|
||||
max-height: 96%;
|
||||
@ -1020,13 +811,22 @@ div.action.danger p.action-body{
|
||||
}
|
||||
|
||||
|
||||
#svelte-overlay {
|
||||
#game-overlay {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
|
||||
& + div {
|
||||
pointer-events: none;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
& + div > div {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
& > div {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
@ -1044,19 +844,10 @@ div.action.danger p.action-body{
|
||||
pointer-events: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div.is-silent {
|
||||
position: absolute !important;
|
||||
bottom: 40px;
|
||||
max-height: 20%;
|
||||
transition: right 350ms;
|
||||
right: -1000px;
|
||||
font-size: 20px;
|
||||
padding: 30px 20px;
|
||||
}
|
||||
div.is-silent.hide {
|
||||
right: 15px;
|
||||
&.hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1085,11 +876,6 @@ div.is-silent.hide {
|
||||
supported by Chrome, Edge, Opera and Firefox */
|
||||
}
|
||||
|
||||
.pixel {
|
||||
height: 1px !important;
|
||||
width: 1px !important;
|
||||
}
|
||||
|
||||
.emote-menu .emoji-picker .emoji-picker__emoji {
|
||||
font-family: 'Twemoji Mozilla' !important;
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -x
|
||||
set -o nounset errexit
|
||||
template_file_index=dist/index.tmpl.html
|
||||
generated_file_index=dist/index.tmpl.html.tmp
|
||||
index_file=dist/index.html
|
||||
tmp_trackcodefile=/tmp/trackcode
|
||||
|
||||
# To inject tracking code, you have two choices:
|
||||
@ -21,6 +20,6 @@ if [[ "${GA_TRACKING_ID:-}" != "" || "${INSERT_ANALYTICS:-NO}" != "NO" ]]; then
|
||||
sed "s#<!-- TRACKING NUMBER -->#${GA_TRACKING_ID:-}#g" "${ANALYTICS_CODE_PATH}" > "$tmp_trackcodefile"
|
||||
fi
|
||||
|
||||
echo "Templating ${generated_file_index} from ${template_file_index}"
|
||||
sed "/<!-- TRACK CODE -->/r ${tmp_trackcodefile}" "${template_file_index}" > "${generated_file_index}"
|
||||
echo "Templating ${index_file}"
|
||||
sed --in-place "/<!-- TRACK CODE -->/r ${tmp_trackcodefile}" "${index_file}"
|
||||
rm "${tmp_trackcodefile}"
|
||||
|
@ -1,6 +1,8 @@
|
||||
import ForkTsCheckerWebpackPlugin from "fork-ts-checker-webpack-plugin";
|
||||
import fs from 'fs/promises';
|
||||
import HtmlWebpackPlugin from "html-webpack-plugin";
|
||||
import MiniCssExtractPlugin from "mini-css-extract-plugin";
|
||||
import CssMinimizerPlugin from "css-minimizer-webpack-plugin";
|
||||
import NodePolyfillPlugin from "node-polyfill-webpack-plugin";
|
||||
import path from "path";
|
||||
import sveltePreprocess from "svelte-preprocess";
|
||||
@ -33,6 +35,35 @@ module.exports = {
|
||||
disableDotRule: true,
|
||||
},
|
||||
liveReload: process.env.LIVE_RELOAD != "0" && process.env.LIVE_RELOAD != "false",
|
||||
before: (app) => {
|
||||
let appConfigContent = '';
|
||||
const TEMPLATE_PATH = path.join(__dirname, 'dist', 'env-config.template.js');
|
||||
|
||||
function renderTemplateWithEnvVars(content: string): string {
|
||||
let result = content;
|
||||
const regex = /\$\{([a-zA-Z_]+[a-zA-Z0-9_]*?)\}/g;
|
||||
|
||||
let matched: RegExpExecArray | null;
|
||||
while ((matched = regex.exec(content))) {
|
||||
result = result.replace(`\${${matched[1]}}`, process.env[matched[1]] || '');
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void (async () => {
|
||||
const content = (await fs.readFile(TEMPLATE_PATH)).toString();
|
||||
appConfigContent = renderTemplateWithEnvVars(content);
|
||||
})();
|
||||
|
||||
app.get('/env-config.js', (_, response) => {
|
||||
response.setHeader('Content-Type', 'application/javascript; charset=utf-8');
|
||||
response.setHeader('Cache-Control', 'no-cache');
|
||||
response.setHeader('Content-Length', Buffer.byteLength(appConfigContent, 'utf8'));
|
||||
|
||||
response.send(appConfigContent);
|
||||
});
|
||||
},
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
@ -49,33 +80,9 @@ module.exports = {
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
test: /\.(sc|c)ss$/,
|
||||
exclude: /node_modules/,
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
{
|
||||
loader: "css-loader",
|
||||
options: {
|
||||
//url: false,
|
||||
sourceMap: true,
|
||||
},
|
||||
},
|
||||
"sass-loader",
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
exclude: /node_modules/,
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
{
|
||||
loader: "css-loader",
|
||||
options: {
|
||||
//url: false,
|
||||
sourceMap: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
|
||||
},
|
||||
{
|
||||
test: /\.(html|svelte)$/,
|
||||
@ -155,6 +162,10 @@ module.exports = {
|
||||
extensions: [".tsx", ".ts", ".js", ".svelte"],
|
||||
mainFields: ["svelte", "browser", "module", "main"],
|
||||
},
|
||||
optimization: {
|
||||
minimize: isProduction,
|
||||
minimizer: [new CssMinimizerPlugin(), "..."],
|
||||
},
|
||||
output: {
|
||||
filename: (pathData) => {
|
||||
// Add a content hash only for the main bundle.
|
||||
@ -173,7 +184,7 @@ module.exports = {
|
||||
}),
|
||||
new MiniCssExtractPlugin({ filename: "[name].[contenthash].css" }),
|
||||
new HtmlWebpackPlugin({
|
||||
template: "./dist/index.tmpl.html.tmp",
|
||||
template: "./dist/index.ejs",
|
||||
minify: {
|
||||
collapseWhitespace: true,
|
||||
keepClosingSlash: true,
|
||||
@ -189,33 +200,5 @@ module.exports = {
|
||||
Phaser: "phaser",
|
||||
}),
|
||||
new NodePolyfillPlugin(),
|
||||
new webpack.EnvironmentPlugin({
|
||||
API_URL: null,
|
||||
SKIP_RENDER_OPTIMIZATIONS: false,
|
||||
DISABLE_NOTIFICATIONS: false,
|
||||
PUSHER_URL: undefined,
|
||||
UPLOADER_URL: null,
|
||||
ADMIN_URL: null,
|
||||
CONTACT_URL: null,
|
||||
PROFILE_URL: null,
|
||||
ICON_URL: null,
|
||||
DEBUG_MODE: null,
|
||||
STUN_SERVER: null,
|
||||
TURN_SERVER: null,
|
||||
TURN_USER: null,
|
||||
TURN_PASSWORD: null,
|
||||
JITSI_URL: null,
|
||||
JITSI_PRIVATE_MODE: null,
|
||||
START_ROOM_URL: null,
|
||||
MAX_USERNAME_LENGTH: 8,
|
||||
MAX_PER_GROUP: 4,
|
||||
DISPLAY_TERMS_OF_USE: false,
|
||||
POSTHOG_API_KEY: null,
|
||||
POSTHOG_URL: null,
|
||||
NODE_ENV: mode,
|
||||
DISABLE_ANONYMOUS: false,
|
||||
OPID_LOGIN_SCREEN_PROVIDER: null,
|
||||
FALLBACK_LANGUAGE: null,
|
||||
}),
|
||||
],
|
||||
} as Configuration & WebpackDevServer.Configuration;
|
||||
|
535
front/yarn.lock
535
front/yarn.lock
@ -208,6 +208,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.12.0.tgz#b7395688a79403c6df8d8bb8d81deb8222519853"
|
||||
integrity sha512-urtgLzE4EDMAYQHYdkgC0Ei9QvLajodK1ntg71bGn0Pm84QUpaqpPDfHRU+i6jLeteyC7kWwa5O5W1m/jrjGXA==
|
||||
|
||||
"@trysound/sax@0.2.0":
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad"
|
||||
integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==
|
||||
|
||||
"@tsconfig/node10@^1.0.7":
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9"
|
||||
@ -774,11 +779,25 @@ ajv-errors@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d"
|
||||
integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==
|
||||
|
||||
ajv-formats@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520"
|
||||
integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==
|
||||
dependencies:
|
||||
ajv "^8.0.0"
|
||||
|
||||
ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2:
|
||||
version "3.5.2"
|
||||
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d"
|
||||
integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==
|
||||
|
||||
ajv-keywords@^5.0.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16"
|
||||
integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.3"
|
||||
|
||||
ajv@^6.1.0, ajv@^6.10.0, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5:
|
||||
version "6.12.6"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
|
||||
@ -789,6 +808,21 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5:
|
||||
json-schema-traverse "^0.4.1"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
ajv@^8.0.0, ajv@^8.8.0:
|
||||
version "8.8.2"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.8.2.tgz#01b4fef2007a28bf75f0b7fc009f62679de4abbb"
|
||||
integrity sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.1"
|
||||
json-schema-traverse "^1.0.0"
|
||||
require-from-string "^2.0.2"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
alphanum-sort@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
|
||||
integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=
|
||||
|
||||
ansi-colors@^3.0.0:
|
||||
version "3.2.4"
|
||||
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf"
|
||||
@ -1212,6 +1246,17 @@ browserify-zlib@^0.2.0:
|
||||
dependencies:
|
||||
pako "~1.0.5"
|
||||
|
||||
browserslist@^4.0.0, browserslist@^4.16.0, browserslist@^4.16.6:
|
||||
version "4.19.1"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3"
|
||||
integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==
|
||||
dependencies:
|
||||
caniuse-lite "^1.0.30001286"
|
||||
electron-to-chromium "^1.4.17"
|
||||
escalade "^3.1.1"
|
||||
node-releases "^2.0.1"
|
||||
picocolors "^1.0.0"
|
||||
|
||||
browserslist@^4.14.5:
|
||||
version "4.16.6"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2"
|
||||
@ -1307,6 +1352,21 @@ camelcase@^6.2.0:
|
||||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.2.0.tgz#924af881c9d525ac9d87f40d964e5cea982a1809"
|
||||
integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
|
||||
|
||||
caniuse-api@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0"
|
||||
integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==
|
||||
dependencies:
|
||||
browserslist "^4.0.0"
|
||||
caniuse-lite "^1.0.0"
|
||||
lodash.memoize "^4.1.2"
|
||||
lodash.uniq "^4.5.0"
|
||||
|
||||
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001286:
|
||||
version "1.0.30001292"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001292.tgz#4a55f61c06abc9595965cfd77897dc7bc1cdc456"
|
||||
integrity sha512-jnT4Tq0Q4ma+6nncYQVe7d73kmDmE9C3OGTx3MvW7lBM/eY1S1DZTMBON7dqV481RhNiS5OxD7k9JQvmDOTirw==
|
||||
|
||||
caniuse-lite@^1.0.30001219:
|
||||
version "1.0.30001228"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz#bfdc5942cd3326fa51ee0b42fbef4da9d492a7fa"
|
||||
@ -1483,6 +1543,11 @@ color-name@~1.1.4:
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
colord@^2.9.1:
|
||||
version "2.9.2"
|
||||
resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.2.tgz#25e2bacbbaa65991422c07ea209e2089428effb1"
|
||||
integrity sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==
|
||||
|
||||
colorette@^1.2.1, colorette@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
|
||||
@ -1692,6 +1757,13 @@ crypto-browserify@^3.12.0:
|
||||
randombytes "^2.0.0"
|
||||
randomfill "^1.0.3"
|
||||
|
||||
css-declaration-sorter@^6.0.3:
|
||||
version "6.1.3"
|
||||
resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.1.3.tgz#e9852e4cf940ba79f509d9425b137d1f94438dc2"
|
||||
integrity sha512-SvjQjNRZgh4ULK1LDJ2AduPKUKxIqmtU7ZAyi47BTV+M90Qvxr9AB6lKlLbDUfXqI9IQeYA8LbAsCZPpJEV3aA==
|
||||
dependencies:
|
||||
timsort "^0.3.0"
|
||||
|
||||
css-loader@^5.2.4:
|
||||
version "5.2.4"
|
||||
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.4.tgz#e985dcbce339812cb6104ef3670f08f9893a1536"
|
||||
@ -1709,6 +1781,18 @@ css-loader@^5.2.4:
|
||||
schema-utils "^3.0.0"
|
||||
semver "^7.3.5"
|
||||
|
||||
css-minimizer-webpack-plugin@^3.3.1:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.3.1.tgz#5afc4507a4ec13dd223f043cda8953ee0bf6ecfa"
|
||||
integrity sha512-SHA7Hu/EiF0dOwdmV2+agvqYpG+ljlUa7Dvn1AVOmSH3N8KOERoaM9lGpstz9nGsoTjANGyUXdrxl/EwdMScRg==
|
||||
dependencies:
|
||||
cssnano "^5.0.6"
|
||||
jest-worker "^27.0.2"
|
||||
postcss "^8.3.5"
|
||||
schema-utils "^4.0.0"
|
||||
serialize-javascript "^6.0.0"
|
||||
source-map "^0.6.1"
|
||||
|
||||
css-select@^2.0.2:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef"
|
||||
@ -1719,16 +1803,96 @@ css-select@^2.0.2:
|
||||
domutils "^1.7.0"
|
||||
nth-check "^1.0.2"
|
||||
|
||||
css-select@^4.1.3:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.2.1.tgz#9e665d6ae4c7f9d65dbe69d0316e3221fb274cdd"
|
||||
integrity sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==
|
||||
dependencies:
|
||||
boolbase "^1.0.0"
|
||||
css-what "^5.1.0"
|
||||
domhandler "^4.3.0"
|
||||
domutils "^2.8.0"
|
||||
nth-check "^2.0.1"
|
||||
|
||||
css-tree@^1.1.2, css-tree@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d"
|
||||
integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==
|
||||
dependencies:
|
||||
mdn-data "2.0.14"
|
||||
source-map "^0.6.1"
|
||||
|
||||
css-what@^3.2.1:
|
||||
version "3.4.2"
|
||||
resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4"
|
||||
integrity sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==
|
||||
|
||||
css-what@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe"
|
||||
integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==
|
||||
|
||||
cssesc@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
|
||||
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
|
||||
|
||||
cssnano-preset-default@^5.1.9:
|
||||
version "5.1.9"
|
||||
resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.1.9.tgz#79628ac48eccbdad570f70b4018cc38d43d1b7df"
|
||||
integrity sha512-RhkEucqlQ+OxEi14K1p8gdXcMQy1mSpo7P1oC44oRls7BYIj8p+cht4IFBFV3W4iOjTP8EUB33XV1fX9KhDzyA==
|
||||
dependencies:
|
||||
css-declaration-sorter "^6.0.3"
|
||||
cssnano-utils "^2.0.1"
|
||||
postcss-calc "^8.0.0"
|
||||
postcss-colormin "^5.2.2"
|
||||
postcss-convert-values "^5.0.2"
|
||||
postcss-discard-comments "^5.0.1"
|
||||
postcss-discard-duplicates "^5.0.1"
|
||||
postcss-discard-empty "^5.0.1"
|
||||
postcss-discard-overridden "^5.0.1"
|
||||
postcss-merge-longhand "^5.0.4"
|
||||
postcss-merge-rules "^5.0.3"
|
||||
postcss-minify-font-values "^5.0.1"
|
||||
postcss-minify-gradients "^5.0.3"
|
||||
postcss-minify-params "^5.0.2"
|
||||
postcss-minify-selectors "^5.1.0"
|
||||
postcss-normalize-charset "^5.0.1"
|
||||
postcss-normalize-display-values "^5.0.1"
|
||||
postcss-normalize-positions "^5.0.1"
|
||||
postcss-normalize-repeat-style "^5.0.1"
|
||||
postcss-normalize-string "^5.0.1"
|
||||
postcss-normalize-timing-functions "^5.0.1"
|
||||
postcss-normalize-unicode "^5.0.1"
|
||||
postcss-normalize-url "^5.0.4"
|
||||
postcss-normalize-whitespace "^5.0.1"
|
||||
postcss-ordered-values "^5.0.2"
|
||||
postcss-reduce-initial "^5.0.2"
|
||||
postcss-reduce-transforms "^5.0.1"
|
||||
postcss-svgo "^5.0.3"
|
||||
postcss-unique-selectors "^5.0.2"
|
||||
|
||||
cssnano-utils@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-2.0.1.tgz#8660aa2b37ed869d2e2f22918196a9a8b6498ce2"
|
||||
integrity sha512-i8vLRZTnEH9ubIyfdZCAdIdgnHAUeQeByEeQ2I7oTilvP9oHO6RScpeq3GsFUVqeB8uZgOQ9pw8utofNn32hhQ==
|
||||
|
||||
cssnano@^5.0.6:
|
||||
version "5.0.14"
|
||||
resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.0.14.tgz#99bc550f663b48c38e9b8e0ae795697c9de84b47"
|
||||
integrity sha512-qzhRkFvBhv08tbyKCIfWbxBXmkIpLl1uNblt8SpTHkgLfON5OCPX/CCnkdNmEosvo8bANQYmTTMEgcVBlisHaw==
|
||||
dependencies:
|
||||
cssnano-preset-default "^5.1.9"
|
||||
lilconfig "^2.0.3"
|
||||
yaml "^1.10.2"
|
||||
|
||||
csso@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529"
|
||||
integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==
|
||||
dependencies:
|
||||
css-tree "^1.1.2"
|
||||
|
||||
dataloader@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/dataloader/-/dataloader-1.4.0.tgz#bca11d867f5d3f1b9ed9f737bd15970c65dff5c8"
|
||||
@ -1983,10 +2147,10 @@ domhandler@^2.3.0:
|
||||
dependencies:
|
||||
domelementtype "1"
|
||||
|
||||
domhandler@^4.0.0, domhandler@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.0.tgz#f9768a5f034be60a89a27c2e4d0f74eba0d8b059"
|
||||
integrity sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==
|
||||
domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.0.tgz#16c658c626cf966967e306f966b431f77d4a5626"
|
||||
integrity sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==
|
||||
dependencies:
|
||||
domelementtype "^2.2.0"
|
||||
|
||||
@ -1998,10 +2162,10 @@ domutils@^1.5.1, domutils@^1.7.0:
|
||||
dom-serializer "0"
|
||||
domelementtype "1"
|
||||
|
||||
domutils@^2.5.2:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.6.0.tgz#2e15c04185d43fb16ae7057cb76433c6edb938b7"
|
||||
integrity sha512-y0BezHuy4MDYxh6OvolXYsH+1EMGmFbwv5FKW7ovwMG6zTPWqNPq3WF9ayZssFq+UlKdffGLbOEaghNdaOm1WA==
|
||||
domutils@^2.5.2, domutils@^2.8.0:
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
|
||||
integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==
|
||||
dependencies:
|
||||
dom-serializer "^1.0.1"
|
||||
domelementtype "^2.2.0"
|
||||
@ -2032,6 +2196,11 @@ electron-to-chromium@^1.3.723:
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.728.tgz#dbedd6373f595ae10a13d146b66bece4c1afa5bd"
|
||||
integrity sha512-SHv4ziXruBpb1Nz4aTuqEHBYi/9GNCJMYIJgDEXrp/2V01nFXMNFUTli5Z85f5ivSkioLilQatqBYFB44wNJrA==
|
||||
|
||||
electron-to-chromium@^1.4.17:
|
||||
version "1.4.28"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.28.tgz#fef0e92e281df6d568f482d8d53c34ca5374de48"
|
||||
integrity sha512-Gzbf0wUtKfyPaqf0Plz+Ctinf9eQIzxEqBHwSvbGfeOm9GMNdLxyu1dNiCUfM+x6r4BE0xUJNh3Nmg9gfAtTmg==
|
||||
|
||||
elliptic@^6.5.3:
|
||||
version "6.5.4"
|
||||
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
|
||||
@ -3581,6 +3750,15 @@ jest-worker@^26.6.2:
|
||||
merge-stream "^2.0.0"
|
||||
supports-color "^7.0.0"
|
||||
|
||||
jest-worker@^27.0.2:
|
||||
version "27.4.5"
|
||||
resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.4.5.tgz#d696e3e46ae0f24cff3fa7195ffba22889262242"
|
||||
integrity sha512-f2s8kEdy15cv9r7q4KkzGXvlY0JTcmCbMHZBfSQDwW77REr45IDWwd0lksDFeVHH2jJ5pqb90T77XscrjeGzzg==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
merge-stream "^2.0.0"
|
||||
supports-color "^8.0.0"
|
||||
|
||||
js-tokens@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
@ -3608,6 +3786,11 @@ json-schema-traverse@^0.4.1:
|
||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
||||
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
|
||||
|
||||
json-schema-traverse@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
|
||||
integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
|
||||
|
||||
json-stable-stringify-without-jsonify@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
|
||||
@ -3699,6 +3882,11 @@ levn@^0.4.1:
|
||||
prelude-ls "^1.2.1"
|
||||
type-check "~0.4.0"
|
||||
|
||||
lilconfig@^2.0.3:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.4.tgz#f4507d043d7058b380b6a8f5cb7bcd4b34cee082"
|
||||
integrity sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA==
|
||||
|
||||
lines-and-columns@^1.1.6:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
|
||||
@ -3787,11 +3975,21 @@ lodash.isequal@^4.5.0:
|
||||
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
||||
integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA=
|
||||
|
||||
lodash.memoize@^4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
|
||||
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
|
||||
|
||||
lodash.merge@^4.6.2:
|
||||
version "4.6.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
|
||||
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
|
||||
|
||||
lodash.uniq@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
||||
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
|
||||
|
||||
lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.20:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
@ -3870,6 +4068,11 @@ md5.js@^1.3.4:
|
||||
inherits "^2.0.1"
|
||||
safe-buffer "^5.1.2"
|
||||
|
||||
mdn-data@2.0.14:
|
||||
version "2.0.14"
|
||||
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
|
||||
integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==
|
||||
|
||||
media-typer@0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||
@ -4071,7 +4274,7 @@ nan@^2.12.1:
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
|
||||
integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==
|
||||
|
||||
nanoid@^3.1.23:
|
||||
nanoid@^3.1.23, nanoid@^3.1.30:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c"
|
||||
integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==
|
||||
@ -4166,6 +4369,11 @@ node-releases@^1.1.71:
|
||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe"
|
||||
integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==
|
||||
|
||||
node-releases@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5"
|
||||
integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==
|
||||
|
||||
normalize-package-data@^2.3.2:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
|
||||
@ -4188,6 +4396,11 @@ normalize-path@^3.0.0, normalize-path@~3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
|
||||
|
||||
normalize-url@^6.0.1:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
|
||||
integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
|
||||
|
||||
npm-run-all@^4.1.5:
|
||||
version "4.1.5"
|
||||
resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba"
|
||||
@ -4224,6 +4437,13 @@ nth-check@^1.0.2:
|
||||
dependencies:
|
||||
boolbase "~1.0.0"
|
||||
|
||||
nth-check@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2"
|
||||
integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==
|
||||
dependencies:
|
||||
boolbase "^1.0.0"
|
||||
|
||||
object-assign@^4.0.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
@ -4599,6 +4819,11 @@ phaser@^3.54.0:
|
||||
eventemitter3 "^4.0.7"
|
||||
path "^0.12.7"
|
||||
|
||||
picocolors@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
|
||||
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
|
||||
|
||||
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3:
|
||||
version "2.2.3"
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.3.tgz#465547f359ccc206d3c48e46a1bcb89bf7ee619d"
|
||||
@ -4671,6 +4896,103 @@ posix-character-classes@^0.1.0:
|
||||
resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab"
|
||||
integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=
|
||||
|
||||
postcss-calc@^8.0.0:
|
||||
version "8.0.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.0.0.tgz#a05b87aacd132740a5db09462a3612453e5df90a"
|
||||
integrity sha512-5NglwDrcbiy8XXfPM11F3HeC6hoT9W7GUH/Zi5U/p7u3Irv4rHhdDcIZwG0llHXV4ftsBjpfWMXAnXNl4lnt8g==
|
||||
dependencies:
|
||||
postcss-selector-parser "^6.0.2"
|
||||
postcss-value-parser "^4.0.2"
|
||||
|
||||
postcss-colormin@^5.2.2:
|
||||
version "5.2.2"
|
||||
resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.2.2.tgz#019cd6912bef9e7e0924462c5e4ffae241e2f437"
|
||||
integrity sha512-tSEe3NpqWARUTidDlF0LntPkdlhXqfDFuA1yslqpvvGAfpZ7oBaw+/QXd935NKm2U9p4PED0HDZlzmMk7fVC6g==
|
||||
dependencies:
|
||||
browserslist "^4.16.6"
|
||||
caniuse-api "^3.0.0"
|
||||
colord "^2.9.1"
|
||||
postcss-value-parser "^4.2.0"
|
||||
|
||||
postcss-convert-values@^5.0.2:
|
||||
version "5.0.2"
|
||||
resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.0.2.tgz#879b849dc3677c7d6bc94b6a2c1a3f0808798059"
|
||||
integrity sha512-KQ04E2yadmfa1LqXm7UIDwW1ftxU/QWZmz6NKnHnUvJ3LEYbbcX6i329f/ig+WnEByHegulocXrECaZGLpL8Zg==
|
||||
dependencies:
|
||||
postcss-value-parser "^4.1.0"
|
||||
|
||||
postcss-discard-comments@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.0.1.tgz#9eae4b747cf760d31f2447c27f0619d5718901fe"
|
||||
integrity sha512-lgZBPTDvWrbAYY1v5GYEv8fEO/WhKOu/hmZqmCYfrpD6eyDWWzAOsl2rF29lpvziKO02Gc5GJQtlpkTmakwOWg==
|
||||
|
||||
postcss-discard-duplicates@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.1.tgz#68f7cc6458fe6bab2e46c9f55ae52869f680e66d"
|
||||
integrity sha512-svx747PWHKOGpAXXQkCc4k/DsWo+6bc5LsVrAsw+OU+Ibi7klFZCyX54gjYzX4TH+f2uzXjRviLARxkMurA2bA==
|
||||
|
||||
postcss-discard-empty@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.0.1.tgz#ee136c39e27d5d2ed4da0ee5ed02bc8a9f8bf6d8"
|
||||
integrity sha512-vfU8CxAQ6YpMxV2SvMcMIyF2LX1ZzWpy0lqHDsOdaKKLQVQGVP1pzhrI9JlsO65s66uQTfkQBKBD/A5gp9STFw==
|
||||
|
||||
postcss-discard-overridden@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.0.1.tgz#454b41f707300b98109a75005ca4ab0ff2743ac6"
|
||||
integrity sha512-Y28H7y93L2BpJhrdUR2SR2fnSsT+3TVx1NmVQLbcnZWwIUpJ7mfcTC6Za9M2PG6w8j7UQRfzxqn8jU2VwFxo3Q==
|
||||
|
||||
postcss-merge-longhand@^5.0.4:
|
||||
version "5.0.4"
|
||||
resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.0.4.tgz#41f4f3270282ea1a145ece078b7679f0cef21c32"
|
||||
integrity sha512-2lZrOVD+d81aoYkZDpWu6+3dTAAGkCKbV5DoRhnIR7KOULVrI/R7bcMjhrH9KTRy6iiHKqmtG+n/MMj1WmqHFw==
|
||||
dependencies:
|
||||
postcss-value-parser "^4.1.0"
|
||||
stylehacks "^5.0.1"
|
||||
|
||||
postcss-merge-rules@^5.0.3:
|
||||
version "5.0.3"
|
||||
resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.0.3.tgz#b5cae31f53129812a77e3eb1eeee448f8cf1a1db"
|
||||
integrity sha512-cEKTMEbWazVa5NXd8deLdCnXl+6cYG7m2am+1HzqH0EnTdy8fRysatkaXb2dEnR+fdaDxTvuZ5zoBdv6efF6hg==
|
||||
dependencies:
|
||||
browserslist "^4.16.6"
|
||||
caniuse-api "^3.0.0"
|
||||
cssnano-utils "^2.0.1"
|
||||
postcss-selector-parser "^6.0.5"
|
||||
|
||||
postcss-minify-font-values@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.0.1.tgz#a90cefbfdaa075bd3dbaa1b33588bb4dc268addf"
|
||||
integrity sha512-7JS4qIsnqaxk+FXY1E8dHBDmraYFWmuL6cgt0T1SWGRO5bzJf8sUoelwa4P88LEWJZweHevAiDKxHlofuvtIoA==
|
||||
dependencies:
|
||||
postcss-value-parser "^4.1.0"
|
||||
|
||||
postcss-minify-gradients@^5.0.3:
|
||||
version "5.0.3"
|
||||
resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.0.3.tgz#f970a11cc71e08e9095e78ec3a6b34b91c19550e"
|
||||
integrity sha512-Z91Ol22nB6XJW+5oe31+YxRsYooxOdFKcbOqY/V8Fxse1Y3vqlNRpi1cxCqoACZTQEhl+xvt4hsbWiV5R+XI9Q==
|
||||
dependencies:
|
||||
colord "^2.9.1"
|
||||
cssnano-utils "^2.0.1"
|
||||
postcss-value-parser "^4.1.0"
|
||||
|
||||
postcss-minify-params@^5.0.2:
|
||||
version "5.0.2"
|
||||
resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.0.2.tgz#1b644da903473fbbb18fbe07b8e239883684b85c"
|
||||
integrity sha512-qJAPuBzxO1yhLad7h2Dzk/F7n1vPyfHfCCh5grjGfjhi1ttCnq4ZXGIW77GSrEbh9Hus9Lc/e/+tB4vh3/GpDg==
|
||||
dependencies:
|
||||
alphanum-sort "^1.0.2"
|
||||
browserslist "^4.16.6"
|
||||
cssnano-utils "^2.0.1"
|
||||
postcss-value-parser "^4.1.0"
|
||||
|
||||
postcss-minify-selectors@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.1.0.tgz#4385c845d3979ff160291774523ffa54eafd5a54"
|
||||
integrity sha512-NzGBXDa7aPsAcijXZeagnJBKBPMYLaJJzB8CQh6ncvyl2sIndLVWfbcDi0SBjRWk5VqEjXvf8tYwzoKf4Z07og==
|
||||
dependencies:
|
||||
alphanum-sort "^1.0.2"
|
||||
postcss-selector-parser "^6.0.5"
|
||||
|
||||
postcss-modules-extract-imports@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d"
|
||||
@ -4699,6 +5021,96 @@ postcss-modules-values@^4.0.0:
|
||||
dependencies:
|
||||
icss-utils "^5.0.0"
|
||||
|
||||
postcss-normalize-charset@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.0.1.tgz#121559d1bebc55ac8d24af37f67bd4da9efd91d0"
|
||||
integrity sha512-6J40l6LNYnBdPSk+BHZ8SF+HAkS4q2twe5jnocgd+xWpz/mx/5Sa32m3W1AA8uE8XaXN+eg8trIlfu8V9x61eg==
|
||||
|
||||
postcss-normalize-display-values@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.1.tgz#62650b965981a955dffee83363453db82f6ad1fd"
|
||||
integrity sha512-uupdvWk88kLDXi5HEyI9IaAJTE3/Djbcrqq8YgjvAVuzgVuqIk3SuJWUisT2gaJbZm1H9g5k2w1xXilM3x8DjQ==
|
||||
dependencies:
|
||||
cssnano-utils "^2.0.1"
|
||||
postcss-value-parser "^4.1.0"
|
||||
|
||||
postcss-normalize-positions@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.0.1.tgz#868f6af1795fdfa86fbbe960dceb47e5f9492fe5"
|
||||
integrity sha512-rvzWAJai5xej9yWqlCb1OWLd9JjW2Ex2BCPzUJrbaXmtKtgfL8dBMOOMTX6TnvQMtjk3ei1Lswcs78qKO1Skrg==
|
||||
dependencies:
|
||||
postcss-value-parser "^4.1.0"
|
||||
|
||||
postcss-normalize-repeat-style@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.1.tgz#cbc0de1383b57f5bb61ddd6a84653b5e8665b2b5"
|
||||
integrity sha512-syZ2itq0HTQjj4QtXZOeefomckiV5TaUO6ReIEabCh3wgDs4Mr01pkif0MeVwKyU/LHEkPJnpwFKRxqWA/7O3w==
|
||||
dependencies:
|
||||
cssnano-utils "^2.0.1"
|
||||
postcss-value-parser "^4.1.0"
|
||||
|
||||
postcss-normalize-string@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.0.1.tgz#d9eafaa4df78c7a3b973ae346ef0e47c554985b0"
|
||||
integrity sha512-Ic8GaQ3jPMVl1OEn2U//2pm93AXUcF3wz+OriskdZ1AOuYV25OdgS7w9Xu2LO5cGyhHCgn8dMXh9bO7vi3i9pA==
|
||||
dependencies:
|
||||
postcss-value-parser "^4.1.0"
|
||||
|
||||
postcss-normalize-timing-functions@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.1.tgz#8ee41103b9130429c6cbba736932b75c5e2cb08c"
|
||||
integrity sha512-cPcBdVN5OsWCNEo5hiXfLUnXfTGtSFiBU9SK8k7ii8UD7OLuznzgNRYkLZow11BkQiiqMcgPyh4ZqXEEUrtQ1Q==
|
||||
dependencies:
|
||||
cssnano-utils "^2.0.1"
|
||||
postcss-value-parser "^4.1.0"
|
||||
|
||||
postcss-normalize-unicode@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.1.tgz#82d672d648a411814aa5bf3ae565379ccd9f5e37"
|
||||
integrity sha512-kAtYD6V3pK0beqrU90gpCQB7g6AOfP/2KIPCVBKJM2EheVsBQmx/Iof+9zR9NFKLAx4Pr9mDhogB27pmn354nA==
|
||||
dependencies:
|
||||
browserslist "^4.16.0"
|
||||
postcss-value-parser "^4.1.0"
|
||||
|
||||
postcss-normalize-url@^5.0.4:
|
||||
version "5.0.4"
|
||||
resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.0.4.tgz#3b0322c425e31dd275174d0d5db0e466f50810fb"
|
||||
integrity sha512-cNj3RzK2pgQQyNp7dzq0dqpUpQ/wYtdDZM3DepPmFjCmYIfceuD9VIAcOdvrNetjIU65g1B4uwdP/Krf6AFdXg==
|
||||
dependencies:
|
||||
normalize-url "^6.0.1"
|
||||
postcss-value-parser "^4.2.0"
|
||||
|
||||
postcss-normalize-whitespace@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.1.tgz#b0b40b5bcac83585ff07ead2daf2dcfbeeef8e9a"
|
||||
integrity sha512-iPklmI5SBnRvwceb/XH568yyzK0qRVuAG+a1HFUsFRf11lEJTiQQa03a4RSCQvLKdcpX7XsI1Gen9LuLoqwiqA==
|
||||
dependencies:
|
||||
postcss-value-parser "^4.1.0"
|
||||
|
||||
postcss-ordered-values@^5.0.2:
|
||||
version "5.0.2"
|
||||
resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.0.2.tgz#1f351426977be00e0f765b3164ad753dac8ed044"
|
||||
integrity sha512-8AFYDSOYWebJYLyJi3fyjl6CqMEG/UVworjiyK1r573I56kb3e879sCJLGvR3merj+fAdPpVplXKQZv+ey6CgQ==
|
||||
dependencies:
|
||||
cssnano-utils "^2.0.1"
|
||||
postcss-value-parser "^4.1.0"
|
||||
|
||||
postcss-reduce-initial@^5.0.2:
|
||||
version "5.0.2"
|
||||
resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.0.2.tgz#fa424ce8aa88a89bc0b6d0f94871b24abe94c048"
|
||||
integrity sha512-v/kbAAQ+S1V5v9TJvbGkV98V2ERPdU6XvMcKMjqAlYiJ2NtsHGlKYLPjWWcXlaTKNxooId7BGxeraK8qXvzKtw==
|
||||
dependencies:
|
||||
browserslist "^4.16.6"
|
||||
caniuse-api "^3.0.0"
|
||||
|
||||
postcss-reduce-transforms@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.1.tgz#93c12f6a159474aa711d5269923e2383cedcf640"
|
||||
integrity sha512-a//FjoPeFkRuAguPscTVmRQUODP+f3ke2HqFNgGPwdYnpeC29RZdCBvGRGTsKpMURb/I3p6jdKoBQ2zI+9Q7kA==
|
||||
dependencies:
|
||||
cssnano-utils "^2.0.1"
|
||||
postcss-value-parser "^4.1.0"
|
||||
|
||||
postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4:
|
||||
version "6.0.6"
|
||||
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea"
|
||||
@ -4707,6 +5119,35 @@ postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4:
|
||||
cssesc "^3.0.0"
|
||||
util-deprecate "^1.0.2"
|
||||
|
||||
postcss-selector-parser@^6.0.5:
|
||||
version "6.0.8"
|
||||
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.8.tgz#f023ed7a9ea736cd7ef70342996e8e78645a7914"
|
||||
integrity sha512-D5PG53d209Z1Uhcc0qAZ5U3t5HagH3cxu+WLZ22jt3gLUpXM4eXXfiO14jiDWST3NNooX/E8wISfOhZ9eIjGTQ==
|
||||
dependencies:
|
||||
cssesc "^3.0.0"
|
||||
util-deprecate "^1.0.2"
|
||||
|
||||
postcss-svgo@^5.0.3:
|
||||
version "5.0.3"
|
||||
resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.0.3.tgz#d945185756e5dfaae07f9edb0d3cae7ff79f9b30"
|
||||
integrity sha512-41XZUA1wNDAZrQ3XgWREL/M2zSw8LJPvb5ZWivljBsUQAGoEKMYm6okHsTjJxKYI4M75RQEH4KYlEM52VwdXVA==
|
||||
dependencies:
|
||||
postcss-value-parser "^4.1.0"
|
||||
svgo "^2.7.0"
|
||||
|
||||
postcss-unique-selectors@^5.0.2:
|
||||
version "5.0.2"
|
||||
resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.0.2.tgz#5d6893daf534ae52626708e0d62250890108c0c1"
|
||||
integrity sha512-w3zBVlrtZm7loQWRPVC0yjUwwpty7OM6DnEHkxcSQXO1bMS3RJ+JUS5LFMSDZHJcvGsRwhZinCWVqn8Kej4EDA==
|
||||
dependencies:
|
||||
alphanum-sort "^1.0.2"
|
||||
postcss-selector-parser "^6.0.5"
|
||||
|
||||
postcss-value-parser@^4.0.2, postcss-value-parser@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
|
||||
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
|
||||
|
||||
postcss-value-parser@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb"
|
||||
@ -4730,6 +5171,15 @@ postcss@^8.2.10:
|
||||
nanoid "^3.1.23"
|
||||
source-map "^0.6.1"
|
||||
|
||||
postcss@^8.3.5:
|
||||
version "8.4.5"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.5.tgz#bae665764dfd4c6fcc24dc0fdf7e7aa00cc77f95"
|
||||
integrity sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==
|
||||
dependencies:
|
||||
nanoid "^3.1.30"
|
||||
picocolors "^1.0.0"
|
||||
source-map-js "^1.0.1"
|
||||
|
||||
posthog-js@^1.14.1:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/posthog-js/-/posthog-js-1.14.1.tgz#68553b9074c686784b994b3f433ad035b241deaa"
|
||||
@ -5057,6 +5507,11 @@ require-directory@^2.1.1:
|
||||
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
||||
integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
|
||||
|
||||
require-from-string@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
|
||||
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
|
||||
|
||||
require-main-filename@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
|
||||
@ -5262,6 +5717,16 @@ schema-utils@^3.0.0:
|
||||
ajv "^6.12.5"
|
||||
ajv-keywords "^3.5.2"
|
||||
|
||||
schema-utils@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7"
|
||||
integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.9"
|
||||
ajv "^8.8.0"
|
||||
ajv-formats "^2.1.1"
|
||||
ajv-keywords "^5.0.0"
|
||||
|
||||
select-hose@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
|
||||
@ -5322,6 +5787,13 @@ serialize-javascript@^5.0.1:
|
||||
dependencies:
|
||||
randombytes "^2.1.0"
|
||||
|
||||
serialize-javascript@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8"
|
||||
integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==
|
||||
dependencies:
|
||||
randombytes "^2.1.0"
|
||||
|
||||
serve-index@^1.9.1:
|
||||
version "1.9.1"
|
||||
resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239"
|
||||
@ -5547,6 +6019,11 @@ source-map-js@^0.6.2:
|
||||
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e"
|
||||
integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==
|
||||
|
||||
source-map-js@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.1.tgz#a1741c131e3c77d048252adfa24e23b908670caf"
|
||||
integrity sha512-4+TN2b3tqOCd/kaGRJ/sTYA0tR0mdXx26ipdolxcwtJVqEnqNYvlCAt1q3ypy4QMlYus+Zh34RNtYLoq2oQ4IA==
|
||||
|
||||
source-map-resolve@^0.5.0:
|
||||
version "0.5.3"
|
||||
resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a"
|
||||
@ -5642,6 +6119,11 @@ split-string@^3.0.1, split-string@^3.0.2:
|
||||
dependencies:
|
||||
extend-shallow "^3.0.0"
|
||||
|
||||
stable@^0.1.8:
|
||||
version "0.1.8"
|
||||
resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
|
||||
integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==
|
||||
|
||||
standardized-audio-context@^25.2.4:
|
||||
version "25.2.4"
|
||||
resolved "https://registry.yarnpkg.com/standardized-audio-context/-/standardized-audio-context-25.2.4.tgz#d64dbdd70615171ec90d1b7151a0d945af94cf3d"
|
||||
@ -5808,6 +6290,14 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
|
||||
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
|
||||
|
||||
stylehacks@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.0.1.tgz#323ec554198520986806388c7fdaebc38d2c06fb"
|
||||
integrity sha512-Es0rVnHIqbWzveU1b24kbw92HsebBepxfcqe5iix7t9j0PQqhs0IxXVXv0pY2Bxa08CgMkzD6OWql7kbGOuEdA==
|
||||
dependencies:
|
||||
browserslist "^4.16.0"
|
||||
postcss-selector-parser "^6.0.4"
|
||||
|
||||
supports-color@^5.3.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
|
||||
@ -5829,6 +6319,13 @@ supports-color@^7.0.0, supports-color@^7.1.0:
|
||||
dependencies:
|
||||
has-flag "^4.0.0"
|
||||
|
||||
supports-color@^8.0.0:
|
||||
version "8.1.1"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
|
||||
integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
|
||||
dependencies:
|
||||
has-flag "^4.0.0"
|
||||
|
||||
svelte-check@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/svelte-check/-/svelte-check-2.1.0.tgz#3ee8ad86068256346ebca862bbee8417a757fc53"
|
||||
@ -5878,6 +6375,19 @@ svelte@^3.38.2:
|
||||
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.38.2.tgz#55e5c681f793ae349b5cc2fe58e5782af4275ef5"
|
||||
integrity sha512-q5Dq0/QHh4BLJyEVWGe7Cej5NWs040LWjMbicBGZ+3qpFWJ1YObRmUDZKbbovddLC9WW7THTj3kYbTOFmU9fbg==
|
||||
|
||||
svgo@^2.7.0:
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24"
|
||||
integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==
|
||||
dependencies:
|
||||
"@trysound/sax" "0.2.0"
|
||||
commander "^7.2.0"
|
||||
css-select "^4.1.3"
|
||||
css-tree "^1.1.3"
|
||||
csso "^4.2.0"
|
||||
picocolors "^1.0.0"
|
||||
stable "^0.1.8"
|
||||
|
||||
tabbable@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-4.0.0.tgz#5bff1d1135df1482cf0f0206434f15eadbeb9261"
|
||||
@ -5945,6 +6455,11 @@ timers-browserify@^2.0.12:
|
||||
dependencies:
|
||||
setimmediate "^1.0.4"
|
||||
|
||||
timsort@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
|
||||
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
|
||||
|
||||
tiny-emitter@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
|
||||
@ -6573,7 +7088,7 @@ yallist@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
|
||||
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
||||
|
||||
yaml@^1.10.0, yaml@^1.7.2:
|
||||
yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2:
|
||||
version "1.10.2"
|
||||
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
|
||||
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user