Migrate to esbuild & ts
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
122
src/api.ts
Normal file
122
src/api.ts
Normal file
@ -0,0 +1,122 @@
|
||||
import axios from "axios";
|
||||
|
||||
export const load = (id: string) =>
|
||||
axios.get("/api/" + id).then((response) => {
|
||||
if (response.data == "") throw "Invalid Journey Data Received";
|
||||
let res = response.data;
|
||||
|
||||
for (let e of res.main) {
|
||||
if (e.dateRange) {
|
||||
e.dateRange[0] = new Date(e.dateRange[0]);
|
||||
e.dateRange[1] = new Date(e.dateRange[1]);
|
||||
}
|
||||
e.step_title = e.step_title || [];
|
||||
}
|
||||
return res;
|
||||
});
|
||||
|
||||
export const save = (id: string, v: string) =>
|
||||
axios
|
||||
.post("/api/" + id, v)
|
||||
.then((response) => {
|
||||
console.log("Saved...");
|
||||
})
|
||||
.catch((error) => {
|
||||
console.warn("Error! Could not reach the API.");
|
||||
});
|
||||
|
||||
export const query_nominatim = (
|
||||
q: string,
|
||||
f: (v: string) => Boolean = () => true,
|
||||
) =>
|
||||
axios
|
||||
.get("/api/place/" + q)
|
||||
.then((res) => res.data)
|
||||
.then((res) => res.filter(f));
|
||||
|
||||
export const query_flight = (q: string) =>
|
||||
axios.get("/api/flight/" + q).then((res) => res.data);
|
||||
|
||||
type NominatimResult = {
|
||||
type: string;
|
||||
category: string;
|
||||
display_name: string; // DEBUG ONLY
|
||||
};
|
||||
|
||||
export const is_restauration_type = (e: NominatimResult) =>
|
||||
["restaurant", "cafe", "pub", "bar", "fast_food", "food_court"].indexOf(
|
||||
e.type,
|
||||
) != -1;
|
||||
|
||||
export const is_attraction_type = (e: NominatimResult): boolean =>
|
||||
[
|
||||
"tourism",
|
||||
"leisure",
|
||||
"place",
|
||||
"amenity",
|
||||
"highway",
|
||||
"historic",
|
||||
"natural",
|
||||
"waterway",
|
||||
].indexOf(e.category) != -1 ||
|
||||
[
|
||||
"place_of_worship",
|
||||
"national_park",
|
||||
"nature_reserve",
|
||||
"protected_area",
|
||||
].indexOf(e.type) != -1;
|
||||
|
||||
export const icon_type = (item: NominatimResult): string => {
|
||||
let t = item.type;
|
||||
let c = item.category;
|
||||
const arr = ["restaurant", "cafe", "pub", "bar", "fast_food", "food_court"];
|
||||
if (arr.indexOf(t) != -1) {
|
||||
return "utensils";
|
||||
} else if (t == "hotel" || t == "hostel" || t == "guest_house") {
|
||||
return "bed";
|
||||
} else if (t == "museum" || c == "historic" || t == "place_of_worship") {
|
||||
return "landmark";
|
||||
} else if (t == "peak" || t == "viewpoint") {
|
||||
return "mountain";
|
||||
} else if (t == "parking") {
|
||||
return "parking";
|
||||
} else if (
|
||||
t == "water" ||
|
||||
t == "river" ||
|
||||
t == "lake" ||
|
||||
t == "torrent" ||
|
||||
t == "aquarium"
|
||||
) {
|
||||
return "water";
|
||||
} else if (t == "community_centre" || t == "locality") {
|
||||
return "building";
|
||||
} else if (t == "attraction") {
|
||||
return "landmark";
|
||||
} else if (t == "information" || t == "university") {
|
||||
return "landmark";
|
||||
} else if (t == "bridge") {
|
||||
return "archway";
|
||||
} else if (
|
||||
t == "woodland" ||
|
||||
t == "shieling" ||
|
||||
t == "national_park" ||
|
||||
t == "zoo" ||
|
||||
t == "park" ||
|
||||
t == "garden" ||
|
||||
0
|
||||
) {
|
||||
return "tree";
|
||||
} else if (t == "water_park" || t == "theme_park") {
|
||||
return "dice-five";
|
||||
} else if (
|
||||
t == "?" ||
|
||||
t == "neighbourhood" ||
|
||||
t == "quarter" ||
|
||||
c == "highway"
|
||||
) {
|
||||
return "";
|
||||
} else {
|
||||
console.log(item.display_name, item.category, item.type);
|
||||
return "question";
|
||||
}
|
||||
};
|
13
src/app.ts
Normal file
13
src/app.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import "./types/ext";
|
||||
import "./api";
|
||||
import "./old.js";
|
||||
|
||||
console.log("TEST");
|
||||
|
||||
if (false) {
|
||||
console.log("B");
|
||||
}
|
||||
|
||||
function test() {
|
||||
console.log("CC");
|
||||
}
|
344
src/old.js
Normal file
344
src/old.js
Normal file
@ -0,0 +1,344 @@
|
||||
import * as api from "./api";
|
||||
|
||||
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);
|
||||
Vue.component("multiselect", window.VueMultiselect.default);
|
||||
Vue.use(window.VueTextareaAutosize);
|
||||
|
||||
const app = new Vue({
|
||||
el: "#app",
|
||||
data: {
|
||||
journey_edit:
|
||||
["view", "short"].indexOf(window.location.pathname.split("/")[1]) == -1,
|
||||
journey_id: window.location.pathname.split("/").pop() || String.gen_id(16),
|
||||
|
||||
journey_step_data: { day: 1, section: 0 },
|
||||
journey_data: {
|
||||
name: "New Journey",
|
||||
main: [],
|
||||
},
|
||||
|
||||
query: { hotel: [], flight: [], nominatim: [] },
|
||||
querying: { hotel: false, flight: false, place: false, food: false },
|
||||
impexp: "",
|
||||
lang: {
|
||||
format: "ddd D MMM",
|
||||
formatLocale: {
|
||||
firstDayOfWeek: 1,
|
||||
},
|
||||
monthBeforeYear: true,
|
||||
},
|
||||
},
|
||||
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({
|
||||
title: "?",
|
||||
step_title: [],
|
||||
map: { zoom: 2 },
|
||||
hotel: { latlon: [0, 0] },
|
||||
places: { restaurants: [], places: [] },
|
||||
});
|
||||
},
|
||||
step_len: function (idx) {
|
||||
return this.journey_data.main[idx].dateRange
|
||||
? (this.journey_data.main[idx].dateRange[1] -
|
||||
this.journey_data.main[idx].dateRange[0]) /
|
||||
(1000 * 60 * 60 * 24) +
|
||||
1
|
||||
: 1;
|
||||
},
|
||||
next_step: function () {
|
||||
this.journey_step_data.day += 1;
|
||||
let s = this.journey_step_data.section;
|
||||
let cd = this.step_len(s);
|
||||
|
||||
if (this.journey_step_data.day > cd) {
|
||||
this.journey_step_data.section += 1;
|
||||
if (this.journey_step_data.section >= this.journey_data.main.length) {
|
||||
this.journey_step_data.section = this.journey_data.main.length - 1;
|
||||
this.journey_step_data.day = cd;
|
||||
} else {
|
||||
this.journey_step_data.day = 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
prev_step: function () {
|
||||
this.journey_step_data.day -= 1;
|
||||
if (this.journey_step_data.day <= 0) {
|
||||
this.journey_step_data.section -= 1;
|
||||
if (this.journey_step_data.section < 0) {
|
||||
this.first_step();
|
||||
} else {
|
||||
let s = this.journey_step_data.section;
|
||||
|
||||
let cd = this.step_len(s);
|
||||
this.journey_step_data.day = cd;
|
||||
}
|
||||
}
|
||||
},
|
||||
nextnext_step: function () {
|
||||
this.journey_step_data.section += 1;
|
||||
this.journey_step_data.day = 1;
|
||||
if (this.journey_step_data.section >= this.journey_data.main.length)
|
||||
this.first_step();
|
||||
},
|
||||
prevprev_step: function () {
|
||||
this.journey_step_data.section -= 1;
|
||||
this.journey_step_data.day = 1;
|
||||
if (this.journey_step_data.section < 0) this.first_step();
|
||||
},
|
||||
first_step: function () {
|
||||
this.journey_step_data.section = 0;
|
||||
this.journey_step_data.day = 1;
|
||||
},
|
||||
|
||||
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) {
|
||||
return (
|
||||
["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"][d.getDay()] +
|
||||
" " +
|
||||
d.getDate() +
|
||||
" " +
|
||||
[
|
||||
"Jan",
|
||||
"Feb",
|
||||
"Mar",
|
||||
"Apr",
|
||||
"May",
|
||||
"Jun",
|
||||
"Jul",
|
||||
"Aug",
|
||||
"Sep",
|
||||
"Oct",
|
||||
"Nov",
|
||||
"Dec",
|
||||
][d.getMonth()]
|
||||
);
|
||||
},
|
||||
|
||||
total_days: function () {
|
||||
if (this.journey_data.main.length == 0) return 0;
|
||||
try {
|
||||
return (
|
||||
(this.journey_data.main[this.journey_data.main.length - 1]
|
||||
.dateRange[1] -
|
||||
this.journey_data.main[0].dateRange[0]) /
|
||||
(1000 * 60 * 60 * 24)
|
||||
);
|
||||
} catch {
|
||||
return "?";
|
||||
}
|
||||
},
|
||||
total_date: function () {
|
||||
if (this.journey_data.main.length == 0) return "";
|
||||
try {
|
||||
return `${this.format_date(
|
||||
this.journey_data.main[0].dateRange[0],
|
||||
)} - ${this.format_date(
|
||||
this.journey_data.main[this.journey_data.main.length - 1]
|
||||
.dateRange[1],
|
||||
)}`;
|
||||
} catch {
|
||||
return "?";
|
||||
}
|
||||
},
|
||||
update_date: function (idx) {
|
||||
let dateRange = this.journey_data.main[idx].dateRange;
|
||||
let start_end = [0, 0];
|
||||
let step_len = 0;
|
||||
|
||||
let last_start = dateRange[0];
|
||||
for (let i = idx - 1; i >= 0; --i) {
|
||||
step_len = this.step_len(i) - 1;
|
||||
if (this.journey_data.main[i].dateRange) {
|
||||
start_end = [last_start.getDate() - step_len, last_start.getDate()];
|
||||
} else {
|
||||
this.journey_data.main[i].dateRange = [new Date(), new Date()];
|
||||
start_end = [last_start.getDate() - step_len, last_start.getDate()];
|
||||
}
|
||||
this.journey_data.main[i].dateRange[0].setTime(last_start.getTime());
|
||||
this.journey_data.main[i].dateRange[0].setDate(start_end[0]);
|
||||
this.journey_data.main[i].dateRange[1].setTime(last_start.getTime());
|
||||
this.journey_data.main[i].dateRange[1].setDate(start_end[1]);
|
||||
last_start = this.journey_data.main[i].dateRange[0];
|
||||
}
|
||||
|
||||
let last_end = dateRange[1];
|
||||
for (let i = idx + 1; i < this.journey_data.main.length; ++i) {
|
||||
step_len = this.step_len(i) - 1;
|
||||
if (this.journey_data.main[i].dateRange) {
|
||||
start_end = [last_end.getDate(), last_end.getDate() + step_len];
|
||||
} else {
|
||||
this.journey_data.main[i].dateRange = [new Date(), new Date()];
|
||||
start_end = [last_end.getDate(), last_end.getDate() + step_len];
|
||||
}
|
||||
this.journey_data.main[i].dateRange[0].setTime(last_end.getTime());
|
||||
this.journey_data.main[i].dateRange[0].setDate(start_end[0]);
|
||||
this.journey_data.main[i].dateRange[1].setTime(last_end.getTime());
|
||||
this.journey_data.main[i].dateRange[1].setDate(start_end[1]);
|
||||
last_end = this.journey_data.main[i].dateRange[1];
|
||||
}
|
||||
},
|
||||
|
||||
rm_section: function (idx) {
|
||||
this.journey_data.main.splice(idx, 1);
|
||||
if (this.journey_step_data.section == idx) {
|
||||
this.prevprev_step();
|
||||
}
|
||||
},
|
||||
sel_section: function (idx) {
|
||||
this.journey_step_data.section = idx;
|
||||
this.journey_step_data.day = 1;
|
||||
},
|
||||
search_nominatim: function (txt, f) {
|
||||
if (txt == "") {
|
||||
this.query.nominatim = [];
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
return query_nominatim(txt, f).then((results) => {
|
||||
results.forEach((r) => {
|
||||
r.latlon = [parseFloat(r.lat), parseFloat(r.lon)];
|
||||
r.sname = r.display_name.split(",")[0];
|
||||
});
|
||||
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;
|
||||
});
|
||||
},
|
||||
generate_icon: function (item, fcolor) {
|
||||
return L.AwesomeMarkers.icon({
|
||||
icon: api.icon_type(item) || "star",
|
||||
prefix: "fa",
|
||||
markerColor: fcolor || item.color || "blue",
|
||||
}).createIcon().outerHTML;
|
||||
},
|
||||
|
||||
save_data: function () {
|
||||
this.impexp = JSON.stringify(this.journey_data).toEncoded();
|
||||
api.save(this.journey_id, this.journey_data);
|
||||
},
|
||||
import_data: function () {
|
||||
this.journey_data = Object.assign(
|
||||
{},
|
||||
JSON.parse(this.impexp.toDecoded()),
|
||||
);
|
||||
this.journey_data.main.forEach((e) => {
|
||||
if (e.dateRange) {
|
||||
e.dateRange[0] = new Date(e.dateRange[0]);
|
||||
e.dateRange[1] = new Date(e.dateRange[1]);
|
||||
}
|
||||
});
|
||||
},
|
||||
export_data: function () {
|
||||
this.impexp = JSON.stringify(this.journey_data).toEncoded();
|
||||
},
|
||||
filter_selected: function (list, step) {
|
||||
return list.filter((e) =>
|
||||
step ? e.step == this.journey_step_data.day : 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);
|
||||
},
|
||||
|
||||
keyboardEvent(e) {
|
||||
if (e.which === 13) {
|
||||
}
|
||||
},
|
||||
},
|
||||
created: function () {
|
||||
window.addEventListener("keydown", (e) => {
|
||||
switch (e.key) {
|
||||
case "ArrowLeft":
|
||||
this.prev_step();
|
||||
break;
|
||||
case "ArrowRight":
|
||||
this.next_step();
|
||||
break;
|
||||
default:
|
||||
console.log(e.key);
|
||||
}
|
||||
});
|
||||
|
||||
api.load(this.journey_id).then((r) => (app.journey_data = r));
|
||||
|
||||
this.debounceSave = _.debounce(this.save_data, 500);
|
||||
this.debounceSearch = {
|
||||
hotel: _.debounce((q) => {
|
||||
this.querying.hotel = true;
|
||||
this.search_nominatim(
|
||||
q,
|
||||
(r) =>
|
||||
r.type == "hotel" || r.type == "hostel" || r.type == "guest_house",
|
||||
).then((r) => {
|
||||
this.querying.hotel = false;
|
||||
});
|
||||
}, 500),
|
||||
restaurants: _.debounce((q) => {
|
||||
this.querying.food = true;
|
||||
this.search_nominatim(q, (r) => api.is_restauration_type(r)).then(
|
||||
(r) => {
|
||||
this.querying.food = false;
|
||||
},
|
||||
);
|
||||
}, 500),
|
||||
places: _.debounce((q) => {
|
||||
this.querying.place = true;
|
||||
this.search_nominatim(q, (r) => api.is_attraction_type(r)).then((r) => {
|
||||
this.querying.place = false;
|
||||
});
|
||||
}, 500),
|
||||
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();
|
||||
},
|
||||
deep: true,
|
||||
},
|
||||
},
|
||||
});
|
79
src/types/ext.ts
Normal file
79
src/types/ext.ts
Normal file
@ -0,0 +1,79 @@
|
||||
// DATE EXTENTION
|
||||
declare global {
|
||||
interface Date {
|
||||
toJSONLocal: () => string;
|
||||
}
|
||||
}
|
||||
Date.prototype.toJSONLocal = function () {
|
||||
function addZ(n: number): string {
|
||||
return n <= 9 ? `0${n}` : `${n}`;
|
||||
}
|
||||
return [
|
||||
this.getFullYear(),
|
||||
addZ(this.getMonth() + 1),
|
||||
addZ(this.getDate()),
|
||||
].join("-");
|
||||
};
|
||||
|
||||
// ARRAY EXTENTION
|
||||
declare global {
|
||||
interface Array<T> {
|
||||
foldl<B>(f: (x: T, acc: B) => B, acc: B): B;
|
||||
foldr<B>(f: (x: T, acc: B) => B, acc: B): B;
|
||||
}
|
||||
}
|
||||
Array.prototype.foldr = function <T, B>(f: (x: T, acc: B) => B, acc: B): B {
|
||||
return this.reverse().foldl(f, acc);
|
||||
};
|
||||
|
||||
Array.prototype.foldl = function <T, B>(f: (x: T, acc: B) => B, acc: B): B {
|
||||
for (let i = 0; i < this.length; i++) acc = f(this[i], acc);
|
||||
return acc;
|
||||
};
|
||||
|
||||
// STRING EXTENTION
|
||||
declare global {
|
||||
interface String {
|
||||
btoa: () => String;
|
||||
toEncoded: () => String;
|
||||
toDecoded: () => String;
|
||||
}
|
||||
}
|
||||
|
||||
String.prototype.btoa = function () {
|
||||
return window.btoa(this);
|
||||
};
|
||||
|
||||
String.prototype.toEncoded = function () {
|
||||
return window.btoa(
|
||||
Array.from(this as string, (c) => c.charCodeAt(0)).foldl(
|
||||
(e, v) => v + String.fromCharCode(e),
|
||||
"",
|
||||
),
|
||||
);
|
||||
};
|
||||
|
||||
String.prototype.toDecoded = function () {
|
||||
return Array.from(window.atob(this), (c) => c.charCodeAt(0)).foldl(
|
||||
(e, v) => v + String.fromCharCode(e),
|
||||
"",
|
||||
);
|
||||
};
|
||||
|
||||
declare global {
|
||||
interface StringConstructor {
|
||||
gen_id: (l: Number) => String;
|
||||
}
|
||||
}
|
||||
|
||||
String.gen_id = function (length) {
|
||||
const characters =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
return Array.from(Array(length))
|
||||
.map((_v) =>
|
||||
characters.charAt(Math.floor(Math.random() * characters.length)),
|
||||
)
|
||||
.join("");
|
||||
};
|
||||
|
||||
export {};
|
Reference in New Issue
Block a user