Compare commits
11
Commits
506c8bd946
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
56d8f46434 | ||
|
|
a70f6fe64c | ||
|
|
dc4480c4e2 | ||
|
|
e2a694ba03 | ||
|
|
8efd74406f | ||
|
|
51837ef1ac | ||
|
|
842bb56fcc | ||
|
|
0acec1f37e | ||
|
|
8ebfb2d830 | ||
|
|
aa8f80451d | ||
|
|
f4e2781172 |
Generated
+2844
-5
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,26 @@
|
|||||||
<VirtualHost *:80>
|
<VirtualHost *:80>
|
||||||
ServerName localhost
|
ServerName localhost
|
||||||
ServerAlias maui.local
|
ServerAlias maui.local
|
||||||
DocumentRoot /var/www/html/
|
DocumentRoot /var/www/html/
|
||||||
|
|
||||||
|
RewriteEngine on
|
||||||
|
RewriteCond %{HTTPS} off
|
||||||
|
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [END,NE,R=permanent]
|
||||||
|
</VirtualHost>
|
||||||
|
|
||||||
|
<IfModule mod_ssl.c>
|
||||||
|
<VirtualHost *:443>
|
||||||
|
ServerName localhost
|
||||||
|
ServerAlias maui.local
|
||||||
|
DocumentRoot /var/www/html/
|
||||||
|
|
||||||
|
SSLCertificateFile /etc/letsencrypt/live/mushu.nest.lutran.ch/fullchain.pem
|
||||||
|
SSLCertificateKeyFile /etc/letsencrypt/live/mushu.nest.lutran.ch/privkey.pem
|
||||||
|
Include /etc/letsencrypt/options-ssl-apache.conf
|
||||||
|
|
||||||
DirectoryIndex index.php
|
DirectoryIndex index.php
|
||||||
|
|
||||||
# Serve http://localhost/livetrail/ from the public web root.
|
# Serve https://localhost/livetrail/ from the public web root.
|
||||||
Alias /livetrail /var/www/html/livetrail/public
|
Alias /livetrail /var/www/html/livetrail/public
|
||||||
|
|
||||||
<Directory /var/www/html/livetrail/public>
|
<Directory /var/www/html/livetrail/public>
|
||||||
@@ -52,3 +67,4 @@
|
|||||||
</IfModule>
|
</IfModule>
|
||||||
</Directory>
|
</Directory>
|
||||||
</VirtualHost>
|
</VirtualHost>
|
||||||
|
</IfModule>
|
||||||
|
|||||||
+3
-1
@@ -49,6 +49,8 @@ class Controller extends PhpObject {
|
|||||||
$this->setReqVal('t', $asReq['t'] ?? '');
|
$this->setReqVal('t', $asReq['t'] ?? '');
|
||||||
$this->setReqVal('name', $asReq['name'] ?? '');
|
$this->setReqVal('name', $asReq['name'] ?? '');
|
||||||
$this->setReqVal('content', $asReq['content'] ?? '');
|
$this->setReqVal('content', $asReq['content'] ?? '');
|
||||||
|
$this->setReqVal('ref_type', $asReq['ref_type'] ?? '');
|
||||||
|
$this->setReqVal('ref_id', $asReq['ref_id'] ?? 0, 'positiveInt');
|
||||||
$this->setReqVal('id_project', $asReq['id_project'] ?? 0, 'positiveInt');
|
$this->setReqVal('id_project', $asReq['id_project'] ?? 0, 'positiveInt');
|
||||||
$this->setReqVal('id', $asReq['id'] ?? 0);
|
$this->setReqVal('id', $asReq['id'] ?? 0);
|
||||||
$this->setReqVal('id_entity', $asReq['id'] ?? 0, 'positiveInt');
|
$this->setReqVal('id_entity', $asReq['id'] ?? 0, 'positiveInt');
|
||||||
@@ -133,7 +135,7 @@ class Controller extends PhpObject {
|
|||||||
'last_update' => $this->oLivetrail->getLastUpdate(),
|
'last_update' => $this->oLivetrail->getLastUpdate(),
|
||||||
'next_feed' => $this->oLivetrail->getNextFeed($this->asReq['id']),
|
'next_feed' => $this->oLivetrail->getNextFeed($this->asReq['id']),
|
||||||
'new_feed' => $this->oLivetrail->getNewFeed($this->asReq['id']),
|
'new_feed' => $this->oLivetrail->getNewFeed($this->asReq['id']),
|
||||||
'add_post' => $this->oLivetrail->addPost($this->asReq['name'], $this->asReq['content']),
|
'add_post' => $this->oLivetrail->addPost($this->asReq['name'], $this->asReq['content'], $this->asReq['ref_type'], $this->asReq['ref_id']),
|
||||||
'subscribe' => $this->oLivetrail->subscribe(),
|
'subscribe' => $this->oLivetrail->subscribe(),
|
||||||
'unsubscribe' => $this->oLivetrail->unsubscribe(),
|
'unsubscribe' => $this->oLivetrail->unsubscribe(),
|
||||||
'login' => $this->oLivetrail->login($this->asReq['email'], $this->asReq['password'], $this->asReq['name']),
|
'login' => $this->oLivetrail->login($this->asReq['email'], $this->asReq['password'], $this->asReq['name']),
|
||||||
|
|||||||
+24
-4
@@ -34,6 +34,7 @@ use \Settings;
|
|||||||
class Livetrail extends Main {
|
class Livetrail extends Main {
|
||||||
//Database
|
//Database
|
||||||
public const POST_TABLE = 'posts';
|
public const POST_TABLE = 'posts';
|
||||||
|
private const REF_TYPES = ['post', 'media', 'message'];
|
||||||
|
|
||||||
private const FEED_CHUNK_SIZE = 15;
|
private const FEED_CHUNK_SIZE = 15;
|
||||||
private const MAIL_CHUNK_SIZE = 5;
|
private const MAIL_CHUNK_SIZE = 5;
|
||||||
@@ -87,7 +88,7 @@ class Livetrail extends Main {
|
|||||||
Feed::FEED_TABLE => ['ref_feed_id', Db::getId(Feed::SPOT_TABLE), Db::getId(Project::PROJ_TABLE), 'name', 'description', 'status', 'last_update'],
|
Feed::FEED_TABLE => ['ref_feed_id', Db::getId(Feed::SPOT_TABLE), Db::getId(Project::PROJ_TABLE), 'name', 'description', 'status', 'last_update'],
|
||||||
Feed::SPOT_TABLE => ['ref_spot_id', 'name', 'model'],
|
Feed::SPOT_TABLE => ['ref_spot_id', 'name', 'model'],
|
||||||
Project::PROJ_TABLE => ['name', 'codename', 'active_from', 'active_to'],
|
Project::PROJ_TABLE => ['name', 'codename', 'active_from', 'active_to'],
|
||||||
self::POST_TABLE => [Db::getId(Project::PROJ_TABLE), Db::getId(User::USER_TABLE), 'name', 'content', 'site_time', 'timezone'],
|
self::POST_TABLE => [Db::getId(Project::PROJ_TABLE), Db::getId(User::USER_TABLE), 'name', 'content', 'site_time', 'timezone', 'ref_id', 'ref_type'],
|
||||||
Media::MEDIA_TABLE => [Db::getId(Project::PROJ_TABLE), 'filename', 'type', 'taken_on', 'posted_on', 'timezone', 'latitude', 'longitude', 'altitude', 'width', 'height', 'rotate', 'comment'],
|
Media::MEDIA_TABLE => [Db::getId(Project::PROJ_TABLE), 'filename', 'type', 'taken_on', 'posted_on', 'timezone', 'latitude', 'longitude', 'altitude', 'width', 'height', 'rotate', 'comment'],
|
||||||
User::USER_TABLE => ['name', 'email', 'password', 'token', 'token_exp', 'gravatar', 'language', 'timezone', 'subscribed', 'clearance'],
|
User::USER_TABLE => ['name', 'email', 'password', 'token', 'token_exp', 'gravatar', 'language', 'timezone', 'subscribed', 'clearance'],
|
||||||
Map::MAP_TABLE => ['codename', 'pattern', 'token', 'tile_size', 'min_zoom', 'max_zoom', 'attribution'],
|
Map::MAP_TABLE => ['codename', 'pattern', 'token', 'tile_size', 'min_zoom', 'max_zoom', 'attribution'],
|
||||||
@@ -119,6 +120,8 @@ class Livetrail extends Main {
|
|||||||
'ref_feed_id' => 'VARCHAR(40)',
|
'ref_feed_id' => 'VARCHAR(40)',
|
||||||
'ref_msg_id' => 'VARCHAR(15)',
|
'ref_msg_id' => 'VARCHAR(15)',
|
||||||
'ref_spot_id' => 'VARCHAR(10)',
|
'ref_spot_id' => 'VARCHAR(10)',
|
||||||
|
'ref_id' => 'INT UNSIGNED',
|
||||||
|
'ref_type' => 'VARCHAR(20)',
|
||||||
'rotate' => 'SMALLINT',
|
'rotate' => 'SMALLINT',
|
||||||
'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)',
|
||||||
@@ -469,7 +472,7 @@ class Livetrail extends Main {
|
|||||||
return $asMedias;
|
return $asMedias;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getPosts($asPostIds=[]) {
|
private function getPosts($asPostIds=[], $bResolveRef=true) {
|
||||||
$asInfo = [
|
$asInfo = [
|
||||||
'select' => [Db::getFullColumnName(self::POST_TABLE, '*'), 'gravatar'],
|
'select' => [Db::getFullColumnName(self::POST_TABLE, '*'), 'gravatar'],
|
||||||
'from' => self::POST_TABLE,
|
'from' => self::POST_TABLE,
|
||||||
@@ -489,6 +492,20 @@ class Livetrail extends Main {
|
|||||||
unset($asPost[Db::getId(User::USER_TABLE)]);
|
unset($asPost[Db::getId(User::USER_TABLE)]);
|
||||||
|
|
||||||
$this->addTimeStamp($asPost, $iUnixTimeStamp, $asPost['timezone']);
|
$this->addTimeStamp($asPost, $iUnixTimeStamp, $asPost['timezone']);
|
||||||
|
|
||||||
|
if($bResolveRef && !empty($asPost['ref_type']) && !empty($asPost['ref_id'])) {
|
||||||
|
switch($asPost['ref_type']) {
|
||||||
|
case 'post': $asRefs = $this->getPosts([$asPost['ref_id']], false); break;
|
||||||
|
case 'media': $asRefs = $this->getMedias('posted_on', [$asPost['ref_id']]); break;
|
||||||
|
case 'message': $asRefs = $this->getSpotMessages([$asPost['ref_id']]); break;
|
||||||
|
default: $asRefs = [];
|
||||||
|
}
|
||||||
|
$asPost['ref_item'] = reset($asRefs);
|
||||||
|
$asPost['ref_item']['type'] = $asPost['ref_type'];
|
||||||
|
$asPost['ref_item']['id'] = $asPost['ref_id'];
|
||||||
|
}
|
||||||
|
unset($asPost['ref_id']);
|
||||||
|
unset($asPost['ref_type']);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $asPosts;
|
return $asPosts;
|
||||||
@@ -658,17 +675,20 @@ class Livetrail extends Main {
|
|||||||
return ['ref_id_last'=>$iRefIdLast, 'ref_id_first'=>$iRefIdFirst, 'sort'=>$sSort, 'feed'=>$asItems];
|
return ['ref_id_last'=>$iRefIdLast, 'ref_id_first'=>$iRefIdFirst, 'sort'=>$sSort, 'feed'=>$asItems];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function addPost($sName, $sPost) {
|
public function addPost($sName, $sPost, $sRefType='', $iRefId=0) {
|
||||||
$iPostId = 0;
|
$iPostId = 0;
|
||||||
$sLangId = '';
|
$sLangId = '';
|
||||||
|
|
||||||
if($this->oProject->isEditable()) {
|
if($this->oProject->isEditable()) {
|
||||||
|
$bHasRef = ($iRefId > 0) && in_array($sRefType, self::REF_TYPES, true);
|
||||||
$asData = [
|
$asData = [
|
||||||
Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId(),
|
Db::getId(Project::PROJ_TABLE) => $this->oProject->getProjectId(),
|
||||||
'name' => mb_strtolower(trim($sName)),
|
'name' => mb_strtolower(trim($sName)),
|
||||||
'content' => trim($sPost),
|
'content' => trim($sPost),
|
||||||
'site_time' => date(Db::TIMESTAMP_FORMAT), //Now in Site Time
|
'site_time' => date(Db::TIMESTAMP_FORMAT), //Now in Site Time
|
||||||
'timezone' => date_default_timezone_get() //Site Time Zone
|
'timezone' => date_default_timezone_get(), //Site Time Zone
|
||||||
|
'ref_id' => $bHasRef?$iRefId:'NULL',
|
||||||
|
'ref_type' => $bHasRef?$sRefType:'NULL'
|
||||||
];
|
];
|
||||||
if($this->oUser->getUserId() > 0) $asData[Db::getId(User::USER_TABLE)] = $this->oUser->getUserId();
|
if($this->oUser->getUserId() > 0) $asData[Db::getId(User::USER_TABLE)] = $this->oUser->getUserId();
|
||||||
|
|
||||||
|
|||||||
Generated
+227
-137
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "livetrail",
|
"name": "livetrail",
|
||||||
"version": "3.0.0",
|
"version": "3.0.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "livetrail",
|
"name": "livetrail",
|
||||||
"version": "3.0.0",
|
"version": "3.0.1",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-svg-core": "^7.2.0",
|
"@fortawesome/fontawesome-svg-core": "^7.2.0",
|
||||||
"@fortawesome/free-solid-svg-icons": "^7.2.0",
|
"@fortawesome/free-solid-svg-icons": "^7.2.0",
|
||||||
@@ -74,6 +74,30 @@
|
|||||||
"node": ">=6.9.0"
|
"node": ">=6.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@cacheable/memory": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@cacheable/utils": "^2.5.0",
|
||||||
|
"@keyv/bigmap": "^1.3.1",
|
||||||
|
"hookified": "^1.15.1",
|
||||||
|
"keyv": "^5.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@cacheable/utils": {
|
||||||
|
"version": "2.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.5.0.tgz",
|
||||||
|
"integrity": "sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"hashery": "^1.5.1",
|
||||||
|
"keyv": "^5.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@eslint-community/eslint-utils": {
|
"node_modules/@eslint-community/eslint-utils": {
|
||||||
"version": "4.10.1",
|
"version": "4.10.1",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz",
|
||||||
@@ -189,9 +213,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/plugin-kit": {
|
"node_modules/@eslint/plugin-kit": {
|
||||||
"version": "0.7.2",
|
"version": "0.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.3.tgz",
|
||||||
"integrity": "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==",
|
"integrity": "sha512-IkO+/KEUvwbVpiURZg+P7zF74z5Jxe0UgJxVni+RtoHQ6IZieXaO02kmadomap/q+l6bc/jdPGGqTjhuZnuz1Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -312,9 +336,33 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@jridgewell/sourcemap-codec": {
|
"node_modules/@jridgewell/sourcemap-codec": {
|
||||||
"version": "1.5.5",
|
"version": "1.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz",
|
||||||
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
|
"integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@keyv/bigmap": {
|
||||||
|
"version": "1.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@keyv/bigmap/-/bigmap-1.3.1.tgz",
|
||||||
|
"integrity": "sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"hashery": "^1.4.0",
|
||||||
|
"hookified": "^1.15.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"keyv": "^5.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@keyv/serialize": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@mapbox/jsonlint-lines-primitives": {
|
"node_modules/@mapbox/jsonlint-lines-primitives": {
|
||||||
@@ -365,9 +413,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@maplibre/maplibre-gl-style-spec": {
|
"node_modules/@maplibre/maplibre-gl-style-spec": {
|
||||||
"version": "26.4.1",
|
"version": "26.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-26.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-style-spec/-/maplibre-gl-style-spec-26.4.2.tgz",
|
||||||
"integrity": "sha512-I/qcIKVFHFSg1Meu/eqHrkSTjIez0gCsSaK56TNPutM3TkE61aSq6F1cZ4Kg4KiNs3cpViLtubDjfyRcQCdEJQ==",
|
"integrity": "sha512-6J0vZqMZvRAJKtdWJdDGHEh1YJ2ZHG08/GOur8gCArYhO8ZkM//OXqtI2AAEz4jc2G+Wq4MfcePg8qNK5TZ4Kg==",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mapbox/jsonlint-lines-primitives": "^2.0.3",
|
"@mapbox/jsonlint-lines-primitives": "^2.0.3",
|
||||||
@@ -384,9 +432,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@maplibre/mlt": {
|
"node_modules/@maplibre/mlt": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@maplibre/mlt/-/mlt-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@maplibre/mlt/-/mlt-1.2.1.tgz",
|
||||||
"integrity": "sha512-g45M8gEI4sMO3X9ib4K7n3ZKFf0qQOL+NMkHCnEK51lOrYFHiEssOuZncx1+miIgi1IEE2NcbRMcq8RBkL+QHA==",
|
"integrity": "sha512-5n5dgolE2EYxwCKgx8vlwURCB8A+kyfJJyThlYimjlGgOcOe2Bhw9VxxnnHC91OC9PgHg+nVdgVPTYPkIo62vg==",
|
||||||
"license": "(MIT OR Apache-2.0)",
|
"license": "(MIT OR Apache-2.0)",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mapbox/point-geometry": "^1.1.0"
|
"@mapbox/point-geometry": "^1.1.0"
|
||||||
@@ -404,13 +452,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@oxc-project/types": {
|
"node_modules/@oxc-project/types": {
|
||||||
"version": "0.147.0",
|
"version": "0.149.0",
|
||||||
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.147.0.tgz",
|
"resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.149.0.tgz",
|
||||||
"integrity": "sha512-IJ3s6ltHLp45S0bh7phkX+gJO7A1Wuz2EaqpAhb8WjqDwbzMiWKHhyyT42tskaWjEYXtHtVCPpnBJVT9+dcRLg==",
|
"integrity": "sha512-Efcc+iF0j3Bf67YjEqIqWXbX5XddXoK/Mw4K1/JuXwRCZ8N16VR7iT23nlCc9XrveFVh/E5Rqs2StT0V8v9LdA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/Boshen"
|
"url": "https://github.com/sponsors/oxc-project"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@parcel/watcher": {
|
"node_modules/@parcel/watcher": {
|
||||||
@@ -707,9 +755,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-android-arm-eabi": {
|
"node_modules/@rolldown/binding-android-arm-eabi": {
|
||||||
"version": "1.2.6",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.8.tgz",
|
||||||
"integrity": "sha512-b+jTcARdTiFLI6jB4a5XjTm0RWd6KcRfQj/I2356fxUZemiho9zQLxo0RtCuMDAyKcLo6cEltkgbQp6d1+sjjQ==",
|
"integrity": "sha512-tN5aztYkKCte4i5SIrrz5yK/HMjEuCqCSCJa418jOV8tZ1cBY3YF2otxB1ktPxzsLA1BeTqwapK0bfjxNvHJVw==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -724,9 +772,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-android-arm64": {
|
"node_modules/@rolldown/binding-android-arm64": {
|
||||||
"version": "1.2.6",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.8.tgz",
|
||||||
"integrity": "sha512-lkWU8ZJaRk9q3CIEY1Tc7vIFALp3Xw5NfGJo2hQg5oIqNgxWi1zI+IiDEK3r70BF5Dzol1tcXsnzsRc8NLhG+Q==",
|
"integrity": "sha512-dIYTWl9XprMUiQFoc55KUyk/oS8SKYH3zFl0LTR7RT0Xj4hgSVyuJcroH8JUu8RcpF8fTB6E0aOwCkZoYPcDSQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -741,9 +789,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-darwin-arm64": {
|
"node_modules/@rolldown/binding-darwin-arm64": {
|
||||||
"version": "1.2.6",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.8.tgz",
|
||||||
"integrity": "sha512-dgR56NYnvAszm7Ob1B2/Vn0e8bUQYZH2UjVaMMtMVOCKFSfjhfLmuA/9+O+F+ajUdG6B/bSssrKW6JJYASa8jA==",
|
"integrity": "sha512-PCSDQGXD2IyTEFrcgPyBM8jJuGmrbCMuoIOXdbEGVemruKACXoLQJrb+A45Z0L5t1RQkdfJprAYPkikbh7dzdA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -758,9 +806,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-darwin-x64": {
|
"node_modules/@rolldown/binding-darwin-x64": {
|
||||||
"version": "1.2.6",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.8.tgz",
|
||||||
"integrity": "sha512-vpVxFvUCFioJqug7OTvqptkc4yb8UX0AwfDmJpaR/0sWz+BUmqSVAf7c8JkUgnN8YLspb4a/N6NhTyMAmdyQ7Q==",
|
"integrity": "sha512-Uk7lRsGhPFHVX/sAUC6D5H9Ol30dFHd6iquokll2th3LpdJ3F5CzQB+7DHn0Ri2mG+U7k2zXiPHDrwZenXhwSA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -775,9 +823,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-freebsd-x64": {
|
"node_modules/@rolldown/binding-freebsd-x64": {
|
||||||
"version": "1.2.6",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.8.tgz",
|
||||||
"integrity": "sha512-h1wG6Y6K3JlRswxsI64qQJqBAy4vrLuHgRbc8CZMGSWTOFRY6ghMApM1NKzB2I0n5xV1fjkE18SuVl2QpLeNpA==",
|
"integrity": "sha512-DjszaTEVogPqA5bYzsEeqDCQxbcp2fexQwKcRspYji2yzR68fCf+e4fx6kBSRDwX5/brZaHw/hWS9+A/+/w9sQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -792,9 +840,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-linux-arm-gnueabihf": {
|
"node_modules/@rolldown/binding-linux-arm-gnueabihf": {
|
||||||
"version": "1.2.6",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.8.tgz",
|
||||||
"integrity": "sha512-tbCiqub0q2MVWJKgF5PoAlNWCtQydiOYSLIkd8sByqK/6MMYLJRcSXSYodqYtd0O+Fw7QaVmKKlS4oL94YRZ0w==",
|
"integrity": "sha512-zmwa7FTmdzB6aaEEuuls18H6Ap5JmJPSoPTuXixeJZV6tG40SyLkApQtz1g8ptZtiEKqj9OM0oNLPh1AgvE31Q==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm"
|
"arm"
|
||||||
],
|
],
|
||||||
@@ -809,9 +857,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-linux-arm64-gnu": {
|
"node_modules/@rolldown/binding-linux-arm64-gnu": {
|
||||||
"version": "1.2.6",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.8.tgz",
|
||||||
"integrity": "sha512-oxK9+baEBPhZG5HB4URY+uU04zJWeZlH6Tb9rB5DK4DF9XR1uXNLXt5Q5ZsugTKayNCNLhkcwz/ye74hRI98dg==",
|
"integrity": "sha512-KdYQDPHwJVnbFwdTGMgxsI9SqblBlz6STGM+w1We/d5B8OWWidYH0MwkU/uA1wM5fIpO2MkOVxXrNzzuZhw9ew==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -829,9 +877,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-linux-arm64-musl": {
|
"node_modules/@rolldown/binding-linux-arm64-musl": {
|
||||||
"version": "1.2.6",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.8.tgz",
|
||||||
"integrity": "sha512-muWCk27FVBEZtv0MsK8gnfSmgczA8KQ0uRVJbTABKhkRfQc38aUrcb7fhi3BNiyseFmgcRsoMfQsSNJ+DbZdSw==",
|
"integrity": "sha512-jFJTifHnNPY+yzOoNZQfSIysrVyXzEQPhPnOUjmD1bcQGHH6s7c8cViKWar8YplQImE5N9JRqMCLrM2CdxOrZA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -849,9 +897,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-linux-ppc64-gnu": {
|
"node_modules/@rolldown/binding-linux-ppc64-gnu": {
|
||||||
"version": "1.2.6",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.8.tgz",
|
||||||
"integrity": "sha512-eWDoSfU7Co2qj3vgB3Dt4lj1mG6CoWbcJQkRMP3XJplyCMtuaq3LHvPFjS9QIPvMGWVadJC04Xiy0IdcVPtnwQ==",
|
"integrity": "sha512-FhiOziBDWPBjbcmRzfLyIJnaP7AVMFXT7YCXPjXxj7wKU3vx24RjrCNN/zjvVa+N2vVoHJwCoUBvsrN/DG3zIA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"ppc64"
|
"ppc64"
|
||||||
],
|
],
|
||||||
@@ -869,9 +917,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-linux-s390x-gnu": {
|
"node_modules/@rolldown/binding-linux-s390x-gnu": {
|
||||||
"version": "1.2.6",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.8.tgz",
|
||||||
"integrity": "sha512-2bWNjRSIayvupRKxXUY2tWG9fYdoUlTqWywHRvE8Eq3GvuQ+f2HeIkve697fIt+IQs/PV8yFsdWuhp1aJ1PdnA==",
|
"integrity": "sha512-WnHfADMzOV2Y55wlx1hzzQnar/wDt/VdvWSD99r18Mz9ylNieIGOkRx3UV21h7m/eJvjySYJkO26VvGNFkwsIQ==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"s390x"
|
"s390x"
|
||||||
],
|
],
|
||||||
@@ -889,9 +937,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-linux-x64-gnu": {
|
"node_modules/@rolldown/binding-linux-x64-gnu": {
|
||||||
"version": "1.2.6",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.8.tgz",
|
||||||
"integrity": "sha512-KekI0gS0wLxe1UBSQSjenBVwou/JkcQPDzBPICGZjxUv9k3RteHDPBQaiOicZUFKRIH2wKEimGwVpnJsbPzu7w==",
|
"integrity": "sha512-H9tRr5ibfXFVLxbPOseVewewFpl28zcEdjRDt2FTUZU7odxP0gEv1ki4/kGmcGOh78oRwZuuQllGLZ9zTJp84g==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -909,9 +957,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-linux-x64-musl": {
|
"node_modules/@rolldown/binding-linux-x64-musl": {
|
||||||
"version": "1.2.6",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.8.tgz",
|
||||||
"integrity": "sha512-TvtPnfVr+HtyGiDmPK4VWmlNm7QhNNAcK5Q9A7aOXsI8545yCyaoMaicXrFZ72JzeYjaUVk7yT243zT0jzjFKQ==",
|
"integrity": "sha512-UefiqfM3D6IVNlZ8tSGs9+Ejjud2T+oxO0IHADU45Y+lyEjD2dVFyZHbkfX0LUb5Zugo/oIv1eCO/KVYhgYJYA==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -929,9 +977,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-openharmony-arm64": {
|
"node_modules/@rolldown/binding-openharmony-arm64": {
|
||||||
"version": "1.2.6",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.8.tgz",
|
||||||
"integrity": "sha512-iOo0VEay2XFhaCcH0sps5XIimkSuOnNaZrf6+ZkoSOQBJPKNU48RkmJv0/lSpipexu5P+ouFgafe5IGr/DiQfg==",
|
"integrity": "sha512-637Ke4kWSy6rp9cxQ9gMOXlxPgIw/c1beASV4M//3+9I4uwBVOOl74G+e3zyU3u19U7RkRl/HuewixZ/Z6+Rjg==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -946,9 +994,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-win32-arm64-msvc": {
|
"node_modules/@rolldown/binding-win32-arm64-msvc": {
|
||||||
"version": "1.2.6",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.8.tgz",
|
||||||
"integrity": "sha512-y5NTmmasMS455JlOCO4ZM9krIchv3Mvm1crL1iUPGOPgEzSkves9n0SdC5Sjz6+qWDFhd8/JpfWMH8NSWNHe+A==",
|
"integrity": "sha512-xWBkPOF1Q9k/Gv1nQXnVdLxKu74jXppuOM4Z3mnypVUJJJwLsMl7hNJGRAUJoG8A5MgOI1ACKM+wBFxSJzKy4A==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
@@ -963,9 +1011,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@rolldown/binding-win32-x64-msvc": {
|
"node_modules/@rolldown/binding-win32-x64-msvc": {
|
||||||
"version": "1.2.6",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.8.tgz",
|
||||||
"integrity": "sha512-np8iZSLfXlAD4kWhiyq/u0Yt8oZDtRQ8lGhQaCXo2rl37KNjeU0GjJuwr4P3oeZ++ROfofsKNBqR5LTO8aXyWQ==",
|
"integrity": "sha512-uz2ZvfgXbxqNwijjjbxrnvALwpyODDcgc1T1N8N3rf/DXKQmaFwmB4LX4yyjggpwN2obdQLb2rgirX5ffCWYng==",
|
||||||
"cpu": [
|
"cpu": [
|
||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
@@ -1029,9 +1077,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@uppy/core": {
|
"node_modules/@uppy/core": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@uppy/core/-/core-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@uppy/core/-/core-6.0.1.tgz",
|
||||||
"integrity": "sha512-qaNqf4t2nxnbFFLSVmLr7Jw9TaA4fzvl8paR/ggwiOo5XFgAfbCFzjDzP8l2r5UzR6cCt3wS95QWvrm82UGZ+g==",
|
"integrity": "sha512-H+v4tOBPYY8Cf0JWoGa3+JPTl9Of8SBaVUH5TNwGgynncTWrQtuyGK91hv9wOjm0SFds3X5psPx1ArhngdSrBg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@transloadit/prettier-bytes": "^2.0.0",
|
"@transloadit/prettier-bytes": "^2.0.0",
|
||||||
@@ -1245,6 +1293,20 @@
|
|||||||
"node": "20 || >=22"
|
"node": "20 || >=22"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cacheable": {
|
||||||
|
"version": "2.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.5.0.tgz",
|
||||||
|
"integrity": "sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@cacheable/memory": "^2.2.0",
|
||||||
|
"@cacheable/utils": "^2.5.0",
|
||||||
|
"hookified": "^1.15.0",
|
||||||
|
"keyv": "^5.6.0",
|
||||||
|
"qified": "^0.10.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/chokidar": {
|
"node_modules/chokidar": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz",
|
||||||
@@ -1367,9 +1429,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint": {
|
"node_modules/eslint": {
|
||||||
"version": "10.9.1",
|
"version": "10.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-10.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/eslint/-/eslint-10.10.0.tgz",
|
||||||
"integrity": "sha512-9VaAkDURekixUQJy0oJYl2DcN6oKMfxay7XzaGYAWQwsb6qfKf+x76R2k1L8kb1boc+FyCAaTA9GmiKaaiaF+A==",
|
"integrity": "sha512-NPXn6r5zl4uET1DAVPaOwzX3rut4c0wcmw3dWJAfOsTM5+TogXo0DDjz8pwm/hL8cyVNpHqeK4JpN0NjnyFFNw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
@@ -1381,7 +1443,7 @@
|
|||||||
"@eslint/config-array": "^0.23.5",
|
"@eslint/config-array": "^0.23.5",
|
||||||
"@eslint/config-helpers": "^0.7.0",
|
"@eslint/config-helpers": "^0.7.0",
|
||||||
"@eslint/core": "^1.2.1",
|
"@eslint/core": "^1.2.1",
|
||||||
"@eslint/plugin-kit": "^0.7.2",
|
"@eslint/plugin-kit": "^0.7.3",
|
||||||
"@humanfs/node": "^0.16.6",
|
"@humanfs/node": "^0.16.6",
|
||||||
"@humanwhocodes/module-importer": "^1.0.1",
|
"@humanwhocodes/module-importer": "^1.0.1",
|
||||||
"@humanwhocodes/retry": "^0.4.2",
|
"@humanwhocodes/retry": "^0.4.2",
|
||||||
@@ -1396,7 +1458,7 @@
|
|||||||
"esquery": "^1.7.0",
|
"esquery": "^1.7.0",
|
||||||
"esutils": "^2.0.2",
|
"esutils": "^2.0.2",
|
||||||
"fast-deep-equal": "^3.1.3",
|
"fast-deep-equal": "^3.1.3",
|
||||||
"file-entry-cache": "^8.0.0",
|
"file-entry-cache": "11.1.5 || >11.1.6 <12",
|
||||||
"find-up": "^5.0.0",
|
"find-up": "^5.0.0",
|
||||||
"glob-parent": "^6.0.2",
|
"glob-parent": "^6.0.2",
|
||||||
"ignore": "^5.2.0",
|
"ignore": "^5.2.0",
|
||||||
@@ -1426,9 +1488,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-vue": {
|
"node_modules/eslint-plugin-vue": {
|
||||||
"version": "10.10.0",
|
"version": "10.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.11.0.tgz",
|
||||||
"integrity": "sha512-dL9x9rBHqqNcByWiLOHK6L0SB97V82/NC0cZRn9cXPjM7pCuWlpQQP9bFH4vjBv80ej1ZpzAkuD8zWH1o9bZbA==",
|
"integrity": "sha512-fGt38SsaPCZ2FmA3bX/3vOW2qdsPNx0/9x+7Aab6NMX++PhynMtK4LWC4vzXgfQBCqpUAler18H38GA+NBAd0Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -1605,16 +1667,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/file-entry-cache": {
|
"node_modules/file-entry-cache": {
|
||||||
"version": "8.0.0",
|
"version": "11.1.5",
|
||||||
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-11.1.5.tgz",
|
||||||
"integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
|
"integrity": "sha512-+PFTHITI08JIGhnNpGNI8T8inUpgZfk3GNEqfT9R2zZV2iFXg3CvqzSl/uEhs7TSGujYRELEANyDvS8Fj7+S7Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"flat-cache": "^4.0.0"
|
"flat-cache": "^6.1.23"
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=16.0.0"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/find-up": {
|
"node_modules/find-up": {
|
||||||
@@ -1635,17 +1694,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/flat-cache": {
|
"node_modules/flat-cache": {
|
||||||
"version": "4.0.1",
|
"version": "6.1.23",
|
||||||
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.23.tgz",
|
||||||
"integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
|
"integrity": "sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"flatted": "^3.2.9",
|
"cacheable": "^2.5.0",
|
||||||
"keyv": "^4.5.4"
|
"flatted": "^3.4.2",
|
||||||
},
|
"hookified": "^1.15.0"
|
||||||
"engines": {
|
|
||||||
"node": ">=16"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/flatted": {
|
"node_modules/flatted": {
|
||||||
@@ -1690,9 +1747,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/globals": {
|
"node_modules/globals": {
|
||||||
"version": "17.11.0",
|
"version": "17.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/globals/-/globals-17.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/globals/-/globals-17.12.0.tgz",
|
||||||
"integrity": "sha512-Z2I8hM+PbJDXQDq3Icgpzv+mPdwr68iZUU9d5WW4FuXfDUQfkZaZuvjMv42/5crNyw154+9+VWXbYrUgDXbxNw==",
|
"integrity": "sha512-cezEd/DTyyht9cvSSURyygXPfy04GtWO/5e6ZPvH7fCtjKz9PYOmuawphw1Ctd1f6C+5JypXfGD7ahNMXvevBA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -1702,6 +1759,26 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/hashery": {
|
||||||
|
"version": "1.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/hashery/-/hashery-1.5.1.tgz",
|
||||||
|
"integrity": "sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"hookified": "^1.15.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/hookified": {
|
||||||
|
"version": "1.15.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/hookified/-/hookified-1.15.1.tgz",
|
||||||
|
"integrity": "sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/ignore": {
|
"node_modules/ignore": {
|
||||||
"version": "5.3.2",
|
"version": "5.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
||||||
@@ -1770,13 +1847,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/json-buffer": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/json-schema-traverse": {
|
"node_modules/json-schema-traverse": {
|
||||||
"version": "0.4.1",
|
"version": "0.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||||
@@ -1804,13 +1874,13 @@
|
|||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/keyv": {
|
"node_modules/keyv": {
|
||||||
"version": "4.5.4",
|
"version": "5.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz",
|
||||||
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
|
"integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"json-buffer": "3.0.1"
|
"@keyv/serialize": "^1.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/levn": {
|
"node_modules/levn": {
|
||||||
@@ -2138,9 +2208,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/maplibre-gl": {
|
"node_modules/maplibre-gl": {
|
||||||
"version": "6.6.0",
|
"version": "6.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-6.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/maplibre-gl/-/maplibre-gl-6.8.0.tgz",
|
||||||
"integrity": "sha512-EQql6eZYPhbHvJpqY4AwoiuLkUfXFRBHk67S8mDtzNo1F/jAo7xAxunIzO7gJ1vwTcPMgrK9b64dqKHvnkTlDQ==",
|
"integrity": "sha512-+ZkjKTodsVLY0ewQThvXRxXQsclcsSgOm5LlnrBM3G8AloMJKt6Haw8mY4xrOl8T0WMqH6DTYjktZ9zGQXZd4w==",
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@mapbox/point-geometry": "^1.1.0",
|
"@mapbox/point-geometry": "^1.1.0",
|
||||||
@@ -2148,8 +2218,8 @@
|
|||||||
"@mapbox/unitbezier": "^1.0.0",
|
"@mapbox/unitbezier": "^1.0.0",
|
||||||
"@mapbox/vector-tile": "^3.0.0",
|
"@mapbox/vector-tile": "^3.0.0",
|
||||||
"@maplibre/geojson-vt": "^6.1.1",
|
"@maplibre/geojson-vt": "^6.1.1",
|
||||||
"@maplibre/maplibre-gl-style-spec": "^26.3.0",
|
"@maplibre/maplibre-gl-style-spec": "^26.4.1",
|
||||||
"@maplibre/mlt": "^1.2.0",
|
"@maplibre/mlt": "^1.2.1",
|
||||||
"@maplibre/vt-pbf": "^4.3.2",
|
"@maplibre/vt-pbf": "^4.3.2",
|
||||||
"@types/geojson": "^7946.0.16",
|
"@types/geojson": "^7946.0.16",
|
||||||
"earcut": "^3.2.3",
|
"earcut": "^3.2.3",
|
||||||
@@ -2414,9 +2484,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.5.26",
|
"version": "8.5.28",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz",
|
||||||
"integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==",
|
"integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -2433,7 +2503,7 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nanoid": "^3.3.17",
|
"nanoid": "^3.3.18",
|
||||||
"picocolors": "^1.1.1",
|
"picocolors": "^1.1.1",
|
||||||
"source-map-js": "^1.2.1"
|
"source-map-js": "^1.2.1"
|
||||||
},
|
},
|
||||||
@@ -2442,9 +2512,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postcss-selector-parser": {
|
"node_modules/postcss-selector-parser": {
|
||||||
"version": "7.1.5",
|
"version": "7.1.6",
|
||||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.5.tgz",
|
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.6.tgz",
|
||||||
"integrity": "sha512-KvvtD7SrlBP7dlgkBghEE3r84CABm5SmV2aNcG4oCA+qDnJ/tvKonFVvwWAyyWUEwxuNawdfEAZKP9zM3oZ2Uw==",
|
"integrity": "sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -2523,6 +2593,26 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/qified": {
|
||||||
|
"version": "0.10.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/qified/-/qified-0.10.1.tgz",
|
||||||
|
"integrity": "sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"hookified": "^2.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/qified/node_modules/hookified": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/hookified/-/hookified-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/quickselect": {
|
"node_modules/quickselect": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz",
|
||||||
@@ -2561,13 +2651,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/rolldown": {
|
"node_modules/rolldown": {
|
||||||
"version": "1.2.6",
|
"version": "1.2.8",
|
||||||
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.8.tgz",
|
||||||
"integrity": "sha512-vMM4q3aixf46GiF1Kok8jDPFsEpXgFWGjUHXNkNHNm+Y2adXAG2dbX91jkti3i0ZRsOlcmbuzAz1poObSHCmUA==",
|
"integrity": "sha512-Z67nTmhZe7anqnM/EjI392w5i/ANUinjip7QYsOyN37oayduxt3ksdX0hf5OOamkAd53BiIHfbfSzfUmzKFQqQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@oxc-project/types": "=0.147.0",
|
"@oxc-project/types": "=0.149.0",
|
||||||
"@rolldown/pluginutils": "^1.0.0"
|
"@rolldown/pluginutils": "^1.0.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -2577,27 +2667,27 @@
|
|||||||
"node": "^20.19.0 || >=22.12.0"
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@rolldown/binding-android-arm-eabi": "1.2.6",
|
"@rolldown/binding-android-arm-eabi": "1.2.8",
|
||||||
"@rolldown/binding-android-arm64": "1.2.6",
|
"@rolldown/binding-android-arm64": "1.2.8",
|
||||||
"@rolldown/binding-darwin-arm64": "1.2.6",
|
"@rolldown/binding-darwin-arm64": "1.2.8",
|
||||||
"@rolldown/binding-darwin-x64": "1.2.6",
|
"@rolldown/binding-darwin-x64": "1.2.8",
|
||||||
"@rolldown/binding-freebsd-x64": "1.2.6",
|
"@rolldown/binding-freebsd-x64": "1.2.8",
|
||||||
"@rolldown/binding-linux-arm-gnueabihf": "1.2.6",
|
"@rolldown/binding-linux-arm-gnueabihf": "1.2.8",
|
||||||
"@rolldown/binding-linux-arm64-gnu": "1.2.6",
|
"@rolldown/binding-linux-arm64-gnu": "1.2.8",
|
||||||
"@rolldown/binding-linux-arm64-musl": "1.2.6",
|
"@rolldown/binding-linux-arm64-musl": "1.2.8",
|
||||||
"@rolldown/binding-linux-ppc64-gnu": "1.2.6",
|
"@rolldown/binding-linux-ppc64-gnu": "1.2.8",
|
||||||
"@rolldown/binding-linux-s390x-gnu": "1.2.6",
|
"@rolldown/binding-linux-s390x-gnu": "1.2.8",
|
||||||
"@rolldown/binding-linux-x64-gnu": "1.2.6",
|
"@rolldown/binding-linux-x64-gnu": "1.2.8",
|
||||||
"@rolldown/binding-linux-x64-musl": "1.2.6",
|
"@rolldown/binding-linux-x64-musl": "1.2.8",
|
||||||
"@rolldown/binding-openharmony-arm64": "1.2.6",
|
"@rolldown/binding-openharmony-arm64": "1.2.8",
|
||||||
"@rolldown/binding-win32-arm64-msvc": "1.2.6",
|
"@rolldown/binding-win32-arm64-msvc": "1.2.8",
|
||||||
"@rolldown/binding-win32-x64-msvc": "1.2.6"
|
"@rolldown/binding-win32-x64-msvc": "1.2.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sass": {
|
"node_modules/sass": {
|
||||||
"version": "1.103.1",
|
"version": "1.104.0",
|
||||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.103.1.tgz",
|
"resolved": "https://registry.npmjs.org/sass/-/sass-1.104.0.tgz",
|
||||||
"integrity": "sha512-9icZURbP51S6S0QGoyaeqk9uB06GNWxsFYWfH5RgpFgqK5FA8tJcM3AdVxrZEVJ7dz+L87nG95gBKf4VuaMHGw==",
|
"integrity": "sha512-btHMApW2bgolvClhRW8AlQJzgI9lUB3pPSofBQQT+E46GWvf9o0TVQ13SYv5riWZVFyPN+JNz3TKW9XhBlc10w==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chokidar": "^5.0.0",
|
"chokidar": "^5.0.0",
|
||||||
|
|||||||
+9
-9
@@ -1,15 +1,7 @@
|
|||||||
{
|
{
|
||||||
"devDependencies": {
|
|
||||||
"@eslint/js": "^10.0.1",
|
|
||||||
"@vitejs/plugin-vue": "^6.0.8",
|
|
||||||
"eslint": "^10.9.1",
|
|
||||||
"eslint-plugin-vue": "^10.10.0",
|
|
||||||
"globals": "^17.11.0",
|
|
||||||
"vite": "^8.1.5"
|
|
||||||
},
|
|
||||||
"name": "livetrail",
|
"name": "livetrail",
|
||||||
"description": "Self-hosted live journey map combining SPOT GPS tracking, GPX routes, posts, and media",
|
"description": "Self-hosted live journey map combining SPOT GPS tracking, GPX routes, posts, and media",
|
||||||
"version": "3.0.0",
|
"version": "3.0.1",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -19,6 +11,14 @@
|
|||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "Franzz",
|
"author": "Franzz",
|
||||||
|
"devDependencies": {
|
||||||
|
"@eslint/js": "^10.0.1",
|
||||||
|
"@vitejs/plugin-vue": "^6.0.8",
|
||||||
|
"eslint": "^10.9.1",
|
||||||
|
"eslint-plugin-vue": "^10.10.0",
|
||||||
|
"globals": "^17.11.0",
|
||||||
|
"vite": "^8.1.5"
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-svg-core": "^7.2.0",
|
"@fortawesome/fontawesome-svg-core": "^7.2.0",
|
||||||
"@fortawesome/free-solid-svg-icons": "^7.2.0",
|
"@fortawesome/free-solid-svg-icons": "^7.2.0",
|
||||||
|
|||||||
-69644
File diff suppressed because it is too large
Load Diff
@@ -120,7 +120,8 @@
|
|||||||
"link_copied": "Link copied!",
|
"link_copied": "Link copied!",
|
||||||
"message": "Message",
|
"message": "Message",
|
||||||
"name": "Name",
|
"name": "Name",
|
||||||
"new_message": "New message"
|
"new_message": "New message",
|
||||||
|
"reply": "Reply to this message"
|
||||||
},
|
},
|
||||||
"project": {
|
"project": {
|
||||||
"wip": "In progress",
|
"wip": "In progress",
|
||||||
|
|||||||
@@ -120,7 +120,8 @@
|
|||||||
"link_copied": "¡Enlace copiado!",
|
"link_copied": "¡Enlace copiado!",
|
||||||
"message": "Mensaje",
|
"message": "Mensaje",
|
||||||
"name": "Nombre",
|
"name": "Nombre",
|
||||||
"new_message": "Mensaje nuevo"
|
"new_message": "Mensaje nuevo",
|
||||||
|
"reply": "Responder a este mensaje"
|
||||||
},
|
},
|
||||||
"project": {
|
"project": {
|
||||||
"wip": "En curso",
|
"wip": "En curso",
|
||||||
|
|||||||
@@ -120,7 +120,8 @@
|
|||||||
"link_copied": "Lien copié !",
|
"link_copied": "Lien copié !",
|
||||||
"message": "Message",
|
"message": "Message",
|
||||||
"name": "Nom",
|
"name": "Nom",
|
||||||
"new_message": "Nouveau message"
|
"new_message": "Nouveau message",
|
||||||
|
"reply": "Répondre à ce message"
|
||||||
},
|
},
|
||||||
"project": {
|
"project": {
|
||||||
"wip": "En cours",
|
"wip": "En cours",
|
||||||
|
|||||||
+76
-65
@@ -1,24 +1,26 @@
|
|||||||
<script>
|
<script>
|
||||||
import AppIcon from '@components/AppIcon';
|
import AppIcon from '@components/AppIcon';
|
||||||
|
import ProjectRelTime from '@components/ProjectRelTime';
|
||||||
import { getStyleProperty } from '@scripts/common';
|
import { getStyleProperty } from '@scripts/common';
|
||||||
|
|
||||||
/* lightbox (https://github.com/lokesh/lightbox2) converted to a vue component and improved to support videos */
|
/* lightbox (https://github.com/lokesh/lightbox2) converted to a vue component and improved to support videos */
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
AppIcon
|
AppIcon,
|
||||||
|
ProjectRelTime
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
alwaysShowNavOnTouchDevices: {type: Boolean, default: false},
|
alwaysShowNavOnTouchDevices: {type: Boolean, default: false},
|
||||||
positionFromTop: {type: Number, default: 50},
|
positionFromTop: {type: Number, default: 50},
|
||||||
wrapAround: {type: Boolean, default: false},
|
wrapAround: {type: Boolean, default: false},
|
||||||
disableScrolling: {type: Boolean, default: false},
|
disableScrolling: {type: Boolean, default: false},
|
||||||
sanitizeTitle: {type: Boolean, default: false},
|
|
||||||
hasVideo: {type: Boolean, default: true},
|
hasVideo: {type: Boolean, default: true},
|
||||||
maxWidth: {type: Number, default: null},
|
maxWidth: {type: Number, default: null},
|
||||||
maxHeight: {type: Number, default: null}
|
maxHeight: {type: Number, default: null}
|
||||||
},
|
},
|
||||||
emits: ['media-change', 'closing'],
|
emits: ['media-change', 'closing'],
|
||||||
|
inject: ['isMobile'],
|
||||||
data() {
|
data() {
|
||||||
/*
|
/*
|
||||||
fadeDuration/imageFadeDuration/resizeDuration read --trans-quick/--trans-slow
|
fadeDuration/imageFadeDuration/resizeDuration read --trans-quick/--trans-slow
|
||||||
@@ -44,6 +46,33 @@ export default {
|
|||||||
resizeDuration
|
resizeDuration
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
currentMedia() {
|
||||||
|
return this.album[this.currentImageIndex] || null;
|
||||||
|
},
|
||||||
|
relTimeLines() {
|
||||||
|
const media = this.currentMedia;
|
||||||
|
if(!media || this.isMobile()) return [];
|
||||||
|
|
||||||
|
const postedOn = {
|
||||||
|
key: 'posted',
|
||||||
|
icon: 'upload',
|
||||||
|
titleWrapperLangId: 'media.posted_on',
|
||||||
|
localTime: media.postedOnLocalTime,
|
||||||
|
siteTime: media.postedOnSiteTime,
|
||||||
|
offset: media.postedOnDayOffset
|
||||||
|
};
|
||||||
|
const takenOn = {
|
||||||
|
key: 'taken',
|
||||||
|
icon: media.type+'-shot',
|
||||||
|
titleWrapperLangId: 'media.'+media.type+'_taken_on',
|
||||||
|
localTime: media.takenOnLocalTime,
|
||||||
|
siteTime: media.takenOnSiteTime,
|
||||||
|
offset: media.takenOnDayOffset
|
||||||
|
};
|
||||||
|
return (media.source == 'marker') ? [takenOn, postedOn] : [postedOn, takenOn];
|
||||||
|
}
|
||||||
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.setVisible(this.$refs.overlay, false);
|
this.setVisible(this.$refs.overlay, false);
|
||||||
this.setVisible(this.$refs.lightboxEl, false);
|
this.setVisible(this.$refs.lightboxEl, false);
|
||||||
@@ -55,40 +84,18 @@ export default {
|
|||||||
this.$refs.nav.addEventListener('wheel', this.onWheel, {passive: false});
|
this.$refs.nav.addEventListener('wheel', this.onWheel, {passive: false});
|
||||||
this.$refs.nav.addEventListener('mousedown', this.onDragStart);
|
this.$refs.nav.addEventListener('mousedown', this.onDragStart);
|
||||||
window.addEventListener('mouseup', this.onDragEnd);
|
window.addEventListener('mouseup', this.onDragEnd);
|
||||||
|
|
||||||
this.enable();
|
|
||||||
},
|
},
|
||||||
beforeUnmount() {
|
beforeUnmount() {
|
||||||
this.disable();
|
|
||||||
if(this.resizeTimer) clearTimeout(this.resizeTimer);
|
if(this.resizeTimer) clearTimeout(this.resizeTimer);
|
||||||
window.removeEventListener('mouseup', this.onDragEnd);
|
window.removeEventListener('mouseup', this.onDragEnd);
|
||||||
window.removeEventListener('resize', this.sizeOverlay);
|
window.removeEventListener('resize', this.sizeOverlay);
|
||||||
window.removeEventListener('mousemove', this.onDragMove);
|
window.removeEventListener('mousemove', this.onDragMove);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
enable() {
|
open(album, startId, source) {
|
||||||
document.body.addEventListener('click', this.onBodyClick);
|
|
||||||
},
|
|
||||||
disable() {
|
|
||||||
document.body.removeEventListener('click', this.onBodyClick);
|
|
||||||
},
|
|
||||||
onBodyClick(event) {
|
|
||||||
const link = event.target.closest('a[data-lightbox], area[data-lightbox]');
|
|
||||||
if(!link) return;
|
|
||||||
event.preventDefault();
|
|
||||||
this.start(link);
|
|
||||||
},
|
|
||||||
start(link) {
|
|
||||||
this.sizeOverlay();
|
this.sizeOverlay();
|
||||||
this.album = [];
|
this.album = album.map((options) => this.mapMedia(options, source));
|
||||||
let imageNumber = 0;
|
const startIndex = Math.max(this.album.findIndex((media) => media.id == startId), 0);
|
||||||
const setName = link.getAttribute('data-lightbox');
|
|
||||||
|
|
||||||
const links = [...document.querySelectorAll(`${link.tagName}[data-lightbox="${CSS.escape(setName)}"]`)];
|
|
||||||
links.forEach((item, index) => {
|
|
||||||
this.addToAlbum(item);
|
|
||||||
if(item === link) imageNumber = index;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.fade(this.$refs.overlay, true, this.fadeDuration);
|
this.fade(this.$refs.overlay, true, this.fadeDuration);
|
||||||
this.fade(this.$refs.lightboxEl, true, this.fadeDuration);
|
this.fade(this.$refs.lightboxEl, true, this.fadeDuration);
|
||||||
@@ -96,7 +103,7 @@ export default {
|
|||||||
if(this.disableScrolling) document.body.classList.add('lb-disable-scrolling');
|
if(this.disableScrolling) document.body.classList.add('lb-disable-scrolling');
|
||||||
|
|
||||||
window.addEventListener('resize', this.sizeOverlay);
|
window.addEventListener('resize', this.sizeOverlay);
|
||||||
this.changeImage(imageNumber);
|
this.changeImage(startIndex);
|
||||||
},
|
},
|
||||||
end(dispose = false) {
|
end(dispose = false) {
|
||||||
this.disableKeyboardNav();
|
this.disableKeyboardNav();
|
||||||
@@ -117,47 +124,42 @@ export default {
|
|||||||
|
|
||||||
if(this.disableScrolling) document.body.classList.remove('lb-disable-scrolling');
|
if(this.disableScrolling) document.body.classList.remove('lb-disable-scrolling');
|
||||||
},
|
},
|
||||||
addToAlbum(link) {
|
mapMedia(options, source) {
|
||||||
const img = link.querySelector('img');
|
return {
|
||||||
this.album.push({
|
alt: '',
|
||||||
alt: link.getAttribute('data-alt') || '',
|
link: options.media_path,
|
||||||
link: link.getAttribute('href'),
|
orientation: parseInt(options.rotate || '0', 10),
|
||||||
title: link.getAttribute('data-title') || link.getAttribute('title') || '',
|
type: options.subtype || 'image',
|
||||||
orientation: parseInt(link.getAttribute('data-orientation') || '0', 10),
|
id: options.id_media,
|
||||||
type: link.getAttribute('data-type') || 'image',
|
width: parseInt(options.width || '0', 10),
|
||||||
id: link.getAttribute('data-id'),
|
height: parseInt(options.height || '0', 10),
|
||||||
width: parseInt(img?.getAttribute('width') || '0', 10),
|
source,
|
||||||
height: parseInt(img?.getAttribute('height') || '0', 10),
|
comment: options.comment || '',
|
||||||
set: link.getAttribute('data-lightbox') || ''
|
postedOnLocalTime: options.posted_on_formatted_time_local || '',
|
||||||
});
|
postedOnSiteTime: options.posted_on_formatted_time || '',
|
||||||
|
postedOnDayOffset: options.posted_on_day_offset || '',
|
||||||
|
takenOnLocalTime: options.taken_on_formatted_time_local || '',
|
||||||
|
takenOnSiteTime: options.taken_on_formatted_time || '',
|
||||||
|
takenOnDayOffset: options.taken_on_day_offset || ''
|
||||||
|
};
|
||||||
},
|
},
|
||||||
hasMediaAfterCurrent() {
|
hasMediaAfterCurrent() {
|
||||||
return this.currentImageIndex < this.album.length - 1;
|
return this.currentImageIndex < this.album.length - 1;
|
||||||
},
|
},
|
||||||
refreshAlbum() {
|
refreshAlbum(album) {
|
||||||
const current = this.album[this.currentImageIndex];
|
const current = this.currentMedia;
|
||||||
if(!current?.set) return;
|
if(!current) return;
|
||||||
|
|
||||||
const links = [...document.querySelectorAll(`a[data-lightbox="${CSS.escape(current.set)}"], area[data-lightbox="${CSS.escape(current.set)}"]`)];
|
const existingIds = new Set(this.album.map((media) => media.id));
|
||||||
if(!links.length) return;
|
album.forEach((options) => {
|
||||||
|
if(existingIds.has(options.id_media)) return;
|
||||||
|
|
||||||
const existingKeys = new Set(this.album.map((media) => this.getMediaKey(media)));
|
this.album.push(this.mapMedia(options, current.source));
|
||||||
links.forEach((link) => {
|
existingIds.add(options.id_media);
|
||||||
const key = this.getLinkMediaKey(link);
|
|
||||||
if(existingKeys.has(key)) return;
|
|
||||||
|
|
||||||
this.addToAlbum(link);
|
|
||||||
existingKeys.add(key);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.updateNav();
|
this.updateNav();
|
||||||
},
|
},
|
||||||
getMediaKey(media) {
|
|
||||||
return `${media.set}:${media.id}`;
|
|
||||||
},
|
|
||||||
getLinkMediaKey(link) {
|
|
||||||
return `${link.getAttribute('data-lightbox') || ''}:${link.getAttribute('data-id')}`;
|
|
||||||
},
|
|
||||||
getMaxSizes(mediaType) {
|
getMaxSizes(mediaType) {
|
||||||
let maxWidth = window.innerWidth - this.containerPadding.left - this.containerPadding.right;
|
let maxWidth = window.innerWidth - this.containerPadding.left - this.containerPadding.right;
|
||||||
let maxHeight = window.innerHeight - this.containerPadding.top - this.containerPadding.bottom - this.positionFromTop;
|
let maxHeight = window.innerHeight - this.containerPadding.top - this.containerPadding.bottom - this.positionFromTop;
|
||||||
@@ -346,16 +348,16 @@ export default {
|
|||||||
this.$refs.next.style.opacity = '';
|
this.$refs.next.style.opacity = '';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
hasCaption(media) {
|
||||||
|
return !!(media && (media.comment || media.postedOnSiteTime || media.takenOnSiteTime));
|
||||||
|
},
|
||||||
updateDetails(media = this.album[this.currentImageIndex], show = true) {
|
updateDetails(media = this.album[this.currentImageIndex], show = true) {
|
||||||
if(!media) return;
|
if(!media) return;
|
||||||
|
|
||||||
if(media.title) {
|
if(this.hasCaption(media)) {
|
||||||
if(this.sanitizeTitle) this.$refs.caption.textContent = media.title;
|
|
||||||
else this.$refs.caption.innerHTML = media.title;
|
|
||||||
if(show) this.fade(this.$refs.caption, true, 200);
|
if(show) this.fade(this.$refs.caption, true, 200);
|
||||||
else this.setVisible(this.$refs.caption, true);
|
else this.setVisible(this.$refs.caption, true);
|
||||||
} else {
|
} else {
|
||||||
this.$refs.caption.textContent = '';
|
|
||||||
this.setVisible(this.$refs.caption, false);
|
this.setVisible(this.$refs.caption, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -567,10 +569,19 @@ export default {
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="lb-dataContainer desktop" ref="dataContainer" @click="end()">
|
<div class="lb-dataContainer" ref="dataContainer" @click="end()">
|
||||||
<div class="lb-data">
|
<div class="lb-data">
|
||||||
<div class="lb-details">
|
<div class="lb-details">
|
||||||
<span class="lb-caption" ref="caption"></span>
|
<span class="lb-caption" ref="caption">
|
||||||
|
<template v-if="hasCaption(currentMedia)">
|
||||||
|
<span v-if="!!currentMedia?.comment" class="lb-caption-line comment">
|
||||||
|
<AppIcon icon="post" width="fixed" size="lg" text-classes="comment-text" :text="currentMedia.comment" />
|
||||||
|
</span>
|
||||||
|
<span v-for="line in relTimeLines" :key="line.key" class="lb-caption-line">
|
||||||
|
<ProjectRelTime :icon="line.icon" :titleWrapperLangId="line.titleWrapperLangId" :localTime="line.localTime" :siteTime="line.siteTime" :offset="line.offset" />
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="lb-closeContainer">
|
<div class="lb-closeContainer">
|
||||||
<a class="lb-close" ref="closeButton" href="#" role="button" @click.prevent.stop="end()" @keyup="onCloseKeyup">
|
<a class="lb-close" ref="closeButton" href="#" role="button" @click.prevent.stop="end()" @keyup="onCloseKeyup">
|
||||||
|
|||||||
+20
-11
@@ -69,6 +69,9 @@ export default {
|
|||||||
isMarkerVisible: (oLngLat) => this.$refs.mapCtrl.isMarkerVisible(oLngLat),
|
isMarkerVisible: (oLngLat) => this.$refs.mapCtrl.isMarkerVisible(oLngLat),
|
||||||
findMarkerByMediaId: (iMediaId) => this.$refs.mapCtrl.findMarkerByMediaId(iMediaId)
|
findMarkerByMediaId: (iMediaId) => this.$refs.mapCtrl.findMarkerByMediaId(iMediaId)
|
||||||
},
|
},
|
||||||
|
lightbox: {
|
||||||
|
open: (iMediaId, sSource) => this.openLightbox(iMediaId, sSource)
|
||||||
|
},
|
||||||
project: this
|
project: this
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -119,13 +122,19 @@ export default {
|
|||||||
const pMapReady = this.initProjectMap();
|
const pMapReady = this.initProjectMap();
|
||||||
await this.feed.init(pMapReady);
|
await this.feed.init(pMapReady);
|
||||||
},
|
},
|
||||||
|
openLightbox(iMediaId, sSource) {
|
||||||
|
const aoAlbum = (sSource == 'marker')
|
||||||
|
? (this.$refs.mapCtrl.findMarkerByMediaId(iMediaId)?.medias || [])
|
||||||
|
: this.feed.posts.filter((oPost) => oPost.type == 'media');
|
||||||
|
this.$refs.lightbox.open(aoAlbum, iMediaId, sSource);
|
||||||
|
},
|
||||||
async onLightboxMediaChange(oMedia) {
|
async onLightboxMediaChange(oMedia) {
|
||||||
this.hash.items = [this.project.codename, 'media', oMedia.id];
|
this.hash.items = [this.project.codename, 'media', oMedia.id];
|
||||||
if(oMedia.set == 'post-medias') {
|
if(oMedia.source == 'post') {
|
||||||
(await this.feed.findPost('media', oMedia.id))?.panMapToMarker();
|
(await this.feed.findPost('media', oMedia.id))?.panMapToMarker();
|
||||||
if(!this.$refs.lightbox.hasMediaAfterCurrent()) {
|
if(!this.$refs.lightbox.hasMediaAfterCurrent()) {
|
||||||
await this.feed.getNextFeed();
|
await this.feed.getNextFeed();
|
||||||
this.$refs.lightbox.refreshAlbum();
|
this.$refs.lightbox.refreshAlbum(this.feed.posts.filter((oPost) => oPost.type == 'media'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -220,14 +229,6 @@ export default {
|
|||||||
v-model:base-map="baseMap"
|
v-model:base-map="baseMap"
|
||||||
:terrain-enabled="terrainEnabled"
|
:terrain-enabled="terrainEnabled"
|
||||||
/>
|
/>
|
||||||
<Lightbox
|
|
||||||
ref="lightbox"
|
|
||||||
:always-show-nav-on-touch-devices="true"
|
|
||||||
:position-from-top="0"
|
|
||||||
:has-video="true"
|
|
||||||
@media-change="onLightboxMediaChange"
|
|
||||||
@closing="onLightboxClosing"
|
|
||||||
/>
|
|
||||||
<ProjectSettings
|
<ProjectSettings
|
||||||
:ref="setSettings"
|
:ref="setSettings"
|
||||||
:projects="projectOptions"
|
:projects="projectOptions"
|
||||||
@@ -247,5 +248,13 @@ export default {
|
|||||||
@new-markers="addNewMarkers"
|
@new-markers="addNewMarkers"
|
||||||
@toggle="(bIsOpen, iAnimDuration) => onPanelToggle('right', bIsOpen, iAnimDuration)"
|
@toggle="(bIsOpen, iAnimDuration) => onPanelToggle('right', bIsOpen, iAnimDuration)"
|
||||||
/>
|
/>
|
||||||
|
<Lightbox
|
||||||
|
ref="lightbox"
|
||||||
|
:always-show-nav-on-touch-devices="true"
|
||||||
|
:position-from-top="0"
|
||||||
|
:has-video="true"
|
||||||
|
@media-change="onLightboxMediaChange"
|
||||||
|
@closing="onLightboxClosing"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import Simplebar from 'simplebar-vue';
|
|||||||
|
|
||||||
import AppIcon from '@components/AppIcon';
|
import AppIcon from '@components/AppIcon';
|
||||||
import ProjectPost from '@components/ProjectPost';
|
import ProjectPost from '@components/ProjectPost';
|
||||||
|
import { createSwipeToClose, initialSwipeState } from '@scripts/swipeToClose';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -26,7 +27,7 @@ export default {
|
|||||||
isOpen: false,
|
isOpen: false,
|
||||||
posts: [],
|
posts: [],
|
||||||
refreshRate: 60,
|
refreshRate: 60,
|
||||||
swipe: {x: null, y: null}
|
swipe: initialSwipeState()
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
emits: ['request-last-update', 'new-markers', 'toggle'],
|
emits: ['request-last-update', 'new-markers', 'toggle'],
|
||||||
@@ -35,7 +36,9 @@ export default {
|
|||||||
return {
|
return {
|
||||||
feed: {
|
feed: {
|
||||||
checkNewFeed: this.checkNewFeed,
|
checkNewFeed: this.checkNewFeed,
|
||||||
toggle: this.toggle
|
toggle: this.toggle,
|
||||||
|
reply: this.reply,
|
||||||
|
findLinkedPost: this.findLinkedPost
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@@ -74,7 +77,6 @@ export default {
|
|||||||
this.refIdLast = 0;
|
this.refIdLast = 0;
|
||||||
this.firstChunk = true;
|
this.firstChunk = true;
|
||||||
this.posts = [];
|
this.posts = [];
|
||||||
this.swipe = {x: null, y: null};
|
|
||||||
|
|
||||||
this.toggle(!this.isMobile(), 0);
|
this.toggle(!this.isMobile(), 0);
|
||||||
this.getScrollElement().scrollTop = 0;
|
this.getScrollElement().scrollTop = 0;
|
||||||
@@ -90,7 +92,7 @@ export default {
|
|||||||
getScrollElement() {
|
getScrollElement() {
|
||||||
return this.$refs.feedSimpleBar?.scrollElement;
|
return this.$refs.feedSimpleBar?.scrollElement;
|
||||||
},
|
},
|
||||||
async findLinkedPost(sPostType, iPostId, pMapIsReady) {
|
async findLinkedPost(sPostType, iPostId, pMapIsReady=Promise.resolve()) {
|
||||||
let vPost = await this.findPost(sPostType, iPostId, true);
|
let vPost = await this.findPost(sPostType, iPostId, true);
|
||||||
if(vPost) {
|
if(vPost) {
|
||||||
await pMapIsReady;
|
await pMapIsReady;
|
||||||
@@ -160,23 +162,7 @@ export default {
|
|||||||
|
|
||||||
if((box.scrollTop + box.clientHeight) / (content?.offsetHeight || 1) >= 0.8) this.getNextFeed();
|
if((box.scrollTop + box.clientHeight) / (content?.offsetHeight || 1) >= 0.8) this.getNextFeed();
|
||||||
},
|
},
|
||||||
onTouchStart(oEvent) {
|
...createSwipeToClose(1),
|
||||||
if(!this.isMobile() || !this.isOpen || oEvent.touches.length != 1) return;
|
|
||||||
|
|
||||||
const oTouch = oEvent.touches[0];
|
|
||||||
this.swipe = {x: oTouch.clientX, y: oTouch.clientY};
|
|
||||||
},
|
|
||||||
onTouchEnd(oEvent) {
|
|
||||||
const oTouch = oEvent.changedTouches[0];
|
|
||||||
if(!oTouch || this.swipe.x === null) return;
|
|
||||||
|
|
||||||
const iDeltaX = oTouch.clientX - this.swipe.x;
|
|
||||||
const iDeltaY = oTouch.clientY - this.swipe.y;
|
|
||||||
|
|
||||||
if(iDeltaX > 80 && Math.abs(iDeltaX) > Math.abs(iDeltaY) * 1.5) this.toggle();
|
|
||||||
|
|
||||||
this.swipe = {x: null, y: null};
|
|
||||||
},
|
|
||||||
setUpdateTimer(iSeconds) {
|
setUpdateTimer(iSeconds) {
|
||||||
if(typeof this.feedTimer != 'undefined') clearTimeout(this.feedTimer);
|
if(typeof this.feedTimer != 'undefined') clearTimeout(this.feedTimer);
|
||||||
if(iSeconds >= 0) this.feedTimer = setTimeout(this.onUpdateTimer, iSeconds * 1000);
|
if(iSeconds >= 0) this.feedTimer = setTimeout(this.onUpdateTimer, iSeconds * 1000);
|
||||||
@@ -206,6 +192,9 @@ export default {
|
|||||||
if(aoMarkers.length > 0) this.$emit('new-markers', aoMarkers);
|
if(aoMarkers.length > 0) this.$emit('new-markers', aoMarkers);
|
||||||
this.$emit('request-last-update');
|
this.$emit('request-last-update');
|
||||||
},
|
},
|
||||||
|
reply(oQuote) {
|
||||||
|
this.$refs.poster?.addQuote(oQuote);
|
||||||
|
},
|
||||||
toggle(bShow, iAnimDuration=500) {
|
toggle(bShow, iAnimDuration=500) {
|
||||||
this.isOpen = (typeof bShow == 'boolean')?bShow:(!this.isOpen);
|
this.isOpen = (typeof bShow == 'boolean')?bShow:(!this.isOpen);
|
||||||
this.$emit('toggle', this.isOpen, iAnimDuration);
|
this.$emit('toggle', this.isOpen, iAnimDuration);
|
||||||
@@ -219,11 +208,11 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div id="feed" class="panel panel-right" @touchstart.passive="onTouchStart" @touchend.passive="onTouchEnd">
|
<div id="feed" class="panel panel-right" @touchstart.passive="onTouchStart" @touchmove.passive="onTouchMove" @touchend.passive="onTouchEnd">
|
||||||
<Simplebar id="feed-panel" class="panel-content" ref="feedSimpleBar" :aria-busy="loading">
|
<Simplebar id="feed-panel" class="panel-content" ref="feedSimpleBar" :aria-busy="loading">
|
||||||
<div id="feed-header">
|
<div id="feed-header">
|
||||||
<ProjectPost v-if="modeHisto" :options="{type: 'archived', headerless: true}" />
|
<ProjectPost v-if="modeHisto" :options="{type: 'archived', headerless: true}" />
|
||||||
<ProjectPost v-else :options="{type: 'poster', relative_time: lang.get('post.new_message')}" />
|
<ProjectPost v-else :options="{type: 'poster', relative_time: lang.get('post.new_message')}" ref="poster" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="project" v-show="!loadingPost" id="feed-posts">
|
<div v-if="project" v-show="!loadingPost" id="feed-posts">
|
||||||
<ProjectPost v-for="post in posts" :key="post.ref" :options="post" ref="posts" />
|
<ProjectPost v-for="post in posts" :key="post.ref" :options="post" ref="posts" />
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export default {
|
|||||||
baseMap: String
|
baseMap: String
|
||||||
},
|
},
|
||||||
emits: ['update:base-map'],
|
emits: ['update:base-map'],
|
||||||
inject: ['lang', 'consts', 'isMobile', 'projects', 'hash'],
|
inject: ['lang', 'consts', 'isMobile', 'projects', 'hash', 'lightbox'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
map: null,
|
map: null,
|
||||||
@@ -331,7 +331,9 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
findMarkerByMediaId(iMediaId) {
|
findMarkerByMediaId(iMediaId) {
|
||||||
return this.markers.find((oMarker) => (oMarker.medias || []).some((oMedia) => oMedia.id_media == iMediaId)) || null;
|
return this.markers.find((oMarker) => oMarker.type == 'media' && oMarker.id == iMediaId) //Look for an actual media marker first
|
||||||
|
|| this.markers.find((oMarker) => (oMarker.medias || []).some((oMedia) => oMedia.id_media == iMediaId)) //Look for a media within a message marker
|
||||||
|
|| null;
|
||||||
},
|
},
|
||||||
openMarkerPopup(iMarkerId, sMarkerType) {
|
openMarkerPopup(iMarkerId, sMarkerType) {
|
||||||
let oMarker = this.markers.find((oCandidate) => oCandidate.id == iMarkerId && oCandidate.type == sMarkerType);
|
let oMarker = this.markers.find((oCandidate) => oCandidate.id == iMarkerId && oCandidate.type == sMarkerType);
|
||||||
@@ -370,6 +372,7 @@ export default {
|
|||||||
.provide('lang', this.lang)
|
.provide('lang', this.lang)
|
||||||
.provide('consts', this.consts)
|
.provide('consts', this.consts)
|
||||||
.provide('isMobile', this.isMobile)
|
.provide('isMobile', this.isMobile)
|
||||||
|
.provide('lightbox', this.lightbox)
|
||||||
.mount($Popup);
|
.mount($Popup);
|
||||||
},
|
},
|
||||||
closePopup() {
|
closePopup() {
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
<script>
|
<script>
|
||||||
import appIcon from '@components/AppIcon';
|
import appIcon from '@components/AppIcon';
|
||||||
import projectRelTime from '@components/ProjectRelTime';
|
|
||||||
import projectMapLink from '@components/ProjectMapLink';
|
import projectMapLink from '@components/ProjectMapLink';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
appIcon,
|
appIcon,
|
||||||
projectRelTime,
|
|
||||||
projectMapLink
|
projectMapLink
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
@@ -14,22 +12,11 @@ export default {
|
|||||||
type: String
|
type: String
|
||||||
},
|
},
|
||||||
emits: ['opening-lightbox'],
|
emits: ['opening-lightbox'],
|
||||||
data() {
|
inject: ['lang', 'isMobile', 'lightbox'],
|
||||||
return {
|
|
||||||
title:''
|
|
||||||
};
|
|
||||||
},
|
|
||||||
inject: ['lang', 'isMobile'],
|
|
||||||
mounted() {
|
|
||||||
this.title =
|
|
||||||
(this.$refs.comment?this.$refs.comment.outerHTML:'') +
|
|
||||||
this.$refs[this.type=='marker'?'takenon':'postedon'].outerHTML +
|
|
||||||
this.$refs[this.type=='marker'?'postedon':'takenon'].outerHTML
|
|
||||||
;
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
openMedia() {
|
openMedia() {
|
||||||
this.$refs.link.click();
|
this.$emit('opening-lightbox', this.options);
|
||||||
|
this.lightbox.open(this.options.id_media, this.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -39,15 +26,9 @@ export default {
|
|||||||
<a
|
<a
|
||||||
class="media-link drill"
|
class="media-link drill"
|
||||||
:href="options.media_path"
|
:href="options.media_path"
|
||||||
:data-lightbox="type+'-medias'"
|
@click.prevent="openMedia"
|
||||||
:data-type="options.subtype"
|
|
||||||
:data-id="options.id_media"
|
|
||||||
:data-title="title"
|
|
||||||
:data-orientation="options.rotate"
|
|
||||||
@click="$emit('opening-lightbox', $event)"
|
|
||||||
ref="link"
|
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:src="options.thumb_path"
|
:src="options.thumb_path"
|
||||||
:width="options.width"
|
:width="options.width"
|
||||||
:height="options.height"
|
:height="options.height"
|
||||||
@@ -65,27 +46,4 @@ export default {
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<div style="display:none">
|
|
||||||
<span v-if="options.comment" ref="comment" class="lb-caption-line comment desktop">
|
|
||||||
<appIcon icon="post" width="fixed" size="lg" text-classes="comment-text" :text="options.comment" />
|
|
||||||
</span>
|
|
||||||
<span ref="postedon" class="lb-caption-line">
|
|
||||||
<projectRelTime
|
|
||||||
icon="upload"
|
|
||||||
titleWrapperLangId="media.posted_on"
|
|
||||||
:localTime="options.posted_on_formatted_time_local"
|
|
||||||
:siteTime="options.posted_on_formatted_time"
|
|
||||||
:offset="options.posted_on_day_offset"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
<span ref="takenon" class="lb-caption-line">
|
|
||||||
<projectRelTime
|
|
||||||
:icon="options.subtype+'-shot'"
|
|
||||||
:titleWrapperLangId="'media.'+options.subtype+'_taken_on'"
|
|
||||||
:localTime="options.taken_on_formatted_time_local"
|
|
||||||
:siteTime="options.taken_on_formatted_time"
|
|
||||||
:offset="options.taken_on_day_offset"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
import projectMediaLink from '@components/ProjectMediaLink';
|
import projectMediaLink from '@components/ProjectMediaLink';
|
||||||
import projectMapLink from '@components/ProjectMapLink';
|
import projectMapLink from '@components/ProjectMapLink';
|
||||||
import projectRelTime from '@components/ProjectRelTime';
|
import projectRelTime from '@components/ProjectRelTime';
|
||||||
|
import projectPostQuote from '@components/ProjectPostQuote';
|
||||||
|
import projectPostSignature from '@components/ProjectPostSignature';
|
||||||
import { LngLat } from 'maplibre-gl';
|
import { LngLat } from 'maplibre-gl';
|
||||||
import { copyTextToClipboard } from '@scripts/common';
|
import { copyTextToClipboard } from '@scripts/common';
|
||||||
|
|
||||||
@@ -17,7 +19,9 @@
|
|||||||
appButton,
|
appButton,
|
||||||
projectMediaLink,
|
projectMediaLink,
|
||||||
projectMapLink,
|
projectMapLink,
|
||||||
projectRelTime
|
projectRelTime,
|
||||||
|
projectPostQuote,
|
||||||
|
projectPostSignature
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
options: Object
|
options: Object
|
||||||
@@ -31,11 +35,14 @@
|
|||||||
anchorVisible: ['message', 'media', 'post'].includes(this.options.type),
|
anchorVisible: ['message', 'media', 'post'].includes(this.options.type),
|
||||||
anchorTitle: this.lang.get('post.copy_to_clipboard'),
|
anchorTitle: this.lang.get('post.copy_to_clipboard'),
|
||||||
anchorIcon: 'link',
|
anchorIcon: 'link',
|
||||||
|
replyTitle: this.lang.get('post.reply'),
|
||||||
popupRequested: false,
|
popupRequested: false,
|
||||||
mouseOverDrill: false,
|
mouseOverDrill: false,
|
||||||
postMessage: '',
|
postMessage: '',
|
||||||
|
quote: null,
|
||||||
sending: false,
|
sending: false,
|
||||||
focusZoomLevel: 15
|
focusZoomLevel: 15,
|
||||||
|
panAnimDuration: 500 //ms
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
inject: ['api', 'lang', 'project', 'feed', 'user', 'map', 'hash', 'consts', 'isMobile', 'getAnchor'],
|
inject: ['api', 'lang', 'project', 'feed', 'user', 'map', 'hash', 'consts', 'isMobile', 'getAnchor'],
|
||||||
@@ -65,8 +72,13 @@
|
|||||||
modeHisto() {
|
modeHisto() {
|
||||||
return (this.project?.project?.mode == this.consts.modes.histo);
|
return (this.project?.project?.mode == this.consts.modes.histo);
|
||||||
},
|
},
|
||||||
|
replyVisible() {
|
||||||
|
return this.anchorVisible && !this.modeHisto;
|
||||||
|
},
|
||||||
relTime() {
|
relTime() {
|
||||||
return this.modeHisto?(this.options.formatted_time || '').substr(0, 10):this.options.relative_time;
|
return this.modeHisto?
|
||||||
|
(this.options.formatted_time || '').substr(0, 10):
|
||||||
|
this.options.relative_time;
|
||||||
},
|
},
|
||||||
relatedMarker() {
|
relatedMarker() {
|
||||||
//Find corresponding marker
|
//Find corresponding marker
|
||||||
@@ -85,9 +97,57 @@
|
|||||||
relatedMarkerLatLng() {
|
relatedMarkerLatLng() {
|
||||||
let oRelatedMarker = this.relatedMarker;
|
let oRelatedMarker = this.relatedMarker;
|
||||||
return new LngLat(oRelatedMarker.longitude, oRelatedMarker.latitude);
|
return new LngLat(oRelatedMarker.longitude, oRelatedMarker.latitude);
|
||||||
|
},
|
||||||
|
messageLines() {
|
||||||
|
return (this.options.content || '').split('\n');
|
||||||
|
},
|
||||||
|
quoteRef() {
|
||||||
|
return this.options.ref_item?this.buildQuote(this.options.ref_item):null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
buildQuote(oItem) {
|
||||||
|
let sContent = '', sImage = null;
|
||||||
|
switch(oItem.type) {
|
||||||
|
case 'post':
|
||||||
|
sContent = oItem.content || '';
|
||||||
|
break;
|
||||||
|
case 'media':
|
||||||
|
sContent = oItem.comment || this.lang.get('media.posted_on', oItem.posted_on_formatted_time);
|
||||||
|
sImage = oItem.thumb_path;
|
||||||
|
break;
|
||||||
|
case 'message':
|
||||||
|
sContent = oItem.lat_dms+' '+oItem.lon_dms;
|
||||||
|
sImage = oItem.static_img_url;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: oItem.type,
|
||||||
|
id: oItem.id,
|
||||||
|
author: oItem.formatted_name || '',
|
||||||
|
gravatar: oItem.gravatar || null,
|
||||||
|
content: sContent,
|
||||||
|
image: sImage
|
||||||
|
};
|
||||||
|
},
|
||||||
|
reply() {
|
||||||
|
this.feed.reply(this.buildQuote(this.options));
|
||||||
|
},
|
||||||
|
goToQuote() {
|
||||||
|
if(this.quoteRef) this.feed.findLinkedPost(this.quoteRef.type, this.quoteRef.id);
|
||||||
|
},
|
||||||
|
addQuote(oQuote) {
|
||||||
|
this.quote = oQuote;
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.post.focus();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
formatQuote(oQuote) {
|
||||||
|
return (oQuote.author?oQuote.author+':\n':'')
|
||||||
|
+ oQuote.content.split('\n').map((sLine) => '> '+sLine).join('\n');
|
||||||
|
},
|
||||||
copyAnchor() {
|
copyAnchor() {
|
||||||
copyTextToClipboard(this.consts.server+this.anchorLink);
|
copyTextToClipboard(this.consts.server+this.anchorLink);
|
||||||
this.anchorTitle = this.lang.get('post.link_copied');
|
this.anchorTitle = this.lang.get('post.link_copied');
|
||||||
@@ -97,15 +157,13 @@
|
|||||||
this.anchorIcon = 'link';
|
this.anchorIcon = 'link';
|
||||||
}, 5000);
|
}, 5000);
|
||||||
},
|
},
|
||||||
panMapToMarker(iAnimDuration=500) {
|
panMapToMarker(bCloseFeed=false) {
|
||||||
if(typeof iAnimDuration !== 'number') iAnimDuration = 500; //panMapToMarker will provide event on direct call in vue template
|
|
||||||
|
|
||||||
this.popupRequested = true;
|
this.popupRequested = true;
|
||||||
|
|
||||||
if(this.isMobile()) this.feed.toggle(false);
|
if(bCloseFeed===true) this.feed.toggle(false);
|
||||||
this.hash.items = [this.project.project.codename, this.options.type, this.options.id];
|
this.hash.items = [this.project.project.codename, this.options.type, this.options.id];
|
||||||
|
|
||||||
return this.map.panToBetweenPanels(this.relatedMarkerLatLng, this.focusZoomLevel, iAnimDuration).then(() => {
|
return this.map.panToBetweenPanels(this.relatedMarkerLatLng, this.focusZoomLevel, this.panAnimDuration).then(() => {
|
||||||
this.openMarkerPopup();
|
this.openMarkerPopup();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -135,11 +193,14 @@
|
|||||||
{
|
{
|
||||||
id_project: this.project.project.id,
|
id_project: this.project.project.id,
|
||||||
name: this.user.name,
|
name: this.user.name,
|
||||||
content: this.postMessage
|
content: this.postMessage,
|
||||||
|
ref_type: this.quote?.type || '',
|
||||||
|
ref_id: this.quote?.id || 0
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.postMessage = '';
|
this.postMessage = '';
|
||||||
|
this.quote = null;
|
||||||
this.feed.checkNewFeed();
|
this.feed.checkNewFeed();
|
||||||
this.sending = false;
|
this.sending = false;
|
||||||
})
|
})
|
||||||
@@ -173,7 +234,10 @@
|
|||||||
<div class="header" v-if="!options.headerless">
|
<div class="header" v-if="!options.headerless">
|
||||||
<div class="index">
|
<div class="index">
|
||||||
<appIcon :icon="subType" :text="displayedId" width="auto" />
|
<appIcon :icon="subType" :text="displayedId" width="auto" />
|
||||||
<a v-if="anchorVisible" class="link desktop" @click="copyAnchor" ref="anchor" :href="anchorLink" :title="anchorTitle">
|
<a v-if="replyVisible" class="reply clickable" @click="reply" :title="replyTitle">
|
||||||
|
<appIcon :icon="'reply'" />
|
||||||
|
</a>
|
||||||
|
<a v-if="anchorVisible && !isMobile()" class="link" @click="copyAnchor" ref="anchor" :href="anchorLink" :title="anchorTitle">
|
||||||
<appIcon :icon="anchorIcon" />
|
<appIcon :icon="anchorIcon" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -186,7 +250,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<div v-if="options.type == 'message'" class="body-box">
|
<div v-if="options.type == 'message'" class="body-box">
|
||||||
<div class="drill" @click.prevent="panMapToMarker" @pointerenter="onMouseEnter" @pointerleave="onMouseLeave">
|
<div class="drill" @click.prevent="()=>{panMapToMarker(isMobile());}" @pointerenter="onMouseEnter" @pointerleave="onMouseLeave">
|
||||||
<span v-if="options.weather_icon && options.weather_icon!='unknown'" class="weather clickable" :title="lang.get('weather.'+options.weather_icon)">
|
<span v-if="options.weather_icon && options.weather_icon!='unknown'" class="weather clickable" :title="lang.get('weather.'+options.weather_icon)">
|
||||||
<appIcon :icon="options.weather_icon" :text="Math.round(options.weather_temp)+'°C'" text-classes="temperature" />
|
<appIcon :icon="options.weather_icon" :text="Math.round(options.weather_temp)+'°C'" text-classes="temperature" />
|
||||||
</span>
|
</span>
|
||||||
@@ -203,31 +267,31 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="options.type == 'media'" class="body-box">
|
<div v-else-if="options.type == 'media'" class="body-box" @pointerenter="onMouseEnter" @pointerleave="onMouseLeave">
|
||||||
<projectMediaLink :options="options" :type="'post'" ref="medialink" @opening-lightbox="panMapToMarker" />
|
<projectMediaLink :options="options" :type="'post'" ref="medialink" @opening-lightbox="panMapToMarker" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="options.type == 'post'">
|
<template v-else-if="options.type == 'post'">
|
||||||
<p class="message">{{ options.content }}</p>
|
<projectPostQuote v-if="quoteRef" :quote="quoteRef" class="clickable" @click="goToQuote" />
|
||||||
<p class="signature">
|
<div class="message">
|
||||||
<img v-if="options.gravatar" :src="'data:image/png;base64, '+options.gravatar" width="24" height="24" alt="--" />
|
<p v-for="(sLine, iIndex) in messageLines" :key="iIndex">{{ sLine }}</p>
|
||||||
<span v-else>-- </span>
|
</div>
|
||||||
<span>{{ options.formatted_name }}</span>
|
<projectPostSignature :name="options.formatted_name" :gravatar="options.gravatar" />
|
||||||
</p>
|
</template>
|
||||||
</div>
|
|
||||||
<div v-else-if="options.type == 'poster'" class="poster-form">
|
<div v-else-if="options.type == 'poster'" class="poster-form">
|
||||||
|
<projectPostQuote v-if="quote" :quote="quote" />
|
||||||
<textarea ref="post" name="post" :placeholder="lang.get('post.message')" class="autoExpand" rows="1" v-model="postMessage"></textarea>
|
<textarea ref="post" name="post" :placeholder="lang.get('post.message')" class="autoExpand" rows="1" v-model="postMessage"></textarea>
|
||||||
<div class="poster-actions">
|
<div class="poster-actions">
|
||||||
<input type="text" name="name" :placeholder="lang.get('post.name')" v-model="user.name" />
|
<input type="text" name="name" :placeholder="lang.get('post.name')" v-model="user.name" />
|
||||||
<appButton name="submit" :aria-label="lang.get('action.send')" :title="lang.get('action.send')" :icon="'send'" @click="send()" :iconClasses="sending?'flicker':''" />
|
<appButton name="submit" :aria-label="lang.get('action.send')" :title="lang.get('action.send')" :icon="'send'" @click="send()" :iconClasses="sending?'flicker':''" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="options.type == 'archived'">
|
<template v-else-if="options.type == 'archived'">
|
||||||
<p><appIcon :icon="'success'" /></p>
|
<p><appIcon :icon="'success'" /></p>
|
||||||
<p>{{ lang.get('project.modes.histo') }}</p>
|
<p>{{ lang.get('project.modes.histo') }}</p>
|
||||||
</div>
|
</template>
|
||||||
<div v-else-if="options.type == 'loading'">
|
<p v-else-if="options.type == 'loading'" class="flicker">
|
||||||
<p class="flicker"><appIcon :icon="'post'" /></p>
|
<appIcon :icon="'post'" />
|
||||||
</div>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<script>
|
||||||
|
import projectPostSignature from '@components/ProjectPostSignature';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
projectPostSignature
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
quote: Object
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :class="'quote '+quote.type">
|
||||||
|
<img v-if="quote.image" class="image" :src="quote.image" />
|
||||||
|
<div class="text">
|
||||||
|
<p class="content">{{ quote.content }}</p>
|
||||||
|
<projectPostSignature v-if="quote.author" :name="quote.author" :gravatar="quote.gravatar" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
name: String,
|
||||||
|
gravatar: String
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="signature">
|
||||||
|
<img v-if="gravatar" :src="'data:image/png;base64, '+gravatar" width="24" height="24" alt="--" />
|
||||||
|
<span v-else>-- </span>
|
||||||
|
<span>{{ name }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.signature {
|
||||||
|
text-align: right;
|
||||||
|
font-style: italic;
|
||||||
|
|
||||||
|
img {
|
||||||
|
vertical-align: baseline;
|
||||||
|
margin: 0 0.2em calc((1em - 24px)/2) 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -5,6 +5,7 @@ import AppIcon from '@components/AppIcon';
|
|||||||
import ProjectAccount from '@components/ProjectAccount';
|
import ProjectAccount from '@components/ProjectAccount';
|
||||||
import logoIconUrl from '@images/icons/favicon.svg';
|
import logoIconUrl from '@images/icons/favicon.svg';
|
||||||
import logoTitleUrl from '@images/logo_title.svg';
|
import logoTitleUrl from '@images/logo_title.svg';
|
||||||
|
import { createSwipeToClose, initialSwipeState } from '@scripts/swipeToClose';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -26,7 +27,8 @@ export default {
|
|||||||
isOpen: false,
|
isOpen: false,
|
||||||
lastUpdate: {unix_time: 0, relative_time: '', formatted_time: ''},
|
lastUpdate: {unix_time: 0, relative_time: '', formatted_time: ''},
|
||||||
logoIconUrl,
|
logoIconUrl,
|
||||||
logoTitleUrl
|
logoTitleUrl,
|
||||||
|
swipe: initialSwipeState()
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
emits: ['update:baseMap', 'update:projectCodeName', 'update:terrainEnabled', 'toggle'],
|
emits: ['update:baseMap', 'update:projectCodeName', 'update:terrainEnabled', 'toggle'],
|
||||||
@@ -81,13 +83,14 @@ export default {
|
|||||||
},
|
},
|
||||||
getWidth() {
|
getWidth() {
|
||||||
return this.$el.getBoundingClientRect().width;
|
return this.$el.getBoundingClientRect().width;
|
||||||
}
|
},
|
||||||
|
...createSwipeToClose(-1)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div id="settings" class="panel panel-left">
|
<div id="settings" class="panel panel-left" @touchstart.passive="onTouchStart" @touchmove.passive="onTouchMove" @touchend.passive="onTouchEnd">
|
||||||
<div id="settings-panel" class="panel-content">
|
<div id="settings-panel" class="panel-content">
|
||||||
<div class="settings-header settings-box">
|
<div class="settings-header settings-box">
|
||||||
<img :src="logoIconUrl" class="logo-icon clickable" :title="lang.get('project.overview')" @click="hash.items = []" />
|
<img :src="logoIconUrl" class="logo-icon clickable" :title="lang.get('project.overview')" @click="hash.items = []" />
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import {
|
|||||||
faPersonHiking,
|
faPersonHiking,
|
||||||
faPhotoFilm,
|
faPhotoFilm,
|
||||||
faPlus,
|
faPlus,
|
||||||
|
faReply,
|
||||||
faScrewdriverWrench,
|
faScrewdriverWrench,
|
||||||
faShoePrints,
|
faShoePrints,
|
||||||
faSun,
|
faSun,
|
||||||
@@ -134,6 +135,7 @@ const ICONS = {
|
|||||||
'image-shot': faCamera,
|
'image-shot': faCamera,
|
||||||
link: faLink,
|
link: faLink,
|
||||||
copied: faCheck,
|
copied: faCheck,
|
||||||
|
reply: faReply,
|
||||||
'find-me-spot': findMeSpot,
|
'find-me-spot': findMeSpot,
|
||||||
|
|
||||||
/* Feed - Poster */
|
/* Feed - Poster */
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/* Swipe-to-close gesture for a slide-in side panel */
|
||||||
|
|
||||||
|
// Initial value for the swipe data field createSwipeToClose()'s handlers expect on the component
|
||||||
|
export function initialSwipeState() {
|
||||||
|
return {x: null, y: null, dragging: false};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Builds touchstart/touchmove/touchend handlers for a panel that closes by
|
||||||
|
// dragging it towards its own off-screen side. iDirection is:
|
||||||
|
// +1 for a panel that opens from the right
|
||||||
|
// -1 for one that opens from the left
|
||||||
|
export function createSwipeToClose(iDirection) {
|
||||||
|
return {
|
||||||
|
onTouchStart(oEvent) {
|
||||||
|
if(!this.isMobile() || !this.isOpen || oEvent.touches.length != 1) return;
|
||||||
|
|
||||||
|
const oTouch = oEvent.touches[0];
|
||||||
|
this.swipe = {...initialSwipeState(), x: oTouch.clientX, y: oTouch.clientY};
|
||||||
|
},
|
||||||
|
onTouchMove(oEvent) {
|
||||||
|
if(this.swipe.x === null || oEvent.touches.length != 1) return;
|
||||||
|
|
||||||
|
const oTouch = oEvent.touches[0];
|
||||||
|
const iDeltaX = oTouch.clientX - this.swipe.x;
|
||||||
|
const iDeltaY = oTouch.clientY - this.swipe.y;
|
||||||
|
|
||||||
|
if(!this.swipe.dragging) {
|
||||||
|
//Only commit to a horizontal drag once the gesture is clearly not a vertical scroll
|
||||||
|
if(iDeltaX * iDirection <= 10 || Math.abs(iDeltaX) <= Math.abs(iDeltaY) * 1.5) return;
|
||||||
|
this.swipe.dragging = true;
|
||||||
|
this.$el.classList.add('moving');
|
||||||
|
}
|
||||||
|
|
||||||
|
const iDragX = iDirection * Math.min(Math.max(iDeltaX * iDirection, 0), this.getWidth());
|
||||||
|
this.$el.style.setProperty('--drag-x', `${iDragX}px`);
|
||||||
|
},
|
||||||
|
onTouchEnd(oEvent) {
|
||||||
|
const oTouch = oEvent.changedTouches[0];
|
||||||
|
if(!oTouch || this.swipe.x === null) return;
|
||||||
|
|
||||||
|
const iDeltaX = oTouch.clientX - this.swipe.x;
|
||||||
|
const iDeltaY = oTouch.clientY - this.swipe.y;
|
||||||
|
|
||||||
|
if(this.swipe.dragging) {
|
||||||
|
this.$el.classList.remove('moving');
|
||||||
|
this.$el.style.removeProperty('--drag-x');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(iDeltaX * iDirection > 80 && Math.abs(iDeltaX) > Math.abs(iDeltaY) * 1.5) this.toggle(false);
|
||||||
|
|
||||||
|
this.swipe = initialSwipeState();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -25,18 +25,22 @@ $post-input-bg: #ffffff;
|
|||||||
$post: $default;
|
$post: $default;
|
||||||
$post-hover: $default-hover;
|
$post-hover: $default-hover;
|
||||||
$post-bg: $default-bg;
|
$post-bg: $default-bg;
|
||||||
|
$post-bg-light: $default-bg-light;
|
||||||
|
$post-bg-trans: $default-bg-trans;
|
||||||
|
|
||||||
$message: $main;
|
$message: $main;
|
||||||
$message-flashy: $flashy;
|
$message-flashy: $flashy;
|
||||||
$message-hover: color.adjust($message, $lightness: -10%, $space: hsl);
|
$message-hover: color.adjust($message, $lightness: -10%, $space: hsl);
|
||||||
$message-bg: color.adjust($message, $lightness: 60%, $space: hsl);
|
$message-bg: color.adjust($message, $lightness: 60%, $space: hsl);
|
||||||
$message-bg-light: color.adjust($message, $lightness: 70%, $alpha: -0.3, $space: hsl);
|
$message-bg-light: color.adjust($message, $lightness: 65%, $space: hsl);
|
||||||
|
$message-bg-trans: color.adjust($message, $lightness: 70%, $alpha: -0.3, $space: hsl);
|
||||||
|
|
||||||
$media: hsl(214, 45%, 27%);
|
$media: hsl(214, 45%, 27%);
|
||||||
$media-flashy: hsl(193, 100%, 50%);
|
$media-flashy: hsl(193, 100%, 50%);
|
||||||
$media-hover: color.adjust($media, $lightness: -10%, $space: hsl);
|
$media-hover: color.adjust($media, $lightness: -10%, $space: hsl);
|
||||||
$media-bg: color.adjust($media, $lightness: 60%, $space: hsl);
|
$media-bg: color.adjust($media, $lightness: 60%, $space: hsl);
|
||||||
$media-bg-light: color.adjust($media, $lightness: 70%, $alpha: -0.3, $space: hsl);
|
$media-bg-light: color.adjust($media, $lightness: 65%, $space: hsl);
|
||||||
|
$media-bg-trans: color.adjust($media, $lightness: 70%, $alpha: -0.3, $space: hsl);
|
||||||
|
|
||||||
//Over image colors
|
//Over image colors
|
||||||
$over-img: #DDD;
|
$over-img: #DDD;
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ h2 {
|
|||||||
height: var(--track-width);
|
height: var(--track-width);
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
border-radius: var.$block-radius;
|
border-radius: var.$block-radius;
|
||||||
vertical-align: center;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
.desc {
|
.desc {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ body.lb-disable-scrolling {
|
|||||||
|
|
||||||
.lb-dataContainer {
|
.lb-dataContainer {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: color.$media-bg-light;
|
background-color: color.$media-bg-trans;
|
||||||
|
|
||||||
.lb-data {
|
.lb-data {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -58,6 +58,15 @@ body.lb-disable-scrolling {
|
|||||||
.lb-caption-line.comment {
|
.lb-caption-line.comment {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
|
||||||
|
.app-icon-with-text {
|
||||||
|
display: flex;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-text {
|
||||||
|
@include common.no-text-overflow();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,10 +10,6 @@
|
|||||||
--button-width: 51px;
|
--button-width: 51px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.desktop {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.projects {
|
.projects {
|
||||||
.panel-control-elem {
|
.panel-control-elem {
|
||||||
font-size: 2em;
|
font-size: 2em;
|
||||||
@@ -56,13 +52,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.panel.panel-right {
|
.panel.panel-right {
|
||||||
transform: translateX(calc(var(--button-width) + var.$block-spacing * 2));
|
transform: translateX(calc(var(--button-width) + var.$block-spacing * 2 + var(--drag-x, 0px)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.with-left-panel {
|
&.with-left-panel {
|
||||||
.panel.panel-left {
|
.panel.panel-left {
|
||||||
transform: translateX(0);
|
transform: translateX(var(--drag-x, 0px));
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel.panel-right {
|
.panel.panel-right {
|
||||||
|
|||||||
@@ -4,6 +4,66 @@
|
|||||||
|
|
||||||
#feed {
|
#feed {
|
||||||
#feed-panel {
|
#feed-panel {
|
||||||
|
.quote {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var.$elem-spacing;
|
||||||
|
padding: var.$elem-spacing;
|
||||||
|
border-radius: var.$block-radius;
|
||||||
|
border-left-width: var.$border-thick;
|
||||||
|
border-left-style: solid;
|
||||||
|
font-size: 0.9em;
|
||||||
|
box-shadow: var.$elem-shadow;
|
||||||
|
|
||||||
|
&.post {
|
||||||
|
border-left-color: color.$post;
|
||||||
|
background: color.$post-bg-light;
|
||||||
|
color: color.$post;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.message {
|
||||||
|
border-left-color: color.$message;
|
||||||
|
background: color.$message-bg-light;
|
||||||
|
color: color.$message;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.media {
|
||||||
|
border-left-color: color.$media;
|
||||||
|
background: color.$media-bg-light;
|
||||||
|
color: color.$media;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: 3 * var.$block-spacing;
|
||||||
|
height: 3 * var.$block-spacing;
|
||||||
|
object-fit: cover;
|
||||||
|
border-radius: var.$block-radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-width: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var.$text-spacing;
|
||||||
|
|
||||||
|
.content {
|
||||||
|
margin: 0;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
line-clamp: 3;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
transform: scaleX(90%) scaleY(90%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#feed-header {
|
#feed-header {
|
||||||
.poster {
|
.poster {
|
||||||
.poster-form {
|
.poster-form {
|
||||||
@@ -70,7 +130,7 @@
|
|||||||
gap: var.$elem-spacing;
|
gap: var.$elem-spacing;
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
|
|
||||||
.link {
|
.link, .reply {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
}
|
}
|
||||||
@@ -162,7 +222,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.comment {
|
.comment {
|
||||||
background: color.$message-bg-light;
|
background: color.$message-bg-trans;
|
||||||
}
|
}
|
||||||
|
|
||||||
.weather {
|
.weather {
|
||||||
@@ -203,21 +263,16 @@
|
|||||||
|
|
||||||
&.post {
|
&.post {
|
||||||
.body {
|
.body {
|
||||||
padding: 0 var.$block-spacing var.$elem-spacing;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
.message {
|
gap: var.$elem-spacing;
|
||||||
|
padding-bottom: var.$elem-spacing;
|
||||||
|
|
||||||
|
.message p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
|
||||||
|
|
||||||
.signature {
|
& + p {
|
||||||
margin: var.$elem-spacing 0 0 0;
|
margin-top: var.$text-spacing;
|
||||||
text-align: right;
|
|
||||||
font-style: italic;
|
|
||||||
|
|
||||||
img {
|
|
||||||
vertical-align: baseline;
|
|
||||||
margin: 0 0.2em calc((1em - 24px)/2) 0;
|
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,7 +304,7 @@
|
|||||||
|
|
||||||
&.drill {
|
&.drill {
|
||||||
.comment {
|
.comment {
|
||||||
background: color.$media-bg-light;
|
background: color.$media-bg-trans;
|
||||||
}
|
}
|
||||||
|
|
||||||
.drill-icon {
|
.drill-icon {
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ $panel-actual-width: min($panel-width, #{$panel-width-max});
|
|||||||
}
|
}
|
||||||
|
|
||||||
.panel.panel-left {
|
.panel.panel-left {
|
||||||
transform: translateX(0);
|
transform: translateX(var(--drag-x, 0px));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,17 +53,18 @@ $panel-actual-width: min($panel-width, #{$panel-width-max});
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
touch-action: pan-y;
|
||||||
width: #{$panel-width};
|
width: #{$panel-width};
|
||||||
max-width: calc(#{$panel-width-max});
|
max-width: calc(#{$panel-width-max});
|
||||||
transition: transform var.$trans-slow;
|
transition: transform var.$trans-slow;
|
||||||
|
|
||||||
&.moving {
|
&.moving {
|
||||||
cursor: grabbing;
|
cursor: grabbing;
|
||||||
transition: none;
|
transition: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.panel-left {
|
&.panel-left {
|
||||||
transform: translateX(-100%);
|
transform: translateX(calc(-100% + var(--drag-x, 0px)));
|
||||||
|
|
||||||
.panel-content {
|
.panel-content {
|
||||||
width: calc(100% - var.$block-spacing);
|
width: calc(100% - var.$block-spacing);
|
||||||
@@ -81,8 +82,8 @@ $panel-actual-width: min($panel-width, #{$panel-width-max});
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.panel-right {
|
&.panel-right {
|
||||||
transform: translateX(100vw);
|
transform: translateX(calc(100vw + var(--drag-x, 0px)));
|
||||||
|
|
||||||
.panel-content {
|
.panel-content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding-top: var.$block-spacing;
|
padding-top: var.$block-spacing;
|
||||||
|
|||||||
@@ -14,4 +14,8 @@ $elem-shadow: 0px 1px 1px color.$over-img-shadow;
|
|||||||
//Transitions
|
//Transitions
|
||||||
$trans-quick: 200ms;
|
$trans-quick: 200ms;
|
||||||
$trans-slow: 500ms;
|
$trans-slow: 500ms;
|
||||||
$zoom-scale: 1.15;
|
$zoom-scale: 1.15;
|
||||||
|
|
||||||
|
//Border
|
||||||
|
$border-thin: 1px;
|
||||||
|
$border-thick: 3px;
|
||||||
|
|||||||
Reference in New Issue
Block a user