429 lines
14 KiB
JavaScript
429 lines
14 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, showSelectModal, 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 class="center">
|
|
<form class="search" onsubmit="return false;">
|
|
<div class="title">
|
|
<div class="logo"></div>
|
|
<h1>Öffisearch</h1>
|
|
</div>
|
|
<label for="from">${t('from')}:</label>
|
|
<input type="text" name="from" id="from" placeholder="${t('from')}" value="${fromValue}" autocomplete="off" @keyup=${loadSuggestions} @focus=${startTyping} @blur=${stopTyping} @keypress=${onKeypress} required>
|
|
<div class="suggestions" id="fromSuggestions"></div>
|
|
|
|
<label for="to">${t('to')}:</label>
|
|
<input type="text" name="to" id="to" placeholder="${t('to')}" value="${toValue}" autocomplete="off" @keyup=${loadSuggestions} @focus=${startTyping} @blur=${stopTyping} @keypress=${onKeypress} required>
|
|
<div class="suggestions" id="toSuggestions"></div>
|
|
|
|
<div class="row">
|
|
<label class="switch">
|
|
<input type="checkbox" id="isarr" name="isarr" ?checked=${isArrValue}>
|
|
<span class="slider ${t('lang_short')}"></span>
|
|
<label for="isarr"> <br></label>
|
|
</label>
|
|
|
|
<label for="date">${t('date')}:</label>
|
|
<input type="date" name="date" id="date" value="${dateValue}" placeholder="${t('date')}" pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}" @keypress=${onKeypressSubmit} required>
|
|
|
|
<label for="time"><br>${t('time')}:</label>
|
|
<input type="time" name="time" id="time" value="${timeValue}" placeholder="${t('time')}" pattern="[0-9]{2}:[0-9]{2}" @keypress=${onKeypressSubmit} required>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<span class="hidden">${t('products')}:</span>
|
|
<div class="selector">
|
|
${dataStorage.settings.advancedSelection ? html`
|
|
<input type="checkbox" id="nationalExp" name="nationalExp" checked>
|
|
<label for="nationalExp" title="${t('iceonly')}">${t('iceonly')}<br></label>
|
|
|
|
<input type="checkbox" id="national" name="national" checked>
|
|
<label class="ic" for="national" title="${t('iconly')}">${t('iconly')}<br></label>
|
|
` : html`
|
|
<input type="checkbox" id="national" name="national" checked>
|
|
<label class="ic-ice" for="national" title="${t('longdistancetrain')}">${t('longdistancetrain')}<br></label>
|
|
`}
|
|
|
|
${dataStorage.settings.advancedSelection ? html`
|
|
<input type="checkbox" id="regionalExp" name="regionalExp" checked>
|
|
<label for="regionalExp" title="${t('dzug')}">${t('dzug')}<br></label>
|
|
|
|
<input type="checkbox" id="regional" name="regional" checked>
|
|
<label for="regional" title="${t('regionaltrain')}">${t('regionaltrain')}<br></label>
|
|
` : html`
|
|
<input type="checkbox" id="regional" name="regional" checked>
|
|
<label for="regional" title="${t('regionaltrain')}">${t('regionaltrain')}<br></label>
|
|
`}
|
|
|
|
<input type="checkbox" id="suburban" name="suburban" checked>
|
|
<label for="suburban" title="${t('suburbantrain')}">${t('suburbantrain')}<br></label>
|
|
|
|
<input type="checkbox" id="subway" name="subway" checked>
|
|
<label for="subway" title="${t('subway')}">${t('subway')}<br></label>
|
|
|
|
<input type="checkbox" id="tram" name="tram" checked>
|
|
<label for="tram" title="${t('tram')}">${t('tram')}<br></label>
|
|
|
|
<input type="checkbox" id="bus" name="bus" checked>
|
|
<label for="bus" title="${t('bus')}">${t('bus')}<br></label>
|
|
|
|
<input type="checkbox" id="ferry" name="ferry" checked>
|
|
<label for="ferry" title="${t('ferry')}">${t('ferry')}<br></label>
|
|
|
|
<input type="checkbox" id="taxi" name="taxi" checked>
|
|
<label for="taxi" title="${t('taxi')}">${t('taxi')}<br></label>
|
|
</div>
|
|
|
|
<span class="hidden">{{LABEL_ACCESSIBILITY}}:</span>
|
|
<div class="selector">
|
|
<input type="radio" id="accessibilityNone" name="accessibility" value="none" ?checked=${dataStorage.settings.accessibility === "none"}>
|
|
<label for="accessibilityNone" title="{{LABEL_ACCESSIBILITY_NONE}}">{{LABEL_ACCESSIBILITY_NONE}}<br></label>
|
|
|
|
<input type="radio" id="accessibilityPartial" name="accessibility" value="partial" ?checked=${dataStorage.settings.accessibility === "partial"}>
|
|
<label for="accessibilityPartial" title="{{LABEL_ACCESSIBILITY_PARTIAL}}">{{LABEL_ACCESSIBILITY_PARTIAL}}<br></label>
|
|
|
|
<input type="radio" id="accessibilityComplete" name="accessibility" value="complete" ?checked=${dataStorage.settings.accessibility === "complete"}>
|
|
<label for="accessibilityComplete" title="{{LABEL_ACCESSIBILITY_FULL}}">{{LABEL_ACCESSIBILITY_FULL}}<br></label>
|
|
</div>
|
|
|
|
<div class="selector" >
|
|
<div class="btn swap" title="${t('swap')}" @click=${swapFromTo}></div>
|
|
<div class="btn settings" title="${t('settings')}" @click=${showSettings}></div>
|
|
</div>
|
|
|
|
<div class="button btn go" tabindex="0" id="go" @click=${search}>
|
|
${t('search')}
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 2L4.5 20.29l.71.71L12 18l6.79 3 .71-.71z"/></svg>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
${journeysHistory.length ? html`
|
|
<input type="checkbox" id="btn-history" class="btn history hidden">
|
|
<label for="btn-history"></label>
|
|
${journeysHistoryTemplate(journeysHistory)}
|
|
` : ''}
|
|
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
const journeysHistoryTemplate = (journeysHistory) => html`
|
|
<div class="history">
|
|
${journeysHistory.map(element => html`
|
|
<div class="row history" @click=${() => {journeysHistoryAction(journeysHistory, element)}}">
|
|
<div class="history from">
|
|
<small>${t('from')}:</small><br>
|
|
${parseName(element.fromPoint)}
|
|
</div>
|
|
<div class="history arrow"></div>
|
|
<div class="history to">
|
|
<small>${t('to')}:</small><br>
|
|
${parseName(element.toPoint)}
|
|
</div>
|
|
</div>
|
|
`)}
|
|
</div>
|
|
`;
|
|
|
|
const journeysHistoryAction = (journeysHistory, element) => {
|
|
ConsoleLog(element);
|
|
showSelectModal(html`
|
|
<a @click=${() => {setFromHistory(journeysHistory.length - 1 - journeysHistory.indexOf(element));hideLoader()}}>${t('setfromto')}</a>
|
|
<a @click=${() => {go("/"+element.reqId);hideLoader();}}>${t('journeyoverview')}</a>
|
|
${element.journeyId === '' ? '' : html`
|
|
<a @click=${() => {go("/"+element.reqId+"/"+element.journeyId);hideLoader();}}>${t('lastjourney')}</a>
|
|
`}
|
|
`);
|
|
};
|
|
|
|
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 = document.querySelector('input[name="accessibility"]:checked').value;
|
|
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;
|
|
dataStorage.settings.accessibility = accessibility;
|
|
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);
|
|
return false;
|
|
};
|
|
|
|
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.national = true;
|
|
|
|
if (dataStorage.settings.advancedSelection !== true) {
|
|
products.nationalExp = true;
|
|
}
|
|
}
|
|
|
|
if (ElementById('regional').checked !== false) {
|
|
products.regional = true;
|
|
|
|
if (dataStorage.settings.advancedSelection !== true) {
|
|
products.regionalExp = true;
|
|
}
|
|
}
|
|
|
|
if (dataStorage.settings.advancedSelection !== false) {
|
|
if (ElementById('nationalExp').checked !== false) {
|
|
products.nationalExp = true;
|
|
}
|
|
|
|
if (ElementById('regionalExp').checked !== false) {
|
|
products.regionalExp = 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('go').click();
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
|
|
const onKeypressSubmit = (e) => {
|
|
if (e.which == 13 || e.keyCode == 13) { // enter
|
|
ElementById('go').click();
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|