diff --git a/crouton.php b/crouton.php index f53efbf9..f9197a2e 100644 --- a/crouton.php +++ b/crouton.php @@ -5,7 +5,7 @@ Description: A tabbed based display for showing meeting information. Author: bmlt-enabled Author URI: https://bmlt.app -Version: 3.19.2 +Version: 3.19.3 */ /* Disallow direct access to the plugin file */ if (basename($_SERVER['PHP_SELF']) == basename(__FILE__)) { @@ -842,6 +842,11 @@ public function adminOptionsPage()
  • serviceBodyDescription
  • serviceBodyContactEmail (must be comfigured in root server)
  • serviceBodyType
  • +
  • parentServiceBodyUrl
  • +
  • parentServiceBodyPhone
  • +
  • parentServiceBodyName
  • +
  • parentServiceBodyDescription
  • +
  • parentServiceBodyType
  • To include a map in the meeting details, use the "crouton_map" helper function, ie, {{{crouton_map}}}. diff --git a/croutonjs/meetingMap/css/meeting_map.css b/croutonjs/meetingMap/css/meeting_map.css index fdfa6b37..a84ab5c9 100644 --- a/croutonjs/meetingMap/css/meeting_map.css +++ b/croutonjs/meetingMap/css/meeting_map.css @@ -264,6 +264,7 @@ div.bmlt_map_container_div button { left: 8%; max-width: 85%; overflow-y: auto; + overflow-x: hidden; } /* The Close Button */ @@ -272,11 +273,32 @@ div.bmlt_map_container_div button { float: right; font-size: 28px; font-weight: bold; - position: absolute; - top: 10px; - right: 5px; line-height: 0; } +.modal-right { + color: #aaa; + font-size: 35px; + font-weight: bold; + position: absolute; + top: 50%; + right: 2px; + line-height: 38px; + opacity: 30%; + border-radius: 10px; + background-color: black; +} +.modal-left { + color: #aaa; + font-size: 35px; + font-weight: bold; + position: absolute; + top: 50%; + left: 2px; + line-height: 38px; + opacity: 30%; + border-radius: 10px; + background-color: black; +} .table-close { color: white; float: right; diff --git a/croutonjs/meetingMap/js/meeting_map.js b/croutonjs/meetingMap/js/meeting_map.js index 46c95372..f384bbdb 100644 --- a/croutonjs/meetingMap/js/meeting_map.js +++ b/croutonjs/meetingMap/js/meeting_map.js @@ -218,13 +218,14 @@ function MeetingMap(inConfig) { retrieveGeolocation().then(position => { showThrobber(); crouton.searchByCoordinates(position.latitude, position.longitude, config.map_search.width); + if (activeModal == gSearchModal) closeModalWindow(gSearchModal); }).catch(error => { console.error(error.message); + if (activeModal != gSearchModal) showBmltSearchDialog(); }); - showBmltSearchDialog(); - closeModalWindow(gSearchModal); }; function clickSearch(e) { + croutonMap.showMap(); gDelegate.clickSearch(e, function(lat,lng) { showThrobber(); crouton.searchByCoordinates(lat, lng, config.map_search.width); @@ -315,6 +316,9 @@ function MeetingMap(inConfig) { }, {}); } var g_suspendedFullscreen = false; + var g_overflowX; + var activeModal = null; + var swipableModal = false; function closeModalWindow(modal) { gDelegate.modalOff(); activeModal = null; @@ -327,24 +331,43 @@ function MeetingMap(inConfig) { toggleFullscreen(); } } + if (swipableModal) { + const body = document.getElementsByTagName("BODY")[0]; + const scrollY = body.style.top; + body.style.overflowX = g_overflowX; + body.style.position = ''; + body.style.top = ''; + body.style.width = ''; + window.scrollTo(0, parseInt(scrollY || '0') * -1); + } } - var activeModal = null; document.addEventListener("keydown", function(event) { if (activeModal && event.key == "Escape") { closeModalWindow(activeModal); } }, true); - function openModalWindow(modal) { + function openModalWindow(modal,swipe=false) { if (isFullscreen()) { g_suspendedFullscreen = true; toggleFullscreen(); } modal.style.display = "block"; + swipableModal = swipe; modal.focus(); activeModal = modal; dd = document.getElementById("map-menu-dropdown"); if (dd) dd.style.display = "none"; gDelegate.modalOn(); + if (swipableModal) { + const body = document.getElementsByTagName("BODY")[0]; + g_overflowX = body.style.overflowX; + const newTop = -window.scrollY+'px'; + const newWidth = window.width+'px'; + body.style.overflowX = 'hidden'; + body.style.position = 'fixed'; + body.style.top = newTop; + body.style.width = newWidth; + } } function showFilterDialog(e) { openModalWindow(document.getElementById('filter_modal')); diff --git a/croutonjs/src/js/crouton-core.js b/croutonjs/src/js/crouton-core.js index c95b0113..ae78194d 100644 --- a/croutonjs/src/js/crouton-core.js +++ b/croutonjs/src/js/crouton-core.js @@ -559,7 +559,7 @@ function Crouton(config) { }); } self.getServiceBodies = function(service_bodies_id) { - var requires_parents = self.config.has_regions; + const requires_parents = true; var url = this.config['root_server'] + '/client_interface/jsonp/?switcher=GetServiceBodies' + (requires_parents ? '&parents=1' : '') + getServiceBodiesQueryString(service_bodies_id); @@ -896,7 +896,7 @@ function Crouton(config) { window.croutonMap = new MeetingMap(self.config); if (self.config['map_search']) self.searchMap(); } - self.meetingSearch(); + else if (!self.config['map_search']) self.meetingSearch(); } Crouton.prototype.setConfig = function(config) { @@ -994,8 +994,10 @@ Crouton.prototype.doHandlebars = function() { .then(function(data) { hbs_Crouton['localization'] = self.localization; self.all_service_bodies = []; - var service_body = data[0][0]; - self.all_service_bodies.push(service_body); + var service_bodies = data[0]; + for (var i = 0; i < service_bodies.length; i++) { + self.all_service_bodies.push(service_bodies[i]); + } var enrichedMeetingData = self.enrichMeetings(self.meetingData); var customStartupTemplate = crouton_Handlebars.compile('{{startup}}'); customStartupTemplate(enrichedMeetingData); @@ -1010,18 +1012,59 @@ Crouton.prototype.doHandlebars = function() { Crouton.prototype.meetingModal = function(meetingId) { let self = this; + const tabs = document.getElementById('bmlt-tabs'); + let el = document.createElement('bmlt-handlebar'); - let tabs = document.getElementById('bmlt-tabs'); tabs.appendChild(el); let span = document.createElement('span'); - let meeting = self.meetingData.find((m) => m.id_bigint == meetingId); el.appendChild(span); span.textContent = self.config.meetingpage_frame_template; + let meeting = self.meetingData.find((m) => m.id_bigint == meetingId); self.handlebars(meeting, tabs.getElementsByTagName('bmlt-handlebar')); + [...tabs.getElementsByClassName('modal-close')].forEach((elem)=>elem.addEventListener('click', (e)=>{croutonMap.closeModalWindow(e.target); document.getElementById('meeting_modal').remove()})); - document.body.appendChild(document.getElementById('meeting_modal')); - croutonMap.openModalWindow(document.getElementById('meeting_modal')); + let mm = document.getElementById('meeting_modal'); + document.body.appendChild(mm); + croutonMap.openModalWindow(mm, true); croutonMap.showMap(true); + let visibleMeetings = jQuery('.bmlt-data-row:visible'); + let index = -1; + const prefix = "meeting-data-row-"; + for (k=0; k= 0 && index < visibleMeetings.length) { + const newMeeting = visibleMeetings[index]; + meetingId = newMeeting.id.substring(prefix.length); + mm.getElementsByClassName('modal-close').item(0).dispatchEvent(new MouseEvent("click")); + self.meetingModal(meetingId); + } + } + swipedetect(mm, doSwipe); + if (index <= 0) { + jQuery(".modal-left").addClass("hide"); + } else { + mm.getElementsByClassName('modal-left').item(0).addEventListener("click", ev=>doSwipe("right")); + } + if (index >= visibleMeetings.length-1) { + jQuery(".modal-right").addClass("hide"); + } else { + mm.getElementsByClassName('modal-right').item(0).addEventListener("click", ev=>doSwipe("left")); + } } Crouton.prototype.searchMap = function() { var self = this; @@ -1798,3 +1841,35 @@ Array.prototype.sortByKey = function (key) { }); return this; }; +function swipedetect(el, callback){ + + var touchsurface = el, + swipedir, + startX, + startY, + distX, + distY, + threshold = 150, //required min distance traveled to be considered swipe + restraint = 100, // maximum distance allowed at the same time in perpendicular direction + handleswipe = callback || function(swipedir){} + + touchsurface.addEventListener('touchstart', function(e){ + var touchobj = e.changedTouches[0] + swipedir = 'none' + startX = touchobj.pageX + startY = touchobj.pageY + }, false) + + + touchsurface.addEventListener('touchend', function(e){ + if (!e.cancelable) return; + var touchobj = e.changedTouches[0] + distX = touchobj.pageX - startX // get horizontal dist traveled by finger while in contact with surface + distY = touchobj.pageY - startY // get vertical dist traveled by finger while in contact with surface + if (Math.abs(distX) >= threshold && Math.abs(distY) <= restraint){ // 2nd condition for horizontal swipe met + swipedir = (distX < 0)? 'left' : 'right' // if dist traveled is negative, it indicates left swipe + handleswipe(swipedir) + e.preventDefault() + } + }, false) +} diff --git a/croutonjs/src/js/crouton-default-templates.js b/croutonjs/src/js/crouton-default-templates.js index 7ea5e90f..8d6ce4c3 100644 --- a/croutonjs/src/js/crouton-default-templates.js +++ b/croutonjs/src/js/crouton-default-templates.js @@ -71,7 +71,7 @@ var croutonDefaultTemplates = { meetingpage_frame_template: `