Compare commits

...

15 Commits

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
b3cd217e28 Add altitude on image 2023-10-15 18:33:36 +02:00
5f597647b4 Support geo located images & videos 2023-08-12 23:35:40 +02:00
199e3a1269 Bump leaflet to 1.9.4 2023-08-09 23:10:04 +02:00
04f5ce8a9c Change log folder 2023-08-06 13:54:59 +02:00
402d8f271e Add KMS hitchhike 2023-08-05 22:10:32 +02:00
24 changed files with 84218 additions and 14452 deletions

7
.gitignore vendored
View File

@@ -1,11 +1,5 @@
/build.xml
/settings.php /settings.php
/.externalToolBuilders/
/.sass-cache/
/.buildpath
/.project
/style/.sass-cache/ /style/.sass-cache/
/.settings/
/files/**/*.jpg /files/**/*.jpg
/files/**/*.JPG /files/**/*.JPG
/files/**/*.jpeg /files/**/*.jpeg
@@ -17,3 +11,4 @@
/geo/*.geojson /geo/*.geojson
/spot_cron.sh /spot_cron.sh
/vendor/* /vendor/*
/log.html

30
composer.lock generated
View File

@@ -12,7 +12,7 @@
"dist": { "dist": {
"type": "path", "type": "path",
"url": "../objects", "url": "../objects",
"reference": "25c0f66cff31e30c730a6891e5e15b1cc209af67" "reference": "e1cf78b992a6f52742d6834f7508c0ef373ac860"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@@ -27,16 +27,16 @@
}, },
{ {
"name": "phpmailer/phpmailer", "name": "phpmailer/phpmailer",
"version": "v6.6.4", "version": "v6.8.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git", "url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b" "reference": "df16b615e371d81fb79e506277faea67a1be18f1"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a94fdebaea6bd17f51be0c2373ab80d3d681269b", "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/df16b615e371d81fb79e506277faea67a1be18f1",
"reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b", "reference": "df16b615e371d81fb79e506277faea67a1be18f1",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -46,22 +46,24 @@
"php": ">=5.5.0" "php": ">=5.5.0"
}, },
"require-dev": { "require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "dealerdirect/phpcodesniffer-composer-installer": "^0.7.2",
"doctrine/annotations": "^1.2", "doctrine/annotations": "^1.2.6 || ^1.13.3",
"php-parallel-lint/php-console-highlighter": "^1.0.0", "php-parallel-lint/php-console-highlighter": "^1.0.0",
"php-parallel-lint/php-parallel-lint": "^1.3.2", "php-parallel-lint/php-parallel-lint": "^1.3.2",
"phpcompatibility/php-compatibility": "^9.3.5", "phpcompatibility/php-compatibility": "^9.3.5",
"roave/security-advisories": "dev-latest", "roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.6.2", "squizlabs/php_codesniffer": "^3.7.1",
"yoast/phpunit-polyfills": "^1.0.0" "yoast/phpunit-polyfills": "^1.0.4"
}, },
"suggest": { "suggest": {
"ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
"ext-openssl": "Needed for secure SMTP sending and DKIM signing",
"greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication",
"hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
"league/oauth2-google": "Needed for Google XOAUTH2 authentication", "league/oauth2-google": "Needed for Google XOAUTH2 authentication",
"psr/log": "For optional PSR-3 debug logging", "psr/log": "For optional PSR-3 debug logging",
"stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)",
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" "thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@@ -93,7 +95,7 @@
"description": "PHPMailer is a full-featured email creation and transfer class for PHP", "description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": { "support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues", "issues": "https://github.com/PHPMailer/PHPMailer/issues",
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.4" "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.8.0"
}, },
"funding": [ "funding": [
{ {
@@ -101,7 +103,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2022-08-22T09:22:00+00:00" "time": "2023-03-06T14:43:22+00:00"
} }
], ],
"packages-dev": [], "packages-dev": [],
@@ -114,5 +116,5 @@
"prefer-lowest": false, "prefer-lowest": false,
"platform": [], "platform": [],
"platform-dev": [], "platform-dev": [],
"plugin-api-version": "2.2.0" "plugin-api-version": "2.3.0"
} }

View File

@@ -0,0 +1,3 @@
ALTER TABLE medias ADD latitude DECIMAL(7,5) AFTER timezone;
ALTER TABLE medias ADD longitude DECIMAL(8,5) AFTER latitude;
ALTER TABLE medias ADD altitude SMALLINT AFTER longitude;

28811
geo/pct.gpx

File diff suppressed because it is too large Load Diff

69304
geo/snt.gpx Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -19,7 +19,7 @@ use \Settings;
class Converter extends PhpObject { class Converter extends PhpObject {
public function __construct() { public function __construct() {
parent::__construct(__CLASS__, Settings::DEBUG); parent::__construct(__CLASS__);
} }
public static function convertToGeoJson($sCodeName) { public static function convertToGeoJson($sCodeName) {
@@ -36,8 +36,11 @@ class Converter extends PhpObject {
public static function isGeoJsonValid($sCodeName) { public static function isGeoJsonValid($sCodeName) {
$bResult = false; $bResult = false;
$sGpxFilePath = Geo::getFilePath($sCodeName, Gpx::EXT);
$sGeoJsonFilePath = Geo::getFilePath($sCodeName, GeoJson::EXT); $sGeoJsonFilePath = Geo::getFilePath($sCodeName, GeoJson::EXT);
if(file_exists($sGeoJsonFilePath) && filemtime($sGeoJsonFilePath) > filemtime(Geo::getFilePath($sCodeName, Gpx::EXT))) $bResult = true;
//No need to generate if gpx is missing
if(!file_exists($sGpxFilePath) || file_exists($sGeoJsonFilePath) && filemtime($sGeoJsonFilePath) > filemtime(Geo::getFilePath($sCodeName, Gpx::EXT))) $bResult = true;
return $bResult; return $bResult;
} }
} }
@@ -80,6 +83,8 @@ class Gpx extends Geo {
private function parseFile() { private function parseFile() {
$this->addNotice('Parsing: '.$this->sFilePath); $this->addNotice('Parsing: '.$this->sFilePath);
if(!file_exists($this->sFilePath)) $this->addError($this->sFilePath.' file missing');
else {
$oXml = simplexml_load_file($this->sFilePath); $oXml = simplexml_load_file($this->sFilePath);
//Tracks //Tracks
@@ -109,6 +114,7 @@ class Gpx extends Geo {
$this->addNotice('Ignoring '.count($oXml->wpt).' waypoints'); $this->addNotice('Ignoring '.count($oXml->wpt).' waypoints');
} }
} }
}
class GeoJson extends Geo { class GeoJson extends Geo {

View File

@@ -22,6 +22,7 @@ class Email extends PhpObject {
private $asDests; private $asDests;
public function __construct($sServName, $sTemplateName='') { public function __construct($sServName, $sTemplateName='') {
parent::__construct(__CLASS__);
$this->sServName = $sServName; $this->sServName = $sServName;
$this->setTemplate($sTemplateName); $this->setTemplate($sTemplateName);
$this->asDests = array(); $this->asDests = array();

View File

@@ -54,7 +54,7 @@ class Feed extends PhpObject {
private $iLastUpdate; private $iLastUpdate;
public function __construct(Db &$oDb, $iFeedId=0) { public function __construct(Db &$oDb, $iFeedId=0) {
parent::__construct(__CLASS__, Settings::DEBUG); parent::__construct(__CLASS__);
$this->oDb = &$oDb; $this->oDb = &$oDb;
if($iFeedId > 0) $this->setFeedId($iFeedId); if($iFeedId > 0) $this->setFeedId($iFeedId);
} }
@@ -168,6 +168,31 @@ class Feed extends PhpObject {
return $bNewMsg; 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() { private function updateFeed() {
$bNewMsg = false; $bNewMsg = false;
$asData = $this->retrieveFeed(); $asData = $this->retrieveFeed();

View File

@@ -15,7 +15,7 @@ class Map extends PhpObject {
private $asMaps; private $asMaps;
public function __construct(Db &$oDb) { public function __construct(Db &$oDb) {
parent::__construct(__CLASS__, Settings::DEBUG); parent::__construct(__CLASS__);
$this->oDb = &$oDb; $this->oDb = &$oDb;
$this->setMaps(); $this->setMaps();
} }

View File

@@ -35,7 +35,7 @@ class Media extends PhpObject {
private $iMediaId; private $iMediaId;
public function __construct(Db &$oDb, &$oProject, $iMediaId=0) { public function __construct(Db &$oDb, &$oProject, $iMediaId=0) {
parent::__construct(__CLASS__, Settings::DEBUG); parent::__construct(__CLASS__);
$this->oDb = &$oDb; $this->oDb = &$oDb;
$this->oProject = &$oProject; $this->oProject = &$oProject;
$this->asMedia = array(); $this->asMedia = array();
@@ -76,7 +76,7 @@ class Media extends PhpObject {
if($bOwnMedia && empty($this->asMedia) || !$bOwnMedia && empty($this->asMedias) || $bConstraintArray) { if($bOwnMedia && empty($this->asMedia) || !$bOwnMedia && empty($this->asMedias) || $bConstraintArray) {
if($this->oProject->getProjectId()) { if($this->oProject->getProjectId()) {
$asParams = array( $asParams = array(
'select' => array(Db::getId(self::MEDIA_TABLE), 'filename', 'taken_on', 'posted_on', 'timezone', 'width', 'height', 'rotate', 'type AS subtype', 'comment'), 'select' => array(Db::getId(self::MEDIA_TABLE), 'filename', 'taken_on', 'posted_on', 'timezone', 'latitude', 'longitude', 'altitude', 'width', 'height', 'rotate', 'type AS subtype', 'comment'),
'from' => self::MEDIA_TABLE, 'from' => self::MEDIA_TABLE,
'constraint'=> array(Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId()) 'constraint'=> array(Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId())
); );
@@ -128,6 +128,9 @@ class Media extends PhpObject {
'taken_on' => date(Db::TIMESTAMP_FORMAT, ($asMediaInfo['taken_ts'] > 0)?$asMediaInfo['taken_ts']:$asMediaInfo['file_ts']), 'taken_on' => date(Db::TIMESTAMP_FORMAT, ($asMediaInfo['taken_ts'] > 0)?$asMediaInfo['taken_ts']:$asMediaInfo['file_ts']),
'posted_on' => date(Db::TIMESTAMP_FORMAT, $asMediaInfo['file_ts']), 'posted_on' => date(Db::TIMESTAMP_FORMAT, $asMediaInfo['file_ts']),
'timezone' => $asMediaInfo['timezone'], 'timezone' => $asMediaInfo['timezone'],
'latitude' => is_null($asMediaInfo['latitude'])?'NULL':$asMediaInfo['latitude'],
'longitude' => is_null($asMediaInfo['longitude'])?'NULL':$asMediaInfo['longitude'],
'altitude' => is_null($asMediaInfo['altitude'])?'NULL':$asMediaInfo['altitude'],
'width' => $asMediaInfo['width'], 'width' => $asMediaInfo['width'],
'height' => $asMediaInfo['height'], 'height' => $asMediaInfo['height'],
'rotate' => $asMediaInfo['rotate'], 'rotate' => $asMediaInfo['rotate'],
@@ -151,21 +154,23 @@ class Media extends PhpObject {
{ {
$sMediaPath = self::getMediaPath($sMediaName); $sMediaPath = self::getMediaPath($sMediaName);
$sType = self::getMediaType($sMediaName); $sType = self::getMediaType($sMediaName);
$iPostedOn = filemtime($sMediaPath); $iPostedOn = filemtime($sMediaPath);
$sTimeZone = date_default_timezone_get(); $sTimeZone = date_default_timezone_get();
$iWidth = 0; $iWidth = 0;
$iHeight = 0; $iHeight = 0;
$sRotate = '0'; $sRotate = '0';
$sTakenOn = ''; $sTakenOn = '';
$fLat = null;
$fLng = null;
$iAlt = null;
switch($sType) { switch($sType) {
case 'video': case 'video':
$asResult = array(); $asResult = array();
$sParams = implode(' ', array( $sParams = implode(' ', array(
'-loglevel error', //Remove comments '-loglevel error', //Remove comments
'-select_streams v:0', //First video channel '-select_streams v:0', //First video channel
'-show_entries '. //filter tags : Width, Height, Creation Time & Rotation '-show_entries '. //filter tags : Width, Height, Creation Time, Location & Rotation
'format_tags=creation_time,com.apple.quicktime.creationdate:'. 'format_tags=creation_time,com.apple.quicktime.creationdate,com.apple.quicktime.location.ISO6709:'.
'stream_tags=rotate,creation_time:'. 'stream_tags=rotate,creation_time:'.
'stream=width,height', 'stream=width,height',
'-print_format json', //output format: json '-print_format json', //output format: json
@@ -181,6 +186,11 @@ class Media extends PhpObject {
} }
else $sTakenOn = $asExif['format']['tags']['creation_time'] ?? $asExif['streams'][0]['tags']['creation_time']; else $sTakenOn = $asExif['format']['tags']['creation_time'] ?? $asExif['streams'][0]['tags']['creation_time'];
//Location
if(isset($asExif['format']['tags']['com.apple.quicktime.location.ISO6709'])) {
list($fLat, $fLng, $iAlt) = self::getLatLngAltFromISO6709($asExif['format']['tags']['com.apple.quicktime.location.ISO6709']);
}
//Width & Height //Width & Height
$iWidth = $asExif['streams'][0]['width']; $iWidth = $asExif['streams'][0]['width'];
$iHeight = $asExif['streams'][0]['height']; $iHeight = $asExif['streams'][0]['height'];
@@ -209,6 +219,14 @@ class Media extends PhpObject {
$sTimeZone = $asExif['EXIF']['OffsetTimeOriginal'] ?? $asExif['EXIF']['UndefinedTag:0x9011'] ?? Spot::getTimeZoneFromDate($sTakenOn) ?? $sTimeZone; $sTimeZone = $asExif['EXIF']['OffsetTimeOriginal'] ?? $asExif['EXIF']['UndefinedTag:0x9011'] ?? Spot::getTimeZoneFromDate($sTakenOn) ?? $sTimeZone;
} }
//Location
if(array_key_exists('GPS', $asExif)) {
$asGps = $asExif['GPS'];
$fLat = self::getLatLngFromExif($asGps['GPSLatitudeRef'] ?? $asGps['UndefinedTag:0x0001'], $asGps['GPSLatitude'] ?? $asGps['UndefinedTag:0x0002']);
$fLng = self::getLatLngFromExif($asGps['GPSLongitudeRef'] ?? $asGps['UndefinedTag:0x0003'], $asGps['GPSLongitude'] ?? $$asGps['UndefinedTag:0x0004']);
$iAlt = (($asGps['GPSAltitudeRef'] ?? $asGps['UndefinedTag:0x0005'] ?? '0') == '1'?-1:1) * ($asGps['GPSAltitude'] ?? $asGps['UndefinedTag:0x0006'] ?? 0);
}
//Orientation //Orientation
if(array_key_exists('IFD0', $asExif) && array_key_exists('Orientation', $asExif['IFD0'])) { if(array_key_exists('IFD0', $asExif) && array_key_exists('Orientation', $asExif['IFD0'])) {
switch($asExif['IFD0']['Orientation']) switch($asExif['IFD0']['Orientation'])
@@ -232,6 +250,9 @@ class Media extends PhpObject {
return array( return array(
'timezone' => $sTimeZone, 'timezone' => $sTimeZone,
'latitude' => $fLat,
'longitude' => $fLng,
'altitude' => $iAlt,
'taken_ts' => $iTakenOn, 'taken_ts' => $iTakenOn,
'file_ts' => $iPostedOn, 'file_ts' => $iPostedOn,
'width' => $iWidth, 'width' => $iWidth,
@@ -290,4 +311,29 @@ class Media extends PhpObject {
return $sType; return $sType;
} }
private static function getLatLngFromExif($sDirection, $asCoords) {
$fCoord = 0;
foreach($asCoords as $iIndex=>$sCoord) {
$fValue = 0;
$asCoordParts = explode('/', $sCoord);
switch(count($asCoordParts)) {
case 1:
$fValue = $asCoordParts[0];
break;
case 2:
$fValue = floatval($asCoordParts[0]) / floatval($asCoordParts[1]);
break;
}
$fCoord += $fValue / pow(60, $iIndex);
}
return $fCoord * (($sDirection == 'W' || $sDirection == 'S')?-1:1);
}
private static function getLatLngAltFromISO6709($sIso6709) {
preg_match('/^(?P<lat>[\+\-][0,1]?\d{2}\.\d+)(?P<lng>[\+\-][0,1]?\d{2}\.\d+)(?P<alt>[\+\-]\d+)?/', $sIso6709, $asMatches);
return array(floatval($asMatches['lat']), floatval($asMatches['lng']), floatval($asMatches['alt'] ?? 0));
}
} }

View File

@@ -22,14 +22,16 @@ class Project extends PhpObject {
*/ */
private $oDb; private $oDb;
private $iProjectId; private $iProjectId;
private $sMode;
private $sName; private $sName;
private $sCodeName; private $sCodeName;
private $sMode;
private $asActive; private $asActive;
private $asGeo;
public function __construct(Db &$oDb, $iProjectId=0) { public function __construct(Db &$oDb, $iProjectId=0) {
parent::__construct(__CLASS__, Settings::DEBUG); parent::__construct(__CLASS__);
$this->oDb = &$oDb; $this->oDb = &$oDb;
if($iProjectId > 0) $this->setProjectId($iProjectId); if($iProjectId > 0) $this->setProjectId($iProjectId);
} }
@@ -179,10 +181,10 @@ class Project extends PhpObject {
if($this->getProjectId() > 0) { if($this->getProjectId() > 0) {
$asProject = $this->getProject(); $asProject = $this->getProject();
$this->sName = $asProject['name'];
$this->sCodeName = $asProject['codename'];
$this->sMode = $asProject['mode']; $this->sMode = $asProject['mode'];
$this->asActive = array('from'=>$asProject['active_from'], 'to'=>$asProject['active_to']); $this->asActive = array('from'=>$asProject['active_from'], 'to'=>$asProject['active_to']);
$this->sCodeName = $asProject['codename'];
$this->sName = $asProject['name'];
$this->asGeo = array('geofile'=>$asProject['geofilepath'], 'gpxfile'=>$asProject['gpxfilepath']); $this->asGeo = array('geofile'=>$asProject['geofilepath'], 'gpxfile'=>$asProject['gpxfilepath']);
} }
else $this->addError('Error while setting project: no project ID'); else $this->addError('Error while setting project: no project ID');

View File

@@ -47,7 +47,7 @@ class Spot extends Main
public function __construct($sProcessPage, $sTimezone) public function __construct($sProcessPage, $sTimezone)
{ {
parent::__construct($sProcessPage, true, __FILE__, $sTimezone); parent::__construct($sProcessPage, true, $sTimezone);
$this->oUser = new User($this->oDb); $this->oUser = new User($this->oDb);
@@ -87,7 +87,7 @@ class Spot extends Main
Feed::SPOT_TABLE => array('ref_spot_id', 'name', 'model'), Feed::SPOT_TABLE => array('ref_spot_id', 'name', 'model'),
Project::PROJ_TABLE => array('name', 'codename', 'active_from', 'active_to'), Project::PROJ_TABLE => array('name', 'codename', 'active_from', 'active_to'),
self::POST_TABLE => array(Db::getId(Project::PROJ_TABLE), Db::getId(User::USER_TABLE), 'name', 'content', 'site_time', 'timezone'), self::POST_TABLE => array(Db::getId(Project::PROJ_TABLE), Db::getId(User::USER_TABLE), 'name', 'content', 'site_time', 'timezone'),
Media::MEDIA_TABLE => array(Db::getId(Project::PROJ_TABLE), 'filename', 'type', 'taken_on', 'posted_on', 'timezone', 'width', 'height', 'rotate', 'comment'), Media::MEDIA_TABLE => array(Db::getId(Project::PROJ_TABLE), 'filename', 'type', 'taken_on', 'posted_on', 'timezone', 'latitude', 'longitude', 'altitude', 'width', 'height', 'rotate', 'comment'),
User::USER_TABLE => array('name', 'email', 'gravatar', 'language', 'timezone', 'active', 'clearance'), User::USER_TABLE => array('name', 'email', 'gravatar', 'language', 'timezone', 'active', 'clearance'),
Map::MAP_TABLE => array('codename', 'pattern', 'token', 'tile_size', 'min_zoom', 'max_zoom', 'attribution'), Map::MAP_TABLE => array('codename', 'pattern', 'token', 'tile_size', 'min_zoom', 'max_zoom', 'attribution'),
Map::MAPPING_TABLE => array(Db::getId(Map::MAP_TABLE) , Db::getId(Project::PROJ_TABLE)) Map::MAPPING_TABLE => array(Db::getId(Map::MAP_TABLE) , Db::getId(Project::PROJ_TABLE))
@@ -110,6 +110,7 @@ class Spot extends Main
'last_update' => "TIMESTAMP DEFAULT 0", 'last_update' => "TIMESTAMP DEFAULT 0",
'latitude' => "DECIMAL(7,5)", 'latitude' => "DECIMAL(7,5)",
'longitude' => "DECIMAL(8,5)", 'longitude' => "DECIMAL(8,5)",
'altitude' => "SMALLINT",
'model' => "VARCHAR(20)", 'model' => "VARCHAR(20)",
'name' => "VARCHAR(100)", 'name' => "VARCHAR(100)",
'pattern' => "VARCHAR(200) NOT NULL", 'pattern' => "VARCHAR(200) NOT NULL",
@@ -248,8 +249,7 @@ class Spot extends Main
} }
$bSuccess = $oEmail->send(); $bSuccess = $oEmail->send();
if(!$bSuccess) $sDesc = $oEmail->ErrorInfo; $sDesc = $bSuccess?'mail_sent':'mail_failure';
else $sDesc = 'mail_sent';
} }
else $sDesc = 'no_new_msg'; else $sDesc = 'no_new_msg';
@@ -270,10 +270,11 @@ class Spot extends Main
public function getMarkers($asMessageIds=array(), $asMediaIds=array(), $bInternal=false) public function getMarkers($asMessageIds=array(), $asMediaIds=array(), $bInternal=false)
{ {
$asMessages = $this->getSpotMessages($asMessageIds); $asMessages = $this->getSpotMessages($asMessageIds);
$asGeoMedias = array();
usort($asMessages, function($a, $b){return $a['unix_time'] > $b['unix_time'];}); usort($asMessages, function($a, $b){return $a['unix_time'] > $b['unix_time'];});
$bHasMsg = !empty($asMessages);
//Add medias //Add medias
if(!empty($asMessages)) {
$asMedias = $this->getMedias('taken_on', $asMediaIds); $asMedias = $this->getMedias('taken_on', $asMediaIds);
usort($asMedias, function($a, $b){return $a['unix_time'] > $b['unix_time'];}); usort($asMedias, function($a, $b){return $a['unix_time'] > $b['unix_time'];});
@@ -281,9 +282,9 @@ class Spot extends Main
$iIndex = 0; $iIndex = 0;
$iMaxIndex = count($asMessages) - 1; $iMaxIndex = count($asMessages) - 1;
foreach($asMedias as $asMedia) { foreach($asMedias as $asMedia) {
while($iIndex <= $iMaxIndex && $asMedia['unix_time'] > $asMessages[$iIndex]['unix_time']) { if($asMedia['latitude']!='' && $asMedia['longitude']!='') $asGeoMedias[] = $asMedia;
$iIndex++; elseif($bHasMsg) {
} while($iIndex <= $iMaxIndex && $asMedia['unix_time'] > $asMessages[$iIndex]['unix_time']) $iIndex++;
//All medias before first message or after last message are assigned to first/last message respectively //All medias before first message or after last message are assigned to first/last message respectively
if($iIndex == 0) $iMsgIndex = $iIndex; if($iIndex == 0) $iMsgIndex = $iIndex;
@@ -303,6 +304,7 @@ class Spot extends Main
$asResult = array( $asResult = array(
'messages' => $asMessages, 'messages' => $asMessages,
'medias' => $asGeoMedias,
'maps' => $this->oMap->getProjectMaps($this->oProject->getProjectId()), 'maps' => $this->oMap->getProjectMaps($this->oProject->getProjectId()),
'last_update' => $asLastUpdate 'last_update' => $asLastUpdate
); );
@@ -628,6 +630,13 @@ class Spot extends Main
return self::getJsonResult($asResult['result'], $asResult['desc'], $asResult['data']); 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='') { public function getAdminSettings($sType='') {
$oFeed = new Feed($this->oDb); $oFeed = new Feed($this->oDb);
$asData = array( $asData = array(
@@ -742,6 +751,10 @@ class Spot extends Main
)); ));
} }
public function buildGeoJSON($sCodeName) {
return Converter::convertToGeoJson($sCodeName);
}
public static function decToDms($dValue, $sType) { public static function decToDms($dValue, $sType) {
if($sType=='lat') $sDirection = ($dValue >= 0)?'N':'S'; //Latitude if($sType=='lat') $sDirection = ($dValue >= 0)?'N':'S'; //Latitude
else $sDirection = ($dValue >= 0)?'E':'W'; //Longitude else $sDirection = ($dValue >= 0)?'E':'W'; //Longitude

View File

@@ -31,7 +31,7 @@ class User extends PhpObject {
private $asUserInfo; private $asUserInfo;
public function __construct(Db &$oDb) { public function __construct(Db &$oDb) {
parent::__construct(__CLASS__, Settings::DEBUG); parent::__construct(__CLASS__);
$this->oDb = &$oDb; $this->oDb = &$oDb;
$this->iUserId = 0; $this->iUserId = 0;
$this->asUserInfo = array( $this->asUserInfo = array(

View File

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

View File

@@ -282,7 +282,7 @@ function initProject(sProjectCodeName, oFocusPost){
).done(function(aoMessages, aoTracks) { ).done(function(aoMessages, aoTracks) {
var asData = aoMessages[0]['data']; var asData = aoMessages[0]['data'];
setMapLayers(asData['maps']); setMapLayers(asData['maps']);
initSpotMessages(asData['messages'], aoTracks[0]); initSpotMessages(asData['messages'], aoTracks[0], asData['medias']);
updateSettingsPanel(asData['last_update']); updateSettingsPanel(asData['last_update']);
}); });
@@ -420,7 +420,7 @@ function setMapLayers(asLayers) {
}); });
} }
function initSpotMessages(aoMessages, aoTracks) { function initSpotMessages(aoMessages, aoTracks, aoMedias) {
var bIsMobile = isMobile(); var bIsMobile = isMobile();
//Map //Map
@@ -656,7 +656,10 @@ function initSpotMessages(aoMessages, aoTracks) {
} }
//Add Spot messages //Add Spot messages
addSpotMessages(aoMessages); addSpotMarkers(aoMessages);
//Add Medias
addMediaMarkers(aoMedias)
//Open tooltip on latest message in mobile mode //Open tooltip on latest message in mobile mode
if( if(
@@ -672,7 +675,7 @@ function initSpotMessages(aoMessages, aoTracks) {
*/ */
} }
function addSpotMessages(aoMessages) { function addSpotMarkers(aoMessages) {
//Spot Messages //Spot Messages
var iWorkSpaceMinWidth = isMobile()?self.tmp('$Projects').width():(self.tmp('$Projects').width() - self.tmp('$Feed').outerWidth(true) - self.tmp('$Settings').outerWidth(true)); var iWorkSpaceMinWidth = isMobile()?self.tmp('$Projects').width():(self.tmp('$Projects').width() - self.tmp('$Feed').outerWidth(true) - self.tmp('$Settings').outerWidth(true));
@@ -689,7 +692,7 @@ function addSpotMessages(aoMessages) {
$Tooltip = $('<div>', {'class':'info-window'}) $Tooltip = $('<div>', {'class':'info-window'})
.append($('<h1>') .append($('<h1>')
.addIcon('fa-message fa-lg', true) .addIcon('fa-message fa-lg', true)
.append($('<span>').text('Message '+oSpot.lang('counter', oMsg.displayed_id))) .append($('<span>').text(oSpot.lang('post_message')+' '+oSpot.lang('counter', oMsg.displayed_id)))
.append($('<span>', {'class':'message-type'}).text('('+oMsg.type+')')) .append($('<span>', {'class':'message-type'}).text('('+oMsg.type+')'))
) )
.append($('<div>', {'class':'separator'})) .append($('<div>', {'class':'separator'}))
@@ -746,6 +749,74 @@ function addSpotMessages(aoMessages) {
}); });
} }
function addMediaMarkers(aoMedias) {
var iWorkSpaceMinWidth = isMobile()?self.tmp('$Projects').width():(self.tmp('$Projects').width() - self.tmp('$Feed').outerWidth(true) - self.tmp('$Settings').outerWidth(true));
$.each(aoMedias, function(iKey, oMedia){
var oMarker = L.marker(L.latLng(oMedia.latitude, oMedia.longitude), {
id: oMedia.id_media,
riseOnHover: true,
icon: getDivIcon(oMedia.subtype)
}).addTo(self.tmp('map'));
//Tooltip
$Tooltip = $('<div>', {'class':'info-window'})
.append($('<h1>')
.addIcon('fa-'+oMedia.subtype+' fa-lg', true)
.append($('<span>').text(oSpot.lang(oMedia.subtype)+' '+oSpot.lang('counter', oMedia.displayed_id || oMedia.id_media)))
)
.append($('<div>', {'class':'separator'}))
.append($('<p>', {'class':'time'})
.addIcon('fa-time fa-fw fa-lg', true)
.append(oMedia.formatted_time+(self.vars(['project', 'mode'])==self.consts.modes.blog?' ('+oMedia.relative_time+')':'')));
//Tooltip: Time Zone
if(oMedia.formatted_time_local != oMedia.formatted_time) {
$Tooltip.append($('<p>', {'class':'timezone'})
.addIcon('fa-timezone fa-fw fa-lg', true)
.append(oSpot.lang('local_time', getRelativeTime(oMedia.formatted_time_local, oMedia.day_offset))));
}
//Tooltip: Altitude
if(oMedia.altitude) {
$Tooltip.append($('<p>', {'class':'altitude'})
.addIcon('fa-altitude fa-fw fa-lg', true)
.append(oMedia.altitude+'m'));
}
$Tooltip.data('medias', [oMedia]);
oSpot.tmp(['marker-media-tooltips', oMedia.id_media], $Tooltip);
oMarker.bindPopup(
function(e) {
let $Tooltip = oSpot.tmp(['marker-media-tooltips', e.options.id]);
$Tooltip.on('mouseout', function(){e.closePopup();});
//Tooltip: Medias: Set on the fly to avoid resource load
let oMedias = $Tooltip.data('medias');
let $Medias = $Tooltip.find('.medias');
if(oMedias && $Medias.length == 0) {
$Medias = $('<div>', {'class':'medias'});
$.each(oMedias, function(iKey, asMedia) {
$Medias.append(getMediaLink(asMedia, 'marker'));
});
$Tooltip.append($Medias);
}
return $Tooltip[0];
},
{
maxWidth: iWorkSpaceMinWidth,
autoPan: false,
closeOnClick: true,
offset: new L.Point(0, -30)
}
);
oMarker.on('mouseover', function(e) {this.openPopup();});
});
}
function toggleSoftPopup(e, sMode) { function toggleSoftPopup(e, sMode) {
switch(sMode) { switch(sMode) {
case 'open': case 'open':
@@ -806,7 +877,7 @@ function checkNewFeed() {
self.tmp('$PostList').prepend($Posts.children()); self.tmp('$PostList').prepend($Posts.children());
//Markers //Markers
addSpotMessages(asData.messages); addSpotMarkers(asData.messages);
//Message Last Update //Message Last Update
updateSettingsPanel(asData.last_update); updateSettingsPanel(asData.last_update);

View File

@@ -6,6 +6,9 @@
<div class="bar" style="width: 0%;"></div> <div class="bar" style="width: 0%;"></div>
</div> </div>
<div id="comments"></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 id="status"></div>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
@@ -35,6 +38,27 @@ oSpot.pageInit = function(asHash) {
$('#progress .bar').css('width', progress+'%'); $('#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); else addStatus(self.lang('upload_mode_archived', [asProject.name]), true);
}; };

View File

@@ -3,6 +3,7 @@
## Dependencies ## Dependencies
* php-mbstring * php-mbstring
* php-imagick * php-imagick
* php-gd
* php-mysql * php-mysql
* php-exif * php-exif
* ffprobe & ffmpeg * ffprobe & ffmpeg
@@ -21,10 +22,11 @@
4. Copy settings-sample.php to settings.php and populate 4. Copy settings-sample.php to settings.php and populate
5. Go to #admin and create a new project, feed & maps 5. Go to #admin and create a new project, feed & maps
6. Add a GPX file named <project_codename>.gpx to /geo/ 6. Add a GPX file named <project_codename>.gpx to /geo/
7. Run composer install
## To Do List ## To Do List
* ECMA import/export * ECMA import/export
* Add mail frequency slider * Add mail frequency slider
* Use WMTS servers directly when not using Geo Caching Server * Use WMTS servers directly when not using Geo Caching Server
* Allow HEIF picture format * Allow HEIF picture format
* Vector tiles support (https://www.arcgis.com/home/item.html?id=7dc6cea0b1764a1f9af2e679f642f0f5) + Use of GL library. Use Mapbox GL JS / Maplibre GL JS / ESRI-Leaflet-vector? * Vector tiles support (https://www.arcgis.com/home/item.html?id=7dc6cea0b1764a1f9af2e679f642f0f5) + Use of GL library. Use Mapbox GL JS / Maplibre GL JS / ESRI-Leaflet-vector?
* Fix .MOV playback on firefox * Fix .MOV playback on windows firefox

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
/*! /*!
* Lightbox v2.11.3 * Lightbox v2.11.4
* by Lokesh Dhakar * by Lokesh Dhakar
* *
* More info: * More info:
@@ -46,8 +46,6 @@
fadeDuration: 600, fadeDuration: 600,
fitImagesInViewport: true, fitImagesInViewport: true,
imageFadeDuration: 600, imageFadeDuration: 600,
// maxWidth: 800,
// maxHeight: 600,
positionFromTop: 50, positionFromTop: 50,
resizeDuration: 700, resizeDuration: 700,
showImageNumberLabel: true, showImageNumberLabel: true,
@@ -62,10 +60,8 @@
to prevent xss and other injection attacks. to prevent xss and other injection attacks.
*/ */
sanitizeTitle: false sanitizeTitle: false
//ADDED-START
, hasVideo: true , hasVideo: true
, onMediaChange: (oMedia) => {} , onMediaChange: (oMedia) => {}
//ADDED-END
}; };
Lightbox.prototype.option = function(options) { Lightbox.prototype.option = function(options) {
@@ -147,7 +143,6 @@
</div>\ </div>\
').appendTo($('body')); ').appendTo($('body'));
// Cache jQuery objects // Cache jQuery objects
this.$lightbox = $('#lightbox'); this.$lightbox = $('#lightbox');
this.$overlay = $('#lightboxOverlay'); this.$overlay = $('#lightboxOverlay');
@@ -156,7 +151,6 @@
this.$image = this.$lightbox.find('.lb-image'); this.$image = this.$lightbox.find('.lb-image');
this.$nav = this.$lightbox.find('.lb-nav'); this.$nav = this.$lightbox.find('.lb-nav');
//ADDED-START
if(self.options.hasVideo) { if(self.options.hasVideo) {
this.$video = $('<video class="lb-video" controls autoplay></video>'); this.$video = $('<video class="lb-video" controls autoplay></video>');
this.$image.after(this.$video); this.$image.after(this.$video);
@@ -167,7 +161,6 @@
left: parseInt(this.$video.css('border-left-width'), 10) left: parseInt(this.$video.css('border-left-width'), 10)
}; };
} }
//ADDED-END
// Store css values for future lookup // Store css values for future lookup
this.containerPadding = { this.containerPadding = {
@@ -185,10 +178,7 @@
}; };
// Attach event handlers to the newly minted DOM elements // 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() { this.$overlay.hide().add(this.$lightbox.find('.lb-dataContainer')).on('click', function() {
//ADDED-END
self.end(); self.end();
return false; return false;
}); });
@@ -250,9 +240,13 @@
}); });
this.$lightbox.find('.lb-loader, .lb-close').on('click', function() { 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(); self.end();
return false; return false;
}
}); });
}; };
@@ -265,7 +259,6 @@
this.sizeOverlay(); this.sizeOverlay();
//ADDED-START
//Manage Zoom Event //Manage Zoom Event
this.$nav.mousewheel((e) => { this.$nav.mousewheel((e) => {
var asImg = self.album[this.currentImageIndex]; var asImg = self.album[this.currentImageIndex];
@@ -324,7 +317,6 @@
self.$image.css('--translate-x', fTransX + 'px'); self.$image.css('--translate-x', fTransX + 'px');
self.$image.css('--translate-y', fTransY + 'px'); self.$image.css('--translate-y', fTransY + 'px');
} }
//ADDED-END
this.album = []; this.album = [];
var imageNumber = 0; var imageNumber = 0;
@@ -358,14 +350,7 @@
} }
// Position Lightbox // Position Lightbox
//ADDED-START this.$lightbox.fadeIn(this.options.fadeDuration);
//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
// Disable scrolling of the page while open // Disable scrolling of the page while open
if (this.options.disableScrolling) { if (this.options.disableScrolling) {
@@ -379,20 +364,18 @@
this.album.push({ this.album.push({
alt: $link.attr('data-alt'), alt: $link.attr('data-alt'),
link: $link.attr('href'), link: $link.attr('href'),
title: $link.attr('data-title') || $link.attr('title') title: $link.attr('data-title') || $link.attr('title'),
//ADDED-START
, orientation: $link.attr('data-orientation') orientation: $link.attr('data-orientation'),
, type: $link.attr('data-type') type: $link.attr('data-type'),
, id: $link.attr('data-id') id: $link.attr('data-id'),
, $Media: $link.attr('data-type')=='video'?this.$video:this.$image $Media: $link.attr('data-type')=='video'?this.$video:this.$image,
, width: $link.find('img').attr('width') width: $link.find('img').attr('width'),
, height: $link.find('img').attr('height') height: $link.find('img').attr('height'),
, set: $link.attr('data-lightbox') || $link.attr('rel') set: $link.attr('data-lightbox') || $link.attr('rel')
//ADDED-END
}); });
} }
//ADDED-START
Lightbox.prototype.getMaxSizes = function(iMediaWidth, iMediaHeight, sMediaType) { Lightbox.prototype.getMaxSizes = function(iMediaWidth, iMediaHeight, sMediaType) {
var iWindowWidth = $(window).width(); var iWindowWidth = $(window).width();
var iWindowHeight = $(window).height(); var iWindowHeight = $(window).height();
@@ -536,12 +519,9 @@
this.currentImageIndex = imageNumber; this.currentImageIndex = imageNumber;
}; };
//ADDED-END
// Stretch overlay to fit the viewport // Stretch overlay to fit the viewport
Lightbox.prototype.sizeOverlay = function(e) { Lightbox.prototype.sizeOverlay = function(e) {
//var self = this;
/* /*
We use a setTimeout 0 to pause JS execution and let the rendering catch-up. 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 Why do this? If the `disableScrolling` option is set to true, a class is added to the body
@@ -549,15 +529,6 @@
hidden before we measure the document width, as the presence of the scrollbar will affect the hidden before we measure the document width, as the presence of the scrollbar will affect the
number. number.
*/ */
//ADDED-START
/*
setTimeout(function() {
self.$overlay
.width($(document).width())
.height($(document).height());
}, 0);
*/
if(e) { if(e) {
if(typeof oResizeTimer != 'undefined') clearTimeout(oResizeTimer); if(typeof oResizeTimer != 'undefined') clearTimeout(oResizeTimer);
oResizeTimer = setTimeout( oResizeTimer = setTimeout(
@@ -574,7 +545,6 @@
200 200
); );
} }
//ADDED-END
}; };
// Animate the size of the lightbox to fit the image we are showing // Animate the size of the lightbox to fit the image we are showing
@@ -597,19 +567,13 @@
//ADDED-END //ADDED-END
function postResize() { function postResize() {
//ADDED-START
//self.$lightbox.find('.lb-dataContainer').width(newWidth);
if(self.$lightbox.hasClass('vertical')) 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); else self.$lightbox.find('.lb-dataContainer').height(newHeight);
//ADDED-END
self.$lightbox.find('.lb-prevLink').height(newHeight); self.$lightbox.find('.lb-prevLink').height(newHeight);
self.$lightbox.find('.lb-nextLink').height(newHeight); self.$lightbox.find('.lb-nextLink').height(newHeight);
// Set focus on one of the two root nodes so keyboard events are captured. // Set focus on one of the two root nodes so keyboard events are captured.
//ADDED-START
//self.$overlay.focus();
self.$overlay.trigger('focus'); self.$overlay.trigger('focus');
//ADDED-END
self.showImage(); self.showImage();
} }
@@ -630,11 +594,8 @@
Lightbox.prototype.showImage = function() { Lightbox.prototype.showImage = function() {
this.$lightbox.find('.lb-loader').stop(true).hide(); 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); 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); else this.$lightbox.find('.lb-image').fadeIn(this.options.imageFadeDuration);
//ADDED-END
this.updateNav(); this.updateNav();
this.updateDetails(); this.updateDetails();
@@ -692,28 +653,9 @@
} else { } else {
$caption.html(this.album[this.currentImageIndex].title); $caption.html(this.album[this.currentImageIndex].title);
} }
//ADDED-START
//$caption.fadeIn('fast');
$caption.add(this.$lightbox.find('.lb-close')).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.$outerContainer.removeClass('animating');
this.$lightbox.find('.lb-dataContainer').fadeIn(this.options.resizeDuration, function() { this.$lightbox.find('.lb-dataContainer').fadeIn(this.options.resizeDuration, function() {
@@ -734,9 +676,7 @@
}; };
Lightbox.prototype.enableKeyboardNav = function() { Lightbox.prototype.enableKeyboardNav = function() {
//ADDED-START
this.disableKeyboardNav(); this.disableKeyboardNav();
//ADDED-END
this.$lightbox.on('keyup.keyboard', $.proxy(this.keyboardAction, this)); this.$lightbox.on('keyup.keyboard', $.proxy(this.keyboardAction, this));
this.$overlay.on('keyup.keyboard', $.proxy(this.keyboardAction, this)); this.$overlay.on('keyup.keyboard', $.proxy(this.keyboardAction, this));
}; };
@@ -775,7 +715,6 @@
Lightbox.prototype.end = function() { Lightbox.prototype.end = function() {
this.disableKeyboardNav(); this.disableKeyboardNav();
//ADDED-START
if(this.options.hasVideo) { if(this.options.hasVideo) {
var $lbContainer = this.$lightbox.find('.lb-container'); var $lbContainer = this.$lightbox.find('.lb-container');
var $hasVideoNav = $lbContainer.hasClass('lb-video-nav'); var $hasVideoNav = $lbContainer.hasClass('lb-video-nav');
@@ -784,7 +723,6 @@
if($hasVideoNav) $lbContainer.removeClass('lb-video-nav'); if($hasVideoNav) $lbContainer.removeClass('lb-video-nav');
} }
oSpot.flushHash(); oSpot.flushHash();
//ADDED-END
$(window).off('resize', this.sizeOverlay); $(window).off('resize', this.sizeOverlay);
this.$nav.off('mousewheel'); this.$nav.off('mousewheel');

View File

@@ -16,4 +16,5 @@ class Settings
const WEATHER_TOKEN = ''; //visualcrossing.com const WEATHER_TOKEN = ''; //visualcrossing.com
const TIMEZONE_USER = ''; //geonames.org const TIMEZONE_USER = ''; //geonames.org
const DEBUG = true; const DEBUG = true;
const LOG_FOLDER = __DIR__;
} }

View File

@@ -88,6 +88,7 @@ $fa-css-prefix: fa;
.#{$fa-css-prefix}-message-in:before { content: fa-content($fa-var-shoe-prints); } .#{$fa-css-prefix}-message-in:before { content: fa-content($fa-var-shoe-prints); }
.#{$fa-css-prefix}-time:before { content: fa-content($fa-var-clock); } .#{$fa-css-prefix}-time:before { content: fa-content($fa-var-clock); }
.#{$fa-css-prefix}-coords:before { content: fa-content($fa-var-compass); } .#{$fa-css-prefix}-coords:before { content: fa-content($fa-var-compass); }
.#{$fa-css-prefix}-altitude:before { content: fa-content($fa-var-mountain); }
.#{$fa-css-prefix}-drill-video:before { content: fa-content($fa-var-play-circle); } .#{$fa-css-prefix}-drill-video:before { content: fa-content($fa-var-play-circle); }
.#{$fa-css-prefix}-drill-image:before { content: fa-content($fa-var-search); } .#{$fa-css-prefix}-drill-image:before { content: fa-content($fa-var-search); }
.#{$fa-css-prefix}-drill-message:before { content: fa-content($fa-var-search-location); } .#{$fa-css-prefix}-drill-message:before { content: fa-content($fa-var-search-location); }

View File

@@ -60,6 +60,11 @@
padding: 0; padding: 0;
} }
.leaflet-container img.leaflet-tile {
/* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
mix-blend-mode: plus-lighter;
}
.leaflet-container.leaflet-touch-zoom { .leaflet-container.leaflet-touch-zoom {
-ms-touch-action: pan-x pan-y; -ms-touch-action: pan-x pan-y;
touch-action: pan-x pan-y; touch-action: pan-x pan-y;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long