Fix message event in feed

This commit is contained in:
2026-01-16 21:46:51 +01:00
parent e7d4c840c2
commit b86d5d2cb1
2 changed files with 98 additions and 99 deletions

View File

@@ -32,8 +32,8 @@ export default {
feedSimpleBar: null, feedSimpleBar: null,
settingsPanelOpen: false, settingsPanelOpen: false,
markerSize: {width: 32, height: 32}, markerSize: {width: 32, height: 32},
project: {}, currProject: {},
projectCodename: null, currProjectCodeName: null,
modeHisto: false, modeHisto: false,
posts: [], posts: [],
nlFeedbacks: [], nlFeedbacks: [],
@@ -45,7 +45,8 @@ export default {
hikes: { hikes: {
colors:{'main':'#00ff78', 'off-track':'#0000ff', 'hitchhiking':'#FF7814'}, colors:{'main':'#00ff78', 'off-track':'#0000ff', 'hitchhiking':'#FF7814'},
width: 4 width: 4
} },
popup: null
}; };
}, },
computed: { computed: {
@@ -76,8 +77,8 @@ export default {
if(sOldBaseMap) this.map.setLayoutProperty(sOldBaseMap, 'visibility', 'none'); if(sOldBaseMap) this.map.setLayoutProperty(sOldBaseMap, 'visibility', 'none');
if(sNewBaseMap) this.map.setLayoutProperty(sNewBaseMap, 'visibility', 'visible'); if(sNewBaseMap) this.map.setLayoutProperty(sNewBaseMap, 'visibility', 'visible');
}, },
projectCodename(sNewCodeName, sOldCodeName) { currProjectCodeName(sNewCodeName, sOldCodeName) {
//console.log('change in projectCodename: '+sNewCodeName); //console.log('change in currProjectCodeName: '+sNewCodeName);
//this.toggleSettingsPanel(false); //this.toggleSettingsPanel(false);
this.$parent.setHash(this.$parent.hash.page, [sNewCodeName]); this.$parent.setHash(this.$parent.hash.page, [sNewCodeName]);
this.init(); this.init();
@@ -85,7 +86,14 @@ export default {
}, },
provide() { provide() {
return { return {
project: this.project map: {
panTo: this.panTo,
openMarkerPopup: this.openMarkerPopup
},
project: {
...this.$data,
toggleFeedPanel: this.toggleFeedPanel
}
}; };
}, },
inject: ['spot', 'projects', 'user'], inject: ['spot', 'projects', 'user'],
@@ -102,19 +110,19 @@ export default {
} }
}); });
this.projectCodename = (this.$parent.hash.items.length==0)?this.spot.vars('default_project_codename'):this.$parent.hash.items[0]; this.currProjectCodeName = (this.$parent.hash.items.length==0)?this.spot.vars('default_project_codename'):this.$parent.hash.items[0];
}, },
methods: { methods: {
init() { init() {
let bFirstLoad = (typeof this.project.codename == 'undefined'); let bFirstLoad = (typeof this.currProject.codename == 'undefined');
this.initProject(); this.initProject();
if(bFirstLoad) this.initLightbox(); if(bFirstLoad) this.initLightbox();
this.initFeed(); this.initFeed();
this.initMap(); this.initMap();
}, },
initProject() { initProject() {
this.project = this.projects[this.projectCodename]; this.currProject = this.projects[this.currProjectCodeName];
this.modeHisto = (this.project.mode == this.spot.consts.modes.histo); this.modeHisto = (this.currProject.mode == this.spot.consts.modes.histo);
this.feed = {loading:false, updatable:true, outOfData:false, refIdFirst:0, refIdLast:0, firstChunk:true}; this.feed = {loading:false, updatable:true, outOfData:false, refIdFirst:0, refIdLast:0, firstChunk:true};
this.posts = []; this.posts = [];
//this.baseMap = null; //this.baseMap = null;
@@ -153,7 +161,7 @@ export default {
}, },
async initMap() { async initMap() {
//Get Map Info //Get Map Info
const aoMarkers = await this.spot.get2('markers', {id_project: this.project.id}); const aoMarkers = await this.spot.get2('markers', {id_project: this.currProject.id});
this.baseMap = null; this.baseMap = null;
this.baseMaps = aoMarkers.maps; this.baseMaps = aoMarkers.maps;
this.messages = aoMarkers.messages; this.messages = aoMarkers.messages;
@@ -194,7 +202,7 @@ export default {
this.baseMap = this.baseMaps.filter((asBM) => asBM.default_map)[0].codename; this.baseMap = this.baseMaps.filter((asBM) => asBM.default_map)[0].codename;
//Get track //Get track
const oTrack = await this.spot.get2('geojson', {id_project: this.project.id}); const oTrack = await this.spot.get2('geojson', {id_project: this.currProject.id});
this.map.addSource('track', { this.map.addSource('track', {
'type': 'geojson', 'type': 'geojson',
'data': oTrack 'data': oTrack
@@ -237,38 +245,6 @@ export default {
'coordinates': [oMsg.longitude, oMsg.latitude] 'coordinates': [oMsg.longitude, oMsg.latitude]
} }
}); });
//Tooltip
/*
let $Tooltip = $($('<div>', {'class':'info-window'})
.append($('<h1>')
.addIcon('fa-message fa-lg', true)
.append($('<span>').text(this.spot.lang('post_message')+' '+this.spot.lang('counter', oMsg.displayed_id)))
.append($('<span>', {'class':'message-type'}).text('('+oMsg.type+')'))
)
.append($('<div>', {'class':'separator'}))
.append($('<p>', {'class':'coordinates'})
.addIcon('fa-coords fa-fw fa-lg', true)
.append(this.getGoogleMapsLink(oMsg))
)
.append($('<p>', {'class':'time'})
.addIcon('fa-time fa-fw fa-lg', true)
.append(oMsg.formatted_time+(this.project.mode==this.spot.consts.modes.blog?' ('+oMsg.relative_time+')':''))))[0];
const vTooltip = h(SpotIcon, {icon:'project', 'classes':'fa-fw', text:'hikes'});
//let vTooltip = h(SpotIcon, {icon:'project', 'classes':'fa-fw', text:'hikes'});
oPopup.setDOMContent(vTooltip);
new Marker({
element: $('<div style="width:'+this.markerSize.width+'px;height:'+this.markerSize.height+'px;"><span class="fa-stack"><i class="fa fa-message fa-stack-2x"></i><i class="fa fa-message-in fa-rotate-270 fa-stack-1x"></i></span></div>')[0],
anchor: 'bottom'
})
.setLngLat(new LngLat(oMsg.longitude, oMsg.latitude))
.setPopup(oPopup)
.addTo(this.map)
;
*/
} }
this.map.addSource('markers', aoMarkerSource); this.map.addSource('markers', aoMarkerSource);
const image = await this.map.loadImage('images/footprint_mapbox.png'); const image = await this.map.loadImage('images/footprint_mapbox.png');
@@ -283,38 +259,16 @@ export default {
//'icon-overlap': 'always' //'icon-overlap': 'always'
} }
}); });
this.map.on("click", "markers", (e) => {
var oPopup = new Popup({
anchor: 'bottom',
offset: [0, this.markerSize.height * -1],
closeButton: false
})
.setHTML('<div id="popup"></div>')
.setLngLat(e.lngLat)
.addTo(this.map);
let rProp = ref(e.features[0].properties);console.log(rProp); this.map.on('click', 'markers', (e) => {
const vPopup = defineComponent({ this.openMarkerPopup(e.features[0]);
extends: ProjectPopup,
setup: () => {
//console.log(rProp.value.medias);
provide('options', rProp.value);
provide('spot', this.spot);
provide('project', this.project);
return {'options': rProp.value, 'medias': JSON.parse(rProp.value.medias || '""'), 'spot':this.spot, 'project':this.project};
}
}); });
nextTick(() => {
createApp(vPopup).mount("#popup");
});
});
//Centering map //Centering map
let bOpenFeedPanel = !this.mobile; let bOpenFeedPanel = !this.mobile;
let oBounds = new LngLatBounds(); let oBounds = new LngLatBounds();
if( if(
this.project.mode == this.spot.consts.modes.blog && this.currProject.mode == this.spot.consts.modes.blog &&
this.messages.length > 0 && this.messages.length > 0 &&
this.$parent.hash.items[2] != 'message' this.$parent.hash.items[2] != 'message'
) { ) {
@@ -352,14 +306,69 @@ export default {
this.toggleFeedPanel(bOpenFeedPanel); this.toggleFeedPanel(bOpenFeedPanel);
}); });
this.map.on('idle', () => { this.map.on('idle', () => { });
});
//Legend //Legend
},
openMarkerPopup(oFeature) {
if(this.popup) {
this.popup.unmount();
this.popup = null;
}
//Convert ID Message to feature
if(typeof oFeature == 'number') {
const oMatchingFeatures = this.map.querySourceFeatures('markers', {
filter: ['==', ['get', 'id_message'], oFeature]
});
if(!oMatchingFeatures.length) {
console.warn('Marker not found: ', oFeature);
return;
}
else oFeature = oMatchingFeatures[0];
}
const $Popup = document.createElement('div');
const oPopup = new Popup({
anchor: 'bottom',
offset: [0, this.markerSize.height * -1],
closeButton: false
})
.setDOMContent($Popup)
.setLngLat(oFeature.geometry.coordinates)
.setMaxWidth(300)
.addTo(this.map);
const rProp = ref(oFeature.properties);
const vPopup = defineComponent({
extends: ProjectPopup,
setup: () => {
provide('spot', this.spot);
return {
options: rProp.value,
medias: JSON.parse(rProp.value.medias || '""'),
spot: this.spot,
project: this.currProject
};
}
});
nextTick(() => {
this.popup = createApp(vPopup);
this.popup.mount($Popup);
});
},
panTo(oLngLat, iZoom, fCallback) {
const iXOffset = (this.settingsPanelOpen?getOuterWidth(this.$refs.settings):0) - (this.feedPanelOpen?getOuterWidth(this.$refs.feed):0);
this.map.easeTo({
center: oLngLat,
zoom: iZoom,
offset: [iXOffset / 2, 0],
duration: 500
});
setTimeout(fCallback, 500);
}, },
getGoogleMapsLink(asInfo) { getGoogleMapsLink(asInfo) {
return $('<a>', { return $('<a>', {
@@ -373,7 +382,7 @@ export default {
if(!this.feed.outOfData && !this.feed.loading) { if(!this.feed.outOfData && !this.feed.loading) {
//Get next chunk //Get next chunk
this.feed.loading = true; this.feed.loading = true;
let aoData = await this.spot.get2('next_feed', {id_project: this.project.id, id: this.feed.refIdLast}); let aoData = await this.spot.get2('next_feed', {id_project: this.currProject.id, id: this.feed.refIdLast});
let iPostCount = Object.keys(aoData.feed).length; let iPostCount = Object.keys(aoData.feed).length;
this.feed.loading = false; this.feed.loading = false;
this.feed.firstChunk = false; this.feed.firstChunk = false;
@@ -514,10 +523,10 @@ export default {
<h1><SpotIcon :icon="'project'" :classes="'fa-fw'" :text="spot.lang('hikes')" /></h1> <h1><SpotIcon :icon="'project'" :classes="'fa-fw'" :text="spot.lang('hikes')" /></h1>
<div class="settings-section-body"> <div class="settings-section-body">
<div class="radio" v-for="project in projects"> <div class="radio" v-for="project in projects">
<input type="radio" :id="project.id" :value="project.codename" v-model="projectCodename" /> <input type="radio" :id="currProject.id" :value="currProject.codename" v-model="currProjectCodeName" />
<label :for="project.id"> <label :for="currProject.id">
<span>{{ project.name }}</span> <span>{{ currProject.name }}</span>
<a class="download" :href="project.gpxfilepath" :title="spot.lang('track_download')" @click.stop="()=>{}"> <a class="download" :href="currProject.gpxfilepath" :title="spot.lang('track_download')" @click.stop="()=>{}">
<SpotIcon :icon="'download'" :classes="'push-left'" /> <SpotIcon :icon="'download'" :classes="'push-left'" />
</a> </a>
</label> </label>
@@ -566,7 +575,7 @@ export default {
</div> </div>
</div> </div>
<div id="title" :class="'map-control settings-control map-control-'+(mobile?'bottom':'top')"> <div id="title" :class="'map-control settings-control map-control-'+(mobile?'bottom':'top')">
<span>{{ project.name }}</span> <span>{{ currProject.name }}</span>
</div> </div>
</div> </div>
<div id="feed" class="map-container map-container-right" ref="feed"> <div id="feed" class="map-container map-container-right" ref="feed">

View File

@@ -4,6 +4,7 @@
import projectMediaLink from './projectMediaLink.vue'; import projectMediaLink from './projectMediaLink.vue';
import projectMapLink from './projectMapLink.vue'; import projectMapLink from './projectMapLink.vue';
import projectRelTime from './projectRelTime.vue'; import projectRelTime from './projectRelTime.vue';
import { LngLat } from 'maplibre-gl';
import autosize from 'autosize'; import autosize from 'autosize';
@@ -48,14 +49,14 @@
return '#'+[asHash.page, asHash.items[0], this.options.type, this.options.id].join(this.spot.consts.hash_sep); return '#'+[asHash.page, asHash.items[0], this.options.type, this.options.id].join(this.spot.consts.hash_sep);
}, },
modeHisto() { modeHisto() {
return (this.project.mode==this.spot.consts.modes.histo); return (this.project.currProject.mode==this.spot.consts.modes.histo);
}, },
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;
}, },
}, },
inject: ['spot', 'project', 'user'], inject: ['spot', 'project', 'user', 'map', 'project'],
methods: { methods: {
copyAnchor() { copyAnchor() {
copyTextToClipboard(this.spot.consts.server+this.spot.hash()); copyTextToClipboard(this.spot.consts.server+this.spot.hash());
@@ -67,23 +68,12 @@
}, 5000); }, 5000);
}, },
panMapToMessage() { panMapToMessage() {
//TODO if(this.spot.isMobile()) this.project.toggleFeedPanel(false, 'panToInstant');
/* this.map.panTo(
var $Parent = $(oEvent.currentTarget).parent(); new LngLat(this.options.longitude, this.options.latitude),
var oMarker = this.spot.tmp(['markers', $Parent.data('id')]); 15,
if(this.isMobile()) { () => {this.map.openMarkerPopup(this.options.id_message);}
this.toggleFeedPanel(false, 'panToInstant'); );
this.spot.tmp('map').setView(oMarker.getLatLng(), 15);
}
else {
var iOffset = (this.isFeedPanelOpen()?1:-1)*this.spot.tmp('$Feed').outerWidth(true)/2 - (this.isSettingsPanelOpen()?1:-1)*this.spot.tmp('$Settings').outerWidth(true)/2;
var iRatio = -1 * iOffset / $('body').outerWidth(true);
this.spot.tmp('map').setOffsetView(iRatio, oMarker.getLatLng(), 15);
}
$Parent.data('clicked', true);
if(!oMarker.isPopupOpen()) oMarker.openPopup();
*/
}, },
openMarkerPopup() { openMarkerPopup() {
//TODO //TODO