Track popup
This commit is contained in:
@@ -130,8 +130,11 @@
|
|||||||
"ref_id": "Ref. Spot ID"
|
"ref_id": "Ref. Spot ID"
|
||||||
},
|
},
|
||||||
"stats": {
|
"stats": {
|
||||||
|
"duration": "Duration",
|
||||||
"distance": "Distance",
|
"distance": "Distance",
|
||||||
"elevation": "Elevation",
|
"elevation": "Elevation",
|
||||||
|
"elevation_gain": "Elevation gain",
|
||||||
|
"elevation_loss": "Elevation loss",
|
||||||
"legend": "Legend",
|
"legend": "Legend",
|
||||||
"segment_length": "Segment length",
|
"segment_length": "Segment length",
|
||||||
"type": "Track Type"
|
"type": "Track Type"
|
||||||
|
|||||||
@@ -130,8 +130,11 @@
|
|||||||
"ref_id": "ID Spot ref."
|
"ref_id": "ID Spot ref."
|
||||||
},
|
},
|
||||||
"stats": {
|
"stats": {
|
||||||
|
"duration": "Duración",
|
||||||
"distance": "Distancia",
|
"distance": "Distancia",
|
||||||
"elevation": "Elevación",
|
"elevation": "Elevación",
|
||||||
|
"elevation_gain": "Ascenso acumulado",
|
||||||
|
"elevation_loss": "Descenso acumulado",
|
||||||
"legend": "Leyenda",
|
"legend": "Leyenda",
|
||||||
"segment_length": "Tamaño del segmento",
|
"segment_length": "Tamaño del segmento",
|
||||||
"type": "Tipo de sendero"
|
"type": "Tipo de sendero"
|
||||||
|
|||||||
@@ -130,8 +130,11 @@
|
|||||||
"ref_id": "ID Spot ref."
|
"ref_id": "ID Spot ref."
|
||||||
},
|
},
|
||||||
"stats": {
|
"stats": {
|
||||||
|
"duration": "Durée",
|
||||||
"distance": "Distance",
|
"distance": "Distance",
|
||||||
"elevation": "Dénivelé",
|
"elevation": "Dénivelé",
|
||||||
|
"elevation_gain": "Dénivelé positif",
|
||||||
|
"elevation_loss": "Dénivelé négatif",
|
||||||
"legend": "Légende",
|
"legend": "Légende",
|
||||||
"segment_length": "Taille du segment",
|
"segment_length": "Taille du segment",
|
||||||
"type": "Type de rando"
|
"type": "Type de rando"
|
||||||
|
|||||||
@@ -588,7 +588,7 @@ class Spot extends Main
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Sort Table IDs by type & Get attributes
|
//Sort Table IDs by type & Get attributes
|
||||||
$asFeedIds = array('message'=>array(), 'media'=>array(), 'message'=>array());
|
$asFeedIds = array('message'=>array(), 'media'=>array(), 'post'=>array());
|
||||||
foreach($asItems as $asItem) {
|
foreach($asItems as $asItem) {
|
||||||
$asFeedIds[$asItem['type']][$asItem['id']] = $asItem;
|
$asFeedIds[$asItem['type']][$asItem['id']] = $asItem;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ export default {
|
|||||||
map: {
|
map: {
|
||||||
panToBetweenPanels: this.panToBetweenPanels,
|
panToBetweenPanels: this.panToBetweenPanels,
|
||||||
openMarkerPopup: this.openMarkerPopup,
|
openMarkerPopup: this.openMarkerPopup,
|
||||||
closeMarkerPopup: this.closeMarkerPopup,
|
closePopup: this.closePopup,
|
||||||
isMarkerVisible: this.isMarkerVisible
|
isMarkerVisible: this.isMarkerVisible
|
||||||
},
|
},
|
||||||
project: this
|
project: this
|
||||||
@@ -142,22 +142,6 @@ export default {
|
|||||||
this.setFeedUpdateTimer(-1);
|
this.setFeedUpdateTimer(-1);
|
||||||
this.map.remove();
|
this.map.remove();
|
||||||
},
|
},
|
||||||
getNaturalDuration(iHours) {
|
|
||||||
var iTimeMinutes = 0, iTimeHours = 0, iTimeDays = Math.floor(iHours/8); //8 hours a day
|
|
||||||
if(iTimeDays > 1) iTimeDays = Math.round(iTimeDays * 2) / 2; //Round down to the closest half day
|
|
||||||
else {
|
|
||||||
iTimeDays = 0;
|
|
||||||
iTimeHours = Math.floor(iHours);
|
|
||||||
iHours -= iTimeHours;
|
|
||||||
|
|
||||||
iTimeMinutes = Math.floor(iHours * 4) * 15; //Round down to the closest 15 minutes
|
|
||||||
}
|
|
||||||
return '~ '
|
|
||||||
+(iTimeDays>0?(iTimeDays+(iTimeDays%2==0?'':'½')+' '+this.lang.get(iTimeDays>1?'unit.days':'unit.day')):'') //Days
|
|
||||||
+((iTimeHours>0 || iTimeDays==0)?iTimeHours+this.lang.get('unit.hour'):'') //Hours
|
|
||||||
+((iTimeDays>0 || iTimeMinutes==0)?'':iTimeMinutes); //Minutes
|
|
||||||
|
|
||||||
},
|
|
||||||
initProject() {
|
initProject() {
|
||||||
this.currProject = this.projects[this.hash.items[0]];
|
this.currProject = this.projects[this.hash.items[0]];
|
||||||
this.modeHisto = (this.currProject.mode == this.consts.modes.histo);
|
this.modeHisto = (this.currProject.mode == this.consts.modes.histo);
|
||||||
@@ -263,9 +247,12 @@ export default {
|
|||||||
},
|
},
|
||||||
addTrack(oTrack, bCenter=false) {
|
addTrack(oTrack, bCenter=false) {
|
||||||
this.track = oTrack;
|
this.track = oTrack;
|
||||||
|
this.track.features.forEach((oFeature, iFeatureId) => {
|
||||||
|
oFeature.properties.track_id = iFeatureId;
|
||||||
|
});
|
||||||
this.map.addSource('track', {
|
this.map.addSource('track', {
|
||||||
'type': 'geojson',
|
'type': 'geojson',
|
||||||
'data': oTrack
|
'data': this.track
|
||||||
});
|
});
|
||||||
|
|
||||||
//Color mapping
|
//Color mapping
|
||||||
@@ -290,6 +277,27 @@ export default {
|
|||||||
'line-width': this.hikes.width
|
'line-width': this.hikes.width
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Enlarged track (click hit box)
|
||||||
|
this.map.addLayer({
|
||||||
|
'id': 'track-hitbox',
|
||||||
|
'type': 'line',
|
||||||
|
'source': 'track',
|
||||||
|
'paint': {
|
||||||
|
'line-opacity': 0,
|
||||||
|
'line-width': this.hikes.width + 20
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.map.on('click', 'track-hitbox', this.openTrackPopup);
|
||||||
|
this.map.on('mouseenter', 'track-hitbox', () => {this.map.getCanvas().style.cursor = 'pointer';});
|
||||||
|
this.map.on('mouseleave', 'track-hitbox', () => {this.map.getCanvas().style.cursor = '';});
|
||||||
|
},
|
||||||
|
openTrackPopup(oEvent) {
|
||||||
|
this.closePopup();
|
||||||
|
this.openPopup({
|
||||||
|
lnglat: oEvent.lngLat,
|
||||||
|
options: this.projects.getTrackInfo(oEvent.features[0], this.track, this.lang),
|
||||||
|
});
|
||||||
},
|
},
|
||||||
addMarker(oMarker) {
|
addMarker(oMarker) {
|
||||||
const $Marker = document.createElement('div');
|
const $Marker = document.createElement('div');
|
||||||
@@ -306,22 +314,27 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
openMarkerPopup(iMarkerId, sMarkerType) {
|
openMarkerPopup(iMarkerId, sMarkerType) {
|
||||||
this.closeMarkerPopup();
|
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({
|
||||||
|
offset: [0, this.markerSize.height * -1], //FIXME
|
||||||
|
lnglat: [oMarker.longitude, oMarker.latitude],
|
||||||
|
options: oMarker
|
||||||
|
});
|
||||||
|
},
|
||||||
|
openPopup({offset=[0, 0], lnglat, options={}} = {}) {
|
||||||
const $Popup = document.createElement('div');
|
const $Popup = document.createElement('div');
|
||||||
this.popup.element = new Popup({
|
this.popup.element = new Popup({
|
||||||
anchor: 'bottom',
|
anchor: 'bottom',
|
||||||
offset: [0, this.markerSize.height * -1], //FIXME
|
offset: offset,
|
||||||
closeButton: false
|
closeButton: false
|
||||||
})
|
})
|
||||||
.setDOMContent($Popup)
|
.setDOMContent($Popup)
|
||||||
.setLngLat([oMarker.longitude, oMarker.latitude])
|
.setLngLat(lnglat)
|
||||||
.addTo(this.map);
|
.addTo(this.map);
|
||||||
|
|
||||||
this.popup.content = createApp(ProjectPopup, {
|
this.popup.content = createApp(ProjectPopup, {
|
||||||
options: oMarker,
|
options: options,
|
||||||
project: this.currProject
|
project: this.currProject
|
||||||
});
|
});
|
||||||
this.popup.content
|
this.popup.content
|
||||||
@@ -330,7 +343,7 @@ export default {
|
|||||||
.provide('consts', this.consts)
|
.provide('consts', this.consts)
|
||||||
.mount($Popup);
|
.mount($Popup);
|
||||||
},
|
},
|
||||||
closeMarkerPopup() {
|
closePopup() {
|
||||||
if(this.popup.content) {
|
if(this.popup.content) {
|
||||||
this.popup.content.unmount();
|
this.popup.content.unmount();
|
||||||
this.popup.content = null;
|
this.popup.content = null;
|
||||||
@@ -444,19 +457,21 @@ export default {
|
|||||||
},
|
},
|
||||||
async checkNewFeed() {
|
async checkNewFeed() {
|
||||||
let aoData = await this.api.get('new_feed', {id_project: this.currProject.id, id: this.feed.refIdFirst});
|
let aoData = await this.api.get('new_feed', {id_project: this.currProject.id, id: this.feed.refIdFirst});
|
||||||
|
const aoFeed = aoData.feed || [];
|
||||||
|
const aoMarkers = aoData.markers || [];
|
||||||
|
|
||||||
if(Object.keys(aoData.feed).length > 0) {
|
if(aoFeed.length > 0) {
|
||||||
//Update pointer
|
//Update pointer
|
||||||
this.feed.refIdFirst = aoData.ref_id_first;
|
this.feed.refIdFirst = aoData.ref_id_first;
|
||||||
|
|
||||||
//Add new posts
|
//Add new posts
|
||||||
this.posts.unshift(...aoData.feed);
|
this.posts.unshift(...aoFeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Add new Markers
|
//Add new Markers
|
||||||
if(Object.keys(aoData.markers).length > 0) {
|
if(aoMarkers.length > 0) {
|
||||||
this.markers.push(...aoData.markers);
|
this.markers.push(...aoMarkers);
|
||||||
aoData.messages.forEach(oMarker => this.addMarker(oMarker));
|
aoMarkers.forEach(oMarker => this.addMarker(oMarker));
|
||||||
}
|
}
|
||||||
|
|
||||||
//Message Last Update
|
//Message Last Update
|
||||||
|
|||||||
@@ -29,33 +29,43 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div :class="options.type">
|
<div :class="options.type+' '+options.subtype">
|
||||||
<div class="header" v-if="options.type=='message'">
|
<div class="header" v-if="options.type=='track'">
|
||||||
<h1>
|
<h1>
|
||||||
<spotIcon :icon="'message'" size="lg" :text="lang.get('feed.counter', options.displayed_id)" width="auto" />
|
<spotIcon :icon="options.subtype" size="lg" :text="this.options.name" width="auto" :textClasses="options.subtype" />
|
||||||
<span class="message-type">({{ options.type }})</span>
|
|
||||||
</h1>
|
</h1>
|
||||||
<div class="separator"></div>
|
<p v-if="options.description" class="description">{{ options.description }}</p>
|
||||||
|
<div v-if="options.subtype!='hitchhiking'" class="separator"></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="options.type=='track'">
|
||||||
|
<div v-if="options.subtype!='hitchhiking'" class="section track-stats">
|
||||||
|
<spotIcon :title="lang.get('stats.distance')" :icon="'distance'" width="fixed" size="lg" :text="options.distance+'km'" />
|
||||||
|
<spotIcon :title="lang.get('stats.duration')" :icon="'time'" width="fixed" size="lg" :text="options.duration" />
|
||||||
|
<spotIcon :title="lang.get('stats.elevation_gain')" :icon="'elev-gain'" width="fixed" size="lg" :text="options.elev_gain+'m'" />
|
||||||
|
<spotIcon :title="lang.get('stats.elevation_loss')" :icon="'elev-drop'" width="fixed" size="lg" :text="options.elev_drop+'m'" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
<div class="section coordinates">
|
<div class="section coordinates">
|
||||||
<spotIcon :icon="'coords'" fixed-width size="lg" margin="right" />
|
<spotIcon :icon="'coords'" width="fixed" size="lg" margin="right" />
|
||||||
<projectMapLink :options="options" />
|
<projectMapLink :options="options" />
|
||||||
</div>
|
</div>
|
||||||
<div class="section altitude" v-if="options.altitude">
|
<div v-if="options.altitude" class="section altitude">
|
||||||
<spotIcon :icon="'altitude'" fixed-width size="lg" :text="options.altitude+'m'" />
|
<spotIcon :icon="'altitude'" width="fixed" size="lg" :text="options.altitude+'m'" />
|
||||||
</div>
|
</div>
|
||||||
<div class="section time">
|
<div class="section time">
|
||||||
<projectRelTime :icon="timeIcon" :localTime="options.formatted_time_local" :siteTime="options.formatted_time" :offset="options.day_offset" />
|
<projectRelTime :icon="timeIcon" :localTime="options.formatted_time_local" :siteTime="options.formatted_time" :offset="options.day_offset" />
|
||||||
<span v-if="project.mode==consts.modes.blog"> ({{ options.relative_time }})</span>
|
<span v-if="project.mode==consts.modes.blog"> ({{ options.relative_time }})</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="section weather" v-if="options.weather_icon && options.weather_icon!='unknown'" :title="options.weather_cond==''?'':lang.get('weather.'+options.weather_icon)">
|
<div class="section weather" v-if="options.weather_icon && options.weather_icon!='unknown'" :title="options.weather_cond==''?'':lang.get('weather.'+options.weather_icon)">
|
||||||
<spotIcon :icon="options.weather_icon" fixed-width size="lg" :text="options.weather_temp+'°C'" />
|
<spotIcon :icon="options.weather_icon" width="fixed" size="lg" :text="options.weather_temp+'°C'" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="medias" class="section medias">
|
<div v-if="medias" class="section medias">
|
||||||
<spotIcon v-if="options.type=='message'" icon="media" fixed-width size="lg" :text="lang.get('media.nearby')" />
|
<spotIcon v-if="options.type=='message'" icon="media" width="fixed" size="lg" :text="lang.get('media.nearby')" />
|
||||||
<div class="medias-list">
|
<div class="medias-list">
|
||||||
<projectMediaLink v-for="media in medias" :options="media" :type="'marker'" />
|
<projectMediaLink v-for="media in medias" :options="media" :type="'marker'" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -91,16 +91,16 @@
|
|||||||
this.hash.items = [this.hash.items[0], this.options.type, this.options.id];
|
this.hash.items = [this.hash.items[0], this.options.type, this.options.id];
|
||||||
|
|
||||||
return this.map.panToBetweenPanels(this.lngLat, this.focusZoomLevel, iAnimDuration).then(() => {
|
return this.map.panToBetweenPanels(this.lngLat, this.focusZoomLevel, iAnimDuration).then(() => {
|
||||||
this.openMarkerPopup();
|
this.openMarkerPopup(false);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
openMarkerPopup() {
|
openMarkerPopup(bMouseEvent=true) {
|
||||||
this.mouseOverDrill = true;
|
this.mouseOverDrill = bMouseEvent;
|
||||||
if(this.map.isMarkerVisible(this.lngLat)) this.map.openMarkerPopup(this.options.id, this.options.type);
|
if(this.map.isMarkerVisible(this.lngLat)) this.map.openMarkerPopup(this.options.id, this.options.type);
|
||||||
},
|
},
|
||||||
closeMarkerPopup() {
|
closeMarkerPopup() {
|
||||||
this.mouseOverDrill = false;
|
this.mouseOverDrill = false;
|
||||||
if(!this.popupRequested) this.map.closeMarkerPopup();
|
if(!this.popupRequested) this.map.closePopup();
|
||||||
this.popupRequested = false;
|
this.popupRequested = false;
|
||||||
},
|
},
|
||||||
send() {
|
send() {
|
||||||
|
|||||||
@@ -88,9 +88,9 @@ const ICONS = {
|
|||||||
map: faMapLocationDot,
|
map: faMapLocationDot,
|
||||||
marker: faLocationPin,
|
marker: faLocationPin,
|
||||||
footprint: faShoePrints,
|
footprint: faShoePrints,
|
||||||
'track-off-track': faPersonHiking,
|
'off-track': faPersonHiking,
|
||||||
'track-main': faPersonHiking,
|
'main': faPersonHiking,
|
||||||
'track-hitchhiking': faCarSide,
|
'hitchhiking': faCarSide,
|
||||||
'track-start': faPersonHiking,
|
'track-start': faPersonHiking,
|
||||||
'track-end': faPersonHiking,
|
'track-end': faPersonHiking,
|
||||||
layers: faLayerGroup,
|
layers: faLayerGroup,
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import { LngLat } from 'maplibre-gl';
|
||||||
|
|
||||||
export default class Projects {
|
export default class Projects {
|
||||||
|
|
||||||
constructor(asProjects = {}) {
|
constructor(asProjects = {}) {
|
||||||
@@ -14,4 +16,83 @@ export default class Projects {
|
|||||||
const sCodeName = this.getDefaultCodeName();
|
const sCodeName = this.getDefaultCodeName();
|
||||||
return this[this.getDefaultCodeName()];
|
return this[this.getDefaultCodeName()];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTrackInfo(oFeature, oTrack, oLang) {
|
||||||
|
const iTrackId = Number(oFeature.properties.track_id);
|
||||||
|
const oTrackFeature = oTrack.features[iTrackId] || oFeature;
|
||||||
|
const aoCoords = oTrackFeature.geometry.coordinates;
|
||||||
|
|
||||||
|
if(oTrackFeature.properties.type == 'hitchhiking') {
|
||||||
|
return {
|
||||||
|
type: 'track',
|
||||||
|
subtype: oTrackFeature.properties.type,
|
||||||
|
name: oTrackFeature.properties.name
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const asStats = this.getTrackStats(aoCoords);
|
||||||
|
return {
|
||||||
|
type: 'track',
|
||||||
|
subtype: oTrackFeature.properties.type,
|
||||||
|
name: oTrackFeature.properties.name,
|
||||||
|
description: oTrackFeature.properties.description,
|
||||||
|
distance: Math.round(asStats.distance / 100) / 10,
|
||||||
|
elev_gain: Math.round(asStats.elevGain),
|
||||||
|
elev_drop: Math.abs(Math.round(asStats.elevDrop)),
|
||||||
|
duration: this.getNaturalDuration(asStats.time, oLang)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
getNaturalDuration(iHours, oLang) {
|
||||||
|
let iTimeMinutes = 0, iTimeHours = 0, iTimeDays = Math.floor(iHours/8); //8 hours a day
|
||||||
|
if(iTimeDays > 1) iTimeDays = Math.round(iTimeDays * 2) / 2; //Round down to the closest half day
|
||||||
|
else {
|
||||||
|
iTimeDays = 0;
|
||||||
|
iTimeHours = Math.floor(iHours);
|
||||||
|
iHours -= iTimeHours;
|
||||||
|
|
||||||
|
iTimeMinutes = Math.floor(iHours * 4) * 15; //Round down to the closest 15 minutes
|
||||||
|
}
|
||||||
|
return '~'
|
||||||
|
+(iTimeDays>0?(iTimeDays+(iTimeDays%2==0?'':'\u00bd')+' '+oLang.get(iTimeDays>1?'unit.days':'unit.day')):'') //Days
|
||||||
|
+((iTimeHours>0 || iTimeDays==0)?iTimeHours+oLang.get('unit.hour'):'') //Hours
|
||||||
|
+((iTimeDays>0 || iTimeMinutes==0)?'':iTimeMinutes); //Minutes
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
getTrackStats(aoCoords) {
|
||||||
|
let iDistance = 0, iElevDrop = 0, iElevGain = 0, iTime = 0;
|
||||||
|
|
||||||
|
for(let i = 1; i < aoCoords.length; i++) {
|
||||||
|
const oCurrPoint = new LngLat(aoCoords[i][0], aoCoords[i][1]);
|
||||||
|
const oPrevPoint = new LngLat(aoCoords[i - 1][0], aoCoords[i - 1][1]);
|
||||||
|
const iCurrElev = Number(aoCoords[i][2]);
|
||||||
|
const iPrevElev = Number(aoCoords[i - 1][2]);
|
||||||
|
const iElevDelta = (Number.isFinite(iCurrElev) && Number.isFinite(iPrevElev))?(iCurrElev - iPrevElev):0;
|
||||||
|
const iSegDistance = oCurrPoint.distanceTo(oPrevPoint);
|
||||||
|
if(iSegDistance <= 0) continue;
|
||||||
|
|
||||||
|
iDistance += iSegDistance;
|
||||||
|
iElevDrop += Math.min(iElevDelta, 0);
|
||||||
|
iElevGain += Math.max(iElevDelta, 0);
|
||||||
|
|
||||||
|
let iSpeedCorrecRatio = 0;
|
||||||
|
const iAngle = iElevDelta / iSegDistance;
|
||||||
|
if(iAngle < -1) iSpeedCorrecRatio = 0.5;
|
||||||
|
else if(iAngle < -0.2) iSpeedCorrecRatio = 1.25;
|
||||||
|
else if(iAngle < 0.1) iSpeedCorrecRatio = 1;
|
||||||
|
else if(iAngle < 0.25) iSpeedCorrecRatio = 0.85;
|
||||||
|
else if(iAngle < 0.5) iSpeedCorrecRatio = 0.6;
|
||||||
|
else if(iAngle < 1) iSpeedCorrecRatio = 0.5;
|
||||||
|
else iSpeedCorrecRatio = 0.25;
|
||||||
|
iTime += iSegDistance / 1000 * iSpeedCorrecRatio / 3.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
distance: iDistance,
|
||||||
|
elevDrop: iElevDrop,
|
||||||
|
elevGain: iElevGain,
|
||||||
|
time: iTime
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,15 +30,16 @@ $thumbnail-max-size: 60px;
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
.message-type {
|
span.hitchhiking {
|
||||||
color: color.$default;
|
font-size: calc(1em / 1.4 * 1.2);
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-size: calc(1em / 1.4);
|
|
||||||
margin-left: 0.5em;
|
|
||||||
vertical-align: center;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
.separator {
|
.separator {
|
||||||
border-top: 1px solid color.$default-bg;
|
border-top: 1px solid color.$default-bg;
|
||||||
margin: var.$elem-spacing 0;
|
margin: var.$elem-spacing 0;
|
||||||
@@ -48,11 +49,21 @@ $thumbnail-max-size: 60px;
|
|||||||
font-size: 1.0em;
|
font-size: 1.0em;
|
||||||
margin: var.$elem-spacing 0 0 0;
|
margin: var.$elem-spacing 0 0 0;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: color.$default;
|
color: color.$default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.track-stats {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
gap: var.$elem-spacing;
|
||||||
|
}
|
||||||
|
|
||||||
.medias-list {
|
.medias-list {
|
||||||
line-height: 0;
|
line-height: 0;
|
||||||
|
|
||||||
@@ -104,10 +115,6 @@ $thumbnail-max-size: 60px;
|
|||||||
}
|
}
|
||||||
|
|
||||||
.media {
|
.media {
|
||||||
.coordinates {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.medias-list {
|
.medias-list {
|
||||||
a.media-link img {
|
a.media-link img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
Reference in New Issue
Block a user