348 lines
11 KiB
JavaScript
348 lines
11 KiB
JavaScript
'use strict';
|
|
|
|
import { showDiv, ElementById, padZeros, isValidDate } from './helpers.js';
|
|
import { getCache, addCache, parseName, saveDataStorage, ConsoleLog, t, loadDS100 } from './app_functions.js';
|
|
import { dataStorage } from './app.js';
|
|
import { get } from './api.js';
|
|
import { go } from './router.js';
|
|
import { html, render } from './lit-html.js';
|
|
import { showAlertModal, showLoader, hideLoader} from './overlays.js';
|
|
import { showSettings } from './settingsView.js';
|
|
|
|
|
|
let currDate = new Date();
|
|
let fromValue = '';
|
|
let toValue = '';
|
|
let isArrValue = false;
|
|
let dateValue = currDate.getFullYear()+'-'+padZeros(currDate.getMonth()+1)+'-'+padZeros(currDate.getDate());;
|
|
let timeValue = padZeros(currDate.getHours())+':'+padZeros(currDate.getMinutes());
|
|
let suggestionsCache = {
|
|
from: {},
|
|
to: {},
|
|
};
|
|
|
|
const searchTemplate = (journeysHistory) => html`
|
|
<div id="searchView">
|
|
<div class="inputs">
|
|
<input type="text" id="from" value="${fromValue}" placeholder="${t('from')}" autocomplete="off" @keyup=${loadSuggestions} @focus=${startTyping} @blur=${stopTyping} @keypress=${onKeypress}>
|
|
<div class="suggestions" id="fromsuggestions"></div>
|
|
<input type="text" id="to" value="${toValue}" placeholder="${t('to')}" autocomplete="off" @keyup=${loadSuggestions} @focus=${startTyping} @blur=${stopTyping} @keypress=${onKeypress}>
|
|
<div class="suggestions" id="tosuggestions"></div>
|
|
<div id="datetime">
|
|
<div id="deparr">
|
|
<label class="switch">
|
|
<input type="checkbox" id="isarr" ?checked=${isArrValue}>
|
|
<span class="slider"></span>
|
|
</label>
|
|
</div>
|
|
<input type="date" id="date" placeholder="${t('date')} (YYYY-MM-DD)" pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}" value="${dateValue}">
|
|
<input type="time" id="time" placeholder="${t('time')} (HH:MM" pattern="[0-9]{2}:[0-9]{2}" value="${timeValue}">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="product_selector">
|
|
<input type="checkbox" id="national">
|
|
<label for="national" title="${t('longdistancetrain')}"> </label>
|
|
|
|
<input type="checkbox" id="regional">
|
|
<label for="regional" title="${t('regionaltrain')}"> </label>
|
|
|
|
<input type="checkbox" id="suburban">
|
|
<label for="suburban" title="${t('suburbantrain')}"> </label>
|
|
|
|
<input type="checkbox" id="subway">
|
|
<label for="subway" title="${t('subway')}"> </label>
|
|
|
|
<input type="checkbox" id="tram">
|
|
<label for="tram" title="${t('tram')}"> </label>
|
|
|
|
<input type="checkbox" id="bus">
|
|
<label for="bus" title="${t('bus')}"> </label>
|
|
|
|
<input type="checkbox" id="ferry">
|
|
<label for="ferry" title="${t('ferry')}"> </label>
|
|
|
|
<input type="checkbox" id="taxi">
|
|
<label for="taxi" title="${t('taxi')}"> </label>
|
|
</div>
|
|
<div class="button swap" id="swap" title="${t('swap')}" @click=${swapFromTo}></div>
|
|
|
|
<a class="button settings" title="${t('settings')}" @click=${showSettings}></a>
|
|
<div class="button search" tabindex="0" id="search" title="${t('search')}" @click=${search}></div>
|
|
</div>
|
|
|
|
${journeysHistory.length ? html`
|
|
${journeysHistoryTemplate(journeysHistory)}
|
|
` : ''}
|
|
</div>
|
|
`;
|
|
|
|
const journeysHistoryTemplate = (journeysHistory) => html`
|
|
<div id="journeysHistory">
|
|
<table>
|
|
<thead>
|
|
<tr><th>${t('from')}</th><th>${t('to')}</th><th>${t('options')}</th></tr>
|
|
</thead>
|
|
<tbody id="journeysHistoryTable">
|
|
${journeysHistory.map(element => html`
|
|
<tr class="fromHistory" @click=${() => setFromHistory(journeysHistory.length - 1 - journeysHistory.indexOf(element))}" title="${t('setfromto')}">
|
|
<td>${parseName(element.fromPoint)}</td>
|
|
<td>${parseName(element.toPoint)}</td>
|
|
<td>
|
|
<a class="departures" href="#/${element.reqId}" title="${t('journeyoverview')}"></a>
|
|
${element.journeyId === '' ? '' : html`
|
|
<a class="directions" href="#/${element.reqId}/${element.journeyId}" title="${t('lastjourney')}"></a>
|
|
`}
|
|
</td>
|
|
</tr>
|
|
`)}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
`;
|
|
|
|
export const searchView = () => {
|
|
const journeysHistory = getCache('journeysHistory').slice().reverse();
|
|
render(searchTemplate(journeysHistory), ElementById('content'));
|
|
|
|
ElementById('from').focus();
|
|
|
|
for (let product in dataStorage.settings.products) {
|
|
if (ElementById(product) !== null) {
|
|
ElementById(product).checked = dataStorage.settings.products[product];
|
|
}
|
|
};
|
|
};
|
|
|
|
export const search = async (requestId) => {
|
|
const provider = dataStorage.settings.provider;
|
|
let products = readProductSelection();
|
|
const accessibility = dataStorage.settings.accessibility;
|
|
let isDep = !ElementById('isarr').checked;
|
|
let date = ElementById('date').value;
|
|
let time = ElementById('time').value;
|
|
let timestamp = '';
|
|
let from = '';
|
|
let to = '';
|
|
|
|
currDate = new Date();
|
|
fromValue = ElementById('from').value;
|
|
toValue = ElementById('to').value;
|
|
dateValue = ElementById('date').value;
|
|
timeValue = ElementById('time').value;
|
|
isArrValue = ElementById('isarr').checked;
|
|
|
|
if (date !== '') {
|
|
if (!isValidDate(date)) {
|
|
showAlertModal('Ungültiges Datum!');
|
|
return;
|
|
}
|
|
} else {
|
|
date = currDate.getFullYear()+'-'+padZeros(currDate.getMonth()+1)+'-'+padZeros(currDate.getDate());
|
|
}
|
|
|
|
if (time !== '') {
|
|
if (!new RegExp('([0-1][0-9]|2[0-3]):([0-5][0-9])').test(time)) {
|
|
showAlertModal('Ungültige Zeitangabe!');
|
|
return;
|
|
}
|
|
} else {
|
|
time = padZeros(currDate.getHours())+':'+padZeros(currDate.getMinutes());
|
|
}
|
|
|
|
if (ElementById('from').value == "" | ElementById('to').value == "") {
|
|
showAlertModal("Abfahrts - und Ankunftsbahnhof müssen ausgefüllt werden.");
|
|
return;
|
|
}
|
|
|
|
if (Object.entries(suggestionsCache.from).length !== 0) {
|
|
from = suggestionsCache.from;
|
|
} else {
|
|
let suggestions = await get("/suggestions", {"query": ElementById('from').value, "results": 1}, true);
|
|
|
|
if (!suggestions[0]) {
|
|
showAlertModal("Abfahrtsbahnof ungültig");
|
|
return;
|
|
}
|
|
|
|
from = suggestions[0]
|
|
}
|
|
|
|
if (Object.entries(suggestionsCache.to).length !== 0) {
|
|
to = suggestionsCache.to;
|
|
} else {
|
|
let suggestions = await get("/suggestions", {"query": ElementById('to').value, "results": 1}, true);
|
|
|
|
if (!suggestions[0]) {
|
|
showAlertModal("Ankunftsbahnhof ungültig");
|
|
return;
|
|
}
|
|
|
|
to = suggestions[0]
|
|
}
|
|
|
|
dataStorage.settings.products = products;
|
|
saveDataStorage();
|
|
|
|
|
|
const split_date = date.split('-');
|
|
const split_time = time.split(':');
|
|
|
|
timestamp = Math.round(new Date(split_date[0], split_date[1]-1, split_date[2], split_time[0], split_time[1]).getTime()/1000);
|
|
|
|
ConsoleLog(timestamp+'///'+date+' '+time+':00');
|
|
|
|
let params = {
|
|
"fromPoint": from,
|
|
"toPoint": to,
|
|
"accessibility": accessibility,
|
|
"products": products
|
|
}
|
|
|
|
if (!isDep) {
|
|
params.arrival = timestamp
|
|
} else {
|
|
params.departure = timestamp
|
|
}
|
|
|
|
const data = await get("/journeys", {"params":params});
|
|
addCache('journeys', data);
|
|
go('/' + data.reqId);
|
|
};
|
|
|
|
const suggestionsTemplate = (suggestions, inputId) => html`
|
|
<div class="suggestionsbox" @mouseover=${mouseOverSuggestions} @mouseout=${stopMouseOverSuggestions}>
|
|
${suggestions.map(element => html`
|
|
<p class="suggestion" @click=${() => setSuggestion(encodeURI(JSON.stringify(element)), inputId)}>${parseName(element)}</p>
|
|
`)}
|
|
</div>
|
|
`;
|
|
|
|
const loadSuggestions = async (e, input) => {
|
|
const val = e.target.value;
|
|
suggestionsCache[e.target.id] = {};
|
|
const suggestions = val ? await get("/suggestions", {"query": val}, true) : [];
|
|
const suggestionsEl = ElementById(e.target.id+'suggestions');
|
|
render(suggestionsTemplate(suggestions, e.target.id), suggestionsEl);
|
|
};
|
|
|
|
export const setSuggestion = (data, inputId) => {
|
|
if (typeof data === 'string') {
|
|
data = JSON.parse(decodeURI(data));
|
|
}
|
|
|
|
suggestionsCache[inputId] = data;
|
|
ElementById(inputId).value = parseName(data);
|
|
|
|
if (inputId === 'from') {
|
|
ElementById('fromsuggestions').classList.remove('mouseover');
|
|
ElementById('to').focus();
|
|
} else if (inputId === 'to') {
|
|
ElementById('tosuggestions').classList.remove('mouseover');
|
|
ElementById('to').blur();
|
|
}
|
|
};
|
|
|
|
export const swapFromTo = () => {
|
|
suggestionsCache.from = [suggestionsCache.to, suggestionsCache.to = suggestionsCache.from][0];
|
|
|
|
let from = ElementById('from');
|
|
let to = ElementById('to');
|
|
|
|
from.value = [to.value, to.value = from.value][0];
|
|
};
|
|
|
|
export const setFromHistory = (id) => {
|
|
const cache = getCache('journeysHistory');
|
|
|
|
if (cache[id] !== undefined){
|
|
setSuggestion(cache[id].fromPoint, 'from');
|
|
setSuggestion(cache[id].toPoint, 'to');
|
|
}
|
|
};
|
|
|
|
export const readProductSelection = () => {
|
|
let products = {
|
|
"nationalExp": false,
|
|
"national": false,
|
|
"regionalExp": false,
|
|
"regional": false,
|
|
"suburban": false,
|
|
"bus": false,
|
|
"ferry": false,
|
|
"subway": false,
|
|
"tram": false,
|
|
"taxi": false
|
|
}
|
|
|
|
if (ElementById('national').checked !== false) {
|
|
products.nationalExp = true;
|
|
products.national = true;
|
|
}
|
|
|
|
if (ElementById('regional').checked !== false) {
|
|
products.regionalExp = true;
|
|
products.regional = true;
|
|
}
|
|
|
|
if (ElementById('suburban').checked !== false) {
|
|
products.suburban = true;
|
|
}
|
|
|
|
if (ElementById('subway').checked !== false) {
|
|
products.subway = true;
|
|
}
|
|
|
|
if (ElementById('tram').checked !== false) {
|
|
products.tram = true;
|
|
}
|
|
|
|
if (ElementById('bus').checked !== false) {
|
|
products.bus = true;
|
|
}
|
|
|
|
if (ElementById('ferry').checked !== false) {
|
|
products.ferry = true;
|
|
}
|
|
|
|
if (ElementById('taxi').checked !== false) {
|
|
products.taxi = true;
|
|
}
|
|
|
|
return products;
|
|
};
|
|
|
|
const startTyping = (e) => {
|
|
ElementById(e.target.id+'suggestions').classList.add('typing');
|
|
if (e.target.id == 'from') ElementById('tosuggestions').classList.remove('mouseover');
|
|
if (e.target.id == 'to') ElementById('fromsuggestions').classList.remove('mouseover');
|
|
};
|
|
|
|
const stopTyping = (e) => {
|
|
ElementById(e.target.id+'suggestions').classList.remove('typing');
|
|
};
|
|
|
|
const mouseOverSuggestions = (e) => {
|
|
let el = e.target;
|
|
let i = 0;
|
|
while (i++ < 10 && el.id !== 'fromsuggestions' && el.id !== 'tosuggestions') el = el.parentElement;
|
|
el.classList.add('mouseover');
|
|
};
|
|
|
|
const stopMouseOverSuggestions = (e) => {
|
|
let el = e.target;
|
|
let i = 0;
|
|
while (i++ < 10 && el.id !== 'fromsuggestions' && el.id !== 'tosuggestions') el = el.parentElement;
|
|
el.classList.remove('mouseover');
|
|
};
|
|
|
|
const onKeypress = (e) => {
|
|
if (e.which == 13 || e.keyCode == 13) { // enter
|
|
document.querySelector(`#${e.target.id}suggestions>.suggestionsbox>:first-child`).click();
|
|
if (e.target.id === 'to') ElementById('search').click();
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|