Replace leaflet with maplibre GL
This commit is contained in:
166
src/components/projectPost.vue
Normal file
166
src/components/projectPost.vue
Normal file
@@ -0,0 +1,166 @@
|
||||
<script>
|
||||
import spotIcon from './spotIcon.vue';
|
||||
import spotButton from './spotButton.vue';
|
||||
import projectMediaLink from './projectMediaLink.vue';
|
||||
import projectMapLink from './projectMapLink.vue';
|
||||
import projectRelTime from './projectRelTime.vue';
|
||||
|
||||
import autosize from 'autosize';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
spotIcon,
|
||||
spotButton,
|
||||
projectMediaLink,
|
||||
projectMapLink,
|
||||
projectRelTime
|
||||
},
|
||||
props: {
|
||||
options: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
time: '',
|
||||
absTime: this.options.formatted_time,
|
||||
absTimeLocal: this.options.formatted_time_local,
|
||||
anchorVisible: ['message', 'media', 'post'].includes(this.options.type),
|
||||
anchorTitle: this.spot.lang('copy_to_clipboard'),
|
||||
anchorIcon: 'link'
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
postClass() {
|
||||
let sHeaderLess = this.options.headerless?' headerless':'';
|
||||
return 'post-item '+this.options.type+sHeaderLess;
|
||||
},
|
||||
postId() {
|
||||
return this.options.id?(this.options.type+'-'+this.options.id):'';
|
||||
},
|
||||
subType() {
|
||||
return this.options.subtype || this.options.type;
|
||||
},
|
||||
displayedId() {
|
||||
return this.options.displayed_id?(' '+this.spot.lang('counter', this.options.displayed_id)):'';
|
||||
},
|
||||
hash() {
|
||||
let asHash = this.spot.getHash();
|
||||
return '#'+[asHash.page, asHash.items[0], this.options.type, this.options.id].join(this.spot.consts.hash_sep);
|
||||
},
|
||||
timeDiff() {
|
||||
return (this.options.formatted_time && this.options.formatted_time_local != this.options.formatted_time);
|
||||
},
|
||||
modeHisto() {
|
||||
return (this.$parent.project.mode==this.spot.consts.modes.histo);
|
||||
},
|
||||
relTime() {
|
||||
return this.modeHisto?this.options.formatted_time.substr(0, 10):this.options.relative_time;
|
||||
}
|
||||
},
|
||||
inject: ['spot'],
|
||||
methods: {
|
||||
copyAnchor() {
|
||||
copyTextToClipboard(this.spot.consts.server+this.spot.hash());
|
||||
this.anchorTitle = this.spot.lang('link_copied');
|
||||
this.anchorIcon = 'copied';
|
||||
setTimeout(()=>{ //TODO animation
|
||||
this.anchorTitle = this.spot.lang('copy_to_clipboard');
|
||||
this.anchorIcon = 'link';
|
||||
}, 5000);
|
||||
},
|
||||
panMapToMessage() {
|
||||
//TODO
|
||||
/*
|
||||
var $Parent = $(oEvent.currentTarget).parent();
|
||||
var oMarker = this.spot.tmp(['markers', $Parent.data('id')]);
|
||||
if(this.isMobile()) {
|
||||
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() {
|
||||
//TODO
|
||||
/*
|
||||
let oMarker = this.spot.tmp(['markers', $(oEvent.currentTarget).data('id')]);
|
||||
if(this.spot.tmp('map') && this.spot.tmp('map').getBounds().contains(oMarker.getLatLng()) && !oMarker.isPopupOpen()) oMarker.openPopup();
|
||||
*/
|
||||
},
|
||||
closeMarkerPopup() {
|
||||
//TODO
|
||||
/*
|
||||
let $This = $(oEvent.currentTarget);
|
||||
let oMarker = this.spot.tmp(['markers', $This.data('id')]);
|
||||
if(oMarker && oMarker.isPopupOpen() && !$This.data('clicked')) oMarker.closePopup();
|
||||
$This.data('clicked', false);
|
||||
*/
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
//Auto-adjust text area height
|
||||
if(this.options.type == 'poster') {
|
||||
autosize(this.$refs.post);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="postClass" :id="postId">
|
||||
<div class="header">
|
||||
<span class="index">
|
||||
<a v-if="anchorVisible" class="link desktop" @click="copyAnchor" ref="anchor" :href="hash" :title="anchorTitle"><spotIcon :icon="anchorIcon" /></a>
|
||||
<spotIcon :icon="subType" :text="displayedId" />
|
||||
</span>
|
||||
<span class="time" @mouseover="time = relTime" @mouseleave="time = timeDiff?spot.lang('your_time', absTime):absTime">{{ time }}</span>
|
||||
</div>
|
||||
<div class="body">
|
||||
<div v-if="options.type == 'message'" class="body-box" @mouseenter="openMarkerPopup" @mouseleave="closeMarkerPopup">
|
||||
<p><spotIcon :icon="'coords'" /><projectMapLink :options="options" /></p>
|
||||
<p><spotIcon :icon="'time'" :text="absTime" /></p>
|
||||
<p v-if="timeDiff"><spotIcon :icon="'timezone'" /><projectRelTime :localTime="absTimeLocal" :offset="options.day_offset" /></p>
|
||||
<a class="drill" @click.prevent="panMapToMessage">
|
||||
<span v-if="options.weather_icon && options.weather_icon!='unknown'" class="weather clickable" :title="spot.lang(options.weather_cond)">
|
||||
<spotIcon :icon="options.weather_icon" />
|
||||
<span>{{ options.weather_temp+'°C' }}</span>
|
||||
</span>
|
||||
<img class="staticmap clickable" :title="spot.lang('click_zoom')" :src="options.static_img_url" />
|
||||
<span class="drill-icon fa-stack clickable">
|
||||
<spotIcon :icon="'message'" :classes="'fa-stack-2x clickable'" />
|
||||
<spotIcon :icon="'message-in'" :classes="'fa-stack-1x fa-rotate-270'" />
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div v-else-if="options.type == 'media'" class="body-box">
|
||||
<projectMediaLink :options="options" :type="'post'" />
|
||||
</div>
|
||||
<div v-else-if="options.type == 'post'">
|
||||
<p class="message">{{ options.content }}</p>
|
||||
<p class="signature">
|
||||
<img v-if="options.gravatar" :src="'data:image/png;base64, '+options.gravatar" width="24" height="24" alt="--" />
|
||||
<span v-else>-- </span>
|
||||
<span>{{ options.formatted_name }}</span>
|
||||
</p>
|
||||
</div>
|
||||
<p v-else-if="options.type == 'poster'" class="message">
|
||||
<textarea ref="post" name="post" :placeholder="spot.lang('post_message')" class="autoExpand" rows="1" v-model="$parent.post"></textarea>
|
||||
<input type="text" name="name" :placeholder="spot.lang('post_name')" v-model="$parent.user.name" />
|
||||
<spotButton name="submit" :aria-label="spot.lang('send')" :title="spot.lang('send')" :icon="'send'" />
|
||||
</p>
|
||||
<div v-else-if="options.type == 'archived'">
|
||||
<p><spotIcon :icon="'success'" /></p>
|
||||
<p>{{ spot.lang('mode_histo') }}</p>
|
||||
</div>
|
||||
<div v-else-if="options.type == 'loading'">
|
||||
<p class="flicker"><spotIcon :icon="'post'" /></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user