mirror of
https://github.com/KevinMidboe/infra-map.git
synced 2026-01-10 19:26:02 +00:00
105 lines
2.5 KiB
Svelte
105 lines
2.5 KiB
Svelte
<script lang="ts">
|
|
import { onMount } from 'svelte';
|
|
import { grey400x225 } from '$lib/utils/staticImageSource';
|
|
import Dialog from './Dialog.svelte';
|
|
|
|
const IMAGE_REFRESH_INTERVAL = 1000;
|
|
|
|
let { imageUrl }: { imageUrl: string } = $props();
|
|
let lastUpdated = new Date();
|
|
let timestamp = $state(0);
|
|
let fullscreen = $state(false);
|
|
|
|
let imageSource: string | ArrayBuffer = grey400x225;
|
|
let lastCacheSize: string;
|
|
|
|
function loadBlob(blob: Blob) {
|
|
const reader = new FileReader();
|
|
reader.onloadend = () => {
|
|
const img = document.getElementById('live-image') as HTMLImageElement;
|
|
if (!img) return;
|
|
|
|
imageSource = reader?.result || '';
|
|
if (imageSource === '') {
|
|
console.log("no image data, returning")
|
|
return
|
|
}
|
|
|
|
// set imageSource to image element
|
|
img.src = `data:image/jpeg;base64; ${imageSource}`;
|
|
lastUpdated = new Date();
|
|
};
|
|
|
|
// load blob into FileReader
|
|
reader.readAsDataURL(blob);
|
|
}
|
|
|
|
function refetchImage() {
|
|
let url;
|
|
try {
|
|
const { protocol, host } = window.location;
|
|
url = new URL(`${protocol}//${host}/image-proxy/${imageUrl}`);
|
|
} catch {
|
|
console.log('url not valid, returning');
|
|
return;
|
|
}
|
|
|
|
const options = {
|
|
method: 'GET',
|
|
headers: {
|
|
'Content-Type': 'image/jpeg',
|
|
'If-None-Match': lastCacheSize
|
|
}
|
|
};
|
|
|
|
fetch(url.href, options)
|
|
.then((resp) => {
|
|
if (resp.status === 304) throw Error('image exists');
|
|
lastCacheSize = resp.headers.get('Content-Length') || '';
|
|
return resp;
|
|
})
|
|
.then((resp) => resp.blob())
|
|
.then((blob) => loadBlob(blob))
|
|
.catch(() => {}); // suppress all exceptions
|
|
}
|
|
|
|
function timeDiff(d: Date) {
|
|
const seconds = d.getTime();
|
|
const v = seconds - lastUpdated.getTime();
|
|
return Math.floor(v / 100) / 10;
|
|
}
|
|
|
|
onMount(() => {
|
|
refetchImage();
|
|
const imageInterval = setInterval(refetchImage, IMAGE_REFRESH_INTERVAL);
|
|
const timerInterval = setInterval(() => (timestamp = timeDiff(new Date())), 80);
|
|
|
|
return () => Promise.all([clearInterval(imageInterval), clearInterval(timerInterval)]);
|
|
});
|
|
</script>
|
|
|
|
<div>
|
|
{#if !fullscreen}
|
|
<img on:click={() => (fullscreen = !fullscreen)} src={String(imageSource)} id="live-image" />
|
|
{:else}
|
|
<Dialog title="Live stream of printer" on:close={() => (fullscreen = false)}>
|
|
<img style="width: 100%;" src={String(imageSource)} id="live-image" />
|
|
<span>Last update {timestamp}s ago</span>
|
|
</Dialog>
|
|
|
|
<img src={String(grey400x225)} />
|
|
{/if}
|
|
<span>Last update {timestamp}s ago</span>
|
|
</div>
|
|
|
|
<style lang="scss">
|
|
img {
|
|
width: 400px;
|
|
border-radius: 0.5rem;
|
|
}
|
|
|
|
span {
|
|
display: block;
|
|
}
|
|
</style>
|