This commit is contained in:
1 parent
f63f5c240e
commit
c5529d5f94
6 files changed
+186
-139
No files matched your search
+160
-118
@@ -37,9 +37,10 @@ export default {
|
|||||||
currProject: null,
|
currProject: null,
|
||||||
modeHisto: null,
|
modeHisto: null,
|
||||||
posts: [],
|
posts: [],
|
||||||
baseMaps: {},
|
baseMaps: [],
|
||||||
baseMap: null,
|
baseMap: null,
|
||||||
map: null,
|
map: null,
|
||||||
|
mapInitializing: false,
|
||||||
lightbox: null,
|
lightbox: null,
|
||||||
hikes: {
|
hikes: {
|
||||||
colors: {},
|
colors: {},
|
||||||
@@ -110,37 +111,40 @@ export default {
|
|||||||
'hitchhiking': this.getStyleProperty('--track-hitchhiking')
|
'hitchhiking': this.getStyleProperty('--track-hitchhiking')
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//Reset values
|
||||||
|
this.setFeedUpdateTimer(-1);
|
||||||
|
this.feed = {loading:false, updatable:true, outOfData:false, refIdFirst:0, refIdLast:0, firstChunk:true};
|
||||||
|
this.posts = [];
|
||||||
|
this.track = null;
|
||||||
|
this.currProject = null;
|
||||||
|
this.removeMapContent();
|
||||||
|
|
||||||
|
//Build Map
|
||||||
|
this.mapInitializing = true;
|
||||||
if(this.hash.items[0] && this.projects[this.hash.items[0]]) await this.initProject(this.hash.items[0]);
|
if(this.hash.items[0] && this.projects[this.hash.items[0]]) await this.initProject(this.hash.items[0]);
|
||||||
else await this.initProjectOverview();
|
else await this.initOverview();
|
||||||
|
this.mapInitializing = false;
|
||||||
},
|
},
|
||||||
quit() {
|
quit() {
|
||||||
this.lightbox.end();
|
this.lightbox.end();
|
||||||
this.$refs.feedSimpleBar?.scrollElement.removeEventListener('scroll', this.onFeedScroll);
|
this.$refs.feedSimpleBar?.scrollElement.removeEventListener('scroll', this.onFeedScroll);
|
||||||
this.setFeedUpdateTimer(-1);
|
this.setFeedUpdateTimer(-1);
|
||||||
this.map.remove();
|
this.removeMap();
|
||||||
},
|
},
|
||||||
async initProjectOverview() {
|
async initOverview() {
|
||||||
|
this.modeHisto = true;
|
||||||
this.hash.items = [this.overview.codename];
|
this.hash.items = [this.overview.codename];
|
||||||
this.setFeedUpdateTimer(-1);
|
this.toggleFeedPanel(false, 'none');
|
||||||
this.currProject = null;
|
|
||||||
this.modeHisto = null;
|
|
||||||
this.feed = {loading:false, updatable:true, outOfData:false, refIdFirst:0, refIdLast:0, firstChunk:true};
|
|
||||||
this.posts = [];
|
|
||||||
this.baseMaps = this.consts.default_maps;
|
|
||||||
|
|
||||||
await this.initMapOverview();
|
await this.initOverviewMap();
|
||||||
},
|
},
|
||||||
async initProject(iProjectId) {
|
async initProject(iProjectId) {
|
||||||
this.setFeedUpdateTimer(-1);
|
|
||||||
this.currProject = this.projects[iProjectId];
|
this.currProject = this.projects[iProjectId];
|
||||||
this.modeHisto = (this.currProject.mode == this.consts.modes.histo);
|
this.modeHisto = (this.currProject.mode == this.consts.modes.histo);
|
||||||
this.feed = {loading:false, updatable:true, outOfData:false, refIdFirst:0, refIdLast:0, firstChunk:true};
|
|
||||||
this.posts = [];
|
|
||||||
this.baseMaps = {};
|
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
this.initFeed(),
|
this.initFeed(),
|
||||||
this.initMapProject()
|
this.initProjectMap()
|
||||||
]);
|
]);
|
||||||
|
|
||||||
//Direct link post action
|
//Direct link post action
|
||||||
@@ -183,9 +187,6 @@ export default {
|
|||||||
|
|
||||||
this.toggleFeedPanel(!this.isMobile(), 'none');
|
this.toggleFeedPanel(!this.isMobile(), 'none');
|
||||||
|
|
||||||
//Add post Event handling
|
|
||||||
//TODO
|
|
||||||
|
|
||||||
//Get first posts batch
|
//Get first posts batch
|
||||||
await this.getNextFeed();
|
await this.getNextFeed();
|
||||||
if(this.$refs.feedSimpleBar) this.$refs.feedSimpleBar.scrollElement.scrollTop = 0;
|
if(this.$refs.feedSimpleBar) this.$refs.feedSimpleBar.scrollElement.scrollTop = 0;
|
||||||
@@ -193,8 +194,7 @@ export default {
|
|||||||
//Start auto-update
|
//Start auto-update
|
||||||
if(!this.modeHisto) this.setFeedUpdateTimer(this.refreshRate);
|
if(!this.modeHisto) this.setFeedUpdateTimer(this.refreshRate);
|
||||||
},
|
},
|
||||||
async initMapProject() {
|
async initProjectMap() {
|
||||||
//Start async calls
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
maps: this.baseMaps,
|
maps: this.baseMaps,
|
||||||
@@ -207,25 +207,26 @@ export default {
|
|||||||
this.api.get('geojson', {id_project: this.currProject.id})
|
this.api.get('geojson', {id_project: this.currProject.id})
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await this.initMapBase({
|
await this.initMap({
|
||||||
setCamera: () => {
|
setCamera: () => {
|
||||||
this.map.fitBounds(this.getInitialMapBounds(), {
|
this.map.fitBounds(this.getInitialMapBounds(), {
|
||||||
padding: 20,
|
padding: 20,
|
||||||
animate: false,
|
animate: false,
|
||||||
maxZoom: 15
|
maxZoom: 15
|
||||||
});
|
});
|
||||||
},
|
|
||||||
addMarkers: () => {
|
|
||||||
this.addTrack(this.track);
|
|
||||||
this.markers.forEach(oMarker => this.addMarker(
|
|
||||||
oMarker,
|
|
||||||
() => this.openMarkerPopup(oMarker.id, oMarker.type)
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
async initMapOverview() {
|
async initOverviewMap() {
|
||||||
await this.initMapBase({
|
this.baseMaps = this.consts.default_maps;
|
||||||
|
this.markers = Object.values(this.projects).map((asProject) => ({
|
||||||
|
type: 'project',
|
||||||
|
subtype: 'project',
|
||||||
|
...asProject,
|
||||||
|
opacityWhenCovered: 0.3
|
||||||
|
}));
|
||||||
|
|
||||||
|
await this.initMap({
|
||||||
setCamera: () => {
|
setCamera: () => {
|
||||||
//Center on default project
|
//Center on default project
|
||||||
const oDefaultProject = this.projects.getDefaultProject();
|
const oDefaultProject = this.projects.getDefaultProject();
|
||||||
@@ -239,25 +240,30 @@ export default {
|
|||||||
center: new LngLat(oDefaultProject.longitude, oDefaultProject.latitude),
|
center: new LngLat(oDefaultProject.longitude, oDefaultProject.latitude),
|
||||||
zoom: Math.log2(iWorldSize / this.map.transform.tileSize)
|
zoom: Math.log2(iWorldSize / this.map.transform.tileSize)
|
||||||
});
|
});
|
||||||
},
|
|
||||||
addMarkers: () => {
|
|
||||||
for(const asProject of Object.values(this.projects)) {
|
|
||||||
this.addMarker(
|
|
||||||
{
|
|
||||||
type: 'project',
|
|
||||||
subtype: 'project',
|
|
||||||
...asProject,
|
|
||||||
opacityWhenCovered: 0.3
|
|
||||||
},
|
|
||||||
() => {this.hash.items = [asProject.codename];},
|
|
||||||
(oEvent, oProject) => {this.openProjectPopup(oProject);}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
async initMapBase({setCamera, addMarkers}) {
|
async initMap({setCamera}) {
|
||||||
if(this.map) this.map.remove();
|
//Build map
|
||||||
|
if(!this.map) this.addMap();
|
||||||
|
this.updateMapPadding();
|
||||||
|
setCamera();
|
||||||
|
|
||||||
|
//Force wait for load event
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
if(this.map.isStyleLoaded()) resolve();
|
||||||
|
else this.map.once('load', resolve);
|
||||||
|
});
|
||||||
|
|
||||||
|
//Add content: Base Maps, Tracks, Markers
|
||||||
|
this.addMapContent();
|
||||||
|
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
if(this.map.loaded() && this.map.areTilesLoaded()) resolve();
|
||||||
|
else this.map.once('idle', resolve);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
addMap() {
|
||||||
this.map = new Map({
|
this.map = new Map({
|
||||||
container: 'map',
|
container: 'map',
|
||||||
aroundCenter: true,
|
aroundCenter: true,
|
||||||
@@ -275,43 +281,49 @@ export default {
|
|||||||
},
|
},
|
||||||
attributionControl: false
|
attributionControl: false
|
||||||
});
|
});
|
||||||
|
|
||||||
this.updateMapPadding();
|
|
||||||
setCamera();
|
|
||||||
this.map.addControl(new ScaleControl({unit: 'metric'}), 'bottom-right');
|
this.map.addControl(new ScaleControl({unit: 'metric'}), 'bottom-right');
|
||||||
|
},
|
||||||
|
removeMap() {
|
||||||
|
this.removeMapContent();
|
||||||
|
this.map?.remove();
|
||||||
|
this.map = null;
|
||||||
|
},
|
||||||
|
addMapContent() {
|
||||||
|
this.baseMaps.forEach(this.addBaseMap);
|
||||||
|
this.addTrack();
|
||||||
|
this.markers.forEach(this.addMarker);
|
||||||
|
},
|
||||||
|
removeMapContent() {
|
||||||
|
if(!this.map) return;
|
||||||
|
|
||||||
//Force wait for load event
|
this.closePopup();
|
||||||
await new Promise((resolve) => {
|
this.removeTrack();
|
||||||
if(this.map.loaded()) resolve();
|
this.markers.forEach(this.removeMarker);
|
||||||
else this.map.once('load', resolve);
|
this.baseMaps.forEach(this.removeBaseMap);
|
||||||
|
},
|
||||||
|
addBaseMap(asBaseMap) {
|
||||||
|
if(asBaseMap.default_map) this.baseMap = asBaseMap.codename;
|
||||||
|
this.map.addSource(asBaseMap.codename, {
|
||||||
|
type: 'raster',
|
||||||
|
tiles: [asBaseMap.pattern],
|
||||||
|
tileSize: asBaseMap.tile_size
|
||||||
});
|
});
|
||||||
|
this.map.addLayer({
|
||||||
//Base maps (raster tiles)
|
id: asBaseMap.codename,
|
||||||
this.baseMap = this.baseMaps.find((asBM) => asBM.default_map)?.codename ?? null;
|
type: 'raster',
|
||||||
for(const asBaseMap of this.baseMaps) {
|
source: asBaseMap.codename,
|
||||||
this.map.addSource(asBaseMap.codename, {
|
'layout': {'visibility': asBaseMap.default_map?'visible':'none'},
|
||||||
type: 'raster',
|
minZoom: asBaseMap.min_zoom,
|
||||||
tiles: [asBaseMap.pattern],
|
maxZoom: asBaseMap.max_zoom
|
||||||
tileSize: asBaseMap.tile_size
|
|
||||||
});
|
|
||||||
this.map.addLayer({
|
|
||||||
id: asBaseMap.codename,
|
|
||||||
type: 'raster',
|
|
||||||
source: asBaseMap.codename,
|
|
||||||
'layout': {'visibility': asBaseMap.codename == this.baseMap ? 'visible' : 'none'},
|
|
||||||
minZoom: asBaseMap.min_zoom,
|
|
||||||
maxZoom: asBaseMap.max_zoom
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
addMarkers();
|
|
||||||
await new Promise((resolve) => {
|
|
||||||
if(this.map.loaded() && this.map.areTilesLoaded()) resolve();
|
|
||||||
else this.map.once('idle', resolve);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
addTrack(oTrack, bCenter=false) {
|
removeBaseMap(asBaseMap) {
|
||||||
this.track = oTrack;
|
if(this.map.getLayer(asBaseMap.codename)) this.map.removeLayer(asBaseMap.codename);
|
||||||
|
if(this.map.getSource(asBaseMap.codename)) this.map.removeSource(asBaseMap.codename);
|
||||||
|
},
|
||||||
|
addTrack() {
|
||||||
|
if(!this.track) return;
|
||||||
|
|
||||||
this.track.features.forEach((oFeature, iFeatureId) => {
|
this.track.features.forEach((oFeature, iFeatureId) => {
|
||||||
oFeature.properties.track_id = iFeatureId;
|
oFeature.properties.track_id = iFeatureId;
|
||||||
});
|
});
|
||||||
@@ -354,11 +366,71 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.map.on('click', 'track-hitbox', this.openTrackPopup);
|
this.map.on('click', 'track-hitbox', this.openTrackPopup);
|
||||||
this.map.on('mouseenter', 'track-hitbox', () => {this.map.getCanvas().style.cursor = 'pointer';});
|
this.map.on('mouseenter', 'track-hitbox', this.onTrackHover);
|
||||||
this.map.on('mouseleave', 'track-hitbox', () => {this.map.getCanvas().style.cursor = '';});
|
this.map.on('mouseleave', 'track-hitbox', this.onTrackHover);
|
||||||
|
},
|
||||||
|
removeTrack() {
|
||||||
|
//Over clickable track
|
||||||
|
if(this.map.getLayer('track-hitbox')) {
|
||||||
|
this.map.off('click', 'track-hitbox', this.openTrackPopup);
|
||||||
|
this.map.off('mouseenter', 'track-hitbox', this.onTrackHover);
|
||||||
|
this.map.off('mouseleave', 'track-hitbox', this.onTrackHover);
|
||||||
|
this.map.removeLayer('track-hitbox');
|
||||||
|
}
|
||||||
|
|
||||||
|
//Actual track
|
||||||
|
if(this.map.getLayer('track')) this.map.removeLayer('track');
|
||||||
|
|
||||||
|
//Track source
|
||||||
|
if(this.map.getSource('track')) this.map.removeSource('track');
|
||||||
|
},
|
||||||
|
addMarker(oMarker) {
|
||||||
|
const $Marker = document.createElement('div');
|
||||||
|
oMarker.app = createApp(SpotIconStack, this.markerProps[oMarker.subtype]);
|
||||||
|
oMarker.app.mount($Marker);
|
||||||
|
|
||||||
|
oMarker.marker = new Marker({element: $Marker, anchor: 'bottom', opacityWhenCovered: oMarker.opacityWhenCovered ?? 0})
|
||||||
|
.setLngLat([oMarker.longitude, oMarker.latitude])
|
||||||
|
.addTo(this.map);
|
||||||
|
|
||||||
|
const $MarkerElement = oMarker.marker.getElement();
|
||||||
|
$MarkerElement.addEventListener('click', (oEvent) => {this.onMarkerClick(oEvent, oMarker);});
|
||||||
|
$MarkerElement.addEventListener('mouseenter', (oEvent) => {this.onMarkerHover(oEvent, oMarker);});
|
||||||
|
$MarkerElement.addEventListener('mouseleave', (oEvent) => {this.onMarkerHover(oEvent, oMarker);});
|
||||||
|
},
|
||||||
|
removeMarker(oMarker) {
|
||||||
|
if(oMarker.app) {
|
||||||
|
oMarker.app.unmount();
|
||||||
|
delete oMarker.app;
|
||||||
|
}
|
||||||
|
if(oMarker.marker) {
|
||||||
|
oMarker.marker.remove();
|
||||||
|
delete oMarker.marker;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onTrackHover(oEvent) {
|
||||||
|
this.map.getCanvas().style.cursor = (oEvent.type == 'mouseenter')?'pointer':'';
|
||||||
|
},
|
||||||
|
onMarkerClick(oEvent, oMarker) {
|
||||||
|
oEvent.preventDefault();
|
||||||
|
oEvent.stopPropagation();
|
||||||
|
switch (oMarker.type) {
|
||||||
|
case 'project':
|
||||||
|
this.hash.items = [oMarker.codename];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.openMarkerPopup(oMarker.id, oMarker.type);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onMarkerHover(oEvent, oMarker) {
|
||||||
|
switch (oMarker.type) {
|
||||||
|
case 'project':
|
||||||
|
if(oEvent.type == 'mouseenter') this.openProjectPopup(oMarker);
|
||||||
|
else this.closePopup();
|
||||||
|
break;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
openProjectPopup(oProject) {
|
openProjectPopup(oProject) {
|
||||||
this.closePopup();
|
|
||||||
this.openPopup({
|
this.openPopup({
|
||||||
lnglat: [oProject.longitude, oProject.latitude],
|
lnglat: [oProject.longitude, oProject.latitude],
|
||||||
options: oProject,
|
options: oProject,
|
||||||
@@ -366,7 +438,6 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
openMarkerPopup(iMarkerId, sMarkerType) {
|
openMarkerPopup(iMarkerId, sMarkerType) {
|
||||||
this.closePopup();
|
|
||||||
let oMarker = this.markers.find((oCandidate) => oCandidate.id == iMarkerId && oCandidate.type == sMarkerType);
|
let oMarker = this.markers.find((oCandidate) => oCandidate.id == iMarkerId && oCandidate.type == sMarkerType);
|
||||||
this.openPopup({
|
this.openPopup({
|
||||||
lnglat: [oMarker.longitude, oMarker.latitude],
|
lnglat: [oMarker.longitude, oMarker.latitude],
|
||||||
@@ -375,13 +446,13 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
openTrackPopup(oEvent) {
|
openTrackPopup(oEvent) {
|
||||||
this.closePopup();
|
|
||||||
this.openPopup({
|
this.openPopup({
|
||||||
lnglat: oEvent.lngLat,
|
lnglat: oEvent.lngLat,
|
||||||
options: this.projects.getTrackInfo(oEvent.features[0], this.track, this.lang),
|
options: this.projects.getTrackInfo(oEvent.features[0], this.track, this.lang),
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
openPopup({lnglat, options={}, offset=[0, 0]} = {}) {
|
openPopup({lnglat, options={}, offset=[0, 0]} = {}) {
|
||||||
|
this.closePopup();
|
||||||
const $Popup = document.createElement('div');
|
const $Popup = document.createElement('div');
|
||||||
this.popup.element = new Popup({
|
this.popup.element = new Popup({
|
||||||
anchor: 'bottom',
|
anchor: 'bottom',
|
||||||
@@ -412,32 +483,6 @@ 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;
|
||||||
@@ -551,10 +596,7 @@ 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(
|
aoMarkers.forEach(this.addMarker);
|
||||||
oMarker,
|
|
||||||
() => this.openMarkerPopup(oMarker.id, oMarker.type)
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Message Last Update
|
//Message Last Update
|
||||||
@@ -671,7 +713,7 @@ export default {
|
|||||||
<h1><SpotIcon :icon="'project'" width="fixed" :text="lang.get('project.hikes')" /></h1>
|
<h1><SpotIcon :icon="'project'" width="fixed" :text="lang.get('project.hikes')" /></h1>
|
||||||
<div class="settings-section-body">
|
<div class="settings-section-body">
|
||||||
<div class="radio" v-for="project in projectOptions" :key="'project-'+project.id">
|
<div class="radio" v-for="project in projectOptions" :key="'project-'+project.id">
|
||||||
<input type="radio" :id="'project-'+project.id" :value="project.codename" v-model="hash.items[0]" />
|
<input type="radio" :id="'project-'+project.id" :value="project.codename" v-model="hash.items[0]" :disabled="mapInitializing" />
|
||||||
<label :for="'project-'+project.id">
|
<label :for="'project-'+project.id">
|
||||||
<span>{{ project.name }}</span>
|
<span>{{ project.name }}</span>
|
||||||
<a v-if="project.gpxfilepath" class="download" :href="project.gpxfilepath" :download="project.codename + '.gpx'" :title="lang.get('track.download')" @click.stop="()=>{}">
|
<a v-if="project.gpxfilepath" class="download" :href="project.gpxfilepath" :download="project.codename + '.gpx'" :title="lang.get('track.download')" @click.stop="()=>{}">
|
||||||
@@ -685,7 +727,7 @@ export default {
|
|||||||
<h1><SpotIcon :icon="'map'" width="fixed" :text="lang.get('map.title')" /></h1>
|
<h1><SpotIcon :icon="'map'" width="fixed" :text="lang.get('map.title')" /></h1>
|
||||||
<div class="settings-section-body">
|
<div class="settings-section-body">
|
||||||
<div class="radio" v-for="bm in baseMaps" :key="'map-'+bm.id_map">
|
<div class="radio" v-for="bm in baseMaps" :key="'map-'+bm.id_map">
|
||||||
<input type="radio" :id="'map-'+bm.id_map" :value="bm.codename" v-model="baseMap" />
|
<input type="radio" :id="'map-'+bm.id_map" :value="bm.codename" v-model="baseMap" :disabled="mapInitializing" />
|
||||||
<label :for="'map-'+bm.id_map">{{ lang.get('map.'+bm.codename) }}</label>
|
<label :for="'map-'+bm.id_map">{{ lang.get('map.'+bm.codename) }}</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -723,12 +765,12 @@ export default {
|
|||||||
</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">
|
||||||
<Simplebar v-if="currProject" id="feed-panel" class="map-panel" ref="feedSimpleBar">
|
<Simplebar id="feed-panel" class="map-panel" ref="feedSimpleBar">
|
||||||
<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')}" />
|
||||||
</div>
|
</div>
|
||||||
<div id="feed-posts">
|
<div v-if="currProject" id="feed-posts">
|
||||||
<ProjectPost v-for="post in posts" :options="post" ref="posts" />
|
<ProjectPost v-for="post in posts" :options="post" ref="posts" />
|
||||||
</div>
|
</div>
|
||||||
<div id="feed-footer" v-if="feed.loading">
|
<div id="feed-footer" v-if="feed.loading">
|
||||||
|
|||||||
@@ -67,9 +67,7 @@ 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">
|
<div v-else-if="options.type=='project'" class="section year">{{ activeTimeInterval }}</div>
|
||||||
<spotIcon icon="calendar" width="fixed" size="lg" :text="activeTimeInterval" />
|
|
||||||
</div>
|
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<div class="section" v-if="options.comment">
|
<div class="section" v-if="options.comment">
|
||||||
<spotIcon icon="post" width="fixed" size="lg" :text="options.comment" />
|
<spotIcon icon="post" width="fixed" size="lg" :text="options.comment" />
|
||||||
|
|||||||
@@ -62,7 +62,7 @@
|
|||||||
return '#'+[this.hash.page, this.project.currProject.codename, this.options.type, this.options.id].join(this.consts.hash_sep);
|
return '#'+[this.hash.page, this.project.currProject.codename, this.options.type, this.options.id].join(this.consts.hash_sep);
|
||||||
},
|
},
|
||||||
modeHisto() {
|
modeHisto() {
|
||||||
return (this.project.currProject.mode == this.consts.modes.histo);
|
return (this.project?.currProject?.mode == this.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;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
faArrowsRotate,
|
faArrowsRotate,
|
||||||
faBars,
|
faBars,
|
||||||
faCalendar,
|
|
||||||
faCamera,
|
faCamera,
|
||||||
faCarSide,
|
faCarSide,
|
||||||
faChartArea,
|
faChartArea,
|
||||||
@@ -120,7 +119,6 @@ const ICONS = {
|
|||||||
image: faImage,
|
image: faImage,
|
||||||
message: faLocationPin,
|
message: faLocationPin,
|
||||||
time: faClock,
|
time: faClock,
|
||||||
calendar: faCalendar,
|
|
||||||
coords: faCompass,
|
coords: faCompass,
|
||||||
altitude: faMountain,
|
altitude: faMountain,
|
||||||
'drill-video': faCirclePlay,
|
'drill-video': faCirclePlay,
|
||||||
|
|||||||
@@ -142,7 +142,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
&.message {
|
&.message {
|
||||||
background: color.$message-bg;
|
background: color.$message-bg;
|
||||||
color: color.$message;
|
color: color.$message;
|
||||||
|
|||||||
@@ -96,23 +96,25 @@ $thumbnail-max-size: 60px;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.message .medias-list {
|
.message {
|
||||||
display: flex;
|
.medias-list {
|
||||||
flex-wrap: wrap;
|
display: flex;
|
||||||
gap: var.$elem-spacing;
|
flex-wrap: wrap;
|
||||||
align-items: center;
|
gap: var.$elem-spacing;
|
||||||
margin-top: var.$elem-spacing;
|
align-items: center;
|
||||||
|
margin-top: var.$elem-spacing;
|
||||||
|
|
||||||
a.media-link {
|
a.media-link {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
max-width: $thumbnail-max-size;
|
max-width: $thumbnail-max-size;
|
||||||
max-height: calc($thumbnail-max-size * 2/3);
|
max-height: calc($thumbnail-max-size * 2/3);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.drill .drill-icon {
|
&.drill .drill-icon {
|
||||||
font-size: 1.5em;
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,5 +126,13 @@ $thumbnail-max-size: 60px;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.project {
|
||||||
|
.year {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 1.2em;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user