Compare commits

10 Commits
vue ... master

Author SHA1 Message Date
789838dd07 Fix SNT track color 2025-07-18 00:28:37 +02:00
a5fe6ebf75 Update DNT GPX file 2025-07-18 00:25:07 +02:00
d0dbb85e28 Add manual message upload 2025-05-11 13:19:59 +02:00
6a42494099 Fix SNT track color 2025-04-23 11:12:49 +02:00
1d90b11aef Add function to rebuild GeoJSON 2025-04-23 11:06:43 +02:00
bc75cbc17d Add Build GeoJSON Catch 2025-04-23 11:02:16 +02:00
2e8372d923 Update geo/snt.gpx 2025-04-22 13:40:51 +02:00
383890a9be Add SNT gpx 2025-04-22 13:40:25 +02:00
ae8a27fa64 Fix lightbox addToAlbum external reference 2023-10-19 21:43:02 +02:00
af05650443 Bump lightbox to 2.11.4 2023-10-19 21:33:59 +02:00
7 changed files with 69427 additions and 115 deletions

69304
geo/snt.gpx Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -168,6 +168,31 @@ class Feed extends PhpObject {
return $bNewMsg;
}
public function addManualPosition($sLat, $sLng, $iTimestamp) {
$sTimeZone = date_default_timezone_get();
$oDateTime = new \DateTime('@'.$iTimestamp);
$oDateTime->setTimezone(new \DateTimeZone($sTimeZone));
$asWeather = $this->getWeather(array($sLat, $sLng), $iTimestamp);
$asMsg = [
'ref_msg_id' => $iTimestamp.'/man',
'id_feed' => $this->getFeedId(),
'type' => 'OK',
'latitude' => $sLat,
'longitude' => $sLng,
'iso_time' => $oDateTime->format("Y-m-d\TH:i:sO"), //Incorrect ISO 8601 format, but compliant with Spot data
'site_time' => $oDateTime->format(Db::TIMESTAMP_FORMAT),
'timezone' => $sTimeZone,
'unix_time' => $iTimestamp,
'content' => '',
'battery_state' => '',
'posted_on' => date(Db::TIMESTAMP_FORMAT),
];
$iMessageId = $this->oDb->insertRow(self::MSG_TABLE, array_merge($asMsg, $asWeather));
return $iMessageId;
}
private function updateFeed() {
$bNewMsg = false;
$asData = $this->retrieveFeed();

View File

@@ -630,6 +630,13 @@ class Spot extends Main
return self::getJsonResult($asResult['result'], $asResult['desc'], $asResult['data']);
}
public function addPosition($sLat, $sLng, $iTimestamp) {
$oFeed = new Feed($this->oDb, $this->oProject->getFeedIds()[0]);
$bResult = ($oFeed->addManualPosition($sLat, $sLng, $iTimestamp) > 0);
return self::getJsonResult($bResult, $bResult?'':$this->oDb->getLastError());
}
public function getAdminSettings($sType='') {
$oFeed = new Feed($this->oDb);
$asData = array(
@@ -744,6 +751,10 @@ class Spot extends Main
));
}
public function buildGeoJSON($sCodeName) {
return Converter::convertToGeoJson($sCodeName);
}
public static function decToDms($dValue, $sType) {
if($sType=='lat') $sDirection = ($dValue >= 0)?'N':'S'; //Latitude
else $sDirection = ($dValue >= 0)?'E':'W'; //Longitude

View File

@@ -25,6 +25,9 @@ $oValue = $_REQUEST['value'] ?? '';
$iId = $_REQUEST['id'] ?? 0 ;
$sType = $_REQUEST['type'] ?? '';
$sEmail = $_REQUEST['email'] ?? '';
$sLat = $_REQUEST['latitude'] ?? '';
$sLng = $_REQUEST['longitude'] ?? '';
$iTimestamp = $_REQUEST['timestamp'] ?? 0;
//Initiate class
$oSpot = new Spot(__FILE__, $sTimezone);
@@ -70,6 +73,9 @@ if($sAction!='')
case 'add_comment':
$sResult = $oSpot->addComment($iId, $sContent);
break;
case 'add_position':
$sResult = $oSpot->addPosition($sLat, $sLng, $iTimestamp);
break;
case 'admin_new':
$sResult = $oSpot->createProject();
break;
@@ -88,6 +94,9 @@ if($sAction!='')
case 'sql':
$sResult = $oSpot->getDbBuildScript();
break;
case 'build_geojson':
$sResult = $oSpot->buildGeoJSON($sName);
break;
default:
$sResult = Main::getJsonResult(false, Main::NOT_FOUND);
}

View File

@@ -6,6 +6,9 @@
<div class="bar" style="width: 0%;"></div>
</div>
<div id="comments"></div>
<div id="location">
<button id="add_loc"><i class="fa fa-message push"></i>New Position</button>
</div>
<div id="status"></div>
</div>
<script type="text/javascript">
@@ -35,6 +38,27 @@ oSpot.pageInit = function(asHash) {
$('#progress .bar').css('width', progress+'%');
}
});
$('#add_loc').click(() => {
if(navigator.geolocation) {
addStatus('Determining position...');
navigator.geolocation.getCurrentPosition(
(position) => {
addStatus('Sending position...');
oSpot.get(
'add_position',
function(asData){addStatus('Position sent');},
{'latitude':position.coords.latitude, 'longitude':position.coords.longitude, 'timestamp':Math.round(position.timestamp / 1000)},
function(sMsgId){addStatus(self.lang(sMsgId));},
);
},
(error) => {
addStatus(error.message);
}
);
}
else addStatus('This browser does not support geolocation');
});
}
else addStatus(self.lang('upload_mode_archived', [asProject.name]), true);
};

View File

@@ -22,6 +22,7 @@
4. Copy settings-sample.php to settings.php and populate
5. Go to #admin and create a new project, feed & maps
6. Add a GPX file named <project_codename>.gpx to /geo/
7. Run composer install
## To Do List
* ECMA import/export
* Add mail frequency slider

View File

@@ -1,5 +1,5 @@
/*!
* Lightbox v2.11.3
* Lightbox v2.11.4
* by Lokesh Dhakar
*
* More info:
@@ -46,8 +46,6 @@
fadeDuration: 600,
fitImagesInViewport: true,
imageFadeDuration: 600,
// maxWidth: 800,
// maxHeight: 600,
positionFromTop: 50,
resizeDuration: 700,
showImageNumberLabel: true,
@@ -62,10 +60,8 @@
to prevent xss and other injection attacks.
*/
sanitizeTitle: false
//ADDED-START
, hasVideo: true
, hasVideo: true
, onMediaChange: (oMedia) => {}
//ADDED-END
};
Lightbox.prototype.option = function(options) {
@@ -147,7 +143,6 @@
</div>\
').appendTo($('body'));
// Cache jQuery objects
this.$lightbox = $('#lightbox');
this.$overlay = $('#lightboxOverlay');
@@ -156,7 +151,6 @@
this.$image = this.$lightbox.find('.lb-image');
this.$nav = this.$lightbox.find('.lb-nav');
//ADDED-START
if(self.options.hasVideo) {
this.$video = $('<video class="lb-video" controls autoplay></video>');
this.$image.after(this.$video);
@@ -166,8 +160,7 @@
bottom: parseInt(this.$video.css('border-bottom-width'), 10),
left: parseInt(this.$video.css('border-left-width'), 10)
};
}
//ADDED-END
}
// Store css values for future lookup
this.containerPadding = {
@@ -185,11 +178,8 @@
};
// Attach event handlers to the newly minted DOM elements
//ADDED-START
//this.$overlay.hide().on('click', function() {
this.$overlay.hide().add(this.$lightbox.find('.lb-dataContainer')).on('click', function() {
//ADDED-END
self.end();
this.$overlay.hide().add(this.$lightbox.find('.lb-dataContainer')).on('click', function() {
self.end();
return false;
});
@@ -250,9 +240,13 @@
});
this.$lightbox.find('.lb-loader, .lb-close').on('click', function() {
self.end();
return false;
this.$lightbox.find('.lb-loader, .lb-close').on('click keyup', function(e) {
// If mouse click OR 'enter' or 'space' keypress, close LB
if (
e.type === 'click' || (e.type === 'keyup' && (e.which === 13 || e.which === 32))) {
self.end();
return false;
}
});
};
@@ -265,7 +259,6 @@
this.sizeOverlay();
//ADDED-START
//Manage Zoom Event
this.$nav.mousewheel((e) => {
var asImg = self.album[this.currentImageIndex];
@@ -324,7 +317,6 @@
self.$image.css('--translate-x', fTransX + 'px');
self.$image.css('--translate-y', fTransY + 'px');
}
//ADDED-END
this.album = [];
var imageNumber = 0;
@@ -349,7 +341,7 @@
// If image is part of a set
$links = $($link.prop('tagName') + '[rel="' + $link.attr('rel') + '"]');
for (var j = 0; j < $links.length; j = ++j) {
this.addToAlbum($($links[j]));
this.addToAlbum($($links[j]));
if ($links[j] === $link[0]) {
imageNumber = j;
}
@@ -358,14 +350,7 @@
}
// Position Lightbox
//ADDED-START
//var top = $window.scrollTop() + this.options.positionFromTop;
//var left = $window.scrollLeft();
this.$lightbox/*.css({
top: top + 'px',
left: left + 'px'
})*/.fadeIn(this.options.fadeDuration);
//ADDED-END
this.$lightbox.fadeIn(this.options.fadeDuration);
// Disable scrolling of the page while open
if (this.options.disableScrolling) {
@@ -379,20 +364,18 @@
this.album.push({
alt: $link.attr('data-alt'),
link: $link.attr('href'),
title: $link.attr('data-title') || $link.attr('title')
//ADDED-START
, orientation: $link.attr('data-orientation')
, type: $link.attr('data-type')
, id: $link.attr('data-id')
, $Media: $link.attr('data-type')=='video'?this.$video:this.$image
, width: $link.find('img').attr('width')
, height: $link.find('img').attr('height')
, set: $link.attr('data-lightbox') || $link.attr('rel')
//ADDED-END
title: $link.attr('data-title') || $link.attr('title'),
orientation: $link.attr('data-orientation'),
type: $link.attr('data-type'),
id: $link.attr('data-id'),
$Media: $link.attr('data-type')=='video'?this.$video:this.$image,
width: $link.find('img').attr('width'),
height: $link.find('img').attr('height'),
set: $link.attr('data-lightbox') || $link.attr('rel')
});
}
//ADDED-START
Lightbox.prototype.getMaxSizes = function(iMediaWidth, iMediaHeight, sMediaType) {
var iWindowWidth = $(window).width();
var iWindowHeight = $(window).height();
@@ -473,20 +456,20 @@
// Hide most UI elements in preparation for the animated resizing of the lightbox.
Lightbox.prototype.changeImage = function(imageNumber) {
var self = this;
var filename = this.album[imageNumber].link;
var self = this;
var filename = this.album[imageNumber].link;
// Disable keyboard nav during transitions
this.disableKeyboardNav();
// Disable keyboard nav during transitions
this.disableKeyboardNav();
// Show loading state
this.$overlay.fadeIn(this.options.fadeDuration);
$('.lb-loader').fadeIn('slow');
// Show loading state
this.$overlay.fadeIn(this.options.fadeDuration);
$('.lb-loader').fadeIn('slow');
this.$lightbox.find('.lb-image, .lb-video, .lb-nav, .lb-prev, .lb-next, .lb-number, .lb-caption, .lb-close').hide();
this.$lightbox.find('.lb-image, .lb-video, .lb-nav, .lb-prev, .lb-next, .lb-number, .lb-caption, .lb-close').hide();
this.$image.css({'--scale': '1', '--translate-x': '0', '--translate-y': '0'});
self.$lightbox.find('.lb-dataContainer').css({width:'200px', height:'30px'});
this.$outerContainer.addClass('animating');
this.$outerContainer.addClass('animating');
this.$container.removeClass('moveable moving');
this.options.onMediaChange(self.album[imageNumber]);
@@ -534,31 +517,19 @@
break;
}
this.currentImageIndex = imageNumber;
this.currentImageIndex = imageNumber;
};
//ADDED-END
// Stretch overlay to fit the viewport
Lightbox.prototype.sizeOverlay = function(e) {
//var self = this;
/*
/*
We use a setTimeout 0 to pause JS execution and let the rendering catch-up.
Why do this? If the `disableScrolling` option is set to true, a class is added to the body
tag that disables scrolling and hides the scrollbar. We want to make sure the scrollbar is
hidden before we measure the document width, as the presence of the scrollbar will affect the
number.
*/
//ADDED-START
/*
setTimeout(function() {
self.$overlay
.width($(document).width())
.height($(document).height());
}, 0);
*/
if(e) {
if(e) {
if(typeof oResizeTimer != 'undefined') clearTimeout(oResizeTimer);
oResizeTimer = setTimeout(
() => {
@@ -573,17 +544,16 @@
},
200
);
}
//ADDED-END
}
};
// Animate the size of the lightbox to fit the image we are showing
// This method also shows the the image.
//ADDED-START
//Lightbox.prototype.sizeContainer = function(imageWidth, imageHeight) {
Lightbox.prototype.sizeContainer = function(imageWidth, imageHeight, media) {
media = media || 'image';
//ADDED-END
Lightbox.prototype.sizeContainer = function(imageWidth, imageHeight, media) {
media = media || 'image';
//ADDED-END
var self = this;
var oldWidth = this.$outerContainer.outerWidth();
@@ -597,19 +567,13 @@
//ADDED-END
function postResize() {
//ADDED-START
//self.$lightbox.find('.lb-dataContainer').width(newWidth);
if(self.$lightbox.hasClass('vertical')) self.$lightbox.find('.lb-dataContainer').width(newWidth);
else self.$lightbox.find('.lb-dataContainer').height(newHeight);
//ADDED-END
self.$lightbox.find('.lb-prevLink').height(newHeight);
self.$lightbox.find('.lb-nextLink').height(newHeight);
// Set focus on one of the two root nodes so keyboard events are captured.
//ADDED-START
//self.$overlay.focus();
self.$overlay.trigger( 'focus' );
//ADDED-END
self.$overlay.trigger('focus');
self.showImage();
}
@@ -630,11 +594,8 @@
Lightbox.prototype.showImage = function() {
this.$lightbox.find('.lb-loader').stop(true).hide();
//ADDED-START
//this.$lightbox.find('.lb-image').fadeIn(this.options.imageFadeDuration);
if(this.options.hasVideo && this.album[this.currentImageIndex].type == 'video') this.$lightbox.find('.lb-video').fadeIn(this.options.imageFadeDuration);
else this.$lightbox.find('.lb-image').fadeIn(this.options.imageFadeDuration);
//ADDED-END
this.updateNav();
this.updateDetails();
@@ -691,29 +652,10 @@
$caption.text(this.album[this.currentImageIndex].title);
} else {
$caption.html(this.album[this.currentImageIndex].title);
}
//ADDED-START
//$caption.fadeIn('fast');
}
$caption.add(this.$lightbox.find('.lb-close')).fadeIn('fast');
//ADDED-END
}
//ADDED-START
/*
//ADDED-END
if (this.album.length > 1 && this.options.showImageNumberLabel) {
var labelText = this.imageCountLabel(this.currentImageIndex + 1, this.album.length);
//ADDED-START
//this.$lightbox.find('.lb-number').text(labelText).fadeIn('fast');
this.$lightbox.find('.lb-number').empty().append(labelText).fadeIn('fast');
//ADDED-END
} else {
this.$lightbox.find('.lb-number').hide();
}
//ADDED-START
*/
//ADDED-END
this.$outerContainer.removeClass('animating');
this.$lightbox.find('.lb-dataContainer').fadeIn(this.options.resizeDuration, function() {
@@ -734,9 +676,7 @@
};
Lightbox.prototype.enableKeyboardNav = function() {
//ADDED-START
this.disableKeyboardNav();
//ADDED-END
this.disableKeyboardNav();
this.$lightbox.on('keyup.keyboard', $.proxy(this.keyboardAction, this));
this.$overlay.on('keyup.keyboard', $.proxy(this.keyboardAction, this));
};
@@ -775,19 +715,17 @@
Lightbox.prototype.end = function() {
this.disableKeyboardNav();
//ADDED-START
if(this.options.hasVideo) {
var $lbContainer = this.$lightbox.find('.lb-container');
var $hasVideoNav = $lbContainer.hasClass('lb-video-nav');
this.$video.attr('src', '');
if(this.options.hasVideo) {
var $lbContainer = this.$lightbox.find('.lb-container');
var $hasVideoNav = $lbContainer.hasClass('lb-video-nav');
this.$video.attr('src', '');
if($hasVideoNav) $lbContainer.removeClass('lb-video-nav');
}
oSpot.flushHash();
//ADDED-END
if($hasVideoNav) $lbContainer.removeClass('lb-video-nav');
}
oSpot.flushHash();
$(window).off('resize', this.sizeOverlay);
this.$nav.off('mousewheel');
this.$nav.off('mousewheel');
this.$lightbox.fadeOut(this.options.fadeDuration);
this.$overlay.fadeOut(this.options.fadeDuration);