Add project popup
All checks were successful
Deploy Spot / deploy (push) Successful in 38s

This commit is contained in:
2026-05-19 17:49:06 +02:00
parent 93a72c628e
commit c43539b640
6 changed files with 69 additions and 32 deletions

View File

@@ -106,6 +106,7 @@
"new_message": "New message" "new_message": "New message"
}, },
"project": { "project": {
"wip": "In progress",
"code_name": "Code name", "code_name": "Code name",
"end": "End", "end": "End",
"hikes": "Hikes", "hikes": "Hikes",

View File

@@ -106,6 +106,7 @@
"new_message": "Mensaje nuevo" "new_message": "Mensaje nuevo"
}, },
"project": { "project": {
"wip": "En curso",
"code_name": "Nombre clave", "code_name": "Nombre clave",
"end": "Fin", "end": "Fin",
"hikes": "Senderos", "hikes": "Senderos",

View File

@@ -106,6 +106,7 @@
"new_message": "Nouveau message" "new_message": "Nouveau message"
}, },
"project": { "project": {
"wip": "En cours",
"code_name": "Nom de code", "code_name": "Nom de code",
"end": "Arrivée", "end": "Arrivée",
"hikes": "Randonnées", "hikes": "Randonnées",

View File

@@ -144,12 +144,9 @@ class Project extends PhpObject {
case 2: $asProject['mode'] = self::MODE_HISTO; break; case 2: $asProject['mode'] = self::MODE_HISTO; break;
} }
$asProject['editable'] = $this->isModeEditable($asProject['mode']); $asProject['editable'] = $this->isModeEditable($asProject['mode']);
//$asProject['geofilepath'] = Spot::addTimestampToFilePath(GeoJson::getDistFilePath($sCodeName));
$asProject['gpxfilepath'] = Spot::addTimestampToFilePath(Gpx::getDistFilePath($sCodeName)); $asProject['gpxfilepath'] = Spot::addTimestampToFilePath(Gpx::getDistFilePath($sCodeName));
$asProject['codename'] = $sCodeName; $asProject['codename'] = $sCodeName;
$asProject['default'] = ($sCodeName == $sDefaultProjectCodeName); $asProject['default'] = ($sCodeName == $sDefaultProjectCodeName);
//$asProject['center'] = [$asProject['latitude'], $asProject['longitude']];
} }
return $bSpecificProj?$asProject:$asProjects; return $bSpecificProj?$asProject:$asProjects;
} }

View File

@@ -217,7 +217,10 @@ export default {
}, },
addMarkers: () => { addMarkers: () => {
this.addTrack(this.track); this.addTrack(this.track);
this.markers.forEach(oMarker => this.addMarker(oMarker)); this.markers.forEach(oMarker => this.addMarker(
oMarker,
() => this.openMarkerPopup(oMarker.id, oMarker.type)
));
} }
}); });
}, },
@@ -239,14 +242,16 @@ export default {
}, },
addMarkers: () => { addMarkers: () => {
for(const asProject of Object.values(this.projects)) { for(const asProject of Object.values(this.projects)) {
this.addMarker({ this.addMarker(
{
type: 'project',
subtype: 'project', subtype: 'project',
longitude: asProject.longitude, ...asProject,
latitude: asProject.latitude,
opacityWhenCovered: 0.3 opacityWhenCovered: 0.3
}, () => { },
this.hash.items = [asProject.codename]; () => {this.hash.items = [asProject.codename];},
}); (oEvent, oProject) => {this.openProjectPopup(oProject);}
);
} }
} }
}); });
@@ -352,26 +357,12 @@ export default {
this.map.on('mouseenter', 'track-hitbox', () => {this.map.getCanvas().style.cursor = 'pointer';}); this.map.on('mouseenter', 'track-hitbox', () => {this.map.getCanvas().style.cursor = 'pointer';});
this.map.on('mouseleave', 'track-hitbox', () => {this.map.getCanvas().style.cursor = '';}); this.map.on('mouseleave', 'track-hitbox', () => {this.map.getCanvas().style.cursor = '';});
}, },
openTrackPopup(oEvent) { openProjectPopup(oProject) {
this.closePopup(); this.closePopup();
this.openPopup({ this.openPopup({
lnglat: oEvent.lngLat, lnglat: [oProject.longitude, oProject.latitude],
options: this.projects.getTrackInfo(oEvent.features[0], this.track, this.lang), options: oProject,
}); offset: [0, -32] //FIXME
},
addMarker(oMarker, fClickCallback=null) {
const $Marker = document.createElement('div');
createApp(SpotIconStack, this.markerProps[oMarker.subtype]).mount($Marker);
new Marker({element: $Marker, anchor: 'bottom', opacityWhenCovered: oMarker.opacityWhenCovered ?? 0})
.setLngLat([oMarker.longitude, oMarker.latitude])
.addTo(this.map)
.getElement()
.addEventListener('click', (oEvent) => {
oEvent.preventDefault();
oEvent.stopPropagation();
if(fClickCallback) fClickCallback(oEvent, oMarker);
else this.openMarkerPopup(oMarker.id, oMarker.type);
}); });
}, },
openMarkerPopup(iMarkerId, sMarkerType) { openMarkerPopup(iMarkerId, sMarkerType) {
@@ -383,6 +374,13 @@ export default {
offset: [0, -32] //FIXME offset: [0, -32] //FIXME
}); });
}, },
openTrackPopup(oEvent) {
this.closePopup();
this.openPopup({
lnglat: oEvent.lngLat,
options: this.projects.getTrackInfo(oEvent.features[0], this.track, this.lang),
});
},
openPopup({lnglat, options={}, offset=[0, 0]} = {}) { openPopup({lnglat, options={}, offset=[0, 0]} = {}) {
const $Popup = document.createElement('div'); const $Popup = document.createElement('div');
this.popup.element = new Popup({ this.popup.element = new Popup({
@@ -414,6 +412,32 @@ export default {
this.popup.element = null; this.popup.element = null;
} }
}, },
addMarker(oMarker, fClickCallback=null, fHoverCallback=null) {
const $Marker = document.createElement('div');
createApp(SpotIconStack, this.markerProps[oMarker.subtype]).mount($Marker);
const $MarkerElement = new Marker({element: $Marker, anchor: 'bottom', opacityWhenCovered: oMarker.opacityWhenCovered ?? 0})
.setLngLat([oMarker.longitude, oMarker.latitude])
.addTo(this.map)
.getElement();
if(fClickCallback) {
$MarkerElement.addEventListener('click', (oEvent) => {
oEvent.preventDefault();
oEvent.stopPropagation();
fClickCallback(oEvent, oMarker);
});
}
if(fHoverCallback) {
$MarkerElement.addEventListener('mouseenter', (oEvent) => {
fHoverCallback(oEvent, oMarker);
});
$MarkerElement.addEventListener('mouseleave', () => {
this.closePopup();
});
}
},
getInitialMapBounds() { getInitialMapBounds() {
let oBounds = new LngLatBounds(); let oBounds = new LngLatBounds();
let oHashMarker; let oHashMarker;
@@ -527,7 +551,10 @@ export default {
//Add new Markers //Add new Markers
if(aoMarkers.length > 0) { if(aoMarkers.length > 0) {
this.markers.push(...aoMarkers); this.markers.push(...aoMarkers);
aoMarkers.forEach(oMarker => this.addMarker(oMarker)); aoMarkers.forEach(oMarker => this.addMarker(
oMarker,
() => this.openMarkerPopup(oMarker.id, oMarker.type)
));
} }
//Message Last Update //Message Last Update

View File

@@ -17,6 +17,13 @@ export default {
}, },
inject: ['lang', 'consts', 'isMobile'], inject: ['lang', 'consts', 'isMobile'],
computed: { computed: {
activeTimeInterval() {
if(this.options.mode == this.consts.modes.blog) return this.lang.get('project.wip');
const sYearFrom = this.options.active_from.substr(0, 4);
const sYearTo = this.options.active_to.substr(0, 4);
return (sYearFrom == sYearTo)?sYearFrom:(sYearFrom + '-' + sYearTo);
},
timeinfo() { timeinfo() {
return (this.options.type == 'media')? return (this.options.type == 'media')?
{ {
@@ -45,7 +52,7 @@ export default {
<template> <template>
<div :class="options.type+' '+options.subtype"> <div :class="options.type+' '+options.subtype">
<div class="header" v-if="options.type=='track'"> <div class="header" v-if="options.type == 'track' || options.type == 'project'">
<h1> <h1>
<spotIcon :icon="options.subtype" size="lg" :text="this.options.name" width="auto" :textClasses="options.subtype" /> <spotIcon :icon="options.subtype" size="lg" :text="this.options.name" width="auto" :textClasses="options.subtype" />
</h1> </h1>
@@ -60,6 +67,9 @@ export default {
<spotIcon :title="lang.get('stats.elevation_loss')" :icon="'elev-drop'" width="fixed" size="lg" :text="options.elev_drop+'m'" /> <spotIcon :title="lang.get('stats.elevation_loss')" :icon="'elev-drop'" width="fixed" size="lg" :text="options.elev_drop+'m'" />
</div> </div>
</div> </div>
<div v-else-if="options.type=='project'" class="section time">
<spotIcon icon="time" width="fixed" size="lg" :text="activeTimeInterval" />
</div>
<div v-else> <div v-else>
<div class="section time"> <div class="section time">
<projectRelTime :icon="timeinfo.icon" :localTime="localTime" :siteTime="timeinfo.site_time" :offset="timeinfo.offset" /> <projectRelTime :icon="timeinfo.icon" :localTime="localTime" :siteTime="timeinfo.site_time" :offset="timeinfo.offset" />