forked from DGNum/metis
145 lines
3 KiB
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>
|