Files
partey_workadventure/front/src/Components/EmbedScreens/CoWebsiteThumbnailSlot.svelte
T

279 lines
8.3 KiB
Svelte

<script lang="ts">
import { onMount } from "svelte";
import { ICON_URL } from "../../Enum/EnvironmentVariable";
import { mainCoWebsite } from "../../Stores/CoWebsiteStore";
import { highlightedEmbedScreen } from "../../Stores/EmbedScreensStore";
import type { CoWebsite } from "../../WebRtc/CoWebsite/CoWesbite";
import { JitsiCoWebsite } from "../../WebRtc/CoWebsite/JitsiCoWebsite";
import { iframeStates } from "../../WebRtc/CoWebsiteManager";
import { coWebsiteManager } from "../../WebRtc/CoWebsiteManager";
import { HtmlUtils } from "../../WebRtc/HtmlUtils";
import { i18nJson } from "../../i18n/locales";
import uploadFile from "../images/jitsi.png";
import { analyticsClient } from "../../Administration/AnalyticsClient";
export let index: number;
export let coWebsite: CoWebsite;
export let vertical: boolean;
let icon: HTMLImageElement;
let iconLoaded = false;
let state = coWebsite.getStateSubscriber();
let isJitsi: boolean = coWebsite instanceof JitsiCoWebsite;
const mainState = coWebsiteManager.getMainStateSubscriber();
onMount(() => {
const fallback = location.protocol + "%2F%2F" + location.host + "%2Fresources%2Ficons%2Fwebsite.png";
icon.src = isJitsi
? uploadFile
: `${ICON_URL}/icon?url=${coWebsite.getUrl().hostname}&size=64..96..256&fallback_icon_color=14304c&fallback_icon_url=${fallback}`;
icon.alt = coWebsite.getUrl().hostname;
icon.onload = () => {
iconLoaded = true;
};
});
async function onClick() {
if (vertical) {
coWebsiteManager.goToMain(coWebsite);
} else if ($mainCoWebsite) {
if ($mainCoWebsite.getId() === coWebsite.getId()) {
if (coWebsiteManager.getMainState() === iframeStates.closed) {
coWebsiteManager.displayMain();
} else if ($highlightedEmbedScreen?.type === "cowebsite") {
coWebsiteManager.goToMain($highlightedEmbedScreen.embed);
} else {
coWebsiteManager.hideMain();
}
} else {
if (coWebsiteManager.getMainState() === iframeStates.closed) {
coWebsiteManager.goToMain(coWebsite);
coWebsiteManager.displayMain();
} else {
highlightedEmbedScreen.toggleHighlight({
type: "cowebsite",
embed: coWebsite,
});
}
}
}
if ($state === "asleep") {
await coWebsiteManager.loadCoWebsite(coWebsite);
}
coWebsiteManager.resizeAllIframes();
}
function noDrag() {
return false;
}
function i18n(text: string | undefined): string {
if (typeof text === "string") {
return i18nJson(text);
}
return "";
}
function sanitize(html : string | undefined): string {
return HtmlUtils.sanitize(html);
}
let isHighlight: boolean = false;
let isMain: boolean = false;
$: {
isMain =
$mainState === iframeStates.opened &&
$mainCoWebsite !== undefined &&
$mainCoWebsite.getId() === coWebsite.getId();
isHighlight =
$highlightedEmbedScreen !== undefined &&
$highlightedEmbedScreen?.type === "cowebsite" &&
$highlightedEmbedScreen?.embed.getId() === coWebsite.getId();
}
</script>
<div
id={"cowebsite-thumbnail-" + index}
class="cowebsite-thumbnail nes-pointer"
class:asleep={$state === "asleep"}
class:loading={$state === "loading"}
class:ready={$state === "ready"}
class:displayed={isMain || isHighlight}
class:vertical
on:click={() => analyticsClient.stackOpenCloseMultiIframe()}
on:click={onClick}
>
<div class="cowebsite-thumnail-container">
<img
class="cowebsite-icon noselect nes-pointer"
class:hide={!iconLoaded}
class:jitsi={isJitsi}
bind:this={icon}
on:dragstart|preventDefault={noDrag}
alt=""
/>
</div>
{#if coWebsite.getHint() && $state === "asleep" }
<div class="cowebsite-thumbnail-hint nes-balloon from-left">
<p>{@html sanitize(i18n(coWebsite.getHint()))}</p>
</div>
{/if}
</div>
<style lang="scss">
.cowebsite-thumbnail {
cursor: url("../../../style/images/cursor_pointer.png"), pointer;
position: relative;
padding: 0;
background-color: rgba(#000000, 0.6);
margin: 12px;
margin-top: auto;
margin-bottom: auto;
&::before {
content: "";
position: absolute;
width: 58px;
height: 58px;
left: -8px;
top: -8px;
margin: 4px;
border-style: solid;
border-width: 4px;
border-image-slice: 3;
border-image-width: 3;
border-image-repeat: stretch;
border-image-source: url('data:image/svg+xml;utf8,<?xml version="1.0" encoding="UTF-8" ?><svg version="1.1" width="8" height="8" xmlns="http://www.w3.org/2000/svg"><path d="M3 1 h1 v1 h-1 z M4 1 h1 v1 h-1 z M2 2 h1 v1 h-1 z M5 2 h1 v1 h-1 z M1 3 h1 v1 h-1 z M6 3 h1 v1 h-1 z M1 4 h1 v1 h-1 z M6 4 h1 v1 h-1 z M2 5 h1 v1 h-1 z M5 5 h1 v1 h-1 z M3 6 h1 v1 h-1 z M4 6 h1 v1 h-1 z" fill="rgb(33,37,41)" /></svg>');
border-image-outset: 1;
z-index: 1;
}
&:not(.vertical) {
transition: all 300ms;
transform: translateY(0px);
}
&.vertical {
margin: 7px;
&::before {
width: 48px;
height: 48px;
}
.cowebsite-icon {
width: 40px;
height: 40px;
}
animation: shake 0.35s ease-in-out;
}
&.displayed {
&:not(.vertical) {
transform: translateY(-15px);
}
}
&.asleep {
.cowebsite-icon {
filter: grayscale(100%);
--webkit-filter: grayscale(100%);
}
}
&.loading {
animation: 2500ms ease-in-out 0s infinite alternate backgroundLoading;
}
&.ready {
&::before {
border-image-source: url('data:image/svg+xml;utf8,<?xml version="1.0" encoding="UTF-8" ?><svg version="1.1" width="8" height="8" xmlns="http://www.w3.org/2000/svg"><path d="M3 1 h1 v1 h-1 z M4 1 h1 v1 h-1 z M2 2 h1 v1 h-1 z M5 2 h1 v1 h-1 z M1 3 h1 v1 h-1 z M6 3 h1 v1 h-1 z M1 4 h1 v1 h-1 z M6 4 h1 v1 h-1 z M2 5 h1 v1 h-1 z M5 5 h1 v1 h-1 z M3 6 h1 v1 h-1 z M4 6 h1 v1 h-1 z" fill="rgb(38, 74, 110)" /></svg>');
}
}
@keyframes backgroundLoading {
0% {
background-color: rgba(#000000, 0.6);
}
100% {
background-color: #25598e;
}
}
@keyframes bounce {
from {
transform: translateY(0);
}
to {
transform: translateY(-15px);
}
}
@keyframes shake {
0% {
transform: translateX(0);
}
20% {
transform: translateX(-10px);
}
40% {
transform: translateX(10px);
}
60% {
transform: translateX(-10px);
}
80% {
transform: translateX(10px);
}
100% {
transform: translateX(0);
}
}
.cowebsite-icon {
width: 50px;
height: 50px;
object-fit: cover;
&.hide {
display: none;
}
&.jitsi {
padding: 7px;
}
}
.cowebsite-thumbnail-hint {
display: none;
position:absolute;
padding: 8px 4px;
text-align: center;
bottom: 50px;
width: clamp(150px, 15vw, 15vw);
left: -10px;
}
&:hover {
.cowebsite-thumbnail-hint {
display: inline-block;
}
}
}
</style>