274 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			274 lines
		
	
	
		
			9.1 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 'use strict';
 | |
| 
 | |
| import Spotlight from './vendor/spotlight.js/src/js/spotlight.js';
 | |
| import { SiteSheet } from './components/SiteSheet.js';
 | |
| import { SiteDocuments } from './components/SiteDocuments.js';
 | |
| import { SiteSurveys } from './components/SiteSurveys.js';
 | |
| import { SiteMedia } from './components/SiteMedia.js';
 | |
| import { NotConserved } from './components/NotConserved.js';
 | |
| import { Finding } from './components/Finding.js';
 | |
| import { Prehistoric } from './components/Prehistoric.js';
 | |
| import { Underwater } from './components/Underwater.js';
 | |
| import { GisState } from "./state.js";
 | |
| import { Reuse } from './components/Reuse.js';
 | |
| 
 | |
| /**
 | |
|  * @namespace UI
 | |
|  */
 | |
| const UI = {};
 | |
| 
 | |
| /**
 | |
|  * Add a Leaflet control to center the map
 | |
|  * @param {Map} map The Leaflet map object
 | |
|  * @param {LatLngExpression} centerCoords The coordinates to center the map
 | |
|  * @param {number} zoom Zoom level
 | |
|  */
 | |
| UI.addCenterMapControl = function (map, centerCoords, zoom) {
 | |
|     L.Control.CenterControl = L.Control.extend({
 | |
|         options: {
 | |
|             position: 'topleft'
 | |
|         },
 | |
|         onAdd: function (map) {
 | |
|             let controlDiv = L.DomUtil.create('div', 'leaflet-draw-toolbar leaflet-bar');
 | |
|             L.DomEvent
 | |
|                 .addListener(controlDiv, 'click', L.DomEvent.stopPropagation)
 | |
|                 .addListener(controlDiv, 'click', L.DomEvent.preventDefault)
 | |
|                 .addListener(controlDiv, 'click', function () {
 | |
|                     map.setView(centerCoords, zoom, {animate: true});
 | |
|                 }
 | |
|             );
 | |
|             let controlUI = L.DomUtil.create('a', 'leaflet-draw-edit-remove', controlDiv);
 | |
|             controlUI.title = 'Centra la mappa';
 | |
|             controlUI.href = '#';
 | |
|             controlUI.innerHTML = `
 | |
| 				<span class="icon is-medium">
 | |
| 					<i>
 | |
| 						<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" class="pt-2" viewBox="0 0 16 16">
 | |
| 						<path fill-rule="evenodd" d="M8 3a5 5 0 1 1-4.546 2.914.5.5 0 0 0-.908-.417A6 6 0 1 0 8 2z"/>
 | |
| 						<path d="M8 4.466V.534a.25.25 0 0 0-.41-.192L5.23 2.308a.25.25 0 0 0 0 .384l2.36 1.966A.25.25 0 0 0 8 4.466"/>
 | |
| 						</svg>
 | |
| 					</i>
 | |
| 				</span>
 | |
| 			`;
 | |
|             return controlDiv;
 | |
|         }
 | |
|     });
 | |
| 
 | |
|     let centerCtr = new L.Control.CenterControl();
 | |
|     map.addControl(centerCtr);
 | |
| }
 | |
| /**
 | |
|  * Toggle burger menu for small screens
 | |
|  * @param {string} burgerClass The CSS class of the burger element
 | |
|  */
 | |
| UI.toggleBurger = function(burgerClass) {
 | |
| 	const burger = document.querySelector(`.${burgerClass}`);
 | |
| 	burger.addEventListener('click', () => {
 | |
| 		burger.classList.toggle('is-active');
 | |
| 		const menuId = burger.getAttribute('data-target');
 | |
| 		document.querySelector(`#${menuId}`).classList.toggle('is-active');
 | |
| 	});
 | |
| }
 | |
| /**
 | |
|  * Open a modal with DB site data
 | |
|  * @param {object} data The data retrieved from the DB to display as modal content
 | |
|  * @param {string} selector The modal selector
 | |
|  */
 | |
| UI.openSiteModal = function (data, selector) {
 | |
| 	const modal = document.querySelector(selector);
 | |
| 	let dataTabs = modal.querySelectorAll('.data-tabs');
 | |
| 	
 | |
| 	// Reset data tabs content
 | |
| 	for (let tab of dataTabs) tab.innerHTML = '';
 | |
| 
 | |
| 	let siteSheet = new SiteSheet();
 | |
| 	siteSheet.siteData = data;
 | |
| 
 | |
| 	GisState.bibliography = siteSheet;
 | |
| 
 | |
| 	modal.querySelector('#short-sheet').innerHTML = siteSheet.renderShort();
 | |
| 	if (data.description) {
 | |
| 		modal.querySelector('#site-sheet').innerHTML = siteSheet.render();
 | |
| 	}
 | |
| 
 | |
| 	let images = modal.querySelector('#photos');
 | |
| 	let docs = modal.querySelector('#documents');
 | |
| 
 | |
| 	let siteDocs = new SiteDocuments;
 | |
| 	siteDocs.siteData = data;
 | |
| 	docs.innerHTML = siteDocs.render();
 | |
| 
 | |
| 	let surveys = data.images.filter(i => i.type === 'Survey');
 | |
| 	let photos = data.images.filter(i => i.type === 'Photo');
 | |
| 	let videos = data.images.filter(i => i.type === 'Video');
 | |
| 	let reconstructions = data.images.filter(i => i.type === 'Reconstruction');
 | |
| 
 | |
| 	const noMedia = surveys.length === 0
 | |
| 		&& photos.length === 0
 | |
| 		&& reconstructions.length === 0
 | |
| 		&& videos.length === 0;
 | |
| 
 | |
| 	if (noMedia) {
 | |
| 		images.innerHTML = '<p class="has-text-centered">Nessuna risorsa visuale disponibile</p>';
 | |
| 	}
 | |
| 
 | |
| 	if (images.innerHTML.length === 0) {
 | |
| 		let siteSurveys = new SiteSurveys;
 | |
| 		siteSurveys.siteData = surveys[0] ?? undefined;
 | |
| 		images.innerHTML += surveys[0] ? siteSurveys.render() : '';
 | |
| 
 | |
| 		let siteMedia = new SiteMedia;
 | |
| 		siteMedia.siteData = photos[0] ?? undefined;
 | |
| 		images.innerHTML += photos[0] ? siteMedia.renderPhotos() : '';
 | |
| 
 | |
| 		siteMedia.siteData = reconstructions[0] ?? undefined;
 | |
| 		images.innerHTML += reconstructions[0] ? siteMedia.renderReconstructions() : '';
 | |
| 
 | |
| 		siteMedia.siteData = videos[0] ?? undefined;
 | |
| 		images.innerHTML += videos[0] ? siteMedia.renderVideos() : '';
 | |
| 	}
 | |
| 
 | |
| 	modal.classList.add('is-active');
 | |
| 
 | |
| 	this.imageGallery('gallery-1', surveys);
 | |
| 	this.imageGallery('gallery-2', photos);
 | |
| 	this.imageGallery('gallery-3d', reconstructions);
 | |
| 	this.imageGallery('gallery-video', videos, true);
 | |
| }
 | |
| /**
 | |
|  * @param {object} data The data retrieved from the DB to display as modal content
 | |
|  * @param {string} selector The modal selector
 | |
|  */
 | |
| UI.openNotConserModal = function (data, selector) {
 | |
| 	const modal = document.querySelector(selector);
 | |
| 	let dataTabs = modal.querySelectorAll('.data-tabs');
 | |
| 	// Reset data tabs content
 | |
| 	for (let tab of dataTabs) tab.innerHTML = '';
 | |
| 
 | |
| 	let notConserved = new NotConserved();
 | |
| 	notConserved.data = data;
 | |
| 	// For Stimulus biblio_controller
 | |
| 	GisState.bibliography = notConserved;
 | |
| 
 | |
| 	notConserved.render().then(html => modal.querySelector('#not-conserved-sheet').innerHTML = html);
 | |
| 	notConserved.renderDocs().then(html => modal.querySelector('#documents').innerHTML = html);
 | |
| 	notConserved.setImages(modal.querySelector('#photos'), this.imageGallery);
 | |
| 	modal.classList.add('is-active');
 | |
| }
 | |
| /**
 | |
|  * @param {object} data The data retrieved from the DB to display as modal content
 | |
|  * @param {string} selector The modal selector
 | |
|  */
 | |
| UI.openFindingModal = function (data, selector) {
 | |
| 	const modal = document.querySelector(selector);
 | |
| 	let dataTabs = modal.querySelectorAll('.data-tabs');
 | |
| 	
 | |
| 	// Reset data tabs content
 | |
| 	for (let tab of dataTabs) tab.innerHTML = '';
 | |
| 
 | |
| 	let finding = new Finding();
 | |
| 	finding.data = data;
 | |
| 
 | |
| 	// For Stimulus biblio_controller
 | |
| 	GisState.bibliography = finding;
 | |
| 
 | |
| 	finding.render().then(html => modal.querySelector('#finding-sheet').innerHTML = html);
 | |
| 	finding.setImages(modal.querySelector('#photos'), this.imageGallery);
 | |
| 
 | |
| 	modal.classList.add('is-active');
 | |
| }
 | |
| /**
 | |
|  * @todo Biblio
 | |
|  * @param {object} data The data retrieved from the DB to display as modal content
 | |
|  * @param {string} selector The modal selector
 | |
|  */
 | |
| UI.openPrehistModal = function (data, selector) {
 | |
| 	const modal = document.querySelector(selector);
 | |
| 	let dataTabs = modal.querySelectorAll('.data-tabs');
 | |
| 	
 | |
| 	// Reset data tabs content
 | |
| 	for (let tab of dataTabs) tab.innerHTML = '';
 | |
| 
 | |
| 	let prehistoric = new Prehistoric();
 | |
| 	prehistoric.data = data;
 | |
| 
 | |
| 	// For Stimulus biblio_controller
 | |
| 	//GisState.bibliography = prehistoric;
 | |
| 	prehistoric.render().then(html => modal.querySelector('#prehist-sheet').innerHTML = html);
 | |
| 	prehistoric.setImages(modal.querySelector('#photos'), this.imageGallery);
 | |
| 	modal.classList.add('is-active');
 | |
| }
 | |
| /**
 | |
|  * @todo Biblio?
 | |
|  * @param {object} data The data retrieved from the DB to display as modal content
 | |
|  * @param {string} selector The modal selector
 | |
|  */
 | |
| UI.openUnderwaterModal = function (data, selector) {
 | |
| 	const modal = document.querySelector(selector);
 | |
| 	
 | |
| 	let underwater = new Underwater();
 | |
| 	underwater.data = data;
 | |
| 
 | |
| 	// For Stimulus biblio_controller
 | |
| 	//GisState.bibliography = underwater;
 | |
| 	underwater.render().then(html => modal.querySelector('#underwater-sheet').innerHTML = html);
 | |
| 	underwater.renderDocs().then(html => modal.querySelector('#documents').innerHTML = html);
 | |
| 	underwater.setImages(modal.querySelector('#photos'), this.imageGallery);
 | |
| 	modal.classList.add('is-active');
 | |
| }
 | |
| /**
 | |
|  * @todo Biblio?
 | |
|  * @param {object} data The data retrieved from the DB to display as modal content
 | |
|  * @param {string} selector The modal selector
 | |
|  */
 | |
| UI.openReuseModal = function (data, selector) {
 | |
| 	const modal = document.querySelector(selector);
 | |
| 	
 | |
| 	let reuse = new Reuse();
 | |
| 	reuse.data = data;
 | |
| 
 | |
|     GisState.bibliography = reuse;
 | |
| 
 | |
| 	// For Stimulus biblio_controller
 | |
| 	//GisState.bibliography = underwater;
 | |
| 	reuse.render().then(html => modal.querySelector('#reuse-sheet').innerHTML = html);
 | |
| 	reuse.setImages(modal.querySelector('#photos'), this.imageGallery);
 | |
| 	modal.classList.add('is-active');
 | |
| }
 | |
| /**
 | |
|  * Open Spotlight gallery
 | |
|  * @param {string} galleryId The id of the trigger element
 | |
|  * @param {Array<Object>} items Array of image objects from DB 
 | |
|  * @param {boolean} video Is this a video gallery?
 | |
|  */
 | |
| UI.imageGallery = function (galleryId, items, video = false) {
 | |
| 	const element = document.querySelector(`#${galleryId}`);
 | |
| 
 | |
| 	if (element) {
 | |
| 		let gallery = [];
 | |
| 		for (let media of items) {
 | |
| 			let author = media.author ? ` (${media.author})` : '';
 | |
| 			let mediaObj = {
 | |
| 				description: media.caption + author
 | |
| 			};
 | |
| 
 | |
| 			if (video) {
 | |
| 				mediaObj.media = 'video';
 | |
| 				mediaObj["src-mp4"] = `video/${media.filename}`;
 | |
| 				mediaObj.poster = `video/${media.filename.replace('mp4', 'png')}`;
 | |
| 				mediaObj.autoplay = true;
 | |
| 			} else {
 | |
| 				mediaObj.src = `img/${media.filename}`;
 | |
| 			}
 | |
| 
 | |
| 			gallery.push(mediaObj);
 | |
| 		}
 | |
| 
 | |
| 		document.querySelector(`#${galleryId}`).addEventListener('click', () => {
 | |
| 			Spotlight.show(gallery);
 | |
| 		});
 | |
| 	}
 | |
| }
 | |
| 
 | |
| export default UI;
 |