metis/src/Share.svelte

145 lines
3 KiB
Svelte

<script>
import {
Button,
Modal,
ModalHeader,
ModalBody,
ModalFooter,
Icon,
Toast
} from 'sveltestrap';
import { ancestors } from './calendar';
export let calendar = null;
export let selectedCalendars = [];
let share = document.URL;
let isOpen = false;
let isToastOpen = false;
let isBinary = false;
let toastText = '';
const toggle = () => {
isOpen = !isOpen;
updateShareLink();
};
const doShare = () => {
navigator.clipboard
.writeText(share)
.then(() => (toastText = '<b>Lien de partage copié dans le presse-papier.</b>'))
.catch(() => (toastText = 'Erreur de copie automatique.'))
.finally((isToastOpen = true));
};
const filter = calendars => {
let reduced = [];
calendars.forEach(c => {
if (!ancestors[c].some(p => calendars.includes(p))) {
reduced.push(c);
}
});
return reduced;
};
const updateShareLink = () => {
const loc = document.location;
const search = new URLSearchParams();
const api = calendar.getAPI();
if (calendar !== null) {
search.append('v', api.view.type);
filter(selectedCalendars).forEach(c => search.append('c', c));
search.append('d', api.getDate().toISOString());
}
if (isBinary) {
const b64 = window.btoa(search.toString());
share = `${loc.origin}${loc.pathname}?b64=${b64}`;
} else {
share = `${loc.origin}${loc.pathname}?${search.toString()}`;
}
};
const toggleBinary = () => {
isBinary = !isBinary;
updateShareLink();
};
$: shareDataIcon = isBinary ? 'code-square' : 'code';
</script>
<div class="share-toast">
<Toast autohide body isOpen={isToastOpen} on:close={() => (isToastOpen = false)}>
{@html toastText}
</Toast>
</div>
<span
class="share-btn fs-4 no-print"
data-bs-toggle="tooltip"
title="Partager"
on:click={toggle}
>
<Icon name="share" />
</span>
<Modal {isOpen} {toggle} centered scrollable>
<ModalHeader {toggle}>
<Icon name="share" class="text-success me-2" />
<b>Partage</b>
</ModalHeader>
<ModalBody>
<p>La vue actuelle du calendrier peut être partagée avec l'URL suivante :</p>
<a id="share-url">{share}</a>
</ModalBody>
<ModalFooter>
<span on:click={toggleBinary} class="share-egg" title="Partager en base64">
<Icon name={shareDataIcon} class="fs-5" />
</span>
<Button size="sm" color="primary" on:click={doShare}>
<Icon name="clipboard2-heart" />
<span class="ms-1">Copier</span>
</Button>
</ModalFooter>
</Modal>
<style>
.share-btn {
position: absolute;
top: 2.5em;
right: 1em;
cursor: pointer;
}
.share-egg {
position: absolute;
cursor: pointer;
left: 1em;
}
#share-url {
max-width: 100%;
display: inline-block;
overflow-wrap: break-word;
cursor: pointer;
user-select: all;
}
.share-toast {
position: absolute;
top: 1.25em;
left: 1em;
z-index: 1100;
}
</style>