Merge pull request #1624 from thecodingmachine/linting
Add lint on Svelte files
This commit is contained in:
commit
2859093648
@ -1,4 +1,4 @@
|
||||
{
|
||||
module.exports = {
|
||||
"root": true,
|
||||
"env": {
|
||||
"browser": true,
|
||||
@ -18,10 +18,18 @@
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018,
|
||||
"sourceType": "module",
|
||||
"project": "./tsconfig.json"
|
||||
"project": "./tsconfig.json",
|
||||
"extraFileExtensions": [".svelte"]
|
||||
},
|
||||
"plugins": [
|
||||
"@typescript-eslint"
|
||||
"@typescript-eslint",
|
||||
"svelte3"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.svelte"],
|
||||
"processor": "svelte3/svelte3"
|
||||
}
|
||||
],
|
||||
"rules": {
|
||||
"no-unused-vars": "off",
|
||||
@ -34,5 +42,9 @@
|
||||
"@typescript-eslint/no-unsafe-return": "off",
|
||||
"@typescript-eslint/no-unsafe-member-access": "off",
|
||||
"@typescript-eslint/restrict-template-expressions": "off"
|
||||
},
|
||||
"settings": {
|
||||
"svelte3/typescript": true,
|
||||
"svelte3/ignore-styles": () => true
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
{
|
||||
"printWidth": 120,
|
||||
"tabWidth": 4
|
||||
"tabWidth": 4,
|
||||
"plugins": ["prettier-plugin-svelte"]
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
"@typescript-eslint/parser": "^4.23.0",
|
||||
"css-loader": "^5.2.4",
|
||||
"eslint": "^7.26.0",
|
||||
"eslint-plugin-svelte3": "^3.2.1",
|
||||
"fork-ts-checker-webpack-plugin": "^6.2.9",
|
||||
"html-webpack-plugin": "^5.3.1",
|
||||
"jasmine": "^3.5.0",
|
||||
@ -24,6 +25,7 @@
|
||||
"node-polyfill-webpack-plugin": "^1.1.2",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.3.1",
|
||||
"prettier-plugin-svelte": "^2.5.0",
|
||||
"sass": "^1.32.12",
|
||||
"sass-loader": "^11.1.0",
|
||||
"svelte": "^3.38.2",
|
||||
@ -67,17 +69,19 @@
|
||||
"build": "cross-env TS_NODE_PROJECT=\"tsconfig-for-webpack.json\" NODE_ENV=production webpack",
|
||||
"build-typings": "cross-env TS_NODE_PROJECT=\"tsconfig-for-webpack.json\" NODE_ENV=production BUILD_TYPINGS=1 webpack",
|
||||
"test": "cross-env TS_NODE_PROJECT=\"tsconfig-for-jasmine.json\" ts-node node_modules/jasmine/bin/jasmine --config=jasmine.json",
|
||||
"lint": "node_modules/.bin/eslint src/ . --ext .ts",
|
||||
"fix": "node_modules/.bin/eslint --fix src/ . --ext .ts",
|
||||
"lint": "node_modules/.bin/eslint src/ . --ext .ts,.svelte",
|
||||
"fix": "node_modules/.bin/eslint --fix src/ . --ext .ts,.svelte",
|
||||
"precommit": "lint-staged",
|
||||
"svelte-check-watch": "svelte-check --fail-on-warnings --fail-on-hints --compiler-warnings \"a11y-no-onchange:ignore,a11y-autofocus:ignore,a11y-media-has-caption:ignore\" --watch",
|
||||
"svelte-check": "svelte-check --fail-on-warnings --fail-on-hints --compiler-warnings \"a11y-no-onchange:ignore,a11y-autofocus:ignore,a11y-media-has-caption:ignore\"",
|
||||
"pretty": "yarn prettier --write 'src/**/*.{ts,tsx}'",
|
||||
"pretty-check": "yarn prettier --check 'src/**/*.{ts,tsx}'"
|
||||
"pretty": "yarn prettier --write 'src/**/*.{ts,svelte}'",
|
||||
"pretty-check": "yarn prettier --check 'src/**/*.{ts,svelte}'"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.ts": [
|
||||
"prettier --write"
|
||||
"*.{ts,svelte}": [
|
||||
"yarn run svelte-check",
|
||||
"yarn run fix",
|
||||
"yarn run pretty"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -1,147 +1,146 @@
|
||||
<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 { 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 { 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 { 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 { loginSceneVisibleStore } from "../Stores/LoginSceneStore";
|
||||
import EnableCameraScene from "./EnableCamera/EnableCameraScene.svelte";
|
||||
import VisitCard from "./VisitCard/VisitCard.svelte";
|
||||
import {requestVisitCardsStore} from "../Stores/GameStore";
|
||||
import { requestVisitCardsStore } from "../Stores/GameStore";
|
||||
|
||||
import type {Game} from "../Phaser/Game/Game";
|
||||
import {chatVisibilityStore} from "../Stores/ChatStore";
|
||||
import {helpCameraSettingsVisibleStore} from "../Stores/HelpCameraSettingsStore";
|
||||
import type { Game } from "../Phaser/Game/Game";
|
||||
import { chatVisibilityStore } from "../Stores/ChatStore";
|
||||
import { helpCameraSettingsVisibleStore } from "../Stores/HelpCameraSettingsStore";
|
||||
import HelpCameraSettingsPopup from "./HelpCameraSettings/HelpCameraSettingsPopup.svelte";
|
||||
import AudioPlaying from "./UI/AudioPlaying.svelte";
|
||||
import {soundPlayingStore} from "../Stores/SoundPlayingStore";
|
||||
import { soundPlayingStore } from "../Stores/SoundPlayingStore";
|
||||
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 { gameOverlayVisibilityStore } from "../Stores/GameOverlayStoreVisibility";
|
||||
import AdminMessage from "./TypeMessage/BanMessage.svelte";
|
||||
import TextMessage from "./TypeMessage/TextMessage.svelte";
|
||||
import {banMessageVisibleStore} from "../Stores/TypeMessageStore/BanMessageStore";
|
||||
import {textMessageVisibleStore} from "../Stores/TypeMessageStore/TextMessageStore";
|
||||
import {warningContainerStore} from "../Stores/MenuStore";
|
||||
import { banMessageVisibleStore } from "../Stores/TypeMessageStore/BanMessageStore";
|
||||
import { textMessageVisibleStore } from "../Stores/TypeMessageStore/TextMessageStore";
|
||||
import { warningContainerStore } from "../Stores/MenuStore";
|
||||
import WarningContainer from "./WarningContainer/WarningContainer.svelte";
|
||||
import {layoutManagerVisibilityStore} from "../Stores/LayoutManagerStore";
|
||||
import { layoutManagerVisibilityStore } from "../Stores/LayoutManagerStore";
|
||||
import LayoutManager from "./LayoutManager/LayoutManager.svelte";
|
||||
import {audioManagerVisibilityStore} from "../Stores/AudioManagerStore";
|
||||
import AudioManager from "./AudioManager/AudioManager.svelte"
|
||||
import { audioManagerVisibilityStore } from "../Stores/AudioManagerStore";
|
||||
import AudioManager from "./AudioManager/AudioManager.svelte";
|
||||
import { showReportScreenStore, userReportEmpty } from "../Stores/ShowReportScreenStore";
|
||||
import ReportMenu from "./ReportMenu/ReportMenu.svelte";
|
||||
|
||||
export let game: Game;
|
||||
|
||||
</script>
|
||||
|
||||
<div>
|
||||
{#if $loginSceneVisibleStore}
|
||||
<div class="scrollable">
|
||||
<LoginScene game={game}></LoginScene>
|
||||
<LoginScene {game} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $selectCharacterSceneVisibleStore}
|
||||
<div>
|
||||
<SelectCharacterScene game={ game }></SelectCharacterScene>
|
||||
<SelectCharacterScene {game} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $customCharacterSceneVisibleStore}
|
||||
<div>
|
||||
<CustomCharacterScene game={ game }></CustomCharacterScene>
|
||||
<CustomCharacterScene {game} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $selectCompanionSceneVisibleStore}
|
||||
<div>
|
||||
<SelectCompanionScene game={ game }></SelectCompanionScene>
|
||||
<SelectCompanionScene {game} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $enableCameraSceneVisibilityStore}
|
||||
<div class="scrollable">
|
||||
<EnableCameraScene game={game}></EnableCameraScene>
|
||||
<EnableCameraScene {game} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $banMessageVisibleStore}
|
||||
<div>
|
||||
<AdminMessage></AdminMessage>
|
||||
<AdminMessage />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $textMessageVisibleStore}
|
||||
<div>
|
||||
<TextMessage></TextMessage>
|
||||
<TextMessage />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $soundPlayingStore}
|
||||
<div>
|
||||
<AudioPlaying url={$soundPlayingStore} />
|
||||
</div>
|
||||
<div>
|
||||
<AudioPlaying url={$soundPlayingStore} />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $audioManagerVisibilityStore}
|
||||
<div>
|
||||
<AudioManager></AudioManager>
|
||||
</div>
|
||||
<div>
|
||||
<AudioManager />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $layoutManagerVisibilityStore}
|
||||
<div>
|
||||
<LayoutManager></LayoutManager>
|
||||
<LayoutManager />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $showReportScreenStore !== userReportEmpty}
|
||||
<div>
|
||||
<ReportMenu></ReportMenu>
|
||||
<ReportMenu />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $menuIconVisiblilityStore}
|
||||
<div>
|
||||
<MenuIcon></MenuIcon>
|
||||
<MenuIcon />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $menuVisiblilityStore}
|
||||
<div>
|
||||
<Menu></Menu>
|
||||
<Menu />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $emoteMenuStore}
|
||||
<div>
|
||||
<EmoteMenu></EmoteMenu>
|
||||
<EmoteMenu />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $gameOverlayVisibilityStore}
|
||||
<div>
|
||||
<VideoOverlay></VideoOverlay>
|
||||
<MyCamera></MyCamera>
|
||||
<CameraControls></CameraControls>
|
||||
<VideoOverlay />
|
||||
<MyCamera />
|
||||
<CameraControls />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $helpCameraSettingsVisibleStore}
|
||||
<div>
|
||||
<HelpCameraSettingsPopup></HelpCameraSettingsPopup>
|
||||
<HelpCameraSettingsPopup />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $requestVisitCardsStore}
|
||||
<VisitCard visitCardUrl={$requestVisitCardsStore}></VisitCard>
|
||||
<VisitCard visitCardUrl={$requestVisitCardsStore} />
|
||||
{/if}
|
||||
{#if $errorStore.length > 0}
|
||||
<div>
|
||||
<ErrorDialog></ErrorDialog>
|
||||
</div>
|
||||
<div>
|
||||
<ErrorDialog />
|
||||
</div>
|
||||
{/if}
|
||||
{#if $chatVisibilityStore}
|
||||
<Chat></Chat>
|
||||
<Chat />
|
||||
{/if}
|
||||
{#if $warningContainerStore}
|
||||
<WarningContainer></WarningContainer>
|
||||
<WarningContainer />
|
||||
{/if}
|
||||
</div>
|
||||
|
@ -1,10 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { localUserStore } from "../../Connexion/LocalUserStore";
|
||||
import type { audioManagerVolume } from "../../Stores/AudioManagerStore";
|
||||
import {
|
||||
audioManagerFileStore,
|
||||
audioManagerVolumeStore,
|
||||
} from "../../Stores/AudioManagerStore";
|
||||
import { audioManagerFileStore, audioManagerVolumeStore } from "../../Stores/AudioManagerStore";
|
||||
import { get } from "svelte/store";
|
||||
import type { Unsubscriber } from "svelte/store";
|
||||
import { onDestroy, onMount } from "svelte";
|
||||
@ -43,8 +40,8 @@
|
||||
HTMLAudioPlayer.volume = audioManager.volume;
|
||||
HTMLAudioPlayer.muted = audioManager.muted;
|
||||
HTMLAudioPlayer.loop = audioManager.loop;
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
if (unsubscriberFileStore) {
|
||||
@ -53,23 +50,23 @@
|
||||
if (unsubscriberVolumeStore) {
|
||||
unsubscriberVolumeStore();
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
function changeVolume() {
|
||||
if (get(audioManagerVolumeStore).muted) {
|
||||
audioPlayerVolumeIcon.classList.add('muted');
|
||||
audioPlayerVolumeIcon.classList.add("muted");
|
||||
audioPlayerVol.value = "0";
|
||||
} else {
|
||||
audioPlayerVol.value = "" + volume;
|
||||
audioPlayerVolumeIcon.classList.remove('muted');
|
||||
audioPlayerVolumeIcon.classList.remove("muted");
|
||||
if (volume < 0.3) {
|
||||
audioPlayerVolumeIcon.classList.add('low');
|
||||
audioPlayerVolumeIcon.classList.add("low");
|
||||
} else if (volume < 0.7) {
|
||||
audioPlayerVolumeIcon.classList.remove('low');
|
||||
audioPlayerVolumeIcon.classList.add('mid');
|
||||
audioPlayerVolumeIcon.classList.remove("low");
|
||||
audioPlayerVolumeIcon.classList.add("mid");
|
||||
} else {
|
||||
audioPlayerVolumeIcon.classList.remove('low');
|
||||
audioPlayerVolumeIcon.classList.remove('mid');
|
||||
audioPlayerVolumeIcon.classList.remove("low");
|
||||
audioPlayerVolumeIcon.classList.remove("mid");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -105,45 +102,67 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<div class="main-audio-manager nes-container is-rounded">
|
||||
<div class="audio-manager-player-volume">
|
||||
<span id="audioplayer_volume_icon_playing" alt="player volume" bind:this={audioPlayerVolumeIcon}
|
||||
on:click={onMute}>
|
||||
<svg width="2em" height="2em" viewBox="0 0 16 16" class="bi bi-volume-up" fill="white"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd"
|
||||
d="M6.717 3.55A.5.5 0 0 1 7 4v8a.5.5 0 0 1-.812.39L3.825 10.5H1.5A.5.5 0 0 1 1 10V6a.5.5 0 0 1 .5-.5h2.325l2.363-1.89a.5.5 0 0 1 .529-.06zM6 5.04L4.312 6.39A.5.5 0 0 1 4 6.5H2v3h2a.5.5 0 0 1 .312.11L6 10.96V5.04z" />
|
||||
<span
|
||||
id="audioplayer_volume_icon_playing"
|
||||
alt="player volume"
|
||||
bind:this={audioPlayerVolumeIcon}
|
||||
on:click={onMute}
|
||||
>
|
||||
<svg
|
||||
width="2em"
|
||||
height="2em"
|
||||
viewBox="0 0 16 16"
|
||||
class="bi bi-volume-up"
|
||||
fill="white"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M6.717 3.55A.5.5 0 0 1 7 4v8a.5.5 0 0 1-.812.39L3.825 10.5H1.5A.5.5 0 0 1 1 10V6a.5.5 0 0 1 .5-.5h2.325l2.363-1.89a.5.5 0 0 1 .529-.06zM6 5.04L4.312 6.39A.5.5 0 0 1 4 6.5H2v3h2a.5.5 0 0 1 .312.11L6 10.96V5.04z"
|
||||
/>
|
||||
<g id="audioplayer_volume_icon_playing_high">
|
||||
<path
|
||||
d="M11.536 14.01A8.473 8.473 0 0 0 14.026 8a8.473 8.473 0 0 0-2.49-6.01l-.708.707A7.476 7.476 0 0 1 13.025 8c0 2.071-.84 3.946-2.197 5.303l.708.707z" />
|
||||
d="M11.536 14.01A8.473 8.473 0 0 0 14.026 8a8.473 8.473 0 0 0-2.49-6.01l-.708.707A7.476 7.476 0 0 1 13.025 8c0 2.071-.84 3.946-2.197 5.303l.708.707z"
|
||||
/>
|
||||
</g>
|
||||
<g id="audioplayer_volume_icon_playing_mid">
|
||||
<path
|
||||
d="M10.121 12.596A6.48 6.48 0 0 0 12.025 8a6.48 6.48 0 0 0-1.904-4.596l-.707.707A5.483 5.483 0 0 1 11.025 8a5.483 5.483 0 0 1-1.61 3.89l.706.706z" />
|
||||
d="M10.121 12.596A6.48 6.48 0 0 0 12.025 8a6.48 6.48 0 0 0-1.904-4.596l-.707.707A5.483 5.483 0 0 1 11.025 8a5.483 5.483 0 0 1-1.61 3.89l.706.706z"
|
||||
/>
|
||||
</g>
|
||||
<g id="audioplayer_volume_icon_playing_low">
|
||||
<path
|
||||
d="M8.707 11.182A4.486 4.486 0 0 0 10.025 8a4.486 4.486 0 0 0-1.318-3.182L8 5.525A3.489 3.489 0 0 1 9.025 8 3.49 3.49 0 0 1 8 10.475l.707.707z" />
|
||||
d="M8.707 11.182A4.486 4.486 0 0 0 10.025 8a4.486 4.486 0 0 0-1.318-3.182L8 5.525A3.489 3.489 0 0 1 9.025 8 3.49 3.49 0 0 1 8 10.475l.707.707z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</span>
|
||||
<input type="range" min="0" max="1" step="0.025" bind:this={audioPlayerVol} on:change={setVolume} on:keydown={disallowKeys}>
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max="1"
|
||||
step="0.025"
|
||||
bind:this={audioPlayerVol}
|
||||
on:change={setVolume}
|
||||
on:keydown={disallowKeys}
|
||||
/>
|
||||
</div>
|
||||
<div class="audio-manager-reduce-conversation">
|
||||
<label>
|
||||
reduce in conversations
|
||||
<input type="checkbox" bind:checked={decreaseWhileTalking} on:change={setDecrease}>
|
||||
<input type="checkbox" bind:checked={decreaseWhileTalking} on:change={setDecrease} />
|
||||
</label>
|
||||
<section class="audio-manager-file">
|
||||
<!-- svelte-ignore a11y-media-has-caption -->
|
||||
<audio class="audio-manager-audioplayer" bind:this={HTMLAudioPlayer}>
|
||||
<source src={$audioManagerFileStore}>
|
||||
<source src={$audioManagerFileStore} />
|
||||
</audio>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
div.main-audio-manager.nes-container.is-rounded {
|
||||
position: relative;
|
||||
@ -208,4 +227,4 @@
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script lang="typescript">
|
||||
import {requestedScreenSharingState, screenSharingAvailableStore} from "../Stores/ScreenSharingStore";
|
||||
import {isSilentStore, requestedCameraState, requestedMicrophoneState} from "../Stores/MediaStore";
|
||||
import { requestedScreenSharingState, screenSharingAvailableStore } from "../Stores/ScreenSharingStore";
|
||||
import { isSilentStore, requestedCameraState, requestedMicrophoneState } from "../Stores/MediaStore";
|
||||
import monitorImg from "./images/monitor.svg";
|
||||
import monitorCloseImg from "./images/monitor-close.svg";
|
||||
import cinemaImg from "./images/cinema.svg";
|
||||
@ -9,10 +9,10 @@
|
||||
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 {LayoutMode} from "../WebRtc/LayoutManager";
|
||||
import {peerStore} from "../Stores/PeerStore";
|
||||
import {onDestroy} from "svelte";
|
||||
import { layoutModeStore } from "../Stores/StreamableCollectionStore";
|
||||
import { LayoutMode } from "../WebRtc/LayoutManager";
|
||||
import { peerStore } from "../Stores/PeerStore";
|
||||
import { onDestroy } from "svelte";
|
||||
|
||||
function screenSharingClick(): void {
|
||||
if (isSilent) return;
|
||||
@ -50,7 +50,7 @@
|
||||
}
|
||||
|
||||
let isSilent: boolean;
|
||||
const unsubscribeIsSilent = isSilentStore.subscribe(value => {
|
||||
const unsubscribeIsSilent = isSilentStore.subscribe((value) => {
|
||||
isSilent = value;
|
||||
});
|
||||
onDestroy(unsubscribeIsSilent);
|
||||
@ -59,31 +59,36 @@
|
||||
<div>
|
||||
<div class="btn-cam-action">
|
||||
<div class="btn-layout" on:click={switchLayoutMode} class:hide={$peerStore.size === 0}>
|
||||
{#if $layoutModeStore === LayoutMode.Presentation }
|
||||
<img src={layoutPresentationImg} style="padding: 2px" alt="Switch to mosaic mode">
|
||||
{#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">
|
||||
<img src={layoutChatImg} style="padding: 2px" alt="Switch to presentation mode" />
|
||||
{/if}
|
||||
</div>
|
||||
<div class="btn-monitor" on:click={screenSharingClick} class:hide={!$screenSharingAvailableStore || isSilent} class:enabled={$requestedScreenSharingState}>
|
||||
<div
|
||||
class="btn-monitor"
|
||||
on:click={screenSharingClick}
|
||||
class:hide={!$screenSharingAvailableStore || isSilent}
|
||||
class:enabled={$requestedScreenSharingState}
|
||||
>
|
||||
{#if $requestedScreenSharingState && !isSilent}
|
||||
<img src={monitorImg} alt="Start screen sharing">
|
||||
<img src={monitorImg} alt="Start screen sharing" />
|
||||
{:else}
|
||||
<img src={monitorCloseImg} alt="Stop screen sharing">
|
||||
<img src={monitorCloseImg} alt="Stop screen sharing" />
|
||||
{/if}
|
||||
</div>
|
||||
<div class="btn-video" on:click={cameraClick} class:disabled={!$requestedCameraState || isSilent}>
|
||||
{#if $requestedCameraState && !isSilent}
|
||||
<img src={cinemaImg} alt="Turn on webcam">
|
||||
<img src={cinemaImg} alt="Turn on webcam" />
|
||||
{:else}
|
||||
<img src={cinemaCloseImg} alt="Turn off webcam">
|
||||
<img src={cinemaCloseImg} alt="Turn off webcam" />
|
||||
{/if}
|
||||
</div>
|
||||
<div class="btn-micro" on:click={microphoneClick} class:disabled={!$requestedMicrophoneState || isSilent}>
|
||||
{#if $requestedMicrophoneState && !isSilent}
|
||||
<img src={microphoneImg} alt="Turn on microphone">
|
||||
<img src={microphoneImg} alt="Turn on microphone" />
|
||||
{:else}
|
||||
<img src={microphoneCloseImg} alt="Turn off microphone">
|
||||
<img src={microphoneCloseImg} alt="Turn off microphone" />
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,23 +1,23 @@
|
||||
<script lang="ts">
|
||||
import { fly } from 'svelte/transition';
|
||||
import { fly } from "svelte/transition";
|
||||
import { chatMessagesStore, chatVisibilityStore } from "../../Stores/ChatStore";
|
||||
import ChatMessageForm from './ChatMessageForm.svelte';
|
||||
import ChatElement from './ChatElement.svelte';
|
||||
import {afterUpdate, beforeUpdate, onMount} from "svelte";
|
||||
import {HtmlUtils} from "../../WebRtc/HtmlUtils";
|
||||
|
||||
import ChatMessageForm from "./ChatMessageForm.svelte";
|
||||
import ChatElement from "./ChatElement.svelte";
|
||||
import { afterUpdate, beforeUpdate, onMount } from "svelte";
|
||||
import { HtmlUtils } from "../../WebRtc/HtmlUtils";
|
||||
|
||||
let listDom: HTMLElement;
|
||||
let chatWindowElement: HTMLElement;
|
||||
let handleFormBlur: { blur():void };
|
||||
let handleFormBlur: { blur(): void };
|
||||
let autoscroll: boolean;
|
||||
|
||||
beforeUpdate(() => {
|
||||
autoscroll = listDom && (listDom.offsetHeight + listDom.scrollTop) > (listDom.scrollHeight - 20);
|
||||
autoscroll = listDom && listDom.offsetHeight + listDom.scrollTop > listDom.scrollHeight - 20;
|
||||
});
|
||||
|
||||
onMount(() => {
|
||||
listDom.scrollTo(0, listDom.scrollHeight);
|
||||
})
|
||||
});
|
||||
|
||||
afterUpdate(() => {
|
||||
if (autoscroll) listDom.scrollTo(0, listDom.scrollHeight);
|
||||
@ -32,83 +32,82 @@
|
||||
function closeChat() {
|
||||
chatVisibilityStore.set(false);
|
||||
}
|
||||
function onKeyDown(e:KeyboardEvent) {
|
||||
if (e.key === 'Escape') {
|
||||
function onKeyDown(e: KeyboardEvent) {
|
||||
if (e.key === "Escape") {
|
||||
closeChat();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window on:keydown={onKeyDown} on:click={onClick}/>
|
||||
<svelte:window on:keydown={onKeyDown} on:click={onClick} />
|
||||
|
||||
|
||||
<aside class="chatWindow" transition:fly="{{ x: -1000, duration: 500 }}" bind:this={chatWindowElement}>
|
||||
<aside class="chatWindow" transition:fly={{ x: -1000, duration: 500 }} bind:this={chatWindowElement}>
|
||||
<p class="close-icon" on:click={closeChat}>×</p>
|
||||
<section class="messagesList" bind:this={listDom}>
|
||||
<ul>
|
||||
<li><p class="system-text">Here is your chat history: </p></li>
|
||||
{#each $chatMessagesStore as message, i}
|
||||
<li><ChatElement message={message} line={i}></ChatElement></li>
|
||||
{/each}
|
||||
<li><p class="system-text">Here is your chat history:</p></li>
|
||||
{#each $chatMessagesStore as message, i}
|
||||
<li><ChatElement {message} line={i} /></li>
|
||||
{/each}
|
||||
</ul>
|
||||
</section>
|
||||
<section class="messageForm">
|
||||
<ChatMessageForm bind:handleForm={handleFormBlur}></ChatMessageForm>
|
||||
<ChatMessageForm bind:handleForm={handleFormBlur} />
|
||||
</section>
|
||||
</aside>
|
||||
|
||||
<style lang="scss">
|
||||
p.close-icon {
|
||||
position: absolute;
|
||||
padding: 4px;
|
||||
right: 12px;
|
||||
font-size: 30px;
|
||||
line-height: 25px;
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
padding: 4px;
|
||||
right: 12px;
|
||||
font-size: 30px;
|
||||
line-height: 25px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
p.system-text {
|
||||
border-radius: 8px;
|
||||
margin-bottom: 10px;
|
||||
padding:6px;
|
||||
overflow-wrap: break-word;
|
||||
max-width: 100%;
|
||||
background: gray;
|
||||
display: inline-block;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 10px;
|
||||
padding: 6px;
|
||||
overflow-wrap: break-word;
|
||||
max-width: 100%;
|
||||
background: gray;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
aside.chatWindow {
|
||||
z-index:100;
|
||||
pointer-events: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100vh;
|
||||
width:30vw;
|
||||
min-width: 350px;
|
||||
background: rgb(5, 31, 51, 0.9);
|
||||
color: whitesmoke;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
z-index: 100;
|
||||
pointer-events: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100vh;
|
||||
width: 30vw;
|
||||
min-width: 350px;
|
||||
background: rgb(5, 31, 51, 0.9);
|
||||
color: whitesmoke;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
padding: 10px;
|
||||
|
||||
border-bottom-right-radius: 16px;
|
||||
border-top-right-radius: 16px;
|
||||
|
||||
.messagesList {
|
||||
margin-top: 35px;
|
||||
overflow-y: auto;
|
||||
flex: auto;
|
||||
padding: 10px;
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding-left: 0;
|
||||
border-bottom-right-radius: 16px;
|
||||
border-top-right-radius: 16px;
|
||||
|
||||
.messagesList {
|
||||
margin-top: 35px;
|
||||
overflow-y: auto;
|
||||
flex: auto;
|
||||
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
.messageForm {
|
||||
flex: 0 70px;
|
||||
padding-top: 15px;
|
||||
}
|
||||
}
|
||||
.messageForm {
|
||||
flex: 0 70px;
|
||||
padding-top: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -1,45 +1,53 @@
|
||||
<script lang="ts">
|
||||
import {ChatMessageTypes} from "../../Stores/ChatStore";
|
||||
import type {ChatMessage} from "../../Stores/ChatStore";
|
||||
import {HtmlUtils} from "../../WebRtc/HtmlUtils";
|
||||
import ChatPlayerName from './ChatPlayerName.svelte';
|
||||
import type {PlayerInterface} from "../../Phaser/Game/PlayerInterface";
|
||||
import { ChatMessageTypes } from "../../Stores/ChatStore";
|
||||
import type { ChatMessage } from "../../Stores/ChatStore";
|
||||
import { HtmlUtils } from "../../WebRtc/HtmlUtils";
|
||||
import ChatPlayerName from "./ChatPlayerName.svelte";
|
||||
import type { PlayerInterface } from "../../Phaser/Game/PlayerInterface";
|
||||
|
||||
export let message: ChatMessage;
|
||||
export let line: number;
|
||||
const chatStyleLink = "color: white; text-decoration: underline;";
|
||||
|
||||
|
||||
$: author = message.author as PlayerInterface;
|
||||
$: targets = message.targets || [];
|
||||
$: texts = message.text || [];
|
||||
|
||||
|
||||
function urlifyText(text: string): string {
|
||||
return HtmlUtils.urlify(text, chatStyleLink);
|
||||
}
|
||||
function renderDate(date: Date) {
|
||||
return date.toLocaleTimeString(navigator.language, {
|
||||
hour: '2-digit',
|
||||
minute:'2-digit'
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
});
|
||||
}
|
||||
function isLastIteration(index: number) {
|
||||
return targets.length -1 === index;
|
||||
return targets.length - 1 === index;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="chatElement">
|
||||
<div class="messagePart">
|
||||
{#if message.type === ChatMessageTypes.userIncoming}
|
||||
>> {#each targets as target, index}<ChatPlayerName player={target} line={line}></ChatPlayerName>{#if !isLastIteration(index)}, {/if}{/each} entered <span class="date">({renderDate(message.date)})</span>
|
||||
>> {#each targets as target, index}<ChatPlayerName
|
||||
player={target}
|
||||
{line}
|
||||
/>{#if !isLastIteration(index)}, {/if}{/each} entered
|
||||
<span class="date">({renderDate(message.date)})</span>
|
||||
{:else if message.type === ChatMessageTypes.userOutcoming}
|
||||
<< {#each targets as target, index}<ChatPlayerName player={target} line={line}></ChatPlayerName>{#if !isLastIteration(index)}, {/if}{/each} left <span class="date">({renderDate(message.date)})</span>
|
||||
<< {#each targets as target, index}<ChatPlayerName
|
||||
player={target}
|
||||
{line}
|
||||
/>{#if !isLastIteration(index)}, {/if}{/each} left
|
||||
<span class="date">({renderDate(message.date)})</span>
|
||||
{:else if message.type === ChatMessageTypes.me}
|
||||
<h4>Me: <span class="date">({renderDate(message.date)})</span></h4>
|
||||
{#each texts as text}
|
||||
<div><p class="my-text">{@html urlifyText(text)}</p></div>
|
||||
{/each}
|
||||
{:else}
|
||||
<h4><ChatPlayerName player={author} line={line}></ChatPlayerName>: <span class="date">({renderDate(message.date)})</span></h4>
|
||||
<h4><ChatPlayerName player={author} {line} />: <span class="date">({renderDate(message.date)})</span></h4>
|
||||
{#each texts as text}
|
||||
<div><p class="other-text">{@html urlifyText(text)}</p></div>
|
||||
{/each}
|
||||
@ -48,37 +56,38 @@
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
h4, p {
|
||||
h4,
|
||||
p {
|
||||
font-family: Lato;
|
||||
}
|
||||
div.chatElement {
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.messagePart {
|
||||
flex-grow:1;
|
||||
max-width: 100%;
|
||||
display: flex;
|
||||
margin-bottom: 20px;
|
||||
|
||||
span.date {
|
||||
font-size: 80%;
|
||||
color: gray;
|
||||
}
|
||||
.messagePart {
|
||||
flex-grow: 1;
|
||||
max-width: 100%;
|
||||
|
||||
div > p {
|
||||
border-radius: 8px;
|
||||
margin-bottom: 10px;
|
||||
padding:6px;
|
||||
overflow-wrap: break-word;
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
&.other-text {
|
||||
background: gray;
|
||||
}
|
||||
|
||||
&.my-text {
|
||||
background: #6489ff;
|
||||
}
|
||||
span.date {
|
||||
font-size: 80%;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
div > p {
|
||||
border-radius: 8px;
|
||||
margin-bottom: 10px;
|
||||
padding: 6px;
|
||||
overflow-wrap: break-word;
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
&.other-text {
|
||||
background: gray;
|
||||
}
|
||||
|
||||
&.my-text {
|
||||
background: #6489ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -1,14 +1,14 @@
|
||||
<script lang="ts">
|
||||
import {chatMessagesStore, chatInputFocusStore} from "../../Stores/ChatStore";
|
||||
import { chatMessagesStore, chatInputFocusStore } from "../../Stores/ChatStore";
|
||||
|
||||
export const handleForm = {
|
||||
blur() {
|
||||
inputElement.blur();
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
let inputElement: HTMLElement;
|
||||
let newMessageText = '';
|
||||
|
||||
let newMessageText = "";
|
||||
|
||||
function onFocus() {
|
||||
chatInputFocusStore.set(true);
|
||||
}
|
||||
@ -19,14 +19,21 @@
|
||||
function saveMessage() {
|
||||
if (!newMessageText) return;
|
||||
chatMessagesStore.addPersonnalMessage(newMessageText);
|
||||
newMessageText = '';
|
||||
newMessageText = "";
|
||||
}
|
||||
</script>
|
||||
|
||||
<form on:submit|preventDefault={saveMessage}>
|
||||
<input type="text" bind:value={newMessageText} placeholder="Enter your message..." on:focus={onFocus} on:blur={onBlur} bind:this={inputElement}>
|
||||
<input
|
||||
type="text"
|
||||
bind:value={newMessageText}
|
||||
placeholder="Enter your message..."
|
||||
on:focus={onFocus}
|
||||
on:blur={onBlur}
|
||||
bind:this={inputElement}
|
||||
/>
|
||||
<button type="submit">
|
||||
<img src="/static/images/send.png" alt="Send" width="20">
|
||||
<img src="/static/images/send.png" alt="Send" width="20" />
|
||||
</button>
|
||||
</form>
|
||||
|
||||
@ -35,28 +42,28 @@
|
||||
display: flex;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
|
||||
|
||||
input {
|
||||
flex: auto;
|
||||
background-color: #254560;
|
||||
color: white;
|
||||
border-bottom-left-radius: 4px;
|
||||
border-top-left-radius: 4px;
|
||||
border: none;
|
||||
font-size: 22px;
|
||||
font-family: Lato;
|
||||
padding-left: 6px;
|
||||
min-width: 0; //Needed so that the input doesn't overflow the container in firefox
|
||||
outline: none;
|
||||
flex: auto;
|
||||
background-color: #254560;
|
||||
color: white;
|
||||
border-bottom-left-radius: 4px;
|
||||
border-top-left-radius: 4px;
|
||||
border: none;
|
||||
font-size: 22px;
|
||||
font-family: Lato;
|
||||
padding-left: 6px;
|
||||
min-width: 0; //Needed so that the input doesn't overflow the container in firefox
|
||||
outline: none;
|
||||
}
|
||||
|
||||
|
||||
button {
|
||||
background-color: #254560;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
border: none;
|
||||
border-left: solid white 1px;
|
||||
font-size: 16px;
|
||||
background-color: #254560;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
border: none;
|
||||
border-left: solid white 1px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -1,8 +1,8 @@
|
||||
<script lang="ts">
|
||||
import type {PlayerInterface} from "../../Phaser/Game/PlayerInterface";
|
||||
import {chatSubMenuVisibilityStore} from "../../Stores/ChatStore";
|
||||
import {onDestroy, onMount} from "svelte";
|
||||
import type {Unsubscriber} from "svelte/store";
|
||||
import type { PlayerInterface } from "../../Phaser/Game/PlayerInterface";
|
||||
import { chatSubMenuVisibilityStore } from "../../Stores/ChatStore";
|
||||
import { onDestroy, onMount } from "svelte";
|
||||
import type { Unsubscriber } from "svelte/store";
|
||||
import ChatSubMenu from "./ChatSubMenu.svelte";
|
||||
|
||||
export let player: PlayerInterface;
|
||||
@ -17,35 +17,33 @@
|
||||
|
||||
onMount(() => {
|
||||
chatSubMenuVisivilytUnsubcribe = chatSubMenuVisibilityStore.subscribe((newValue) => {
|
||||
isSubMenuOpen = (newValue === player.name + line);
|
||||
})
|
||||
})
|
||||
isSubMenuOpen = newValue === player.name + line;
|
||||
});
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
chatSubMenuVisivilytUnsubcribe();
|
||||
})
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<span class="subMenu">
|
||||
<span class="chatPlayerName" style="color: {player.color || 'white'}" on:click={openSubMenu}>
|
||||
{player.name}
|
||||
{player.name}
|
||||
</span>
|
||||
{#if isSubMenuOpen}
|
||||
<ChatSubMenu player={player}/>
|
||||
<ChatSubMenu {player} />
|
||||
{/if}
|
||||
</span>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
span.subMenu {
|
||||
display: inline-block;
|
||||
}
|
||||
span.chatPlayerName {
|
||||
margin-left: 3px;
|
||||
}
|
||||
.chatPlayerName:hover {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
span.subMenu {
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
span.chatPlayerName {
|
||||
margin-left: 3px;
|
||||
}
|
||||
.chatPlayerName:hover {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,10 +1,9 @@
|
||||
<script lang="ts">
|
||||
import type {PlayerInterface} from "../../Phaser/Game/PlayerInterface";
|
||||
import {requestVisitCardsStore} from "../../Stores/GameStore";
|
||||
import type { PlayerInterface } from "../../Phaser/Game/PlayerInterface";
|
||||
import { requestVisitCardsStore } from "../../Stores/GameStore";
|
||||
|
||||
export let player: PlayerInterface;
|
||||
|
||||
|
||||
function openVisitCard() {
|
||||
if (player.visitCardUrl) {
|
||||
requestVisitCardsStore.set(player.visitCardUrl);
|
||||
@ -17,17 +16,16 @@
|
||||
<li><button class="text-btn" disabled>Add friend</button></li>
|
||||
</ul>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
ul.selectMenu {
|
||||
background-color: whitesmoke;
|
||||
position: absolute;
|
||||
padding: 5px;
|
||||
border-radius: 4px;
|
||||
list-style-type: none;
|
||||
ul.selectMenu {
|
||||
background-color: whitesmoke;
|
||||
position: absolute;
|
||||
padding: 5px;
|
||||
border-radius: 4px;
|
||||
list-style-type: none;
|
||||
|
||||
li {
|
||||
text-align: center;
|
||||
li {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script lang="typescript">
|
||||
import type { Game } from "../../Phaser/Game/Game";
|
||||
import {CustomizeScene, CustomizeSceneName} from "../../Phaser/Login/CustomizeScene";
|
||||
import {activeRowStore} from "../../Stores/CustomCharacterStore";
|
||||
import { CustomizeScene, CustomizeSceneName } from "../../Phaser/Login/CustomizeScene";
|
||||
import { activeRowStore } from "../../Stores/CustomCharacterStore";
|
||||
|
||||
export let game: Game;
|
||||
|
||||
@ -30,7 +30,6 @@
|
||||
function finish() {
|
||||
customCharacterScene.nextSceneToCamera();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<form class="customCharacterScene">
|
||||
@ -38,80 +37,100 @@
|
||||
<h2>Customize your WOKA</h2>
|
||||
</section>
|
||||
<section class="action action-move">
|
||||
<button class="customCharacterSceneButton customCharacterSceneButtonLeft nes-btn" on:click|preventDefault={ selectLeft }> < </button>
|
||||
<button class="customCharacterSceneButton customCharacterSceneButtonRight nes-btn" on:click|preventDefault={ selectRight }> > </button>
|
||||
<button
|
||||
class="customCharacterSceneButton customCharacterSceneButtonLeft nes-btn"
|
||||
on:click|preventDefault={selectLeft}
|
||||
>
|
||||
<
|
||||
</button>
|
||||
<button
|
||||
class="customCharacterSceneButton customCharacterSceneButtonRight nes-btn"
|
||||
on:click|preventDefault={selectRight}
|
||||
>
|
||||
>
|
||||
</button>
|
||||
</section>
|
||||
<section class="action">
|
||||
{#if $activeRowStore === 0}
|
||||
<button type="submit" class="customCharacterSceneFormBack nes-btn" on:click|preventDefault={ previousScene }>Return</button>
|
||||
<button type="submit" class="customCharacterSceneFormBack nes-btn" on:click|preventDefault={previousScene}
|
||||
>Return</button
|
||||
>
|
||||
{/if}
|
||||
{#if $activeRowStore !== 0}
|
||||
<button type="submit" class="customCharacterSceneFormBack nes-btn" on:click|preventDefault={ selectUp }>Back <img src="resources/objects/arrow_up_black.png" alt=""/></button>
|
||||
<button type="submit" class="customCharacterSceneFormBack nes-btn" on:click|preventDefault={selectUp}
|
||||
>Back <img src="resources/objects/arrow_up_black.png" alt="" /></button
|
||||
>
|
||||
{/if}
|
||||
{#if $activeRowStore === 5}
|
||||
<button type="submit" class="customCharacterSceneFormSubmit nes-btn is-primary" on:click|preventDefault={ finish }>Finish</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="customCharacterSceneFormSubmit nes-btn is-primary"
|
||||
on:click|preventDefault={finish}>Finish</button
|
||||
>
|
||||
{/if}
|
||||
{#if $activeRowStore !== 5}
|
||||
<button type="submit" class="customCharacterSceneFormSubmit nes-btn is-primary" on:click|preventDefault={ selectDown }>Next <img src="resources/objects/arrow_down.png" alt=""/></button>
|
||||
<button
|
||||
type="submit"
|
||||
class="customCharacterSceneFormSubmit nes-btn is-primary"
|
||||
on:click|preventDefault={selectDown}>Next <img src="resources/objects/arrow_down.png" alt="" /></button
|
||||
>
|
||||
{/if}
|
||||
</section>
|
||||
</form>
|
||||
|
||||
<style lang="scss">
|
||||
form.customCharacterScene {
|
||||
font-family: "Press Start 2P";
|
||||
pointer-events: auto;
|
||||
color: #ebeeee;
|
||||
|
||||
section {
|
||||
margin: 10px;
|
||||
|
||||
&.action {
|
||||
text-align: center;
|
||||
margin-top: 55vh;
|
||||
}
|
||||
|
||||
h2 {
|
||||
form.customCharacterScene {
|
||||
font-family: "Press Start 2P";
|
||||
margin: 1px;
|
||||
}
|
||||
pointer-events: auto;
|
||||
color: #ebeeee;
|
||||
|
||||
&.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
section {
|
||||
margin: 10px;
|
||||
|
||||
button.customCharacterSceneButton {
|
||||
position: absolute;
|
||||
top: 33vh;
|
||||
margin: 0;
|
||||
}
|
||||
&.action {
|
||||
text-align: center;
|
||||
margin-top: 55vh;
|
||||
}
|
||||
|
||||
button.customCharacterSceneFormBack {
|
||||
color: #292929;
|
||||
}
|
||||
h2 {
|
||||
font-family: "Press Start 2P";
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
&.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
button.customCharacterSceneButton {
|
||||
position: absolute;
|
||||
top: 33vh;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
button.customCharacterSceneFormBack {
|
||||
color: #292929;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
font-family: "Press Start 2P";
|
||||
|
||||
&.customCharacterSceneButtonLeft {
|
||||
left: 33vw;
|
||||
}
|
||||
|
||||
&.customCharacterSceneButtonRight {
|
||||
right: 33vw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
font-family: "Press Start 2P";
|
||||
|
||||
&.customCharacterSceneButtonLeft {
|
||||
left: 33vw;
|
||||
}
|
||||
|
||||
&.customCharacterSceneButtonRight {
|
||||
right: 33vw;
|
||||
}
|
||||
@media only screen and (max-width: 800px) {
|
||||
form.customCharacterScene button.customCharacterSceneButtonLeft {
|
||||
left: 5vw;
|
||||
}
|
||||
form.customCharacterScene button.customCharacterSceneButtonRight {
|
||||
right: 5vw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
form.customCharacterScene button.customCharacterSceneButtonLeft{
|
||||
left: 5vw;
|
||||
}
|
||||
form.customCharacterScene button.customCharacterSceneButtonRight{
|
||||
right: 5vw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
@ -1,75 +1,72 @@
|
||||
<script lang="typescript">
|
||||
import type { Unsubscriber } from "svelte/store";
|
||||
import { emoteStore, emoteMenuStore } from "../../Stores/EmoteStore";
|
||||
import { onDestroy, onMount } from "svelte";
|
||||
import { EmojiButton } from "@joeattardi/emoji-button";
|
||||
import { isMobile } from "../../Enum/EnvironmentVariable";
|
||||
|
||||
import type { Unsubscriber } from "svelte/store";
|
||||
import { emoteStore, emoteMenuStore } from "../../Stores/EmoteStore";
|
||||
import { onDestroy, onMount } from "svelte";
|
||||
import { EmojiButton } from '@joeattardi/emoji-button';
|
||||
import { isMobile } from "../../Enum/EnvironmentVariable";
|
||||
let emojiContainer: HTMLElement;
|
||||
let picker: EmojiButton;
|
||||
|
||||
let emojiContainer: HTMLElement;
|
||||
let picker: EmojiButton;
|
||||
let unsubscriber: Unsubscriber | null = null;
|
||||
|
||||
let unsubscriber: Unsubscriber | null = null;
|
||||
onMount(() => {
|
||||
picker = new EmojiButton({
|
||||
rootElement: emojiContainer,
|
||||
styleProperties: {
|
||||
"--font": "Press Start 2P",
|
||||
},
|
||||
emojisPerRow: isMobile() ? 6 : 8,
|
||||
autoFocusSearch: false,
|
||||
style: "twemoji",
|
||||
});
|
||||
//the timeout is here to prevent the menu from flashing
|
||||
setTimeout(() => picker.showPicker(emojiContainer), 100);
|
||||
|
||||
onMount(() => {
|
||||
picker = new EmojiButton({
|
||||
rootElement: emojiContainer,
|
||||
styleProperties: {
|
||||
'--font': 'Press Start 2P'
|
||||
},
|
||||
emojisPerRow: isMobile() ? 6 : 8,
|
||||
autoFocusSearch: false,
|
||||
style: 'twemoji',
|
||||
});
|
||||
//the timeout is here to prevent the menu from flashing
|
||||
setTimeout(() => picker.showPicker(emojiContainer), 100);
|
||||
picker.on("emoji", (selection) => {
|
||||
emoteStore.set({
|
||||
unicode: selection.emoji,
|
||||
url: selection.url,
|
||||
name: selection.name,
|
||||
});
|
||||
});
|
||||
|
||||
picker.on("emoji", (selection) => {
|
||||
emoteStore.set({
|
||||
unicode: selection.emoji,
|
||||
url: selection.url,
|
||||
name: selection.name
|
||||
});
|
||||
picker.on("hidden", () => {
|
||||
emoteMenuStore.closeEmoteMenu();
|
||||
});
|
||||
});
|
||||
|
||||
picker.on("hidden", () => {
|
||||
emoteMenuStore.closeEmoteMenu();
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
function onKeyDown(e:KeyboardEvent) {
|
||||
if (e.key === 'Escape') {
|
||||
emoteMenuStore.closeEmoteMenu();
|
||||
}
|
||||
}
|
||||
|
||||
onDestroy(() => {
|
||||
if (unsubscriber) {
|
||||
unsubscriber();
|
||||
function onKeyDown(e: KeyboardEvent) {
|
||||
if (e.key === "Escape") {
|
||||
emoteMenuStore.closeEmoteMenu();
|
||||
}
|
||||
}
|
||||
|
||||
picker.destroyPicker();
|
||||
})
|
||||
onDestroy(() => {
|
||||
if (unsubscriber) {
|
||||
unsubscriber();
|
||||
}
|
||||
|
||||
picker.destroyPicker();
|
||||
});
|
||||
</script>
|
||||
|
||||
<svelte:window on:keydown={onKeyDown}/>
|
||||
<svelte:window on:keydown={onKeyDown} />
|
||||
|
||||
<div class="emote-menu-container">
|
||||
<div class="emote-menu" bind:this={emojiContainer}></div>
|
||||
<div class="emote-menu" bind:this={emojiContainer} />
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.emote-menu-container {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.emote-menu-container {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.emote-menu {
|
||||
pointer-events: all;
|
||||
}
|
||||
</style>
|
||||
.emote-menu {
|
||||
pointer-events: all;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,22 +1,22 @@
|
||||
<script lang="typescript">
|
||||
import type {Game} from "../../Phaser/Game/Game";
|
||||
import {EnableCameraScene, EnableCameraSceneName} from "../../Phaser/Login/EnableCameraScene";
|
||||
import type { Game } from "../../Phaser/Game/Game";
|
||||
import { EnableCameraScene, EnableCameraSceneName } from "../../Phaser/Login/EnableCameraScene";
|
||||
import {
|
||||
audioConstraintStore,
|
||||
cameraListStore,
|
||||
localStreamStore,
|
||||
microphoneListStore,
|
||||
videoConstraintStore
|
||||
videoConstraintStore,
|
||||
} from "../../Stores/MediaStore";
|
||||
import {onDestroy} from "svelte";
|
||||
import { onDestroy } from "svelte";
|
||||
import HorizontalSoundMeterWidget from "./HorizontalSoundMeterWidget.svelte";
|
||||
import cinemaCloseImg from "../images/cinema-close.svg";
|
||||
import cinemaImg from "../images/cinema.svg";
|
||||
import microphoneImg from "../images/microphone.svg";
|
||||
|
||||
export let game: Game;
|
||||
let selectedCamera : string|undefined = undefined;
|
||||
let selectedMicrophone : string|undefined = undefined;
|
||||
let selectedCamera: string | undefined = undefined;
|
||||
let selectedMicrophone: string | undefined = undefined;
|
||||
|
||||
const enableCameraScene = game.scene.getScene(EnableCameraSceneName) as EnableCameraScene;
|
||||
|
||||
@ -29,16 +29,16 @@
|
||||
return {
|
||||
update(newStream: MediaStream) {
|
||||
if (node.srcObject != newStream) {
|
||||
node.srcObject = newStream
|
||||
node.srcObject = newStream;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
let stream: MediaStream | null;
|
||||
|
||||
const unsubscribe = localStreamStore.subscribe(value => {
|
||||
if (value.type === 'success') {
|
||||
const unsubscribe = localStreamStore.subscribe((value) => {
|
||||
if (value.type === "success") {
|
||||
stream = value.stream;
|
||||
|
||||
if (stream !== null) {
|
||||
@ -62,7 +62,7 @@
|
||||
|
||||
function normalizeDeviceName(label: string): string {
|
||||
// remove IDs (that can appear in Chrome, like: "HD Pro Webcam (4df7:4eda)"
|
||||
return label.replace(/(\([[0-9a-f]{4}:[0-9a-f]{4}\))/g, '').trim();
|
||||
return label.replace(/(\([[0-9a-f]{4}:[0-9a-f]{4}\))/g, "").trim();
|
||||
}
|
||||
|
||||
function selectCamera() {
|
||||
@ -72,28 +72,27 @@
|
||||
function selectMicrophone() {
|
||||
audioConstraintStore.setDeviceId(selectedMicrophone);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<form class="enableCameraScene" on:submit|preventDefault={submit}>
|
||||
<section class="text-center">
|
||||
<h2>Turn on your camera and microphone</h2>
|
||||
</section>
|
||||
{#if $localStreamStore.type === 'success' && $localStreamStore.stream}
|
||||
<video class="myCamVideoSetup" use:srcObject={$localStreamStore.stream} autoplay muted playsinline></video>
|
||||
{:else }
|
||||
<div class="webrtcsetup">
|
||||
<img class="background-img" src={cinemaCloseImg} alt="">
|
||||
</div>
|
||||
{/if}
|
||||
<HorizontalSoundMeterWidget stream={stream}></HorizontalSoundMeterWidget>
|
||||
{#if $localStreamStore.type === "success" && $localStreamStore.stream}
|
||||
<video class="myCamVideoSetup" use:srcObject={$localStreamStore.stream} autoplay muted playsinline />
|
||||
{:else}
|
||||
<div class="webrtcsetup">
|
||||
<img class="background-img" src={cinemaCloseImg} alt="" />
|
||||
</div>
|
||||
{/if}
|
||||
<HorizontalSoundMeterWidget {stream} />
|
||||
|
||||
<section class="selectWebcamForm">
|
||||
|
||||
{#if $cameraListStore.length > 1 }
|
||||
{#if $cameraListStore.length > 1}
|
||||
<div class="control-group">
|
||||
<img src={cinemaImg} alt="Camera" />
|
||||
<div class="nes-select is-dark">
|
||||
<!-- svelte-ignore a11y-no-onchange -->
|
||||
<select bind:value={selectedCamera} on:change={selectCamera}>
|
||||
{#each $cameraListStore as camera}
|
||||
<option value={camera.deviceId}>
|
||||
@ -105,10 +104,11 @@
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if $microphoneListStore.length > 1 }
|
||||
{#if $microphoneListStore.length > 1}
|
||||
<div class="control-group">
|
||||
<img src={microphoneImg} alt="Microphone" />
|
||||
<div class="nes-select is-dark">
|
||||
<!-- svelte-ignore a11y-no-onchange -->
|
||||
<select bind:value={selectedMicrophone} on:change={selectMicrophone}>
|
||||
{#each $microphoneListStore as microphone}
|
||||
<option value={microphone.deviceId}>
|
||||
@ -119,111 +119,109 @@
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
</section>
|
||||
<section class="action">
|
||||
<button type="submit" class="nes-btn is-primary letsgo" >Let's go!</button>
|
||||
<button type="submit" class="nes-btn is-primary letsgo">Let's go!</button>
|
||||
</section>
|
||||
</form>
|
||||
|
||||
<style lang="scss">
|
||||
.enableCameraScene {
|
||||
pointer-events: auto;
|
||||
margin: 20px auto 0;
|
||||
color: #ebeeee;
|
||||
pointer-events: auto;
|
||||
margin: 20px auto 0;
|
||||
color: #ebeeee;
|
||||
|
||||
section.selectWebcamForm {
|
||||
margin-top: 3vh;
|
||||
margin-bottom: 3vh;
|
||||
min-height: 10vh;
|
||||
width: 50vw;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
section.selectWebcamForm {
|
||||
margin-top: 3vh;
|
||||
margin-bottom: 3vh;
|
||||
min-height: 10vh;
|
||||
width: 50vw;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
|
||||
select {
|
||||
font-family: "Press Start 2P";
|
||||
margin-top: 1vh;
|
||||
margin-bottom: 1vh;
|
||||
select {
|
||||
font-family: "Press Start 2P";
|
||||
margin-top: 1vh;
|
||||
margin-bottom: 1vh;
|
||||
}
|
||||
|
||||
option {
|
||||
font-family: "Press Start 2P";
|
||||
}
|
||||
}
|
||||
|
||||
option {
|
||||
section.action {
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-family: "Press Start 2P";
|
||||
}
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
section.action{
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h2{
|
||||
font-family: "Press Start 2P";
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
section.text-center{
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
button.letsgo {
|
||||
font-size: 200%;
|
||||
}
|
||||
|
||||
.control-group {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
max-height: 60px;
|
||||
margin-top: 10px;
|
||||
|
||||
img {
|
||||
width: 30px;
|
||||
margin-right: 10px;
|
||||
section.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.webrtcsetup{
|
||||
margin-top: 2vh;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
height: 28.125vw;
|
||||
width: 50vw;
|
||||
border: white 6px solid;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
img.background-img {
|
||||
width: 40%;
|
||||
button.letsgo {
|
||||
font-size: 200%;
|
||||
}
|
||||
}
|
||||
.myCamVideoSetup {
|
||||
margin-top: 2vh;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-height: 50vh;
|
||||
width: 50vw;
|
||||
border: white 6px solid;
|
||||
-webkit-transform: scaleX(-1);
|
||||
transform: scaleX(-1);
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.control-group {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
max-height: 60px;
|
||||
margin-top: 10px;
|
||||
|
||||
img {
|
||||
width: 30px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.webrtcsetup {
|
||||
margin-top: 2vh;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
height: 28.125vw;
|
||||
width: 50vw;
|
||||
border: white 6px solid;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
img.background-img {
|
||||
width: 40%;
|
||||
}
|
||||
}
|
||||
.myCamVideoSetup {
|
||||
margin-top: 2vh;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-height: 50vh;
|
||||
width: 50vw;
|
||||
border: white 6px solid;
|
||||
-webkit-transform: scaleX(-1);
|
||||
transform: scaleX(-1);
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
.enableCameraScene h2 {
|
||||
font-size: 80%;
|
||||
}
|
||||
.enableCameraScene .control-group .nes-select {
|
||||
font-size: 80%;
|
||||
}
|
||||
.enableCameraScene button.letsgo {
|
||||
font-size: 160%;
|
||||
}
|
||||
.enableCameraScene h2 {
|
||||
font-size: 80%;
|
||||
}
|
||||
.enableCameraScene .control-group .nes-select {
|
||||
font-size: 80%;
|
||||
}
|
||||
.enableCameraScene button.letsgo {
|
||||
font-size: 160%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script lang="typescript">
|
||||
import { AudioContext } from 'standardized-audio-context';
|
||||
import {SoundMeter} from "../../Phaser/Components/SoundMeter";
|
||||
import {onDestroy} from "svelte";
|
||||
import { AudioContext } from "standardized-audio-context";
|
||||
import { SoundMeter } from "../../Phaser/Components/SoundMeter";
|
||||
import { onDestroy } from "svelte";
|
||||
|
||||
export let stream: MediaStream | null;
|
||||
let volume = 0;
|
||||
@ -11,6 +11,7 @@
|
||||
let timeout: ReturnType<typeof setTimeout>;
|
||||
const soundMeter = new SoundMeter();
|
||||
let display = false;
|
||||
let error = false;
|
||||
|
||||
$: {
|
||||
if (stream && stream.getAudioTracks().length > 0) {
|
||||
@ -19,17 +20,19 @@
|
||||
|
||||
if (timeout) {
|
||||
clearInterval(timeout);
|
||||
error = false;
|
||||
}
|
||||
|
||||
timeout = setInterval(() => {
|
||||
try{
|
||||
volume = parseInt((soundMeter.getVolume() / 100 * NB_BARS).toFixed(0));
|
||||
//console.log(volume);
|
||||
}catch(err){
|
||||
|
||||
try {
|
||||
volume = parseInt(((soundMeter.getVolume() / 100) * NB_BARS).toFixed(0));
|
||||
} catch (err) {
|
||||
if (!error) {
|
||||
console.error(err);
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
|
||||
} else {
|
||||
display = false;
|
||||
}
|
||||
@ -40,11 +43,10 @@
|
||||
if (timeout) {
|
||||
clearInterval(timeout);
|
||||
}
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
function color(i: number, volume: number) {
|
||||
const red = 255 * i / NB_BARS;
|
||||
const red = (255 * i) / NB_BARS;
|
||||
const green = 255 * (1 - i / NB_BARS);
|
||||
|
||||
let alpha = 1;
|
||||
@ -52,31 +54,29 @@
|
||||
alpha = 0.5;
|
||||
}
|
||||
|
||||
return 'background-color:rgba('+red+', '+green+', 0, '+alpha+')';
|
||||
return "background-color:rgba(" + red + ", " + green + ", 0, " + alpha + ")";
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<div class="horizontal-sound-meter" class:active={display}>
|
||||
{#each [...Array(NB_BARS).keys()] as i (i)}
|
||||
<div style={color(i, volume)}></div>
|
||||
<div style={color(i, volume)} />
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.horizontal-sound-meter {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 50%;
|
||||
height: 30px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 1vh;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 50%;
|
||||
height: 30px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-top: 1vh;
|
||||
}
|
||||
|
||||
.horizontal-sound-meter div {
|
||||
margin-left: 5px;
|
||||
flex-grow: 1;
|
||||
margin-left: 5px;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<script lang="typescript">
|
||||
import { fly } from 'svelte/transition';
|
||||
import {helpCameraSettingsVisibleStore} from "../../Stores/HelpCameraSettingsStore";
|
||||
import { fly } from "svelte/transition";
|
||||
import { helpCameraSettingsVisibleStore } from "../../Stores/HelpCameraSettingsStore";
|
||||
import firefoxImg from "./images/help-setting-camera-permission-firefox.png";
|
||||
import chromeImg from "./images/help-setting-camera-permission-chrome.png";
|
||||
import {getNavigatorType, isAndroid as isAndroidFct, NavigatorType} from "../../WebRtc/DeviceUtils";
|
||||
import { getNavigatorType, isAndroid as isAndroidFct, NavigatorType } from "../../WebRtc/DeviceUtils";
|
||||
|
||||
let isAndroid = isAndroidFct();
|
||||
let isFirefox = getNavigatorType() === NavigatorType.firefox;
|
||||
@ -16,30 +16,37 @@
|
||||
function close() {
|
||||
helpCameraSettingsVisibleStore.set(false);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<form class="helpCameraSettings nes-container" on:submit|preventDefault={close} transition:fly="{{ y: -900, duration: 500 }}">
|
||||
<form
|
||||
class="helpCameraSettings nes-container"
|
||||
on:submit|preventDefault={close}
|
||||
transition:fly={{ y: -900, duration: 500 }}
|
||||
>
|
||||
<section>
|
||||
<h2>Camera / Microphone access needed</h2>
|
||||
<p class="err">Permission denied</p>
|
||||
<p>You must allow camera and microphone access in your browser.</p>
|
||||
<p>
|
||||
{#if isFirefox }
|
||||
<p class="err">Please click the "Remember this decision" checkbox, if you don't want Firefox to keep asking you the authorization.</p>
|
||||
{#if isFirefox}
|
||||
<p class="err">
|
||||
Please click the "Remember this decision" checkbox, if you don't want Firefox to keep asking you the
|
||||
authorization.
|
||||
</p>
|
||||
<img src={firefoxImg} alt="" />
|
||||
{:else if isChrome && !isAndroid }
|
||||
{:else if isChrome && !isAndroid}
|
||||
<img src={chromeImg} alt="" />
|
||||
{/if}
|
||||
</p>
|
||||
</section>
|
||||
<section>
|
||||
<button class="helpCameraSettingsFormRefresh nes-btn" on:click|preventDefault={refresh}>Refresh</button>
|
||||
<button type="submit" class="helpCameraSettingsFormContinue nes-btn is-primary" on:click|preventDefault={close}>Continue without webcam</button>
|
||||
<button type="submit" class="helpCameraSettingsFormContinue nes-btn is-primary" on:click|preventDefault={close}
|
||||
>Continue without webcam</button
|
||||
>
|
||||
</section>
|
||||
</form>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
.helpCameraSettings {
|
||||
pointer-events: auto;
|
||||
@ -53,13 +60,13 @@
|
||||
text-align: center;
|
||||
|
||||
h2 {
|
||||
font-family: 'Press Start 2P';
|
||||
font-family: "Press Start 2P";
|
||||
}
|
||||
|
||||
section {
|
||||
p {
|
||||
margin: 15px;
|
||||
font-family: 'Press Start 2P';
|
||||
font-family: "Press Start 2P";
|
||||
|
||||
& .err {
|
||||
color: #ff0000;
|
||||
|
@ -6,7 +6,6 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<div class="layout-manager-list">
|
||||
{#each $layoutManagerActionStore as action}
|
||||
<div class="nes-container is-rounded {action.type}" on:click={() => onClick(action.callback)}>
|
||||
@ -15,43 +14,48 @@
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
div.layout-manager-list {
|
||||
pointer-events: auto;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 40px;
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
width: clamp(200px, 20vw, 20vw);
|
||||
div.layout-manager-list {
|
||||
pointer-events: auto;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 40px;
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
width: clamp(200px, 20vw, 20vw);
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
animation: moveMessage .5s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-timing-function: ease-in-out;
|
||||
}
|
||||
|
||||
div.nes-container.is-rounded {
|
||||
padding: 8px 4px;
|
||||
text-align: center;
|
||||
|
||||
font-family: Lato;
|
||||
color: whitesmoke;
|
||||
background-color: rgb(0,0,0,0.5);
|
||||
|
||||
&.warning {
|
||||
background-color: #ff9800eb;
|
||||
color: #000;
|
||||
animation: moveMessage 0.5s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-timing-function: ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes moveMessage {
|
||||
0% {bottom: 40px;}
|
||||
50% {bottom: 30px;}
|
||||
100% {bottom: 40px;}
|
||||
}
|
||||
div.nes-container.is-rounded {
|
||||
padding: 8px 4px;
|
||||
text-align: center;
|
||||
|
||||
font-family: Lato;
|
||||
color: whitesmoke;
|
||||
background-color: rgb(0, 0, 0, 0.5);
|
||||
|
||||
&.warning {
|
||||
background-color: #ff9800eb;
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes moveMessage {
|
||||
0% {
|
||||
bottom: 40px;
|
||||
}
|
||||
50% {
|
||||
bottom: 30px;
|
||||
}
|
||||
100% {
|
||||
bottom: 40px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,22 +1,22 @@
|
||||
<script lang="typescript">
|
||||
import type {Game} from "../../Phaser/Game/Game";
|
||||
import {LoginScene, LoginSceneName} from "../../Phaser/Login/LoginScene";
|
||||
import {DISPLAY_TERMS_OF_USE, MAX_USERNAME_LENGTH} from "../../Enum/EnvironmentVariable";
|
||||
import type { Game } from "../../Phaser/Game/Game";
|
||||
import { LoginScene, LoginSceneName } from "../../Phaser/Login/LoginScene";
|
||||
import { DISPLAY_TERMS_OF_USE, MAX_USERNAME_LENGTH } from "../../Enum/EnvironmentVariable";
|
||||
import logoImg from "../images/logo.png";
|
||||
import {gameManager} from "../../Phaser/Game/GameManager";
|
||||
import { gameManager } from "../../Phaser/Game/GameManager";
|
||||
|
||||
export let game: Game;
|
||||
|
||||
const loginScene = game.scene.getScene(LoginSceneName) as LoginScene;
|
||||
|
||||
let name = gameManager.getPlayerName() || '';
|
||||
let name = gameManager.getPlayerName() || "";
|
||||
let startValidating = false;
|
||||
|
||||
function submit() {
|
||||
startValidating = true;
|
||||
|
||||
let finalName = name.trim();
|
||||
if (finalName !== '') {
|
||||
if (finalName !== "") {
|
||||
loginScene.login(finalName);
|
||||
}
|
||||
}
|
||||
@ -29,17 +29,34 @@
|
||||
<section class="text-center">
|
||||
<h2>Enter your name</h2>
|
||||
</section>
|
||||
<input type="text" name="loginSceneName" class="nes-input is-dark" autofocus maxlength={MAX_USERNAME_LENGTH} bind:value={name} on:keypress={() => {startValidating = true}} class:is-error={name.trim() === '' && startValidating} />
|
||||
<!-- svelte-ignore a11y-autofocus -->
|
||||
<input
|
||||
type="text"
|
||||
name="loginSceneName"
|
||||
class="nes-input is-dark"
|
||||
autofocus
|
||||
maxlength={MAX_USERNAME_LENGTH}
|
||||
bind:value={name}
|
||||
on:keypress={() => {
|
||||
startValidating = true;
|
||||
}}
|
||||
class:is-error={name.trim() === "" && startValidating}
|
||||
/>
|
||||
<section class="error-section">
|
||||
{#if name.trim() === '' && startValidating }
|
||||
<p class="err">The name is empty</p>
|
||||
{/if}
|
||||
{#if name.trim() === "" && startValidating}
|
||||
<p class="err">The name is empty</p>
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
{#if DISPLAY_TERMS_OF_USE}
|
||||
<section class="terms-and-conditions">
|
||||
<p>By continuing, you are agreeing our <a href="https://workadventu.re/terms-of-use" target="_blank">terms of use</a>, <a href="https://workadventu.re/privacy-policy" target="_blank">privacy policy</a> and <a href="https://workadventu.re/cookie-policy" target="_blank">cookie policy</a>.</p>
|
||||
</section>
|
||||
<section class="terms-and-conditions">
|
||||
<p>
|
||||
By continuing, you are agreeing our <a href="https://workadventu.re/terms-of-use" target="_blank"
|
||||
>terms of use</a
|
||||
>, <a href="https://workadventu.re/privacy-policy" target="_blank">privacy policy</a> and
|
||||
<a href="https://workadventu.re/cookie-policy" target="_blank">cookie policy</a>.
|
||||
</p>
|
||||
</section>
|
||||
{/if}
|
||||
<section class="action">
|
||||
<button type="submit" class="nes-btn is-primary loginSceneFormSubmit">Continue</button>
|
||||
@ -47,76 +64,75 @@
|
||||
</form>
|
||||
|
||||
<style lang="scss">
|
||||
.loginScene {
|
||||
pointer-events: auto;
|
||||
margin: 20px auto 0;
|
||||
width: 90%;
|
||||
color: #ebeeee;
|
||||
|
||||
display: flex;
|
||||
flex-flow: column wrap;
|
||||
align-items: center;
|
||||
|
||||
input {
|
||||
text-align: center;
|
||||
font-family: "Press Start 2P";
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.terms-and-conditions {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
p.err {
|
||||
color: #ce372b;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
section {
|
||||
margin: 10px;
|
||||
|
||||
&.error-section {
|
||||
min-height: 2rem;
|
||||
margin: 0;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.action {
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-family: "Press Start 2P";
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
&.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: underline;
|
||||
.loginScene {
|
||||
pointer-events: auto;
|
||||
margin: 20px auto 0;
|
||||
width: 90%;
|
||||
color: #ebeeee;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
font-weight: 700;
|
||||
}
|
||||
display: flex;
|
||||
flex-flow: column wrap;
|
||||
align-items: center;
|
||||
|
||||
p {
|
||||
text-align: left;
|
||||
margin: 10px 10px;
|
||||
}
|
||||
input {
|
||||
text-align: center;
|
||||
font-family: "Press Start 2P";
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.terms-and-conditions {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
p.err {
|
||||
color: #ce372b;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
section {
|
||||
margin: 10px;
|
||||
|
||||
&.error-section {
|
||||
min-height: 2rem;
|
||||
margin: 0;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.action {
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-family: "Press Start 2P";
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
&.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: underline;
|
||||
color: #ebeeee;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
p {
|
||||
text-align: left;
|
||||
margin: 10px 10px;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
margin: 20px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import { gameManager } from "../../Phaser/Game/GameManager";
|
||||
import {onMount} from "svelte";
|
||||
import { onMount } from "svelte";
|
||||
|
||||
let gameScene = gameManager.getCurrentGameScene();
|
||||
|
||||
@ -14,29 +14,33 @@
|
||||
|
||||
onMount(() => {
|
||||
if (gameScene.mapFile.properties !== undefined) {
|
||||
const propertyName = gameScene.mapFile.properties.find((property) => property.name === 'mapName')
|
||||
if ( propertyName !== undefined && typeof propertyName.value === 'string') {
|
||||
const propertyName = gameScene.mapFile.properties.find((property) => property.name === "mapName");
|
||||
if (propertyName !== undefined && typeof propertyName.value === "string") {
|
||||
mapName = propertyName.value;
|
||||
}
|
||||
const propertyDescription = gameScene.mapFile.properties.find((property) => property.name === 'mapDescription')
|
||||
if (propertyDescription !== undefined && typeof propertyDescription.value === 'string') {
|
||||
const propertyDescription = gameScene.mapFile.properties.find(
|
||||
(property) => property.name === "mapDescription"
|
||||
);
|
||||
if (propertyDescription !== undefined && typeof propertyDescription.value === "string") {
|
||||
mapDescription = propertyDescription.value;
|
||||
}
|
||||
const propertyCopyright = gameScene.mapFile.properties.find((property) => property.name === 'mapCopyright')
|
||||
if (propertyCopyright !== undefined && typeof propertyCopyright.value === 'string') {
|
||||
const propertyCopyright = gameScene.mapFile.properties.find((property) => property.name === "mapCopyright");
|
||||
if (propertyCopyright !== undefined && typeof propertyCopyright.value === "string") {
|
||||
mapCopyright = propertyCopyright.value;
|
||||
}
|
||||
}
|
||||
|
||||
for (const tileset of gameScene.mapFile.tilesets) {
|
||||
if (tileset.properties !== undefined) {
|
||||
const propertyTilesetCopyright = tileset.properties.find((property) => property.name === 'tilesetCopyright')
|
||||
if (propertyTilesetCopyright !== undefined && typeof propertyTilesetCopyright.value === 'string') {
|
||||
const propertyTilesetCopyright = tileset.properties.find(
|
||||
(property) => property.name === "tilesetCopyright"
|
||||
);
|
||||
if (propertyTilesetCopyright !== undefined && typeof propertyTilesetCopyright.value === "string") {
|
||||
tilesetCopyright = [...tilesetCopyright, propertyTilesetCopyright.value]; //Assignment needed to trigger Svelte's reactivity
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="about-room-main">
|
||||
@ -44,51 +48,58 @@
|
||||
<section class="container-overflow">
|
||||
<h3>{mapName}</h3>
|
||||
<p class="string-HTML">{mapDescription}</p>
|
||||
<h3 class="nes-pointer hoverable" on:click={() => expandedMapCopyright = !expandedMapCopyright}>Copyrights of the map</h3>
|
||||
<p class="string-HTML" hidden="{!expandedMapCopyright}">{mapCopyright}</p>
|
||||
<h3 class="nes-pointer hoverable" on:click={() => expandedTilesetCopyright = !expandedTilesetCopyright}>Copyrights of the tilesets</h3>
|
||||
<section hidden="{!expandedTilesetCopyright}">
|
||||
<h3 class="nes-pointer hoverable" on:click={() => (expandedMapCopyright = !expandedMapCopyright)}>
|
||||
Copyrights of the map
|
||||
</h3>
|
||||
<p class="string-HTML" hidden={!expandedMapCopyright}>{mapCopyright}</p>
|
||||
<h3 class="nes-pointer hoverable" on:click={() => (expandedTilesetCopyright = !expandedTilesetCopyright)}>
|
||||
Copyrights of the tilesets
|
||||
</h3>
|
||||
<section hidden={!expandedTilesetCopyright}>
|
||||
{#each tilesetCopyright as copyright}
|
||||
<p class="string-HTML">{copyright}</p>
|
||||
{:else}
|
||||
<p>The map creator did not declare a copyright for the tilesets. Warning, This doesn't mean that those tilesets have no license.</p>
|
||||
<p>
|
||||
The map creator did not declare a copyright for the tilesets. Warning, This doesn't mean that those
|
||||
tilesets have no license.
|
||||
</p>
|
||||
{/each}
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
.string-HTML{
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
div.about-room-main {
|
||||
height: calc(100% - 56px);
|
||||
|
||||
h2, h3 {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
.string-HTML {
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
h3.hoverable:hover {
|
||||
background-color: #3c3e40;
|
||||
border-radius: 32px;
|
||||
}
|
||||
|
||||
section.container-overflow {
|
||||
height: calc(100% - 220px);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px), only screen and (max-height: 800px) {
|
||||
div.about-room-main {
|
||||
section.container-overflow {
|
||||
height: calc(100% - 120px);
|
||||
}
|
||||
height: calc(100% - 56px);
|
||||
|
||||
h2,
|
||||
h3 {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h3.hoverable:hover {
|
||||
background-color: #3c3e40;
|
||||
border-radius: 32px;
|
||||
}
|
||||
|
||||
section.container-overflow {
|
||||
height: calc(100% - 220px);
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@media only screen and (max-width: 800px), only screen and (max-height: 800px) {
|
||||
div.about-room-main {
|
||||
section.container-overflow {
|
||||
height: calc(100% - 120px);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -26,31 +26,31 @@
|
||||
const selectedFile = inputAudio.files ? inputAudio.files[0] : null;
|
||||
if (!selectedFile) {
|
||||
errorFile = true;
|
||||
throw 'no file selected';
|
||||
throw "no file selected";
|
||||
}
|
||||
|
||||
const fd = new FormData();
|
||||
fd.append('file', selectedFile);
|
||||
fd.append("file", selectedFile);
|
||||
const res = await gameScene.connection?.uploadAudio(fd);
|
||||
|
||||
const audioGlobalMessage: PlayGlobalMessageInterface = {
|
||||
content: (res as { path: string }).path,
|
||||
type: AUDIO_TYPE,
|
||||
broadcastToWorld: broadcast
|
||||
}
|
||||
inputAudio.value = '';
|
||||
broadcastToWorld: broadcast,
|
||||
};
|
||||
inputAudio.value = "";
|
||||
gameScene.connection?.emitGlobalMessage(audioGlobalMessage);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function inputAudioFile(event: Event) {
|
||||
const eventTarget : EventTargetFiles = (event.target as EventTargetFiles);
|
||||
if(!eventTarget || !eventTarget.files || eventTarget.files.length === 0){
|
||||
const eventTarget: EventTargetFiles = event.target as EventTargetFiles;
|
||||
if (!eventTarget || !eventTarget.files || eventTarget.files.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const file = eventTarget.files[0];
|
||||
if(!file) {
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -61,52 +61,65 @@
|
||||
|
||||
function getFileSize(number: number) {
|
||||
if (number < 1024) {
|
||||
return number + 'bytes';
|
||||
return number + "bytes";
|
||||
} else if (number >= 1024 && number < 1048576) {
|
||||
return (number / 1024).toFixed(1) + 'KB';
|
||||
return (number / 1024).toFixed(1) + "KB";
|
||||
} else if (number >= 1048576) {
|
||||
return (number / 1048576).toFixed(1) + 'MB';
|
||||
return (number / 1048576).toFixed(1) + "MB";
|
||||
} else {
|
||||
return '';
|
||||
return "";
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<section class="section-input-send-audio">
|
||||
<img class="nes-pointer" src="{uploadFile}" alt="Upload a file" on:click|preventDefault={ () => {fileInput.click();}}>
|
||||
<img
|
||||
class="nes-pointer"
|
||||
src={uploadFile}
|
||||
alt="Upload a file"
|
||||
on:click|preventDefault={() => {
|
||||
fileInput.click();
|
||||
}}
|
||||
/>
|
||||
{#if fileName !== undefined}
|
||||
<p>{fileName} : {fileSize}</p>
|
||||
{/if}
|
||||
{#if errorFile}
|
||||
<p class="err">No file selected. You need to upload a file before sending it.</p>
|
||||
{/if}
|
||||
<input type="file" id="input-send-audio" bind:this={fileInput} on:change={(e) => {inputAudioFile(e)}}>
|
||||
<input
|
||||
type="file"
|
||||
id="input-send-audio"
|
||||
bind:this={fileInput}
|
||||
on:change={(e) => {
|
||||
inputAudioFile(e);
|
||||
}}
|
||||
/>
|
||||
</section>
|
||||
|
||||
<style lang="scss">
|
||||
section.section-input-send-audio {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
section.section-input-send-audio {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
|
||||
img {
|
||||
flex: 1 1 auto;
|
||||
max-height: 80%;
|
||||
margin-bottom: 20px;
|
||||
img {
|
||||
flex: 1 1 auto;
|
||||
max-height: 80%;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
p {
|
||||
margin-bottom: 5px;
|
||||
color: whitesmoke;
|
||||
font-size: 1rem;
|
||||
&.err {
|
||||
color: #ce372b;
|
||||
}
|
||||
}
|
||||
input {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin-bottom: 5px;
|
||||
color: whitesmoke;
|
||||
font-size: 1rem;
|
||||
&.err {
|
||||
color: #ce372b;
|
||||
}
|
||||
}
|
||||
input {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
|
||||
function goToGettingStarted() {
|
||||
const sparkHost = "https://workadventu.re/getting-started";
|
||||
window.open(sparkHost, "_blank");
|
||||
@ -10,7 +9,7 @@
|
||||
window.open(sparkHost, "_blank");
|
||||
}
|
||||
|
||||
import {contactPageStore} from "../../Stores/MenuStore";
|
||||
import { contactPageStore } from "../../Stores/MenuStore";
|
||||
</script>
|
||||
|
||||
<div class="create-map-main">
|
||||
@ -18,8 +17,8 @@
|
||||
<section>
|
||||
<h3>Getting started</h3>
|
||||
<p>
|
||||
WorkAdventure allows you to create an online space to communicate spontaneously with others.
|
||||
And it all starts with creating your own space. Choose from a large selection of prefabricated maps by our team.
|
||||
WorkAdventure allows you to create an online space to communicate spontaneously with others. And it all
|
||||
starts with creating your own space. Choose from a large selection of prefabricated maps by our team.
|
||||
</p>
|
||||
<button type="button" class="nes-btn is-primary" on:click={goToGettingStarted}>Getting started</button>
|
||||
</section>
|
||||
@ -30,35 +29,37 @@
|
||||
<button type="button" class="nes-btn" on:click={goToBuildingMap}>Create your map</button>
|
||||
</section>
|
||||
|
||||
<iframe title="contact"
|
||||
src="{$contactPageStore}"
|
||||
allow="clipboard-read; clipboard-write self {$contactPageStore}"
|
||||
allowfullscreen></iframe>
|
||||
<iframe
|
||||
title="contact"
|
||||
src={$contactPageStore}
|
||||
allow="clipboard-read; clipboard-write self {$contactPageStore}"
|
||||
allowfullscreen
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
div.create-map-main {
|
||||
height: calc(100% - 56px);
|
||||
height: calc(100% - 56px);
|
||||
|
||||
text-align: center;
|
||||
text-align: center;
|
||||
|
||||
section {
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
section {
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
section.container-overflow {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
section.container-overflow {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: none;
|
||||
height: calc(100% - 56px);
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
border: none;
|
||||
height: calc(100% - 56px);
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -1,33 +1,32 @@
|
||||
<script lang="ts">
|
||||
import {onDestroy, onMount} from "svelte";
|
||||
import {iframeListener} from "../../Api/IframeListener";
|
||||
import { onDestroy, onMount } from "svelte";
|
||||
import { iframeListener } from "../../Api/IframeListener";
|
||||
|
||||
export let url: string;
|
||||
export let allowApi: boolean;
|
||||
|
||||
let HTMLIframe: HTMLIFrameElement;
|
||||
|
||||
onMount( () => {
|
||||
onMount(() => {
|
||||
if (allowApi) {
|
||||
iframeListener.registerIframe(HTMLIframe);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
onDestroy( () => {
|
||||
onDestroy(() => {
|
||||
if (allowApi) {
|
||||
iframeListener.unregisterIframe(HTMLIframe);
|
||||
}
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<iframe title="customSubMenu" src="{url}" bind:this={HTMLIframe}></iframe>
|
||||
<iframe title="customSubMenu" src={url} bind:this={HTMLIframe} />
|
||||
|
||||
<style lang="scss">
|
||||
iframe {
|
||||
border: none;
|
||||
height: calc(100% - 56px);
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
iframe {
|
||||
border: none;
|
||||
height: calc(100% - 56px);
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import TextGlobalMessage from './TextGlobalMessage.svelte';
|
||||
import AudioGlobalMessage from './AudioGlobalMessage.svelte';
|
||||
import TextGlobalMessage from "./TextGlobalMessage.svelte";
|
||||
import AudioGlobalMessage from "./AudioGlobalMessage.svelte";
|
||||
|
||||
let handleSendText: { sendTextMessage(broadcast: boolean): void };
|
||||
let handleSendAudio: { sendAudioMessage(broadcast: boolean): Promise<void> };
|
||||
@ -32,23 +32,31 @@
|
||||
<div class="global-message-main">
|
||||
<div class="global-message-subOptions">
|
||||
<section>
|
||||
<button type="button" class="nes-btn {inputSendTextActive ? 'is-disabled' : ''}" on:click|preventDefault={activateInputText}>Text</button>
|
||||
<button
|
||||
type="button"
|
||||
class="nes-btn {inputSendTextActive ? 'is-disabled' : ''}"
|
||||
on:click|preventDefault={activateInputText}>Text</button
|
||||
>
|
||||
</section>
|
||||
<section>
|
||||
<button type="button" class="nes-btn {uploadAudioActive ? 'is-disabled' : ''}" on:click|preventDefault={activateUploadAudio}>Audio</button>
|
||||
<button
|
||||
type="button"
|
||||
class="nes-btn {uploadAudioActive ? 'is-disabled' : ''}"
|
||||
on:click|preventDefault={activateUploadAudio}>Audio</button
|
||||
>
|
||||
</section>
|
||||
</div>
|
||||
<div class="global-message-content">
|
||||
{#if inputSendTextActive}
|
||||
<TextGlobalMessage bind:handleSending={handleSendText}/>
|
||||
<TextGlobalMessage bind:handleSending={handleSendText} />
|
||||
{/if}
|
||||
{#if uploadAudioActive}
|
||||
<AudioGlobalMessage bind:handleSending={handleSendAudio}/>
|
||||
<AudioGlobalMessage bind:handleSending={handleSendAudio} />
|
||||
{/if}
|
||||
</div>
|
||||
<div class="global-message-footer">
|
||||
<label>
|
||||
<input type="checkbox" class="nes-checkbox is-dark nes-pointer" bind:checked={broadcastToWorld}>
|
||||
<input type="checkbox" class="nes-checkbox is-dark nes-pointer" bind:checked={broadcastToWorld} />
|
||||
<span>Broadcast to all rooms of the world</span>
|
||||
</label>
|
||||
<section>
|
||||
@ -57,62 +65,59 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
div.global-message-main {
|
||||
height: calc(100% - 50px);
|
||||
display: grid;
|
||||
grid-template-rows: 15% 65% 20%;
|
||||
|
||||
div.global-message-subOptions {
|
||||
height: calc(100% - 50px);
|
||||
display: grid;
|
||||
grid-template-columns: 50% 50%;
|
||||
margin-bottom: 20px;
|
||||
grid-template-rows: 15% 65% 20%;
|
||||
|
||||
section {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
div.global-message-subOptions {
|
||||
display: grid;
|
||||
grid-template-columns: 50% 50%;
|
||||
margin-bottom: 20px;
|
||||
|
||||
div.global-message-footer {
|
||||
margin-bottom: 10px;
|
||||
|
||||
display: grid;
|
||||
grid-template-rows: 50% 50%;
|
||||
|
||||
section {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
section {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
margin: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
div.global-message-footer {
|
||||
margin-bottom: 10px;
|
||||
|
||||
span {
|
||||
font-family: "Press Start 2P";
|
||||
}
|
||||
display: grid;
|
||||
grid-template-rows: 50% 50%;
|
||||
|
||||
section {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
label {
|
||||
margin: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
font-family: "Press Start 2P";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px), only screen and (max-height: 800px) {
|
||||
.global-message-content {
|
||||
height: calc(100% - 5px);
|
||||
}
|
||||
.global-message-footer {
|
||||
margin-bottom: 0;
|
||||
|
||||
label {
|
||||
width: calc(100% - 10px);
|
||||
.global-message-content {
|
||||
height: calc(100% - 5px);
|
||||
}
|
||||
.global-message-footer {
|
||||
margin-bottom: 0;
|
||||
|
||||
label {
|
||||
width: calc(100% - 10px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -1,18 +1,18 @@
|
||||
<script lang="ts">
|
||||
function copyLink() {
|
||||
const input: HTMLInputElement = document.getElementById('input-share-link') as HTMLInputElement;
|
||||
const input: HTMLInputElement = document.getElementById("input-share-link") as HTMLInputElement;
|
||||
input.focus();
|
||||
input.select();
|
||||
document.execCommand('copy');
|
||||
document.execCommand("copy");
|
||||
}
|
||||
|
||||
async function shareLink() {
|
||||
const shareData = {url: location.toString()};
|
||||
const shareData = { url: location.toString() };
|
||||
|
||||
try {
|
||||
await navigator.share(shareData);
|
||||
} catch (err) {
|
||||
console.error('Error: ' + err);
|
||||
console.error("Error: " + err);
|
||||
copyLink();
|
||||
}
|
||||
}
|
||||
@ -22,12 +22,12 @@
|
||||
<section class="container-overflow">
|
||||
<section class="share-url not-mobile">
|
||||
<h3>Share the link of the room !</h3>
|
||||
<input type="text" readonly id="input-share-link" value={location.toString()}>
|
||||
<input type="text" readonly id="input-share-link" value={location.toString()} />
|
||||
<button type="button" class="nes-btn is-primary" on:click={copyLink}>Copy</button>
|
||||
</section>
|
||||
<section class="is-mobile">
|
||||
<h3>Share the link of the room !</h3>
|
||||
<input type="hidden" readonly id="input-share-link" value={location.toString()}>
|
||||
<input type="hidden" readonly id="input-share-link" value={location.toString()} />
|
||||
<button type="button" class="nes-btn is-primary" on:click={shareLink}>Share</button>
|
||||
</section>
|
||||
</section>
|
||||
@ -35,41 +35,41 @@
|
||||
|
||||
<style lang="scss">
|
||||
div.guest-main {
|
||||
height: calc(100% - 56px);
|
||||
height: calc(100% - 56px);
|
||||
|
||||
text-align: center;
|
||||
text-align: center;
|
||||
|
||||
section {
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
section.container-overflow {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
section.is-mobile {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 900px), only screen and (max-height: 600px) {
|
||||
div.guest-main {
|
||||
section.share-url.not-mobile {
|
||||
display: none;
|
||||
}
|
||||
|
||||
section.is-mobile {
|
||||
display: block;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
section {
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
section.container-overflow {
|
||||
height: calc(100% - 120px);
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
section.is-mobile {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@media only screen and (max-width: 900px), only screen and (max-height: 600px) {
|
||||
div.guest-main {
|
||||
section.share-url.not-mobile {
|
||||
display: none;
|
||||
}
|
||||
|
||||
section.is-mobile {
|
||||
display: block;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
section.container-overflow {
|
||||
height: calc(100% - 120px);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,46 +1,46 @@
|
||||
<script lang="typescript">
|
||||
import {fly} from "svelte/transition";
|
||||
import { fly } from "svelte/transition";
|
||||
import SettingsSubMenu from "./SettingsSubMenu.svelte";
|
||||
import ProfileSubMenu from "./ProfileSubMenu.svelte";
|
||||
import AboutRoomSubMenu from "./AboutRoomSubMenu.svelte";
|
||||
import GlobalMessageSubMenu from "./GlobalMessagesSubMenu.svelte";
|
||||
import ContactSubMenu from "./ContactSubMenu.svelte";
|
||||
import CustomSubMenu from "./CustomSubMenu.svelte"
|
||||
import CustomSubMenu from "./CustomSubMenu.svelte";
|
||||
import GuestSubMenu from "./GuestSubMenu.svelte";
|
||||
import {
|
||||
checkSubMenuToShow,
|
||||
customMenuIframe,
|
||||
menuVisiblilityStore,
|
||||
SubMenusInterface,
|
||||
subMenusStore
|
||||
subMenusStore,
|
||||
} from "../../Stores/MenuStore";
|
||||
import {onDestroy, onMount} from "svelte";
|
||||
import {get} from "svelte/store";
|
||||
import type {Unsubscriber} from "svelte/store";
|
||||
import {sendMenuClickedEvent} from "../../Api/iframe/Ui/MenuItem";
|
||||
import { onDestroy, onMount } from "svelte";
|
||||
import { get } from "svelte/store";
|
||||
import type { Unsubscriber } from "svelte/store";
|
||||
import { sendMenuClickedEvent } from "../../Api/iframe/Ui/MenuItem";
|
||||
|
||||
let activeSubMenu: string = SubMenusInterface.profile;
|
||||
let activeComponent: typeof ProfileSubMenu | typeof CustomSubMenu = ProfileSubMenu;
|
||||
let props: { url: string, allowApi: boolean };
|
||||
let props: { url: string; allowApi: boolean };
|
||||
let unsubscriberSubMenuStore: Unsubscriber;
|
||||
|
||||
onMount(() => {
|
||||
unsubscriberSubMenuStore = subMenusStore.subscribe(() => {
|
||||
if(!get(subMenusStore).includes(activeSubMenu)) {
|
||||
if (!get(subMenusStore).includes(activeSubMenu)) {
|
||||
switchMenu(SubMenusInterface.profile);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
checkSubMenuToShow();
|
||||
|
||||
switchMenu(SubMenusInterface.profile);
|
||||
})
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
if(unsubscriberSubMenuStore) {
|
||||
if (unsubscriberSubMenuStore) {
|
||||
unsubscriberSubMenuStore();
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
function switchMenu(menu: string) {
|
||||
if (get(subMenusStore).find((subMenu) => subMenu === menu)) {
|
||||
@ -64,7 +64,7 @@
|
||||
case SubMenusInterface.contact:
|
||||
activeComponent = ContactSubMenu;
|
||||
break;
|
||||
default:
|
||||
default: {
|
||||
const customMenu = customMenuIframe.get(menu);
|
||||
if (customMenu !== undefined) {
|
||||
props = { url: customMenu.url, allowApi: customMenu.allowApi };
|
||||
@ -74,109 +74,113 @@
|
||||
menuVisiblilityStore.set(false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else throw ("There is no menu called " + menu);
|
||||
} else throw "There is no menu called " + menu;
|
||||
}
|
||||
|
||||
function closeMenu() {
|
||||
menuVisiblilityStore.set(false);
|
||||
}
|
||||
function onKeyDown(e:KeyboardEvent) {
|
||||
if (e.key === 'Escape') {
|
||||
function onKeyDown(e: KeyboardEvent) {
|
||||
if (e.key === "Escape") {
|
||||
closeMenu();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window on:keydown={onKeyDown}/>
|
||||
|
||||
<svelte:window on:keydown={onKeyDown} />
|
||||
|
||||
<div class="menu-container-main">
|
||||
<div class="menu-nav-sidebar nes-container is-rounded" transition:fly="{{ x: -1000, duration: 500 }}">
|
||||
<div class="menu-nav-sidebar nes-container is-rounded" transition:fly={{ x: -1000, duration: 500 }}>
|
||||
<h2>Menu</h2>
|
||||
<nav>
|
||||
{#each $subMenusStore as submenu}
|
||||
<button type="button" class="nes-btn {activeSubMenu === submenu ? 'is-disabled' : ''}" on:click|preventDefault={() => switchMenu(submenu)}>
|
||||
<button
|
||||
type="button"
|
||||
class="nes-btn {activeSubMenu === submenu ? 'is-disabled' : ''}"
|
||||
on:click|preventDefault={() => switchMenu(submenu)}
|
||||
>
|
||||
{submenu}
|
||||
</button>
|
||||
{/each}
|
||||
</nav>
|
||||
</div>
|
||||
<div class="menu-submenu-container nes-container is-rounded" transition:fly="{{ y: -1000, duration: 500 }}">
|
||||
<div class="menu-submenu-container nes-container is-rounded" transition:fly={{ y: -1000, duration: 500 }}>
|
||||
<button type="button" class="nes-btn is-error close" on:click={closeMenu}>×</button>
|
||||
<h2>{activeSubMenu}</h2>
|
||||
<svelte:component this={activeComponent} {...props}/>
|
||||
<svelte:component this={activeComponent} {...props} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.nes-container {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
div.menu-container-main {
|
||||
--size-first-columns-grid: 200px;
|
||||
|
||||
font-family: "Press Start 2P";
|
||||
pointer-events: auto;
|
||||
height: 80%;
|
||||
width: 75%;
|
||||
top: 10%;
|
||||
|
||||
position: relative;
|
||||
z-index: 80;
|
||||
margin: auto;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: var(--size-first-columns-grid) calc(100% - var(--size-first-columns-grid));
|
||||
grid-template-rows: 100%;
|
||||
|
||||
h2 {
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
.nes-container {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
div.menu-nav-sidebar {
|
||||
background-color: #333333;
|
||||
color: whitesmoke;
|
||||
|
||||
nav button {
|
||||
width: calc(100% - 10px);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
div.menu-submenu-container {
|
||||
background-color: #333333;
|
||||
color: whitesmoke;
|
||||
|
||||
.nes-btn.is-error.close {
|
||||
position: absolute;
|
||||
top: -20px;
|
||||
right: -20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
div.menu-container-main {
|
||||
--size-first-columns-grid: 120px;
|
||||
height: 70%;
|
||||
top: 55px;
|
||||
width: 100%;
|
||||
font-size: 0.5em;
|
||||
--size-first-columns-grid: 200px;
|
||||
|
||||
div.menu-nav-sidebar {
|
||||
overflow-y: auto;
|
||||
}
|
||||
font-family: "Press Start 2P";
|
||||
pointer-events: auto;
|
||||
height: 80%;
|
||||
width: 75%;
|
||||
top: 10%;
|
||||
|
||||
div.menu-submenu-container {
|
||||
.nes-btn.is-error.close {
|
||||
position: absolute;
|
||||
top: -35px;
|
||||
right: 0;
|
||||
position: relative;
|
||||
z-index: 80;
|
||||
margin: auto;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: var(--size-first-columns-grid) calc(100% - var(--size-first-columns-grid));
|
||||
grid-template-rows: 100%;
|
||||
|
||||
h2 {
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
div.menu-nav-sidebar {
|
||||
background-color: #333333;
|
||||
color: whitesmoke;
|
||||
|
||||
nav button {
|
||||
width: calc(100% - 10px);
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
div.menu-submenu-container {
|
||||
background-color: #333333;
|
||||
color: whitesmoke;
|
||||
|
||||
.nes-btn.is-error.close {
|
||||
position: absolute;
|
||||
top: -20px;
|
||||
right: -20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
div.menu-container-main {
|
||||
--size-first-columns-grid: 120px;
|
||||
height: 70%;
|
||||
top: 55px;
|
||||
width: 100%;
|
||||
font-size: 0.5em;
|
||||
|
||||
div.menu-nav-sidebar {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
div.menu-submenu-container {
|
||||
.nes-btn.is-error.close {
|
||||
position: absolute;
|
||||
top: -35px;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,47 +1,47 @@
|
||||
<script lang="typescript">
|
||||
import logoWA from "../images/logo-WA-pixel.png"
|
||||
import logoTalk from "../images/logo-message-pixel.png"
|
||||
import {menuVisiblilityStore} from "../../Stores/MenuStore";
|
||||
import {chatVisibilityStore} from "../../Stores/ChatStore";
|
||||
import {get} from "svelte/store";
|
||||
import logoWA from "../images/logo-WA-pixel.png";
|
||||
import logoTalk from "../images/logo-message-pixel.png";
|
||||
import { menuVisiblilityStore } from "../../Stores/MenuStore";
|
||||
import { chatVisibilityStore } from "../../Stores/ChatStore";
|
||||
import { get } from "svelte/store";
|
||||
|
||||
function showMenu(){
|
||||
menuVisiblilityStore.set(!get(menuVisiblilityStore))
|
||||
function showMenu() {
|
||||
menuVisiblilityStore.set(!get(menuVisiblilityStore));
|
||||
}
|
||||
function showChat(){
|
||||
function showChat() {
|
||||
chatVisibilityStore.set(true);
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window/>
|
||||
<svelte:window />
|
||||
|
||||
<main class="menuIcon">
|
||||
<img src={logoWA} alt="open menu" class="nes-pointer" on:click|preventDefault={showMenu}>
|
||||
<img src={logoTalk} alt="open menu" class="nes-pointer" on:click|preventDefault={showChat}>
|
||||
<img src={logoWA} alt="open menu" class="nes-pointer" on:click|preventDefault={showMenu} />
|
||||
<img src={logoTalk} alt="open menu" class="nes-pointer" on:click|preventDefault={showChat} />
|
||||
</main>
|
||||
|
||||
<style lang="scss">
|
||||
.menuIcon {
|
||||
display: inline-grid;
|
||||
z-index: 90;
|
||||
position: relative;
|
||||
margin: 25px;
|
||||
img {
|
||||
pointer-events: auto;
|
||||
width: 60px;
|
||||
padding-top: 0;
|
||||
margin: 3px
|
||||
}
|
||||
}
|
||||
.menuIcon img:hover{
|
||||
transform: scale(1.2);
|
||||
}
|
||||
@media only screen and (max-width: 800px), only screen and (max-height: 800px) {
|
||||
.menuIcon {
|
||||
margin: 3px;
|
||||
img {
|
||||
width: 50px;
|
||||
}
|
||||
display: inline-grid;
|
||||
z-index: 90;
|
||||
position: relative;
|
||||
margin: 25px;
|
||||
img {
|
||||
pointer-events: auto;
|
||||
width: 60px;
|
||||
padding-top: 0;
|
||||
margin: 3px;
|
||||
}
|
||||
}
|
||||
.menuIcon img:hover {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
@media only screen and (max-width: 800px), only screen and (max-height: 800px) {
|
||||
.menuIcon {
|
||||
margin: 3px;
|
||||
img {
|
||||
width: 50px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,60 +1,59 @@
|
||||
<script lang="typescript">
|
||||
import {gameManager} from "../../Phaser/Game/GameManager";
|
||||
import {SelectCompanionScene, SelectCompanionSceneName} from "../../Phaser/Login/SelectCompanionScene";
|
||||
import {menuIconVisiblilityStore, menuVisiblilityStore, userIsConnected} from "../../Stores/MenuStore";
|
||||
import {selectCompanionSceneVisibleStore} from "../../Stores/SelectCompanionStore";
|
||||
import {LoginScene, LoginSceneName} from "../../Phaser/Login/LoginScene";
|
||||
import {loginSceneVisibleStore} from "../../Stores/LoginSceneStore";
|
||||
import {selectCharacterSceneVisibleStore} from "../../Stores/SelectCharacterStore";
|
||||
import {SelectCharacterScene, SelectCharacterSceneName} from "../../Phaser/Login/SelectCharacterScene";
|
||||
import {connectionManager} from "../../Connexion/ConnectionManager";
|
||||
import {PROFILE_URL} from "../../Enum/EnvironmentVariable";
|
||||
import {localUserStore} from "../../Connexion/LocalUserStore";
|
||||
import {EnableCameraScene, EnableCameraSceneName} from "../../Phaser/Login/EnableCameraScene";
|
||||
import {enableCameraSceneVisibilityStore} from "../../Stores/MediaStore";
|
||||
import { gameManager } from "../../Phaser/Game/GameManager";
|
||||
import { SelectCompanionScene, SelectCompanionSceneName } from "../../Phaser/Login/SelectCompanionScene";
|
||||
import { menuIconVisiblilityStore, menuVisiblilityStore, userIsConnected } from "../../Stores/MenuStore";
|
||||
import { selectCompanionSceneVisibleStore } from "../../Stores/SelectCompanionStore";
|
||||
import { LoginScene, LoginSceneName } from "../../Phaser/Login/LoginScene";
|
||||
import { loginSceneVisibleStore } from "../../Stores/LoginSceneStore";
|
||||
import { selectCharacterSceneVisibleStore } from "../../Stores/SelectCharacterStore";
|
||||
import { SelectCharacterScene, SelectCharacterSceneName } from "../../Phaser/Login/SelectCharacterScene";
|
||||
import { connectionManager } from "../../Connexion/ConnectionManager";
|
||||
import { PROFILE_URL } from "../../Enum/EnvironmentVariable";
|
||||
import { localUserStore } from "../../Connexion/LocalUserStore";
|
||||
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 btnProfileSubMenuWoka from "../images/btn-menu-profile-woka.svg";
|
||||
|
||||
|
||||
function disableMenuStores(){
|
||||
function disableMenuStores() {
|
||||
menuVisiblilityStore.set(false);
|
||||
menuIconVisiblilityStore.set(false);
|
||||
}
|
||||
|
||||
function openEditCompanionScene(){
|
||||
function openEditCompanionScene() {
|
||||
disableMenuStores();
|
||||
selectCompanionSceneVisibleStore.set(true);
|
||||
gameManager.leaveGame(SelectCompanionSceneName,new SelectCompanionScene());
|
||||
gameManager.leaveGame(SelectCompanionSceneName, new SelectCompanionScene());
|
||||
}
|
||||
|
||||
function openEditNameScene(){
|
||||
function openEditNameScene() {
|
||||
disableMenuStores();
|
||||
loginSceneVisibleStore.set(true);
|
||||
gameManager.leaveGame(LoginSceneName,new LoginScene());
|
||||
gameManager.leaveGame(LoginSceneName, new LoginScene());
|
||||
}
|
||||
|
||||
function openEditSkinScene(){
|
||||
function openEditSkinScene() {
|
||||
disableMenuStores();
|
||||
selectCharacterSceneVisibleStore.set(true);
|
||||
gameManager.leaveGame(SelectCharacterSceneName,new SelectCharacterScene());
|
||||
gameManager.leaveGame(SelectCharacterSceneName, new SelectCharacterScene());
|
||||
}
|
||||
|
||||
function logOut(){
|
||||
function logOut() {
|
||||
disableMenuStores();
|
||||
loginSceneVisibleStore.set(true);
|
||||
connectionManager.logout();
|
||||
}
|
||||
|
||||
function getProfileUrl(){
|
||||
function getProfileUrl() {
|
||||
return PROFILE_URL + `?token=${localUserStore.getAuthToken()}`;
|
||||
}
|
||||
|
||||
function openEnableCameraScene(){
|
||||
function openEnableCameraScene() {
|
||||
disableMenuStores();
|
||||
enableCameraSceneVisibilityStore.showEnableCameraScene();
|
||||
gameManager.leaveGame(EnableCameraSceneName,new EnableCameraScene());
|
||||
gameManager.leaveGame(EnableCameraSceneName, new EnableCameraScene());
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -62,19 +61,19 @@
|
||||
<div class="submenu">
|
||||
<section>
|
||||
<button type="button" class="nes-btn" on:click|preventDefault={openEditNameScene}>
|
||||
<img src={btnProfileSubMenuIdentity} alt="Edit your name">
|
||||
<img src={btnProfileSubMenuIdentity} alt="Edit your name" />
|
||||
<span class="btn-hover">Edit your name</span>
|
||||
</button>
|
||||
<button type="button" class="nes-btn" on:click|preventDefault={openEditSkinScene}>
|
||||
<img src={btnProfileSubMenuWoka} alt="Edit your WOKA">
|
||||
<img src={btnProfileSubMenuWoka} alt="Edit your WOKA" />
|
||||
<span class="btn-hover">Edit your WOKA</span>
|
||||
</button>
|
||||
<button type="button" class="nes-btn" on:click|preventDefault={openEditCompanionScene}>
|
||||
<img src={btnProfileSubMenuCompanion} alt="Edit your companion">
|
||||
<img src={btnProfileSubMenuCompanion} alt="Edit your companion" />
|
||||
<span class="btn-hover">Edit your companion</span>
|
||||
</button>
|
||||
<button type="button" class="nes-btn" on:click|preventDefault={openEnableCameraScene}>
|
||||
<img src={btnProfileSubMenuCamera} alt="Edit your camera">
|
||||
<img src={btnProfileSubMenuCamera} alt="Edit your camera" />
|
||||
<span class="btn-hover">Edit your camera</span>
|
||||
</button>
|
||||
</section>
|
||||
@ -84,7 +83,7 @@
|
||||
{#if $userIsConnected}
|
||||
<section>
|
||||
{#if PROFILE_URL != undefined}
|
||||
<iframe title="profile" src="{getProfileUrl()}"></iframe>
|
||||
<iframe title="profile" src={getProfileUrl()} />
|
||||
{/if}
|
||||
</section>
|
||||
<section>
|
||||
@ -99,68 +98,68 @@
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
div.customize-main{
|
||||
width: 100%;
|
||||
display: inline-flex;
|
||||
|
||||
div.submenu{
|
||||
height: 100%;
|
||||
width: 50px;
|
||||
|
||||
button {
|
||||
transition: all .5s ease;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
margin-bottom: 10px;
|
||||
max-height: 44px;
|
||||
|
||||
img {
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
span.btn-hover{
|
||||
display: none;
|
||||
font-family: "Press Start 2P";
|
||||
}
|
||||
|
||||
&:hover{
|
||||
width: auto;
|
||||
|
||||
span.btn-hover {
|
||||
display: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div.content {
|
||||
div.customize-main {
|
||||
width: 100%;
|
||||
section {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 20px;
|
||||
display: inline-flex;
|
||||
|
||||
iframe {
|
||||
width: 100%;
|
||||
height: 50vh;
|
||||
border: none;
|
||||
}
|
||||
div.submenu {
|
||||
height: 100%;
|
||||
width: 50px;
|
||||
|
||||
button {
|
||||
height: 50px;
|
||||
width: 250px;
|
||||
}
|
||||
button {
|
||||
transition: all 0.5s ease;
|
||||
text-align: left;
|
||||
white-space: nowrap;
|
||||
margin-bottom: 10px;
|
||||
max-height: 44px;
|
||||
|
||||
img {
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
span.btn-hover {
|
||||
display: none;
|
||||
font-family: "Press Start 2P";
|
||||
}
|
||||
|
||||
&:hover {
|
||||
width: auto;
|
||||
|
||||
span.btn-hover {
|
||||
display: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div.content {
|
||||
width: 100%;
|
||||
section {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 20px;
|
||||
|
||||
iframe {
|
||||
width: 100%;
|
||||
height: 50vh;
|
||||
border: none;
|
||||
}
|
||||
|
||||
button {
|
||||
height: 50px;
|
||||
width: 250px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
div.customize-main.content section button {
|
||||
width: 130px;
|
||||
}
|
||||
div.customize-main.content section button {
|
||||
width: 130px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -1,62 +1,62 @@
|
||||
<script lang="typescript">
|
||||
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 { localUserStore } from "../../Connexion/LocalUserStore";
|
||||
import { videoConstraintStore } from "../../Stores/MediaStore";
|
||||
import { HtmlUtils } from "../../WebRtc/HtmlUtils";
|
||||
import { isMobile } from "../../Enum/EnvironmentVariable";
|
||||
import { menuVisiblilityStore } from "../../Stores/MenuStore";
|
||||
|
||||
let fullscreen : boolean = localUserStore.getFullscreen();
|
||||
let notification : boolean = localUserStore.getNotification() === 'granted';
|
||||
let valueGame : number = localUserStore.getGameQualityValue();
|
||||
let valueVideo : number = localUserStore.getVideoQualityValue();
|
||||
let previewValueGame = valueGame;
|
||||
let previewValueVideo = valueVideo;
|
||||
let fullscreen: boolean = localUserStore.getFullscreen();
|
||||
let notification: boolean = localUserStore.getNotification() === "granted";
|
||||
let valueGame: number = localUserStore.getGameQualityValue();
|
||||
let valueVideo: number = localUserStore.getVideoQualityValue();
|
||||
let previewValueGame = valueGame;
|
||||
let previewValueVideo = valueVideo;
|
||||
|
||||
function saveSetting(){
|
||||
if (valueGame !== previewValueGame) {
|
||||
previewValueGame = valueGame;
|
||||
localUserStore.setGameQualityValue(valueGame);
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
if (valueVideo !== previewValueVideo) {
|
||||
previewValueVideo = valueVideo;
|
||||
videoConstraintStore.setFrameRate(valueVideo);
|
||||
}
|
||||
|
||||
closeMenu();
|
||||
}
|
||||
|
||||
function changeFullscreen() {
|
||||
const body = HtmlUtils.querySelectorOrFail('body');
|
||||
if (body) {
|
||||
if (document.fullscreenElement !== null && !fullscreen) {
|
||||
document.exitFullscreen()
|
||||
} else {
|
||||
body.requestFullscreen();
|
||||
function saveSetting() {
|
||||
if (valueGame !== previewValueGame) {
|
||||
previewValueGame = valueGame;
|
||||
localUserStore.setGameQualityValue(valueGame);
|
||||
window.location.reload();
|
||||
}
|
||||
localUserStore.setFullscreen(fullscreen);
|
||||
}
|
||||
}
|
||||
|
||||
function changeNotification() {
|
||||
if (Notification.permission === 'granted') {
|
||||
localUserStore.setNotification(notification ? 'granted' : 'denied');
|
||||
} else {
|
||||
Notification.requestPermission().then((response) => {
|
||||
if (response === 'granted') {
|
||||
localUserStore.setNotification(notification ? 'granted' : 'denied');
|
||||
if (valueVideo !== previewValueVideo) {
|
||||
previewValueVideo = valueVideo;
|
||||
videoConstraintStore.setFrameRate(valueVideo);
|
||||
}
|
||||
|
||||
closeMenu();
|
||||
}
|
||||
|
||||
function changeFullscreen() {
|
||||
const body = HtmlUtils.querySelectorOrFail("body");
|
||||
if (body) {
|
||||
if (document.fullscreenElement !== null && !fullscreen) {
|
||||
document.exitFullscreen();
|
||||
} else {
|
||||
localUserStore.setNotification('denied');
|
||||
notification = false;
|
||||
body.requestFullscreen();
|
||||
}
|
||||
})
|
||||
localUserStore.setFullscreen(fullscreen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function closeMenu() {
|
||||
menuVisiblilityStore.set(false);
|
||||
}
|
||||
function changeNotification() {
|
||||
if (Notification.permission === "granted") {
|
||||
localUserStore.setNotification(notification ? "granted" : "denied");
|
||||
} else {
|
||||
Notification.requestPermission().then((response) => {
|
||||
if (response === "granted") {
|
||||
localUserStore.setNotification(notification ? "granted" : "denied");
|
||||
} else {
|
||||
localUserStore.setNotification("denied");
|
||||
notification = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function closeMenu() {
|
||||
menuVisiblilityStore.set(false);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="settings-main" on:submit|preventDefault={saveSetting}>
|
||||
@ -64,10 +64,12 @@ function closeMenu() {
|
||||
<h3>Game quality</h3>
|
||||
<div class="nes-select is-dark">
|
||||
<select bind:value={valueGame}>
|
||||
<option value="{120}">{isMobile() ? 'High (120 fps)' : 'High video quality (120 fps)'}</option>
|
||||
<option value="{60}">{isMobile() ? 'Medium (60 fps)' : 'Medium video quality (60 fps, recommended)'}</option>
|
||||
<option value="{40}">{isMobile() ? 'Minimum (40 fps)' : 'Minimum video quality (40 fps)'}</option>
|
||||
<option value="{20}">{isMobile() ? 'Small (20 fps)' : 'Small video quality (20 fps)'}</option>
|
||||
<option value={120}>{isMobile() ? "High (120 fps)" : "High video quality (120 fps)"}</option>
|
||||
<option value={60}
|
||||
>{isMobile() ? "Medium (60 fps)" : "Medium video quality (60 fps, recommended)"}</option
|
||||
>
|
||||
<option value={40}>{isMobile() ? "Minimum (40 fps)" : "Minimum video quality (40 fps)"}</option>
|
||||
<option value={20}>{isMobile() ? "Small (20 fps)" : "Small video quality (20 fps)"}</option>
|
||||
</select>
|
||||
</div>
|
||||
</section>
|
||||
@ -75,10 +77,12 @@ function closeMenu() {
|
||||
<h3>Video quality</h3>
|
||||
<div class="nes-select is-dark">
|
||||
<select bind:value={valueVideo}>
|
||||
<option value="{30}">{isMobile() ? 'High (30 fps)' : 'High video quality (30 fps)'}</option>
|
||||
<option value="{20}">{isMobile() ? 'Medium (20 fps)' : 'Medium video quality (20 fps, recommended)'}</option>
|
||||
<option value="{10}">{isMobile() ? 'Minimum (10 fps)' : 'Minimum video quality (10 fps)'}</option>
|
||||
<option value="{5}">{isMobile() ? 'Small (5 fps)' : 'Small video quality (5 fps)'}</option>
|
||||
<option value={30}>{isMobile() ? "High (30 fps)" : "High video quality (30 fps)"}</option>
|
||||
<option value={20}
|
||||
>{isMobile() ? "Medium (20 fps)" : "Medium video quality (20 fps, recommended)"}</option
|
||||
>
|
||||
<option value={10}>{isMobile() ? "Minimum (10 fps)" : "Minimum video quality (10 fps)"}</option>
|
||||
<option value={5}>{isMobile() ? "Small (5 fps)" : "Small video quality (5 fps)"}</option>
|
||||
</select>
|
||||
</div>
|
||||
</section>
|
||||
@ -88,55 +92,65 @@ function closeMenu() {
|
||||
</section>
|
||||
<section class="settings-section-noSaveOption">
|
||||
<label>
|
||||
<input type="checkbox" class="nes-checkbox is-dark" bind:checked={fullscreen} on:change={changeFullscreen}/>
|
||||
<input
|
||||
type="checkbox"
|
||||
class="nes-checkbox is-dark"
|
||||
bind:checked={fullscreen}
|
||||
on:change={changeFullscreen}
|
||||
/>
|
||||
<span>Fullscreen</span>
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" class="nes-checkbox is-dark" bind:checked={notification} on:change={changeNotification}>
|
||||
<input
|
||||
type="checkbox"
|
||||
class="nes-checkbox is-dark"
|
||||
bind:checked={notification}
|
||||
on:change={changeNotification}
|
||||
/>
|
||||
<span>Notifications</span>
|
||||
</label>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
div.settings-main {
|
||||
height: calc(100% - 40px);
|
||||
overflow-y: auto;
|
||||
|
||||
section {
|
||||
width: 100%;
|
||||
padding: 20px 20px 0;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
|
||||
div.nes-select select:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
section.settings-section-save {
|
||||
text-align: center;
|
||||
p {
|
||||
margin: 16px 0;
|
||||
}
|
||||
}
|
||||
section.settings-section-noSaveOption {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
|
||||
label {
|
||||
flex: 1 1 auto;
|
||||
text-align: center;
|
||||
margin: 0 0 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px), only screen and (max-height: 800px) {
|
||||
div.settings-main {
|
||||
section {
|
||||
padding: 0;
|
||||
}
|
||||
height: calc(100% - 40px);
|
||||
overflow-y: auto;
|
||||
|
||||
section {
|
||||
width: 100%;
|
||||
padding: 20px 20px 0;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
|
||||
div.nes-select select:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
section.settings-section-save {
|
||||
text-align: center;
|
||||
p {
|
||||
margin: 16px 0;
|
||||
}
|
||||
}
|
||||
section.settings-section-noSaveOption {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
|
||||
label {
|
||||
flex: 1 1 auto;
|
||||
text-align: center;
|
||||
margin: 0 0 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@media only screen and (max-width: 800px), only screen and (max-height: 800px) {
|
||||
div.settings-main {
|
||||
section {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -8,25 +8,25 @@
|
||||
|
||||
//toolbar
|
||||
const toolbarOptions = [
|
||||
['bold', 'italic', 'underline', 'strike'], // toggled buttons
|
||||
['blockquote', 'code-block'],
|
||||
["bold", "italic", "underline", "strike"], // toggled buttons
|
||||
["blockquote", "code-block"],
|
||||
|
||||
[{'header': 1}, {'header': 2}], // custom button values
|
||||
[{'list': 'ordered'}, {'list': 'bullet'}],
|
||||
[{'script': 'sub'}, {'script': 'super'}], // superscript/subscript
|
||||
[{'indent': '-1'}, {'indent': '+1'}], // outdent/indent
|
||||
[{'direction': 'rtl'}], // text direction
|
||||
[{ header: 1 }, { header: 2 }], // custom button values
|
||||
[{ list: "ordered" }, { list: "bullet" }],
|
||||
[{ script: "sub" }, { script: "super" }], // superscript/subscript
|
||||
[{ indent: "-1" }, { indent: "+1" }], // outdent/indent
|
||||
[{ direction: "rtl" }], // text direction
|
||||
|
||||
[{'size': ['small', false, 'large', 'huge']}], // custom dropdown
|
||||
[{'header': [1, 2, 3, 4, 5, 6, false]}],
|
||||
[{ size: ["small", false, "large", "huge"] }], // custom dropdown
|
||||
[{ header: [1, 2, 3, 4, 5, 6, false] }],
|
||||
|
||||
[{'color': []}, {'background': []}], // dropdown with defaults from theme
|
||||
[{'font': []}],
|
||||
[{'align': []}],
|
||||
[{ color: [] }, { background: [] }], // dropdown with defaults from theme
|
||||
[{ font: [] }],
|
||||
[{ align: [] }],
|
||||
|
||||
['clean'], // remove formatting button
|
||||
["clean"], // remove formatting button
|
||||
|
||||
['link', 'image', 'video']
|
||||
["link", "image", "video"],
|
||||
];
|
||||
|
||||
const gameScene = gameManager.getCurrentGameScene();
|
||||
@ -44,24 +44,24 @@
|
||||
const textGlobalMessage: PlayGlobalMessageInterface = {
|
||||
type: MESSAGE_TYPE,
|
||||
content: text,
|
||||
broadcastToWorld: broadcastToWorld
|
||||
broadcastToWorld: broadcastToWorld,
|
||||
};
|
||||
|
||||
quill.deleteText(0, quill.getLength());
|
||||
gameScene.connection?.emitGlobalMessage(textGlobalMessage);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
//Quill
|
||||
onMount(async () => {
|
||||
// Import quill
|
||||
const {default: Quill} = await import("quill"); // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
const { default: Quill } = await import("quill"); // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
|
||||
quill = new Quill(QUILL_EDITOR, {
|
||||
placeholder: 'Enter your message here...',
|
||||
theme: 'snow',
|
||||
placeholder: "Enter your message here...",
|
||||
theme: "snow",
|
||||
modules: {
|
||||
toolbar: toolbarOptions
|
||||
toolbar: toolbarOptions,
|
||||
},
|
||||
});
|
||||
menuInputFocusStore.set(true);
|
||||
@ -69,14 +69,13 @@
|
||||
|
||||
onDestroy(() => {
|
||||
menuInputFocusStore.set(false);
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<section class="section-input-send-text">
|
||||
<div class="input-send-text" bind:this={QUILL_EDITOR}></div>
|
||||
<div class="input-send-text" bind:this={QUILL_EDITOR} />
|
||||
</section>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
@import 'https://cdn.quilljs.com/1.3.7/quill.snow.css';
|
||||
@import "https://cdn.quilljs.com/1.3.7/quill.snow.css";
|
||||
</style>
|
||||
|
@ -1,14 +1,14 @@
|
||||
<script lang="typescript">
|
||||
import {obtainedMediaConstraintStore} from "../Stores/MediaStore";
|
||||
import {localStreamStore, isSilentStore} from "../Stores/MediaStore";
|
||||
import { obtainedMediaConstraintStore } from "../Stores/MediaStore";
|
||||
import { localStreamStore, isSilentStore } from "../Stores/MediaStore";
|
||||
import SoundMeterWidget from "./SoundMeterWidget.svelte";
|
||||
import {onDestroy} from "svelte";
|
||||
import {srcObject} from "./Video/utils";
|
||||
import { onDestroy } from "svelte";
|
||||
import { srcObject } from "./Video/utils";
|
||||
|
||||
let stream : MediaStream|null;
|
||||
let stream: MediaStream | null;
|
||||
|
||||
const unsubscribe = localStreamStore.subscribe(value => {
|
||||
if (value.type === 'success') {
|
||||
const unsubscribe = localStreamStore.subscribe((value) => {
|
||||
if (value.type === "success") {
|
||||
stream = value.stream;
|
||||
} else {
|
||||
stream = null;
|
||||
@ -17,25 +17,20 @@
|
||||
|
||||
onDestroy(unsubscribe);
|
||||
|
||||
|
||||
let isSilent: boolean;
|
||||
const unsubscribeIsSilent = isSilentStore.subscribe(value => {
|
||||
const unsubscribeIsSilent = isSilentStore.subscribe((value) => {
|
||||
isSilent = value;
|
||||
});
|
||||
|
||||
onDestroy(unsubscribeIsSilent);
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<div>
|
||||
<div class="video-container div-myCamVideo" class:hide={!$obtainedMediaConstraintStore.video || isSilent}>
|
||||
{#if $localStreamStore.type === "success" && $localStreamStore.stream}
|
||||
<video class="myCamVideo" use:srcObject={stream} autoplay muted playsinline></video>
|
||||
<SoundMeterWidget stream={stream}></SoundMeterWidget>
|
||||
<video class="myCamVideo" use:srcObject={stream} autoplay muted playsinline />
|
||||
<SoundMeterWidget {stream} />
|
||||
{/if}
|
||||
</div>
|
||||
<div class="is-silent" class:hide={isSilent}>
|
||||
Silent zone
|
||||
</div>
|
||||
<div class="is-silent" class:hide={isSilent}>Silent zone</div>
|
||||
</div>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import {blackListManager} from "../../WebRtc/BlackListManager";
|
||||
import {showReportScreenStore, userReportEmpty} from "../../Stores/ShowReportScreenStore";
|
||||
import {onMount} from "svelte";
|
||||
import { blackListManager } from "../../WebRtc/BlackListManager";
|
||||
import { showReportScreenStore, userReportEmpty } from "../../Stores/ShowReportScreenStore";
|
||||
import { onMount } from "svelte";
|
||||
|
||||
export let userUUID: string | undefined;
|
||||
export let userName: string;
|
||||
@ -14,7 +14,7 @@
|
||||
} else {
|
||||
userIsBlocked = blackListManager.isBlackListed(userUUID);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
function blockUser(): void {
|
||||
if (userUUID === undefined) {
|
||||
@ -32,13 +32,12 @@
|
||||
<h3>Block</h3>
|
||||
<p>Block any communication from and to {userName}. This can be reverted.</p>
|
||||
<button type="button" class="nes-btn is-error" on:click|preventDefault={blockUser}>
|
||||
{userIsBlocked ? 'Unblock this user' : 'Block this user'}
|
||||
{userIsBlocked ? "Unblock this user" : "Block this user"}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<style lang="scss">
|
||||
div.block-container {
|
||||
text-align: center;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -1,20 +1,20 @@
|
||||
<script lang="ts">
|
||||
import {showReportScreenStore, userReportEmpty} from "../../Stores/ShowReportScreenStore";
|
||||
import { showReportScreenStore, userReportEmpty } from "../../Stores/ShowReportScreenStore";
|
||||
import BlockSubMenu from "./BlockSubMenu.svelte";
|
||||
import ReportSubMenu from "./ReportSubMenu.svelte";
|
||||
import {onDestroy, onMount} from "svelte";
|
||||
import type {Unsubscriber} from "svelte/store";
|
||||
import {playersStore} from "../../Stores/PlayersStore";
|
||||
import {connectionManager} from "../../Connexion/ConnectionManager";
|
||||
import {GameConnexionTypes} from "../../Url/UrlManager";
|
||||
import {get} from "svelte/store";
|
||||
import { onDestroy, onMount } from "svelte";
|
||||
import type { Unsubscriber } from "svelte/store";
|
||||
import { playersStore } from "../../Stores/PlayersStore";
|
||||
import { connectionManager } from "../../Connexion/ConnectionManager";
|
||||
import { GameConnexionTypes } from "../../Url/UrlManager";
|
||||
import { get } from "svelte/store";
|
||||
|
||||
let blockActive = true;
|
||||
let blockActive = true;
|
||||
let reportActive = !blockActive;
|
||||
let anonymous: boolean = false;
|
||||
let userUUID: string | undefined = playersStore.getPlayerById(get(showReportScreenStore).userId)?.userUuid;
|
||||
let userName = "No name";
|
||||
let unsubscriber: Unsubscriber
|
||||
let unsubscriber: Unsubscriber;
|
||||
|
||||
onMount(() => {
|
||||
unsubscriber = showReportScreenStore.subscribe((reportScreenStore) => {
|
||||
@ -25,15 +25,15 @@
|
||||
console.error("Could not find UUID for user with ID " + reportScreenStore.userId);
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
anonymous = connectionManager.getConnexionType === GameConnexionTypes.anonymous;
|
||||
})
|
||||
});
|
||||
|
||||
onDestroy(() => {
|
||||
if (unsubscriber) {
|
||||
unsubscriber();
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
function close() {
|
||||
showReportScreenStore.set(userReportEmpty);
|
||||
@ -49,14 +49,14 @@
|
||||
reportActive = true;
|
||||
}
|
||||
|
||||
function onKeyDown(e:KeyboardEvent) {
|
||||
if (e.key === 'Escape') {
|
||||
function onKeyDown(e: KeyboardEvent) {
|
||||
if (e.key === "Escape") {
|
||||
close();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window on:keydown={onKeyDown}/>
|
||||
<svelte:window on:keydown={onKeyDown} />
|
||||
|
||||
<div class="report-menu-main nes-container is-rounded">
|
||||
<section class="report-menu-title">
|
||||
@ -67,75 +67,83 @@
|
||||
</section>
|
||||
<section class="report-menu-action {anonymous ? 'hidden' : ''}">
|
||||
<section class="justify-center">
|
||||
<button type="button" class="nes-btn {blockActive ? 'is-disabled' : ''}" on:click|preventDefault={activateBlock}>Block</button>
|
||||
<button
|
||||
type="button"
|
||||
class="nes-btn {blockActive ? 'is-disabled' : ''}"
|
||||
on:click|preventDefault={activateBlock}>Block</button
|
||||
>
|
||||
</section>
|
||||
<section class="justify-center">
|
||||
<button type="button" class="nes-btn {reportActive ? 'is-disabled' : ''}" on:click|preventDefault={activateReport}>Report</button>
|
||||
<button
|
||||
type="button"
|
||||
class="nes-btn {reportActive ? 'is-disabled' : ''}"
|
||||
on:click|preventDefault={activateReport}>Report</button
|
||||
>
|
||||
</section>
|
||||
</section>
|
||||
<section class="report-menu-content">
|
||||
{#if blockActive}
|
||||
<BlockSubMenu userUUID="{userUUID}" userName="{userName}"/>
|
||||
<BlockSubMenu {userUUID} {userName} />
|
||||
{:else if reportActive}
|
||||
<ReportSubMenu userUUID="{userUUID}"/>
|
||||
{:else }
|
||||
<ReportSubMenu {userUUID} />
|
||||
{:else}
|
||||
<p>ERROR : There is no action selected.</p>
|
||||
{/if}
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.nes-container {
|
||||
padding: 5px;
|
||||
}
|
||||
.nes-container {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
section.justify-center {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
div.report-menu-main {
|
||||
font-family: "Press Start 2P";
|
||||
pointer-events: auto;
|
||||
background-color: #333333;
|
||||
color: whitesmoke;
|
||||
|
||||
position: relative;
|
||||
height: 70vh;
|
||||
width: 50vw;
|
||||
top: 10vh;
|
||||
margin: auto;
|
||||
|
||||
section.report-menu-title {
|
||||
display: grid;
|
||||
grid-template-columns: calc(100% - 45px) 40px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
h2 {
|
||||
section.justify-center {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
section.report-menu-action {
|
||||
display: grid;
|
||||
grid-template-columns: 50% 50%;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
section.report-menu-action.hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
div.report-menu-main {
|
||||
top: 21vh;
|
||||
height: 60vh;
|
||||
width: 100vw;
|
||||
font-size: 0.5em;
|
||||
font-family: "Press Start 2P";
|
||||
pointer-events: auto;
|
||||
background-color: #333333;
|
||||
color: whitesmoke;
|
||||
|
||||
position: relative;
|
||||
height: 70vh;
|
||||
width: 50vw;
|
||||
top: 10vh;
|
||||
margin: auto;
|
||||
|
||||
section.report-menu-title {
|
||||
display: grid;
|
||||
grid-template-columns: calc(100% - 45px) 40px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
h2 {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
section.report-menu-action {
|
||||
display: grid;
|
||||
grid-template-columns: 50% 50%;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
section.report-menu-action.hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
div.report-menu-main {
|
||||
top: 21vh;
|
||||
height: 60vh;
|
||||
width: 100vw;
|
||||
font-size: 0.5em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,22 +1,22 @@
|
||||
<script lang="ts">
|
||||
import {showReportScreenStore, userReportEmpty} from "../../Stores/ShowReportScreenStore";
|
||||
import {gameManager} from "../../Phaser/Game/GameManager";
|
||||
import { showReportScreenStore, userReportEmpty } from "../../Stores/ShowReportScreenStore";
|
||||
import { gameManager } from "../../Phaser/Game/GameManager";
|
||||
|
||||
export let userUUID: string | undefined;
|
||||
let reportMessage: string;
|
||||
let hiddenError = true;
|
||||
|
||||
function submitReport() {
|
||||
if (reportMessage === '') {
|
||||
if (reportMessage === "") {
|
||||
hiddenError = true;
|
||||
} else {
|
||||
hiddenError = false;
|
||||
if( userUUID === undefined) {
|
||||
console.error('User UUID is not valid.');
|
||||
if (userUUID === undefined) {
|
||||
console.error("User UUID is not valid.");
|
||||
return;
|
||||
}
|
||||
gameManager.getCurrentGameScene().connection?.emitReportPlayerMessage(userUUID, reportMessage);
|
||||
showReportScreenStore.set(userReportEmpty)
|
||||
showReportScreenStore.set(userReportEmpty);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -28,9 +28,9 @@
|
||||
<section>
|
||||
<label>
|
||||
<span>Your message: </span>
|
||||
<textarea type="text" class="nes-textarea" bind:value={reportMessage}></textarea>
|
||||
<textarea type="text" class="nes-textarea" bind:value={reportMessage} />
|
||||
</label>
|
||||
<p hidden="{hiddenError}">Report message cannot to be empty.</p>
|
||||
<p hidden={hiddenError}>Report message cannot to be empty.</p>
|
||||
</section>
|
||||
<section>
|
||||
<button type="submit" class="nes-btn is-error" on:click={submitReport}>Report this user</button>
|
||||
@ -40,16 +40,16 @@
|
||||
|
||||
<style lang="scss">
|
||||
div.report-container-main {
|
||||
text-align: center;
|
||||
text-align: center;
|
||||
|
||||
textarea {
|
||||
height: clamp(100px, 15vh, 300px);
|
||||
}
|
||||
textarea {
|
||||
height: clamp(100px, 15vh, 300px);
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-height: 630px) {
|
||||
div.report-container-main textarea {
|
||||
height: 50px;
|
||||
}
|
||||
div.report-container-main textarea {
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script lang="typescript">
|
||||
import type {Game} from "../../Phaser/Game/Game";
|
||||
import {SelectCompanionScene, SelectCompanionSceneName} from "../../Phaser/Login/SelectCompanionScene";
|
||||
import type { Game } from "../../Phaser/Game/Game";
|
||||
import { SelectCompanionScene, SelectCompanionSceneName } from "../../Phaser/Login/SelectCompanionScene";
|
||||
|
||||
export let game: Game;
|
||||
|
||||
@ -26,62 +26,70 @@
|
||||
<form class="selectCompanionScene">
|
||||
<section class="text-center">
|
||||
<h2>Select your companion</h2>
|
||||
<button class="selectCharacterButton selectCharacterButtonLeft nes-btn" on:click|preventDefault={selectLeft}> < </button>
|
||||
<button class="selectCharacterButton selectCharacterButtonRight nes-btn" on:click|preventDefault={selectRight}> > </button>
|
||||
<button class="selectCharacterButton selectCharacterButtonLeft nes-btn" on:click|preventDefault={selectLeft}>
|
||||
<
|
||||
</button>
|
||||
<button class="selectCharacterButton selectCharacterButtonRight nes-btn" on:click|preventDefault={selectRight}>
|
||||
>
|
||||
</button>
|
||||
</section>
|
||||
<section class="action">
|
||||
<button href="/" class="selectCompanionSceneFormBack nes-btn" on:click|preventDefault={noCompanion}>No companion</button>
|
||||
<button type="submit" class="selectCompanionSceneFormSubmit nes-btn is-primary" on:click|preventDefault={selectCompanion}>Continue</button>
|
||||
<button href="/" class="selectCompanionSceneFormBack nes-btn" on:click|preventDefault={noCompanion}
|
||||
>No companion</button
|
||||
>
|
||||
<button
|
||||
type="submit"
|
||||
class="selectCompanionSceneFormSubmit nes-btn is-primary"
|
||||
on:click|preventDefault={selectCompanion}>Continue</button
|
||||
>
|
||||
</section>
|
||||
</form>
|
||||
|
||||
<style lang="scss">
|
||||
form.selectCompanionScene {
|
||||
font-family: "Press Start 2P";
|
||||
pointer-events: auto;
|
||||
color: #ebeeee;
|
||||
|
||||
section {
|
||||
margin: 10px;
|
||||
|
||||
&.action {
|
||||
text-align: center;
|
||||
margin-top: 55vh;
|
||||
}
|
||||
|
||||
h2 {
|
||||
form.selectCompanionScene {
|
||||
font-family: "Press Start 2P";
|
||||
margin: 1px;
|
||||
}
|
||||
pointer-events: auto;
|
||||
color: #ebeeee;
|
||||
|
||||
&.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
section {
|
||||
margin: 10px;
|
||||
|
||||
button.selectCharacterButton {
|
||||
position: absolute;
|
||||
top: 33vh;
|
||||
margin: 0;
|
||||
}
|
||||
&.action {
|
||||
text-align: center;
|
||||
margin-top: 55vh;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-family: "Press Start 2P";
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
&.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
button.selectCharacterButton {
|
||||
position: absolute;
|
||||
top: 33vh;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
button.selectCharacterButtonLeft {
|
||||
left: 33vw;
|
||||
}
|
||||
|
||||
button.selectCharacterButtonRight {
|
||||
right: 33vw;
|
||||
}
|
||||
}
|
||||
|
||||
button.selectCharacterButtonLeft {
|
||||
left: 33vw;
|
||||
@media only screen and (max-width: 800px) {
|
||||
form.selectCompanionScene button.selectCharacterButtonLeft {
|
||||
left: 5vw;
|
||||
}
|
||||
form.selectCompanionScene button.selectCharacterButtonRight {
|
||||
right: 5vw;
|
||||
}
|
||||
}
|
||||
|
||||
button.selectCharacterButtonRight {
|
||||
right: 33vw;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
form.selectCompanionScene button.selectCharacterButtonLeft{
|
||||
left: 5vw;
|
||||
}
|
||||
form.selectCompanionScene button.selectCharacterButtonRight{
|
||||
right: 5vw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
@ -1,14 +1,15 @@
|
||||
<script lang="typescript">
|
||||
import { AudioContext } from 'standardized-audio-context';
|
||||
import {SoundMeter} from "../Phaser/Components/SoundMeter";
|
||||
import {onDestroy} from "svelte";
|
||||
import { AudioContext } from "standardized-audio-context";
|
||||
import { SoundMeter } from "../Phaser/Components/SoundMeter";
|
||||
import { onDestroy } from "svelte";
|
||||
|
||||
export let stream: MediaStream|null;
|
||||
export let stream: MediaStream | null;
|
||||
let volume = 0;
|
||||
|
||||
let timeout: ReturnType<typeof setTimeout>;
|
||||
const soundMeter = new SoundMeter();
|
||||
let display = false;
|
||||
let error = false;
|
||||
|
||||
$: {
|
||||
if (stream && stream.getAudioTracks().length > 0) {
|
||||
@ -17,17 +18,19 @@
|
||||
|
||||
if (timeout) {
|
||||
clearInterval(timeout);
|
||||
error = false;
|
||||
}
|
||||
|
||||
timeout = setInterval(() => {
|
||||
try{
|
||||
try {
|
||||
volume = soundMeter.getVolume();
|
||||
//console.log(volume);
|
||||
}catch(err){
|
||||
|
||||
} catch (err) {
|
||||
if (!error) {
|
||||
console.error(err);
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
|
||||
} else {
|
||||
display = false;
|
||||
}
|
||||
@ -38,14 +41,13 @@
|
||||
if (timeout) {
|
||||
clearInterval(timeout);
|
||||
}
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<div class="sound-progress" class:active={display}>
|
||||
<span class:active={volume > 5}></span>
|
||||
<span class:active={volume > 10}></span>
|
||||
<span class:active={volume > 15}></span>
|
||||
<span class:active={volume > 40}></span>
|
||||
<span class:active={volume > 70}></span>
|
||||
<span class:active={volume > 5} />
|
||||
<span class:active={volume > 10} />
|
||||
<span class:active={volume > 15} />
|
||||
<span class:active={volume > 40} />
|
||||
<span class:active={volume > 70} />
|
||||
</div>
|
||||
|
@ -1,22 +1,22 @@
|
||||
<script lang="ts">
|
||||
import { fly } from "svelte/transition";
|
||||
import {banMessageVisibleStore, banMessageContentStore} from "../../Stores/TypeMessageStore/BanMessageStore";
|
||||
import {onMount} from "svelte";
|
||||
import { banMessageVisibleStore, banMessageContentStore } from "../../Stores/TypeMessageStore/BanMessageStore";
|
||||
import { onMount } from "svelte";
|
||||
|
||||
const text = $banMessageContentStore;
|
||||
const NAME_BUTTON = 'Ok';
|
||||
const NAME_BUTTON = "Ok";
|
||||
let nbSeconds = 10;
|
||||
let nameButton = '';
|
||||
let nameButton = "";
|
||||
|
||||
onMount(() => {
|
||||
timeToRead()
|
||||
})
|
||||
timeToRead();
|
||||
});
|
||||
|
||||
function timeToRead() {
|
||||
nbSeconds -= 1;
|
||||
nameButton = nbSeconds.toString();
|
||||
if ( nbSeconds > 0 ) {
|
||||
setTimeout( () => {
|
||||
if (nbSeconds > 0) {
|
||||
setTimeout(() => {
|
||||
timeToRead();
|
||||
}, 1000);
|
||||
} else {
|
||||
@ -29,68 +29,76 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="main-ban-message nes-container is-rounded" transition:fly="{{ y: -1000, duration: 500 }}">
|
||||
<h2 class="title-ban-message"><img src="resources/logos/report.svg" alt="***"/> Important message <img src="resources/logos/report.svg" alt="***"/></h2>
|
||||
<div class="main-ban-message nes-container is-rounded" transition:fly={{ y: -1000, duration: 500 }}>
|
||||
<h2 class="title-ban-message">
|
||||
<img src="resources/logos/report.svg" alt="***" /> Important message
|
||||
<img src="resources/logos/report.svg" alt="***" />
|
||||
</h2>
|
||||
<div class="content-ban-message">
|
||||
<p>{text}</p>
|
||||
</div>
|
||||
<div class="footer-ban-message">
|
||||
<button type="button" class="nes-btn {nameButton === NAME_BUTTON ? 'is-primary' : 'is-error'}" disabled="{!(nameButton === NAME_BUTTON)}" on:click|preventDefault={closeBanMessage}>{nameButton}</button>
|
||||
<button
|
||||
type="button"
|
||||
class="nes-btn {nameButton === NAME_BUTTON ? 'is-primary' : 'is-error'}"
|
||||
disabled={!(nameButton === NAME_BUTTON)}
|
||||
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">
|
||||
<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;
|
||||
div.main-ban-message {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
top: 15vh;
|
||||
|
||||
height: 70vh;
|
||||
width: 60vw;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding-bottom: 0;
|
||||
height: 70vh;
|
||||
width: 60vw;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
padding-bottom: 0;
|
||||
|
||||
pointer-events: auto;
|
||||
background-color: #333333;
|
||||
color: whitesmoke;
|
||||
pointer-events: auto;
|
||||
background-color: #333333;
|
||||
color: whitesmoke;
|
||||
|
||||
h2.title-ban-message {
|
||||
flex: 1 1 auto;
|
||||
max-height: 50px;
|
||||
margin-bottom: 20px;
|
||||
h2.title-ban-message {
|
||||
flex: 1 1 auto;
|
||||
max-height: 50px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
text-align: center;
|
||||
text-align: center;
|
||||
|
||||
img {
|
||||
height: 50px;
|
||||
}
|
||||
img {
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
div.content-ban-message {
|
||||
flex: 1 1 auto;
|
||||
max-height: calc(100% - 50px);
|
||||
overflow: auto;
|
||||
|
||||
p {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
|
||||
div.footer-ban-message {
|
||||
height: 50px;
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
|
||||
button {
|
||||
width: 88px;
|
||||
height: 44px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
div.content-ban-message {
|
||||
flex: 1 1 auto;
|
||||
max-height: calc(100% - 50px);
|
||||
overflow: auto;
|
||||
|
||||
p {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
|
||||
div.footer-ban-message {
|
||||
height: 50px;
|
||||
margin-top: 10px;
|
||||
text-align: center;
|
||||
|
||||
button {
|
||||
width: 88px;
|
||||
height: 44px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -1,59 +1,61 @@
|
||||
<script lang="ts">
|
||||
import { fly } from "svelte/transition";
|
||||
import {textMessageContentStore, textMessageVisibleStore} from "../../Stores/TypeMessageStore/TextMessageStore";
|
||||
import { textMessageContentStore, textMessageVisibleStore } from "../../Stores/TypeMessageStore/TextMessageStore";
|
||||
import { QuillDeltaToHtmlConverter } from "quill-delta-to-html";
|
||||
|
||||
const content = JSON.parse($textMessageContentStore);
|
||||
const converter = new QuillDeltaToHtmlConverter(content.ops, {inlineStyles: true});
|
||||
const NAME_BUTTON = 'Ok';
|
||||
const converter = new QuillDeltaToHtmlConverter(content.ops, { inlineStyles: true });
|
||||
const NAME_BUTTON = "Ok";
|
||||
|
||||
function closeTextMessage() {
|
||||
textMessageVisibleStore.set(false);
|
||||
}
|
||||
|
||||
function onKeyDown(e:KeyboardEvent) {
|
||||
if (e.key === 'Escape') {
|
||||
function onKeyDown(e: KeyboardEvent) {
|
||||
if (e.key === "Escape") {
|
||||
closeTextMessage();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:window on:keydown={onKeyDown}/>
|
||||
<svelte:window on:keydown={onKeyDown} />
|
||||
|
||||
<div class="main-text-message nes-container is-rounded" transition:fly="{{ x: -1000, duration: 500 }}">
|
||||
<div class="main-text-message nes-container is-rounded" transition:fly={{ x: -1000, duration: 500 }}>
|
||||
<div class="content-text-message">
|
||||
{@html converter.convert()}
|
||||
</div>
|
||||
<div class="footer-text-message">
|
||||
<button type="button" class="nes-btn is-primary" on:click|preventDefault={closeTextMessage}>{NAME_BUTTON}</button>
|
||||
<button type="button" class="nes-btn is-primary" on:click|preventDefault={closeTextMessage}
|
||||
>{NAME_BUTTON}</button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
div.main-text-message {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
div.main-text-message {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
max-height: 25vh;
|
||||
width: 80vw;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
padding-bottom: 0;
|
||||
max-height: 25vh;
|
||||
width: 80vw;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
padding-bottom: 0;
|
||||
|
||||
pointer-events: auto;
|
||||
background-color: #333333;
|
||||
pointer-events: auto;
|
||||
background-color: #333333;
|
||||
|
||||
div.content-text-message {
|
||||
flex: 1 1 auto;
|
||||
max-height: calc(100% - 50px);
|
||||
color: whitesmoke;
|
||||
div.content-text-message {
|
||||
flex: 1 1 auto;
|
||||
max-height: calc(100% - 50px);
|
||||
color: whitesmoke;
|
||||
|
||||
overflow: auto;
|
||||
}
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
div.footer-text-message {
|
||||
height: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
div.footer-text-message {
|
||||
height: 50px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,8 +1,8 @@
|
||||
<script lang="ts">
|
||||
import { fly } from 'svelte/transition';
|
||||
import { fly } from "svelte/transition";
|
||||
import megaphoneImg from "./images/megaphone.svg";
|
||||
import {soundPlayingStore} from "../../Stores/SoundPlayingStore";
|
||||
import {afterUpdate} from "svelte";
|
||||
import { soundPlayingStore } from "../../Stores/SoundPlayingStore";
|
||||
import { afterUpdate } from "svelte";
|
||||
|
||||
export let url: string;
|
||||
let audio: HTMLAudioElement;
|
||||
@ -16,37 +16,37 @@
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="audio-playing" transition:fly="{{ x: 210, duration: 500 }}">
|
||||
<div class="audio-playing" transition:fly={{ x: 210, duration: 500 }}>
|
||||
<img src={megaphoneImg} alt="Audio playing" />
|
||||
<p>Audio message</p>
|
||||
<audio bind:this={audio} src={url} on:ended={soundEnded} >
|
||||
<track kind="captions">
|
||||
<audio bind:this={audio} src={url} on:ended={soundEnded}>
|
||||
<track kind="captions" />
|
||||
</audio>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
/*audio html when audio message playing*/
|
||||
.audio-playing {
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
height: 54px;
|
||||
right: 0;
|
||||
top: 40px;
|
||||
transition: all 0.1s ease-out;
|
||||
background-color: black;
|
||||
border-radius: 30px 0 0 30px;
|
||||
display: inline-flex;
|
||||
/*audio html when audio message playing*/
|
||||
.audio-playing {
|
||||
position: absolute;
|
||||
width: 200px;
|
||||
height: 54px;
|
||||
right: 0;
|
||||
top: 40px;
|
||||
transition: all 0.1s ease-out;
|
||||
background-color: black;
|
||||
border-radius: 30px 0 0 30px;
|
||||
display: inline-flex;
|
||||
|
||||
img {
|
||||
border-radius: 50%;
|
||||
background-color: #ffda01;
|
||||
padding: 10px;
|
||||
}
|
||||
img {
|
||||
border-radius: 50%;
|
||||
background-color: #ffda01;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
p {
|
||||
color: white;
|
||||
margin-left: 10px;
|
||||
margin-top: 14px;
|
||||
p {
|
||||
color: white;
|
||||
margin-left: 10px;
|
||||
margin-top: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,19 +1,18 @@
|
||||
<script lang="ts">
|
||||
import {errorStore} from "../../Stores/ErrorStore";
|
||||
|
||||
function close(): boolean {
|
||||
errorStore.clearMessages();
|
||||
return false;
|
||||
}
|
||||
import { errorStore } from "../../Stores/ErrorStore";
|
||||
|
||||
function close(): boolean {
|
||||
errorStore.clearMessages();
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="error-div nes-container is-dark is-rounded" open>
|
||||
<p class="nes-text is-error title">Error</p>
|
||||
<div class="body">
|
||||
{#each $errorStore as error}
|
||||
<p>{error}</p>
|
||||
{/each}
|
||||
{#each $errorStore as error}
|
||||
<p>{error}</p>
|
||||
{/each}
|
||||
</div>
|
||||
<div class="button-bar">
|
||||
<button class="nes-btn is-error" on:click={close}>Close</button>
|
||||
@ -22,27 +21,27 @@ function close(): boolean {
|
||||
|
||||
<style lang="scss">
|
||||
div.error-div {
|
||||
pointer-events: auto;
|
||||
margin-top: 10vh;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
width: max-content;
|
||||
max-width: 80vw;
|
||||
pointer-events: auto;
|
||||
margin-top: 10vh;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
width: max-content;
|
||||
max-width: 80vw;
|
||||
|
||||
.button-bar {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.body {
|
||||
max-height: 50vh;
|
||||
}
|
||||
|
||||
p {
|
||||
font-family: "Press Start 2P";
|
||||
|
||||
&.title {
|
||||
text-align: center;
|
||||
.button-bar {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.body {
|
||||
max-height: 50vh;
|
||||
}
|
||||
|
||||
p {
|
||||
font-family: "Press Start 2P";
|
||||
|
||||
&.title {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,21 +1,21 @@
|
||||
<script lang="ts">
|
||||
import {streamableCollectionStore} from "../../Stores/StreamableCollectionStore";
|
||||
import {afterUpdate, onDestroy} from "svelte";
|
||||
import {biggestAvailableAreaStore} from "../../Stores/BiggestAvailableAreaStore";
|
||||
import { streamableCollectionStore } from "../../Stores/StreamableCollectionStore";
|
||||
import { afterUpdate, onDestroy } from "svelte";
|
||||
import { biggestAvailableAreaStore } from "../../Stores/BiggestAvailableAreaStore";
|
||||
import MediaBox from "./MediaBox.svelte";
|
||||
|
||||
let cssClass = 'one-col';
|
||||
let cssClass = "one-col";
|
||||
|
||||
const unsubscribe = streamableCollectionStore.subscribe((displayableMedias) => {
|
||||
const nbUsers = displayableMedias.size;
|
||||
if (nbUsers <= 1) {
|
||||
cssClass = 'one-col';
|
||||
cssClass = "one-col";
|
||||
} else if (nbUsers <= 4) {
|
||||
cssClass = 'two-col';
|
||||
cssClass = "two-col";
|
||||
} else if (nbUsers <= 9) {
|
||||
cssClass = 'three-col';
|
||||
cssClass = "three-col";
|
||||
} else {
|
||||
cssClass = 'four-col';
|
||||
cssClass = "four-col";
|
||||
}
|
||||
});
|
||||
|
||||
@ -25,11 +25,11 @@
|
||||
|
||||
afterUpdate(() => {
|
||||
biggestAvailableAreaStore.recompute();
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="chat-mode {cssClass}">
|
||||
{#each [...$streamableCollectionStore.values()] as peer (peer.uniqueId)}
|
||||
<MediaBox streamable={peer}></MediaBox>
|
||||
<MediaBox streamable={peer} />
|
||||
{/each}
|
||||
</div>
|
||||
|
@ -1,16 +1,15 @@
|
||||
<script lang="typescript">
|
||||
import type {ScreenSharingLocalMedia} from "../../Stores/ScreenSharingStore";
|
||||
import {videoFocusStore} from "../../Stores/VideoFocusStore";
|
||||
import {srcObject} from "./utils";
|
||||
import type { ScreenSharingLocalMedia } from "../../Stores/ScreenSharingStore";
|
||||
import { videoFocusStore } from "../../Stores/VideoFocusStore";
|
||||
import { srcObject } from "./utils";
|
||||
|
||||
export let peer : ScreenSharingLocalMedia;
|
||||
export let peer: ScreenSharingLocalMedia;
|
||||
let stream = peer.stream;
|
||||
export let cssClass : string|undefined;
|
||||
export let cssClass: string | undefined;
|
||||
</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>
|
||||
<video use:srcObject={stream} autoplay muted playsinline on:click={() => videoFocusStore.toggleFocus(peer)} />
|
||||
{/if}
|
||||
</div>
|
||||
|
@ -1,20 +1,20 @@
|
||||
<script lang="ts">
|
||||
import {VideoPeer} from "../../WebRtc/VideoPeer";
|
||||
import { VideoPeer } from "../../WebRtc/VideoPeer";
|
||||
import VideoMediaBox from "./VideoMediaBox.svelte";
|
||||
import ScreenSharingMediaBox from "./ScreenSharingMediaBox.svelte";
|
||||
import {ScreenSharingPeer} from "../../WebRtc/ScreenSharingPeer";
|
||||
import { ScreenSharingPeer } from "../../WebRtc/ScreenSharingPeer";
|
||||
import LocalStreamMediaBox from "./LocalStreamMediaBox.svelte";
|
||||
import type {Streamable} from "../../Stores/StreamableCollectionStore";
|
||||
import type { Streamable } from "../../Stores/StreamableCollectionStore";
|
||||
|
||||
export let streamable: Streamable;
|
||||
</script>
|
||||
|
||||
<div class="media-container">
|
||||
{#if streamable instanceof VideoPeer}
|
||||
<VideoMediaBox peer={streamable}/>
|
||||
<VideoMediaBox peer={streamable} />
|
||||
{:else if streamable instanceof ScreenSharingPeer}
|
||||
<ScreenSharingMediaBox peer={streamable}/>
|
||||
<ScreenSharingMediaBox peer={streamable} />
|
||||
{:else}
|
||||
<LocalStreamMediaBox peer={streamable} cssClass=""/>
|
||||
<LocalStreamMediaBox peer={streamable} cssClass="" />
|
||||
{/if}
|
||||
</div>
|
||||
|
@ -1,26 +1,26 @@
|
||||
<script lang="ts">
|
||||
import {streamableCollectionStore} from "../../Stores/StreamableCollectionStore";
|
||||
import {videoFocusStore} from "../../Stores/VideoFocusStore";
|
||||
import {afterUpdate} from "svelte";
|
||||
import {biggestAvailableAreaStore} from "../../Stores/BiggestAvailableAreaStore";
|
||||
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 }
|
||||
{#if $videoFocusStore}
|
||||
{#key $videoFocusStore.uniqueId}
|
||||
<MediaBox streamable={$videoFocusStore}></MediaBox>
|
||||
<MediaBox streamable={$videoFocusStore} />
|
||||
{/key}
|
||||
{/if}
|
||||
</div>
|
||||
<aside class="sidebar">
|
||||
{#each [...$streamableCollectionStore.values()] as peer (peer.uniqueId)}
|
||||
{#if peer !== $videoFocusStore }
|
||||
<MediaBox streamable={peer}></MediaBox>
|
||||
{#if peer !== $videoFocusStore}
|
||||
<MediaBox streamable={peer} />
|
||||
{/if}
|
||||
{/each}
|
||||
</aside>
|
||||
|
@ -1,33 +1,33 @@
|
||||
<script lang="ts">
|
||||
import type {ScreenSharingPeer} from "../../WebRtc/ScreenSharingPeer";
|
||||
import {videoFocusStore} from "../../Stores/VideoFocusStore";
|
||||
import {getColorByString, srcObject} from "./utils";
|
||||
import type { ScreenSharingPeer } from "../../WebRtc/ScreenSharingPeer";
|
||||
import { videoFocusStore } from "../../Stores/VideoFocusStore";
|
||||
import { getColorByString, srcObject } from "./utils";
|
||||
|
||||
export let peer: ScreenSharingPeer;
|
||||
let streamStore = peer.streamStore;
|
||||
let name = peer.userName;
|
||||
let statusStore = peer.statusStore;
|
||||
|
||||
</script>
|
||||
|
||||
<div class="video-container">
|
||||
{#if $statusStore === 'connecting'}
|
||||
<div class="connecting-spinner"></div>
|
||||
{#if $statusStore === "connecting"}
|
||||
<div class="connecting-spinner" />
|
||||
{/if}
|
||||
{#if $statusStore === 'error'}
|
||||
<div class="rtc-error"></div>
|
||||
{#if $statusStore === "error"}
|
||||
<div class="rtc-error" />
|
||||
{/if}
|
||||
{#if $streamStore === null}
|
||||
<i style="background-color: {getColorByString(name)};">{name}</i>
|
||||
{:else}
|
||||
<video use:srcObject={$streamStore} autoplay playsinline on:click={() => videoFocusStore.toggleFocus(peer)}></video>
|
||||
<!-- svelte-ignore a11y-media-has-caption -->
|
||||
<video use:srcObject={$streamStore} autoplay playsinline on:click={() => videoFocusStore.toggleFocus(peer)} />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.video-container {
|
||||
video {
|
||||
width: 100%;
|
||||
.video-container {
|
||||
video {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,12 +1,12 @@
|
||||
<script lang="ts">
|
||||
import type {VideoPeer} from "../../WebRtc/VideoPeer";
|
||||
import type { VideoPeer } from "../../WebRtc/VideoPeer";
|
||||
import SoundMeterWidget from "../SoundMeterWidget.svelte";
|
||||
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 { videoFocusStore } from "../../Stores/VideoFocusStore";
|
||||
import { showReportScreenStore } from "../../Stores/ShowReportScreenStore";
|
||||
import { getColorByString, srcObject } from "./utils";
|
||||
|
||||
export let peer: VideoPeer;
|
||||
let streamStore = peer.streamStore;
|
||||
@ -15,32 +15,31 @@
|
||||
let constraintStore = peer.constraintsStore;
|
||||
|
||||
function openReport(peer: VideoPeer): void {
|
||||
showReportScreenStore.set({ userId:peer.userId, userName: peer.userName });
|
||||
showReportScreenStore.set({ userId: peer.userId, userName: peer.userName });
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div class="video-container">
|
||||
{#if $statusStore === 'connecting'}
|
||||
<div class="connecting-spinner"></div>
|
||||
{#if $statusStore === "connecting"}
|
||||
<div class="connecting-spinner" />
|
||||
{/if}
|
||||
{#if $statusStore === 'error'}
|
||||
<div class="rtc-error"></div>
|
||||
{#if $statusStore === "error"}
|
||||
<div class="rtc-error" />
|
||||
{/if}
|
||||
{#if !$constraintStore || $constraintStore.video === false}
|
||||
<i style="background-color: {getColorByString(name)};">{name}</i>
|
||||
{/if}
|
||||
{#if $constraintStore && $constraintStore.audio === false}
|
||||
<img src={microphoneCloseImg} class="active" alt="Muted">
|
||||
<img src={microphoneCloseImg} class="active" alt="Muted" />
|
||||
{/if}
|
||||
<button class="report" on:click={() => openReport(peer)}>
|
||||
<img alt="Report this user" src={reportImg}>
|
||||
<img alt="Report this user" src={reportImg} />
|
||||
<span>Report/Block</span>
|
||||
</button>
|
||||
<video use:srcObject={$streamStore} autoplay playsinline on:click={() => videoFocusStore.toggleFocus(peer)}></video>
|
||||
<!-- 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" />
|
||||
{#if $constraintStore && $constraintStore.audio !== false}
|
||||
<SoundMeterWidget stream={$streamStore}></SoundMeterWidget>
|
||||
<SoundMeterWidget stream={$streamStore} />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
@ -1,23 +1,22 @@
|
||||
<script lang="ts">
|
||||
import {LayoutMode} from "../../WebRtc/LayoutManager";
|
||||
import {layoutModeStore} from "../../Stores/StreamableCollectionStore";
|
||||
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 }
|
||||
{:else}
|
||||
<ChatLayout />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.video-overlay {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,11 +1,11 @@
|
||||
<script lang="typescript">
|
||||
import { fly } from 'svelte/transition';
|
||||
import {requestVisitCardsStore} from "../../Stores/GameStore";
|
||||
import {onMount} from "svelte";
|
||||
import { fly } from "svelte/transition";
|
||||
import { requestVisitCardsStore } from "../../Stores/GameStore";
|
||||
import { onMount } from "svelte";
|
||||
|
||||
export let visitCardUrl: string;
|
||||
let w = '500px';
|
||||
let h = '250px';
|
||||
let w = "500px";
|
||||
let h = "250px";
|
||||
let hidden = true;
|
||||
let cvIframe: HTMLIFrameElement;
|
||||
|
||||
@ -13,73 +13,81 @@
|
||||
requestVisitCardsStore.set(null);
|
||||
}
|
||||
|
||||
function handleIframeMessage(message:any) {
|
||||
if (message.data.type === 'cvIframeSize') {
|
||||
w = (message.data.data.w) + 'px';
|
||||
h = (message.data.data.h) + 'px';
|
||||
function handleIframeMessage(message: MessageEvent) {
|
||||
if (message.data.type === "cvIframeSize") {
|
||||
w = message.data.data.w + "px";
|
||||
h = message.data.data.h + "px";
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
cvIframe.onload = () => hidden = false
|
||||
cvIframe.onerror = () => hidden = false
|
||||
})
|
||||
cvIframe.onload = () => (hidden = false);
|
||||
cvIframe.onerror = () => (hidden = false);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
.loader {
|
||||
border: 16px solid #f3f3f3; /* Light grey */
|
||||
border-top: 16px solid #3498db; /* Blue */
|
||||
border-radius: 50%;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
margin:auto;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.visitCard {
|
||||
pointer-events: all;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0);
|
||||
margin-top: 200px;
|
||||
max-width: 80vw;
|
||||
|
||||
iframe {
|
||||
border: 0;
|
||||
max-width: 80vw;
|
||||
overflow: hidden;
|
||||
|
||||
&.hidden {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<section class="visitCard" transition:fly="{{ y: -200, duration: 1000 }}" style="width: {w}">
|
||||
<section class="visitCard" transition:fly={{ y: -200, duration: 1000 }} style="width: {w}">
|
||||
{#if hidden}
|
||||
<div class="loader"></div>
|
||||
<div class="loader" />
|
||||
{/if}
|
||||
<iframe title="visitCard" src={visitCardUrl} allow="clipboard-read; clipboard-write self {visitCardUrl}" style="width: {w}; height: {h}" class:hidden={hidden} bind:this={cvIframe}></iframe>
|
||||
<iframe
|
||||
title="visitCard"
|
||||
src={visitCardUrl}
|
||||
allow="clipboard-read; clipboard-write self {visitCardUrl}"
|
||||
style="width: {w}; height: {h}"
|
||||
class:hidden
|
||||
bind:this={cvIframe}
|
||||
/>
|
||||
{#if !hidden}
|
||||
<div class="buttonContainer">
|
||||
<button class="nes-btn is-popUpElement" on:click={closeCard}>Close</button>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
</section>
|
||||
|
||||
<svelte:window on:message={handleIframeMessage}/>
|
||||
<svelte:window on:message={handleIframeMessage} />
|
||||
|
||||
<style lang="scss">
|
||||
.loader {
|
||||
border: 16px solid #f3f3f3; /* Light grey */
|
||||
border-top: 16px solid #3498db; /* Blue */
|
||||
border-radius: 50%;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
margin: auto;
|
||||
animation: spin 2s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.visitCard {
|
||||
pointer-events: all;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0);
|
||||
margin-top: 200px;
|
||||
max-width: 80vw;
|
||||
|
||||
iframe {
|
||||
border: 0;
|
||||
max-width: 80vw;
|
||||
overflow: hidden;
|
||||
|
||||
&.hidden {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -1,37 +1,39 @@
|
||||
<script lang="typescript">
|
||||
import { fly } from 'svelte/transition';
|
||||
import {userIsAdminStore} from "../../Stores/GameStore";
|
||||
import {ADMIN_URL} from "../../Enum/EnvironmentVariable";
|
||||
|
||||
const upgradeLink = ADMIN_URL+'/pricing';
|
||||
|
||||
import { fly } from "svelte/transition";
|
||||
import { userIsAdminStore } from "../../Stores/GameStore";
|
||||
import { ADMIN_URL } from "../../Enum/EnvironmentVariable";
|
||||
|
||||
const upgradeLink = ADMIN_URL + "/pricing";
|
||||
</script>
|
||||
|
||||
<main class="warningMain" transition:fly="{{ y: -200, duration: 500 }}">
|
||||
<main class="warningMain" transition:fly={{ y: -200, duration: 500 }}>
|
||||
<h2>Warning!</h2>
|
||||
{#if $userIsAdminStore}
|
||||
<p>This world is close to its limit!. You can upgrade its capacity <a href="{upgradeLink}" target="_blank">here</a></p>
|
||||
<p>
|
||||
This world is close to its limit!. You can upgrade its capacity <a href={upgradeLink} target="_blank"
|
||||
>here</a
|
||||
>
|
||||
</p>
|
||||
{:else}
|
||||
<p>This world is close to its limit!</p>
|
||||
{/if}
|
||||
|
||||
{/if}
|
||||
</main>
|
||||
|
||||
<style lang="scss">
|
||||
main.warningMain {
|
||||
pointer-events: auto;
|
||||
width: 100vw;
|
||||
background-color: red;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0);
|
||||
font-family: Lato;
|
||||
min-width: 300px;
|
||||
opacity: 0.9;
|
||||
z-index: 2;
|
||||
main.warningMain {
|
||||
pointer-events: auto;
|
||||
width: 100vw;
|
||||
background-color: red;
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0);
|
||||
font-family: Lato;
|
||||
min-width: 300px;
|
||||
opacity: 0.9;
|
||||
z-index: 2;
|
||||
h2 {
|
||||
padding: 5px;
|
||||
padding: 5px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script lang="typescript">
|
||||
import type { Game } from "../../Phaser/Game/Game";
|
||||
import {SelectCharacterScene, SelectCharacterSceneName} from "../../Phaser/Login/SelectCharacterScene";
|
||||
import { SelectCharacterScene, SelectCharacterSceneName } from "../../Phaser/Login/SelectCharacterScene";
|
||||
|
||||
export let game: Game;
|
||||
|
||||
@ -21,72 +21,81 @@
|
||||
function customizeScene() {
|
||||
selectCharacterScene.nextSceneToCustomizeScene();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<form class="selectCharacterScene">
|
||||
<section class="text-center">
|
||||
<h2>Select your WOKA</h2>
|
||||
<button class="selectCharacterButton selectCharacterButtonLeft nes-btn" on:click|preventDefault={ selectLeft }> < </button>
|
||||
<button class="selectCharacterButton selectCharacterButtonRight nes-btn" on:click|preventDefault={ selectRight }> > </button>
|
||||
<button class="selectCharacterButton selectCharacterButtonLeft nes-btn" on:click|preventDefault={selectLeft}>
|
||||
<
|
||||
</button>
|
||||
<button class="selectCharacterButton selectCharacterButtonRight nes-btn" on:click|preventDefault={selectRight}>
|
||||
>
|
||||
</button>
|
||||
</section>
|
||||
<section class="action">
|
||||
<button type="submit" class="selectCharacterSceneFormSubmit nes-btn is-primary" on:click|preventDefault={ cameraScene }>Continue</button>
|
||||
<button type="submit" class="selectCharacterSceneFormCustomYourOwnSubmit nes-btn" on:click|preventDefault={ customizeScene }>Customize your WOKA</button>
|
||||
<button
|
||||
type="submit"
|
||||
class="selectCharacterSceneFormSubmit nes-btn is-primary"
|
||||
on:click|preventDefault={cameraScene}>Continue</button
|
||||
>
|
||||
<button
|
||||
type="submit"
|
||||
class="selectCharacterSceneFormCustomYourOwnSubmit nes-btn"
|
||||
on:click|preventDefault={customizeScene}>Customize your WOKA</button
|
||||
>
|
||||
</section>
|
||||
</form>
|
||||
|
||||
<style lang="scss">
|
||||
form.selectCharacterScene {
|
||||
font-family: "Press Start 2P";
|
||||
pointer-events: auto;
|
||||
color: #ebeeee;
|
||||
|
||||
section {
|
||||
margin: 10px;
|
||||
|
||||
&.action {
|
||||
text-align: center;
|
||||
margin-top: 55vh;
|
||||
}
|
||||
|
||||
h2 {
|
||||
form.selectCharacterScene {
|
||||
font-family: "Press Start 2P";
|
||||
margin: 1px;
|
||||
}
|
||||
pointer-events: auto;
|
||||
color: #ebeeee;
|
||||
|
||||
&.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
section {
|
||||
margin: 10px;
|
||||
|
||||
button.selectCharacterButton {
|
||||
position: absolute;
|
||||
top: 33vh;
|
||||
margin: 0;
|
||||
}
|
||||
&.action {
|
||||
text-align: center;
|
||||
margin-top: 55vh;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-family: "Press Start 2P";
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
&.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
button.selectCharacterButton {
|
||||
position: absolute;
|
||||
top: 33vh;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
font-family: "Press Start 2P";
|
||||
|
||||
&.selectCharacterButtonLeft {
|
||||
left: 33vw;
|
||||
}
|
||||
|
||||
&.selectCharacterButtonRight {
|
||||
right: 33vw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
font-family: "Press Start 2P";
|
||||
|
||||
&.selectCharacterButtonLeft {
|
||||
left: 33vw;
|
||||
}
|
||||
|
||||
&.selectCharacterButtonRight {
|
||||
right: 33vw;
|
||||
}
|
||||
@media only screen and (max-width: 800px) {
|
||||
form.selectCharacterScene button.selectCharacterButtonLeft {
|
||||
left: 5vw;
|
||||
}
|
||||
form.selectCharacterScene button.selectCharacterButtonRight {
|
||||
right: 5vw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 800px) {
|
||||
form.selectCharacterScene button.selectCharacterButtonLeft{
|
||||
left: 5vw;
|
||||
}
|
||||
form.selectCharacterScene button.selectCharacterButtonRight{
|
||||
right: 5vw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
@ -2040,6 +2040,11 @@ escape-string-regexp@^1.0.5:
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
||||
|
||||
eslint-plugin-svelte3@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-plugin-svelte3/-/eslint-plugin-svelte3-3.2.1.tgz#f0f24150ecea3061c38c69e282bea26dc3e660c6"
|
||||
integrity sha512-YoBR9mLoKCjGghJ/gvpnFZKaMEu/VRcuxpSRS8KuozuEo7CdBH7bmBHa6FmMm0i4kJnOyx+PVsaptz96K6H/4Q==
|
||||
|
||||
eslint-scope@^5.0.0, eslint-scope@^5.1.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
|
||||
@ -4508,6 +4513,11 @@ prelude-ls@^1.2.1:
|
||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
|
||||
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
|
||||
|
||||
prettier-plugin-svelte@^2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/prettier-plugin-svelte/-/prettier-plugin-svelte-2.5.0.tgz#7922534729f7febe59b4c56c3f5360539f0d8ab1"
|
||||
integrity sha512-+iHY2uGChOngrgKielJUnqo74gIL/EO5oeWm8MftFWjEi213lq9QYTOwm1pv4lI1nA61tdgf80CF2i5zMcu1kw==
|
||||
|
||||
prettier@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.1.tgz#76903c3f8c4449bc9ac597acefa24dc5ad4cbea6"
|
||||
|
Loading…
Reference in New Issue
Block a user