Compare commits
15 Commits
44dfd689b8
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 789838dd07 | |||
| a5fe6ebf75 | |||
| d0dbb85e28 | |||
| 6a42494099 | |||
| 1d90b11aef | |||
| bc75cbc17d | |||
| 2e8372d923 | |||
| 383890a9be | |||
| ae8a27fa64 | |||
| af05650443 | |||
| b3cd217e28 | |||
| 5f597647b4 | |||
| 199e3a1269 | |||
| 04f5ce8a9c | |||
| 402d8f271e |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -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
30
composer.lock
generated
@@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||
3
files/db/update_v20_to_v21.sql
Normal file
3
files/db/update_v20_to_v21.sql
Normal 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
28811
geo/pct.gpx
File diff suppressed because it is too large
Load Diff
69304
geo/snt.gpx
Normal file
69304
geo/snt.gpx
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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,33 +83,36 @@ class Gpx extends Geo {
|
|||||||
|
|
||||||
private function parseFile() {
|
private function parseFile() {
|
||||||
$this->addNotice('Parsing: '.$this->sFilePath);
|
$this->addNotice('Parsing: '.$this->sFilePath);
|
||||||
$oXml = simplexml_load_file($this->sFilePath);
|
if(!file_exists($this->sFilePath)) $this->addError($this->sFilePath.' file missing');
|
||||||
|
else {
|
||||||
|
$oXml = simplexml_load_file($this->sFilePath);
|
||||||
|
|
||||||
//Tracks
|
//Tracks
|
||||||
$this->addNotice('Converting '.count($oXml->trk).' tracks');
|
$this->addNotice('Converting '.count($oXml->trk).' tracks');
|
||||||
foreach($oXml->trk as $aoTrack) {
|
foreach($oXml->trk as $aoTrack) {
|
||||||
$asTrack = array(
|
$asTrack = array(
|
||||||
'name' => (string) $aoTrack->name,
|
'name' => (string) $aoTrack->name,
|
||||||
'desc' => str_replace("\n", '', ToolBox::fixEOL((strip_tags($aoTrack->desc)))),
|
'desc' => str_replace("\n", '', ToolBox::fixEOL((strip_tags($aoTrack->desc)))),
|
||||||
'cmt' => ToolBox::fixEOL((strip_tags($aoTrack->cmt))),
|
'cmt' => ToolBox::fixEOL((strip_tags($aoTrack->cmt))),
|
||||||
'color' => (string) $aoTrack->extensions->children('gpxx', true)->TrackExtension->DisplayColor,
|
'color' => (string) $aoTrack->extensions->children('gpxx', true)->TrackExtension->DisplayColor,
|
||||||
'points'=> array()
|
'points'=> array()
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach($aoTrack->trkseg as $asSegment) {
|
foreach($aoTrack->trkseg as $asSegment) {
|
||||||
foreach($asSegment as $asPoint) {
|
foreach($asSegment as $asPoint) {
|
||||||
$asTrack['points'][] = array(
|
$asTrack['points'][] = array(
|
||||||
'lon' => (float) $asPoint['lon'],
|
'lon' => (float) $asPoint['lon'],
|
||||||
'lat' => (float) $asPoint['lat'],
|
'lat' => (float) $asPoint['lat'],
|
||||||
'ele' => (int) $asPoint->ele
|
'ele' => (int) $asPoint->ele
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
$this->asTracks[] = $asTrack;
|
||||||
}
|
}
|
||||||
$this->asTracks[] = $asTrack;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Waypoints
|
//Waypoints
|
||||||
$this->addNotice('Ignoring '.count($oXml->wpt).' waypoints');
|
$this->addNotice('Ignoring '.count($oXml->wpt).' waypoints');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
27
inc/Feed.php
27
inc/Feed.php
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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');
|
||||||
|
|||||||
45
inc/Spot.php
45
inc/Spot.php
@@ -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",
|
||||||
@@ -121,7 +122,7 @@ class Spot extends Main
|
|||||||
'site_time' => "TIMESTAMP DEFAULT 0", //DEFAULT 0 removes auto-set to current time
|
'site_time' => "TIMESTAMP DEFAULT 0", //DEFAULT 0 removes auto-set to current time
|
||||||
'status' => "VARCHAR(10)",
|
'status' => "VARCHAR(10)",
|
||||||
'taken_on' => "TIMESTAMP DEFAULT 0",
|
'taken_on' => "TIMESTAMP DEFAULT 0",
|
||||||
'timezone' => "CHAR(64) NOT NULL", //see mysql.time_zone_name
|
'timezone' => "CHAR(64) NOT NULL", //see mysql.time_zone_name
|
||||||
'token' => "VARCHAR(4096)",
|
'token' => "VARCHAR(4096)",
|
||||||
'type' => "VARCHAR(20)",
|
'type' => "VARCHAR(20)",
|
||||||
'unix_time' => "INT",
|
'unix_time' => "INT",
|
||||||
@@ -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,23 +270,24 @@ 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'];});
|
|
||||||
|
|
||||||
//Assign medias to closest message
|
//Assign medias to closest message
|
||||||
$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;
|
||||||
elseif($iIndex > $iMaxIndex) $iMsgIndex = $iMaxIndex;
|
elseif($iIndex > $iMaxIndex) $iMsgIndex = $iMaxIndex;
|
||||||
else {
|
else {
|
||||||
$iHalfWayPoint = ($asMessages[$iIndex - 1]['unix_time'] + $asMessages[$iIndex]['unix_time'])/2;
|
$iHalfWayPoint = ($asMessages[$iIndex - 1]['unix_time'] + $asMessages[$iIndex]['unix_time'])/2;
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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
|
||||||
6
script/leaflet.min.js
vendored
6
script/leaflet.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -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');
|
||||||
@@ -155,8 +150,7 @@
|
|||||||
this.$container = this.$lightbox.find('.lb-container');
|
this.$container = this.$lightbox.find('.lb-container');
|
||||||
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);
|
||||||
@@ -166,8 +160,7 @@
|
|||||||
bottom: parseInt(this.$video.css('border-bottom-width'), 10),
|
bottom: parseInt(this.$video.css('border-bottom-width'), 10),
|
||||||
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,11 +178,8 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Attach event handlers to the newly minted DOM elements
|
// Attach event handlers to the newly minted DOM elements
|
||||||
//ADDED-START
|
this.$overlay.hide().add(this.$lightbox.find('.lb-dataContainer')).on('click', function() {
|
||||||
//this.$overlay.hide().on('click', function() {
|
self.end();
|
||||||
this.$overlay.hide().add(this.$lightbox.find('.lb-dataContainer')).on('click', function() {
|
|
||||||
//ADDED-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) {
|
||||||
self.end();
|
// If mouse click OR 'enter' or 'space' keypress, close LB
|
||||||
return false;
|
if (
|
||||||
|
e.type === 'click' || (e.type === 'keyup' && (e.which === 13 || e.which === 32))) {
|
||||||
|
self.end();
|
||||||
|
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;
|
||||||
@@ -349,7 +341,7 @@
|
|||||||
// If image is part of a set
|
// If image is part of a set
|
||||||
$links = $($link.prop('tagName') + '[rel="' + $link.attr('rel') + '"]');
|
$links = $($link.prop('tagName') + '[rel="' + $link.attr('rel') + '"]');
|
||||||
for (var j = 0; j < $links.length; j = ++j) {
|
for (var j = 0; j < $links.length; j = ++j) {
|
||||||
this.addToAlbum($($links[j]));
|
this.addToAlbum($($links[j]));
|
||||||
if ($links[j] === $link[0]) {
|
if ($links[j] === $link[0]) {
|
||||||
imageNumber = j;
|
imageNumber = j;
|
||||||
}
|
}
|
||||||
@@ -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();
|
||||||
@@ -473,20 +456,20 @@
|
|||||||
|
|
||||||
// Hide most UI elements in preparation for the animated resizing of the lightbox.
|
// Hide most UI elements in preparation for the animated resizing of the lightbox.
|
||||||
Lightbox.prototype.changeImage = function(imageNumber) {
|
Lightbox.prototype.changeImage = function(imageNumber) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var filename = this.album[imageNumber].link;
|
var filename = this.album[imageNumber].link;
|
||||||
|
|
||||||
// Disable keyboard nav during transitions
|
|
||||||
this.disableKeyboardNav();
|
|
||||||
|
|
||||||
// Show loading state
|
// Disable keyboard nav during transitions
|
||||||
this.$overlay.fadeIn(this.options.fadeDuration);
|
this.disableKeyboardNav();
|
||||||
$('.lb-loader').fadeIn('slow');
|
|
||||||
|
|
||||||
this.$lightbox.find('.lb-image, .lb-video, .lb-nav, .lb-prev, .lb-next, .lb-number, .lb-caption, .lb-close').hide();
|
// 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.$image.css({'--scale': '1', '--translate-x': '0', '--translate-y': '0'});
|
this.$image.css({'--scale': '1', '--translate-x': '0', '--translate-y': '0'});
|
||||||
self.$lightbox.find('.lb-dataContainer').css({width:'200px', height:'30px'});
|
self.$lightbox.find('.lb-dataContainer').css({width:'200px', height:'30px'});
|
||||||
this.$outerContainer.addClass('animating');
|
this.$outerContainer.addClass('animating');
|
||||||
this.$container.removeClass('moveable moving');
|
this.$container.removeClass('moveable moving');
|
||||||
|
|
||||||
this.options.onMediaChange(self.album[imageNumber]);
|
this.options.onMediaChange(self.album[imageNumber]);
|
||||||
@@ -534,31 +517,19 @@
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
tag that disables scrolling and hides the scrollbar. We want to make sure the scrollbar is
|
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
|
hidden before we measure the document width, as the presence of the scrollbar will affect the
|
||||||
number.
|
number.
|
||||||
*/
|
*/
|
||||||
//ADDED-START
|
if(e) {
|
||||||
/*
|
|
||||||
setTimeout(function() {
|
|
||||||
self.$overlay
|
|
||||||
.width($(document).width())
|
|
||||||
.height($(document).height());
|
|
||||||
|
|
||||||
}, 0);
|
|
||||||
*/
|
|
||||||
if(e) {
|
|
||||||
if(typeof oResizeTimer != 'undefined') clearTimeout(oResizeTimer);
|
if(typeof oResizeTimer != 'undefined') clearTimeout(oResizeTimer);
|
||||||
oResizeTimer = setTimeout(
|
oResizeTimer = setTimeout(
|
||||||
() => {
|
() => {
|
||||||
@@ -573,17 +544,16 @@
|
|||||||
},
|
},
|
||||||
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
|
||||||
// This method also shows the the image.
|
// This method also shows the the image.
|
||||||
//ADDED-START
|
//ADDED-START
|
||||||
//Lightbox.prototype.sizeContainer = function(imageWidth, imageHeight) {
|
//Lightbox.prototype.sizeContainer = function(imageWidth, imageHeight) {
|
||||||
Lightbox.prototype.sizeContainer = function(imageWidth, imageHeight, media) {
|
Lightbox.prototype.sizeContainer = function(imageWidth, imageHeight, media) {
|
||||||
media = media || 'image';
|
media = media || 'image';
|
||||||
//ADDED-END
|
//ADDED-END
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var oldWidth = this.$outerContainer.outerWidth();
|
var oldWidth = this.$outerContainer.outerWidth();
|
||||||
@@ -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.trigger('focus');
|
||||||
//self.$overlay.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();
|
||||||
@@ -691,29 +652,10 @@
|
|||||||
$caption.text(this.album[this.currentImageIndex].title);
|
$caption.text(this.album[this.currentImageIndex].title);
|
||||||
} 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,19 +715,17 @@
|
|||||||
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');
|
this.$video.attr('src', '');
|
||||||
this.$video.attr('src', '');
|
|
||||||
|
|
||||||
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');
|
||||||
this.$lightbox.fadeOut(this.options.fadeDuration);
|
this.$lightbox.fadeOut(this.options.fadeDuration);
|
||||||
this.$overlay.fadeOut(this.options.fadeDuration);
|
this.$overlay.fadeOut(this.options.fadeDuration);
|
||||||
|
|
||||||
|
|||||||
@@ -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__;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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); }
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -646,7 +651,7 @@ svg.leaflet-image-layer.leaflet-interactive path {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Printing */
|
/* Printing */
|
||||||
|
|
||||||
@media print {
|
@media print {
|
||||||
/* Prevent printers from removing background-images of controls. */
|
/* Prevent printers from removing background-images of controls. */
|
||||||
.leaflet-control {
|
.leaflet-control {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user