OTM/public/js/main.js

306 lines
12 KiB
JavaScript
Raw Normal View History

2021-07-16 09:12:30 +02:00
const gen_id = (length)=>{
var result = '';
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const len = characters.length;
for (let i = 0; i < length; i++ ) {
result += characters.charAt(Math.floor(Math.random() * len));
}
return result;
}
2021-08-04 14:43:00 +02:00
Date.prototype.toJSONLocal = (function() {
function addZ(n) {
return (n<10? '0' : '') + n;
}
return function() {
return this.getFullYear() + '-' +
addZ(this.getMonth() + 1) + '-' +
addZ(this.getDate());
};
}())
2021-07-16 09:12:30 +02:00
const query_nominatim = (q,f)=>{
2021-07-16 12:17:32 +02:00
const ENDPOINT = '/api/place/'+q;
return axios.get(ENDPOINT).then(res=>res.data).then(res=>res.filter(f));
2021-07-16 09:12:30 +02:00
}
const query_flight = (q)=>{
const ENDPOINT = '/api/flight/'+q;
return axios.get(ENDPOINT).then(res=>res.data);
}
2021-08-04 14:51:33 +02:00
const is_restauration_type = (item)=>{
2021-07-16 09:12:30 +02:00
const arr = ["restaurant", "cafe", "pub", "bar", "fast_food", "food_court"];
2021-08-04 14:51:33 +02:00
return arr.indexOf(item.type)!=-1;
2021-07-16 09:12:30 +02:00
}
const is_attraction_type = (item)=>{
2021-08-04 07:49:39 +02:00
const arr = ["tourism", "leisure", "place", "amenity"];
2021-07-16 09:12:30 +02:00
return arr.indexOf(item.category)!=-1;
}
const icon_type = (item)=>{
let t = item.type
const arr = ["restaurant", "cafe", "pub", "bar", "fast_food", "food_court"];
if(arr.indexOf(t)!=-1){
return 'utensils';
2021-08-04 07:40:26 +02:00
}else if(t=='hotel' || t=='hostel'){
2021-07-16 09:12:30 +02:00
return 'bed';
}else if(t=='museum'){
return 'landmark';
2021-07-16 19:03:55 +02:00
}else if(t=='peak' || t=='viewpoint'){
2021-07-16 09:12:30 +02:00
return 'mountain';
}else if(t=='parking'){
return 'parking';
2021-08-04 15:19:26 +02:00
}else if(t=='water' || t=='river' || t=='lake' || t=='torrent' || t=='aquarium'){
2021-07-16 09:12:30 +02:00
return 'water';
}else if(t=='community_centre'){
return 'building';
}else if(t=='attraction'){
return 'landmark';
2021-08-04 15:19:26 +02:00
}else if(t=='information' || t=='university'){
2021-07-16 09:12:30 +02:00
return 'landmark';
}else if(t=='bridge'){
return 'archway';
2021-08-04 15:19:26 +02:00
}else if(t=='woodland'|| t=='shieling' || t=='national_park' || t=='zoo' || t=='park'){
2021-07-16 19:03:55 +02:00
return 'tree';
2021-07-16 23:28:45 +02:00
}else if(t=='water_park'){
return 'dice-five';
2021-07-16 19:03:55 +02:00
}else if(t=='?'){
2021-07-16 09:12:30 +02:00
return '';
}else{
2021-08-04 15:17:30 +02:00
console.log(item.display_name, item.category, item.type);
2021-07-16 09:12:30 +02:00
return 'question';
}
}
Vue.component('l-map', window.Vue2Leaflet.LMap);
Vue.component('l-tile-layer', window.Vue2Leaflet.LTileLayer);
Vue.component('l-marker', window.Vue2Leaflet.LMarker);
Vue.component('l-icon', window.Vue2Leaflet.LIcon);
Vue.component('l-popup', window.Vue2Leaflet.LPopup);
Vue.component('l-tooltip', window.Vue2Leaflet.LTooltip);
Vue.component('l-control-scale', window.Vue2Leaflet.LControlScale);
2021-07-16 22:53:57 +02:00
Vue.use(window.VueTextareaAutosize);
Vue.component('multiselect', window.VueMultiselect.default);
2021-07-16 09:12:30 +02:00
const app = new Vue({
el: '#app',
data: {
2021-07-16 22:53:57 +02:00
journey_id : window.location.pathname.split('/').pop() || gen_id(16),
2021-08-03 13:18:25 +02:00
journey_step: window.location.hash.slice(1)==""?((['view','short'].indexOf(window.location.pathname.split('/')[1])!=-1)?0:-1):parseInt(window.location.hash.slice(1)),
2021-07-16 09:12:30 +02:00
journey_step_data: {day:-1, section:-1},
journey_data : {
name: "New Journey",
main:[],
step_title:[],
},
2021-08-03 13:18:25 +02:00
vtp: ['view','short'].indexOf(window.location.pathname.split('/')[1]),
2021-07-16 09:12:30 +02:00
query:{hotel:[],flight:[],nominatim:[]},
querying:{hotel:false,flight:false,place:false,food:false},
impexp:"",
2021-08-04 14:43:00 +02:00
lang: {
formatLocale: {
firstDayOfWeek: 1,
},
monthBeforeYear: true,
},
2021-07-16 09:12:30 +02:00
},
methods: {
start_journey: function(event){
window.location.href = '/'+this.journey_id;
},
add_section: function(event){
if(this.journey_data.main===undefined) this.journey_data.main=[];
this.journey_data.main.push({map:{zoom:2}, hotel:{latlon:[0,0]},places:{restaurants:[],places:[]}});
},
next_step: function(){
this.journey_step+=1;
this.journey_step_data = this.step_convert(this.journey_step);
2021-07-16 16:17:55 +02:00
if(this.journey_step_data.section==-1) this.prev_step();
window.location.hash = '#' + this.journey_step;
},
prev_step: function(){
this.journey_step-=1;
if(this.journey_step<-1) this.journey_step=-1;
2021-07-16 16:54:31 +02:00
if(this.journey_step==-1 && this.view) this.journey_step=0;
2021-07-16 16:17:55 +02:00
this.journey_step_data = this.step_convert(this.journey_step);
2021-07-16 09:12:30 +02:00
window.location.hash = '#' + this.journey_step;
},
2021-08-03 13:18:25 +02:00
nextnext_step: function(){
let nd = this.journey_step_data;
let ns = this.journey_step;
while((nd.section==this.journey_step_data.section || nd.day>1)
&& ns>=0){
ns+=1;
nd = this.step_convert(ns)
if(nd.section==-1){
ns-=1;
nd = this.step_convert(ns)
break;
}
}
this.journey_step = ns;
this.journey_step_data = nd;
window.location.hash = '#' + this.journey_step;
},
prevprev_step: function(){
let nd = this.journey_step_data;
let ns = this.journey_step;
while((nd.section==this.journey_step_data.section || nd.day>1)
&& ns>=0){
ns-=1;
nd = this.step_convert(ns)
if(ns==-1){
ns+=1;
nd = this.step_convert(ns)
break;
}
}
this.journey_step = ns;
this.journey_step_data = nd;
window.location.hash = '#' + this.journey_step;
},
2021-07-16 09:12:30 +02:00
first_step: function(){
this.journey_step=-1;
this.journey_step_data = {day:-1, section:-1};
window.location.hash = '';
},
step_convert: function(step){
let steps_left = step+1;
for(let e in this.journey_data.main){
if(this.journey_data.main[e].dateRange && (this.journey_data.main[e].dateRange[0]-(new Date(0))) != 0){
2021-07-16 19:14:45 +02:00
let cd = ((this.journey_data.main[e].dateRange[1]-this.journey_data.main[e].dateRange[0])/(1000*60*60*24))+1;
2021-07-16 09:12:30 +02:00
if(cd>=steps_left){
return {day: steps_left, section:e,start: (steps_left==1), end: (steps_left==cd)};
}else{
steps_left -= cd;
}
}else{
steps_left -= 1;
}
if(steps_left==0){
return {day:0,section:e, start:true,end:true};
}
}
return {day:-1, section:-1};
},
2021-08-03 13:18:25 +02:00
active_date: function(){
if(this.journey_step_data.day < 0) return "?";
if(!this.journey_data.main[this.journey_step_data.section].dateRange) return "?";
var date = new Date(this.journey_data.main[this.journey_step_data.section].dateRange[0]);
date.setDate(date.getDate() + this.journey_step_data.day-1);
return this.format_date(date)
},
format_date: function(d){
2021-08-04 14:43:00 +02:00
var dt = d.toJSONLocal().slice(0, 10);
2021-08-03 13:18:25 +02:00
return dt.slice(8, 10) + '/'
+ dt.slice(5, 7) + '/'
+ dt.slice(0, 4) + ' ('
+ ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'][d.getDay()]
+')';
},
2021-07-16 09:12:30 +02:00
rm_section: function(idx){
this.journey_data.main.splice(idx,1);
},
search_nominatim: function(txt,f){
if(txt==""){
this.query.nominatim=[];
return Promise.resolve([]);
}
return query_nominatim(txt,f)
.then((results) =>{
2021-07-16 16:17:55 +02:00
results.forEach(r=>{
r.latlon=[parseFloat(r.lat),parseFloat(r.lon)];
r.sname=r.display_name.split(',')[0];
})
2021-07-16 09:12:30 +02:00
this.query.nominatim=results;
});
},
search_flight: function(txt){
if(txt=="") return;
this.querying.flight=true;
query_flight(txt.replace(" ", ""))
.then((results) =>{
if(results.results==""){
this.query.flight=[];this.querying.flight=false;return;
}
this.query.flight=results.results;
this.querying.flight=false;
});
},
2021-07-16 16:17:55 +02:00
generate_icon: function(item,fcolor){
return L.AwesomeMarkers.icon({
icon: icon_type(item) || 'star', prefix: 'fa',
markerColor: fcolor || item.color || 'blue'}
2021-07-16 09:12:30 +02:00
).createIcon().outerHTML
},
save_data: function(){
this.impexp = window.btoa(JSON.stringify(this.journey_data));
axios.post('/api/'+this.journey_id, this.journey_data).then(response => {
console.log("Saved...")
}).catch(error => {
console.warn('Error! Could not reach the API.')
})
},
import_data:function(){
2021-07-16 19:11:25 +02:00
this.journey_data = Object.assign({}, JSON.parse(window.atob(this.impexp)));
2021-07-16 09:12:30 +02:00
},
export_data:function(){
this.impexp = window.btoa(JSON.stringify(this.journey_data));
},
filter_selected:function(list,step){
return list.filter(e=>(step?(e.step==this.journey_step):(e.step>=0)))
},
filter_unselected:function(list){
return list.filter(e=>(e.step==undefined || e.step<0))
},
remove_item:function(list,idx){
list[idx].step=-1;
list.splice(idx, 1);
},
log:function(e){console.log(e)},
},
created: function () {
axios.get('/api/'+this.journey_id).then(response =>{
app.journey_data = response.data;
for(let e of app.journey_data.main){
if(e.dateRange && e.dateRange.length===2){
e.dateRange[0]= new Date(e.dateRange[0]);
e.dateRange[1]= new Date(e.dateRange[1]);
}
}
this.journey_step_data = this.step_convert(this.journey_step);
});
this.debounceSave = _.debounce(this.save_data, 500)
2021-08-04 07:40:26 +02:00
this.debounceSearch = {"hotel":_.debounce((q)=>{this.querying.hotel=true;this.search_nominatim(q,(r)=>(r.type=="hotel" || r.type=="hostel")).then((r)=>{this.querying.hotel=false});}, 500),
2021-08-04 14:51:33 +02:00
"restaurants":_.debounce((q)=>{this.querying.food=true;this.search_nominatim(q,(r)=>(is_restauration_type(r))).then((r)=>{this.querying.food=false});}, 500),
"places":_.debounce((q)=>{this.querying.place=true;this.search_nominatim(q,(r)=>(is_attraction_type(r))).then((r)=>{this.querying.place=false});}, 500),
2021-07-16 09:12:30 +02:00
"other":_.debounce((q)=>{this.querying.any=true;this.search_nominatim(q,(r)=>(true)).then((r)=>{this.querying.any=false});}, 500),
"flight":_.debounce((q)=>this.search_flight(q), 500)
}
},
watch: {
journey_data: {
handler:function (ndata, odata){
this.debounceSave()
if(ndata.main.length == odata.main.length){
for(let d in ndata.main){
if(ndata.main[d].hotel != odata.main[d].hotel){
if(ndata.main[d].hotel.latlon){
this.journey_data.main[d].map.center=ndata.main[d].hotel.latlon;
}
}
}
}
},
deep: true,
},
},
})