wip
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
soraefir 2025-03-11 00:15:10 +01:00
parent 7e0157880b
commit 43dfc87546
Signed by: sora
GPG Key ID: A362EA0491E2EEA0
11 changed files with 3066 additions and 1926 deletions

View File

@ -30,4 +30,4 @@
"pug": "^3.0.2",
"undici": "^7.3.0"
}
}
}

View File

@ -75,9 +75,7 @@ type NominatimResult = {
};
export const is_restauration_type = (e: NominatimResult) =>
["restaurant", "cafe", "pub", "bar", "fast_food", "food_court"].indexOf(
e.type
) != -1;
["restaurant", "cafe", "pub", "bar", "fast_food", "food_court"].includes(e.type);
export const is_attraction_type = (e: NominatimResult): boolean =>
[
"tourism",
@ -88,18 +86,18 @@ export const is_attraction_type = (e: NominatimResult): boolean =>
"historic",
"natural",
"waterway",
].indexOf(e.category) != -1 ||
].includes(e.category) ||
[
"place_of_worship",
"national_park",
"nature_reserve",
"protected_area",
].indexOf(e.type) != -1 || is_travel_type(e);
].includes(e.type) || is_travel_type(e);
export const is_hotel_type = (e: NominatimResult): boolean =>
["hotel", "hostel", "guest_house"].indexOf(e.type) != -1
["hotel", "hostel", "guest_house"].includes(e.type)
export const is_travel_type = (e: NominatimResult): boolean =>
["bus_stop", "tram_stop", "station", , "aerodrome", "parking"].indexOf(e.type) != -1
["bus_stop", "tram_stop", "station", , "aerodrome", "parking"].includes(e.type)
export const icon_type = (item: string | NominatimResult): string => {
@ -144,9 +142,9 @@ export const icon_type = (item: string | NominatimResult): string => {
"": ["?", "neighbourhood", "quarter", "highway", "place"],
};
for (let k in types) {
if (types[k].indexOf(t) >= 0 || types[k].indexOf(c) >= 0) return k;
}
for (let k in types)
if (types[k].includes(t) || types[k].includes(c)) return k;
console.log(item.display_name, item.category, item.type);
return "question";
};

View File

@ -1,52 +0,0 @@
import journey_wrapper from '../types/wrapper';
/* LIST HELPERS */
export const filter_selected = function (journey: journey_wrapper, list: geoloc[], step: boolean) {
return list.filter((e) =>
step ? e.step == journey.sel_day : e.step >= 0,
);
}
export const filter_unselected = function (list: geoloc[]) {
return list.filter((e) => e.step == undefined || e.step < 0);
}
export const remove_item = function (list: geoloc[], idx: number) {
list[idx].step = -1;
list.splice(idx, 1);
}
/* JOURNEY ADD/RM ITEM HELPER */
export const journey_add_place = function (journey: journey_wrapper, tpe: String, item: geoloc) {
switch (tpe) {
case 'hotel': return journey.leg_get().hotel = item;
case 'restaurant': return journey.leg_get().places.restaurants.push(item);
case 'place': return journey.leg_get().places.activities.push(item);
case 'other': return;
case 'flight': return journey.leg_get().travel.push(item);
}
}
export const journey_del_place = function (journey: journey_wrapper, tpe: String, idx: number) {
console.log(tpe)
switch (tpe) {
case "hotel": return journey.leg_get().hotel = null;
case "restaurants": return journey.leg_get().places.restaurants.splice(idx, 1);
case "activities": return journey.leg_get().places.activities.splice(idx, 1);
case "other": return;
case "flight": return journey.leg_get().travel.splice(idx, 1);
default: return true;
}
}
export const journey_from_url = function () {
const path = window.location.pathname.slice(1).split('/')
const hash = window.location.hash.slice(1).split('_')
return {
edit: ["view", "short"].indexOf(path.at(0) || "") == -1,
id: path.at(-1) || String.gen_id(16).toString(),
leg: parseInt(hash.at(0) || '0'),
day: parseInt(hash.at(1) || '0')
}
}

View File

@ -9,24 +9,21 @@ var nav = {
const sideScroll = function (element: Element, direction: 'left' | 'right' | 'none', speed: number = 25, step: number = 15) {
nav.scrollDir = direction
if (direction == 'none') return;
nav.scrollInterval = setInterval(() => {
(nav as any).scrollInterval = setInterval(() => {
element.scrollLeft += (direction == 'left') ? -step : step;
}, speed);
}
export const focus_leg = function (journey: journey_wrapper, idx: number | null = null) {
const c = document.querySelector('.scroll-content.nav-leg')!!
console.log(idx, c, journey)
const item = c.children[(idx != null ? idx : journey.sel_leg) + 1];
c.scrollLeft = (item as any).offsetLeft + ((item as any).offsetWidth / 2) - (c as any).offsetWidth / 2
}
export const focus_day = function (journey: journey_wrapper, idx: number | null = null) {
const c = document.querySelector('.scroll-content.nav-day')!!
console.log(idx, c, journey)
const item = c.children[(idx != null ? idx : journey.sel_day) + 1];
c.scrollLeft = (item as any).offsetLeft + ((item as any).offsetWidth / 2) - (c as any).offsetWidth / 2;
//focus_leg(journey) // We dont render both navs anymore
}
export const nav_mousemove = function (e: PointerEvent) {

View File

@ -2,7 +2,6 @@
import * as api from "./api";
import journey_wrapper from "./types/wrapper";
import { migrator } from "./types/migration";
import { journey_add_place, journey_from_url } from "./helper/journey";
import { focus_day, focus_leg, nav_mouseleave, nav_mousemove } from "./helper/nav";
import { set_search_set_results } from "./helper/api";
import toast from "./types/toast";
@ -16,13 +15,11 @@ Vue.component("l-popup", window.Vue2Leaflet.LPopup);
Vue.component("l-tooltip", window.Vue2Leaflet.LTooltip);
Vue.component("l-polyline", window.Vue2Leaflet.LPolyline);
Vue.component("l-control-scale", window.Vue2Leaflet.LControlScale);
const journey_base = journey_from_url()
const app = new Vue({
el: "#app",
data: {
edit_active: journey_base.edit,
journey: new journey_wrapper(journey_base.id),
journey: new journey_wrapper(),
search_drawer: new search_drawer(),
useDay: false,
toast: new toast(),
@ -40,9 +37,9 @@ const app = new Vue({
generate_rotation: function (index, list) {
if (index < 0 || index >= list.length) return 0;
const c0 = list[(index == 0) ? index : (index - 1)]
const c1 = list[(index == list.length - 1) ? index : (index + 1)]
const c1 = list[(index == (list.length - 1)) ? index : (index + 1)]
const brng = Math.atan2(c1[1] - c0[1], c1[0] - c0[0]);
return `rotate:${brng - 0 * Math.PI / 2}rad`;
return `rotate:${brng - Math.PI / 2}rad`;
},
generate_marker: function (item, fcolor) {
@ -107,7 +104,7 @@ const app = new Vue({
this.save_data = api.throttle(() => {
api.save(this.journey.id, this.journey.data);
}, 1000);
}, 2000);
this.pressed_prev_next = api.throttle((dir_prev) => {
if (this.useDay && dir_prev) return this.journey.day_prev();
@ -126,11 +123,9 @@ const app = new Vue({
api.load(this.journey.id).then((r) => {
app.journey.data = migrator(r)
app.journey.sel_leg = Math.min(app.journey.leg_count() - 1, journey_base.leg);
app.journey.sel_day = Math.min(app.journey.day_count() - 1, journey_base.day);
setTimeout(() => focus_leg(this.journey) && focus_day(this.journey), 25);
setTimeout(() => focus_leg(this.journey) && focus_day(this.journey) && this.$refs.map.mapObject.keyboard.disable(), 25);
this.$refs.map.mapObject.keyboard.disable();
;
this.search_drawer.refresh_map = () => { this.$refs.map.mapObject.invalidateSize() }
this.search_drawer.get_leg = () => { return this.journey.leg_get() }
this.search_drawer.get_bb = () => {
@ -144,7 +139,7 @@ const app = new Vue({
watch: {
journey: {
handler: function (ndata, odata) {
if (this.edit_active) this.save_data();
if (this.journey.edit) this.save_data();
window.location.hash = `#${this.journey.sel_leg}_${this.journey.sel_day}`
},
deep: true,

View File

@ -6,12 +6,16 @@ const date_day_diff = (d0: Date, d1: Date): number =>
class journey_wrapper {
id: String
edit: Boolean = true
data: journey = journey_template;
sel_leg: number = 0;
sel_day: number = 0;
constructor(id: String) {
this.id = id;
constructor(id: String | undefined) {
if (id)
this.id = id;
else
this.from_url()
}
leg_first = () => this.data.main[0]
@ -164,6 +168,36 @@ class journey_wrapper {
}
});
}
add_place(tpe: String, item: geoloc) {
switch (tpe) {
case 'hotel': return this.leg_get().hotel = item;
case 'restaurant': return this.leg_get().places.restaurants.push(item);
case 'place': return this.leg_get().places.activities.push(item);
case 'other': return;
case 'flight': return this.leg_get().travel.push(item);
}
}
del_place(tpe: String, idx: number) {
switch (tpe) {
case "hotel": return this.leg_get().hotel = null;
case "restaurants": return this.leg_get().places.restaurants.splice(idx, 1);
case "activities": return this.leg_get().places.activities.splice(idx, 1);
case "other": return;
case "flight": return this.leg_get().travel.splice(idx, 1);
default: return true;
}
}
from_url() {
const path = window.location.pathname.slice(1).split('/')
const hash = window.location.hash.slice(1).split('_')
this.id = path.at(-1) || String.gen_id(16).toString()
this.sel_leg = parseInt(hash.at(0) || '0')
this.sel_day = parseInt(hash.at(1) || '0')
this.edit = !["view", "short"].includes(path.at(0) || "")
}
}
export default journey_wrapper;

View File

@ -13,8 +13,8 @@ interface FlightData {
function clean_times(s: string): string | null {
if (s == "—" || s == "Scheduled") return null
if (s.indexOf("Estimated departure") == 0) return null
if (s.indexOf("Landed") == 0) return s.replace("Landed ", "")
if (s.startsWith("Estimated departure")) return null
if (s.startsWith("Landed")) return s.replace("Landed ", "")
return s
}

View File

@ -19,5 +19,5 @@ l-map(
include map/restaurants.pug
include map/travel.pug
template(v-if="edit_active")
template(v-if="journey.edit")
include map/right_menu.pug

View File

@ -19,13 +19,13 @@ mixin map_marker(place, color_sel_c, color_sel_o, color_else)
:options="{maxWidth:400, minWidth:300}")
h1.row.text-medium.text-center {{ place.sname }}
span.row.text-small.text-gray {{ place.display_name }}
span(v-if="edit_active")
span(v-if="journey.edit")
.row.input()
textarea.col-12.col-sm-12.text-small(
placeholder="",
v-model="place.notes",
)
.leaflet-popup-button-group(v-if="edit_active")
.leaflet-popup-button-group(v-if="journey.edit")
a.text-gray(
v-on:click.prevent="place.step = ((place.step==journey.sel_day)?-1:journey.sel_day)"
v-html="generate_icon(((place.step==journey.sel_day)?'calendar-xmark':'calendar-plus'), 'NA')"

View File

@ -4,15 +4,15 @@ mixin flight_popup()
)
h1.row.text-medium.text-center.text-uppercase {{ travel.id }}
span.row.text-small.text-gray {{ travel.from }} - {{travel.to}}
span(v-if="edit_active")
span(v-if="journey.edit")
.row.input(style="margin-bottom:0")
textarea.col-12.col-sm-12.text-small(
placeholder="",
v-model="travel.notes",
)
span.row.text-small.text-dark(v-else) {{ travel.notes }}
span(v-if="edit_active")
.leaflet-popup-button-group(v-if="edit_active")
span(v-if="journey.edit")
.leaflet-popup-button-group()
a.text-gray(
v-on:click.prevent="place_delete(journey,'flight',idx)"
v-html="generate_icon('trash', 'NA')"

4842
yarn.lock

File diff suppressed because it is too large Load Diff