Merge pull request 'Export current view as a share link' (#34) from thubrecht/selection into master

Reviewed-on: https://git.rz.ens.wtf/Klub-RZ/metis/pulls/34
This commit is contained in:
tomate 2022-07-27 01:17:44 +02:00
commit a837e7ef5d
2 changed files with 139 additions and 3 deletions

View file

@ -14,6 +14,7 @@
import { mkSource, calendarTree, initialCalendars, getSubCalendars } from './calendar';
import { debounce } from 'lodash';
import Help from './Help.svelte';
import Share from './Share.svelte';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap-icons/font/bootstrap-icons.css';
@ -36,7 +37,24 @@
return time.toLocaleTimeString();
})();
const params = new URL(document.location).searchParams.getAll('c');
const allowedViews = [
'resourceTimelineDay',
'dayGridMonth',
'timeGridWeek',
'timeGridDay',
'listWeek'
];
let search = new URL(document.location).searchParams;
if (search.has('b64')) {
// On est dans le cas où les paramètres sont codés en base64
search = new URLSearchParams(window.atob(search.get('b64')));
}
const params = search.getAll('c');
const date = search.has('d') ? new Date(search.get('d')) : now;
const view = search.get('v');
const headers = mobile
? {
@ -53,7 +71,12 @@
let calendar;
let options = writable({
initialView: mobile ? 'listWeek' : 'timeGridWeek',
initialView: allowedViews.includes(view)
? view
: mobile
? 'listWeek'
: 'timeGridWeek',
initialDate: date.toString() === 'Invalid Date' ? now : date,
plugins: [
timeGridPlugin,
dayGridPlugin,
@ -67,7 +90,7 @@
allDayContent: '',
headerToolbar: headers,
buttonText: { resourceTimelineDay: 'Salles' },
scrollTime: "08:00:00",
scrollTime: '08:00:00',
resourceGroupField: 'building',
resourceAreaWidth: '27%',
resources: Object.entries(ENSLocations).flatMap(([building, rooms]) =>
@ -141,6 +164,7 @@
<div class="h-100 d-flex flex-column">
<h1 class="mt-3 title text-center">Calendrier de la vie étudiante à l'ENS</h1>
<Share {calendar} {selectedCalendars} />
<Help />
<FilterBar {calendarTree} bind:selected={selectedCalendars} {initial} />

112
src/Share.svelte Normal file
View file

@ -0,0 +1,112 @@
<script>
import { Modal, ModalHeader, ModalBody, ModalFooter, Icon, Toast } from 'sveltestrap';
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 updateShareLink = () => {
const loc = document.location;
const search = new URLSearchParams();
const api = calendar.getAPI();
if (calendar !== null) {
search.append('v', api.view.type);
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" 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" on:click={doShare}>{share}</a>
</ModalBody>
<ModalFooter>
<span on:click={toggleBinary} class="flex-grow-1" title="Partager en base64">
<Icon name={shareDataIcon} class="fs-5" />
</span>
<Icon name="balloon-heart" class="text-danger fs-5" />
<span class="fs-7">Propulsé par le Club Réseau de l'ENS</span>
</ModalFooter>
</Modal>
<style>
.share-btn {
position: absolute;
top: 2.5em;
right: 1em;
cursor: pointer;
}
#share-url {
max-width: 100%;
display: block;
overflow-wrap: break-word;
cursor: pointer;
user-select: all;
}
.share-toast {
position: absolute;
top: 1.25em;
left: 1em;
z-index: 1100;
}
</style>