index fertig bis auf rank
This commit is contained in:
799
client/scripts/database.js
Normal file
799
client/scripts/database.js
Normal file
@@ -0,0 +1,799 @@
|
||||
const DB_VERSION = 3;
|
||||
|
||||
const USER_ID = localStorage.getItem('auth_user');
|
||||
const USER_NAME = localStorage.getItem('auth_username');
|
||||
|
||||
var canUseLocalDB = false;
|
||||
var syncTimer = null;
|
||||
var updateSyncStatusTimer;
|
||||
var syncInProgress = 0;
|
||||
var db;
|
||||
var user = null;
|
||||
|
||||
var getJSON = function(url, callback) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('POST', url, true);
|
||||
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
||||
xhr.responseType = 'json';
|
||||
xhr.timeout = 60000;
|
||||
xhr.onload = function() {
|
||||
callback(xhr.status, xhr.response);
|
||||
};
|
||||
xhr.ontimeout = function () {
|
||||
console.log("getJSON: timeout");
|
||||
callback(0, null);
|
||||
}
|
||||
xhr.onerror = function () {
|
||||
console.log("getJSON: error");
|
||||
callback(0, null);
|
||||
}
|
||||
if (USER_ID != null) {
|
||||
authString = 'auth[id]=' + localStorage.getItem('auth_id');
|
||||
authString += '&auth[hash]=' + encodeURIComponent(localStorage.getItem('auth_hash'));
|
||||
xhr.send(authString);
|
||||
} else {
|
||||
xhr.send();
|
||||
}
|
||||
};
|
||||
|
||||
function isLoggedIn() {
|
||||
return USER_ID !== null;
|
||||
}
|
||||
|
||||
function search(string, fields) {
|
||||
var keywords = string.split(' ');
|
||||
for (kid in keywords) {
|
||||
var keyword = keywords[kid].toLowerCase();
|
||||
var found = false;
|
||||
for (fid in fields) {
|
||||
var field = fields[fid].toLowerCase();
|
||||
if (field.indexOf(keyword) >= 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function dbGetData(table, id = null) {
|
||||
return new Promise(function(resolve) {
|
||||
if (canUseLocalDB) {
|
||||
if (id == null) {
|
||||
db.transaction(table).objectStore(table).getAll().onsuccess = function (event) {
|
||||
resolve(event.target.result);
|
||||
};
|
||||
} else {
|
||||
var request = db.transaction(table).objectStore(table).get(id.toString());
|
||||
request.onsuccess = function (event) {
|
||||
resolve(typeof request.result != 'undefined' ? request.result : null);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (id == null) {
|
||||
getJSON(QUERY_URL + 'get_' + table, function (code, data) {
|
||||
if (code == 200) {
|
||||
resolve(data.data);
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
fail(strings.error_network, 5000);
|
||||
resolve([]);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
getJSON(QUERY_URL + 'get_' + table.substr(0, table.length - 1) + '?id=' + id, function (code, data) {
|
||||
if (code == 200) {
|
||||
resolve(data.data);
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
fail(strings.error_network, 5000);
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function dbGetDataIndex(table, indexName, value) {
|
||||
return new Promise(function(resolve) {
|
||||
if (canUseLocalDB) {
|
||||
var request = db.transaction(table).objectStore(table).index(indexName).getAll(IDBKeyRange.only(value.toString()));
|
||||
request.onsuccess = function (event) {
|
||||
resolve(request.result);
|
||||
}
|
||||
} else {
|
||||
getJSON(QUERY_URL + 'get_' + table + '?index=' + indexName + '&value=' + value, function (code, data) {
|
||||
if (code == 200) {
|
||||
resolve(data.data);
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
fail(strings.error_network, 5000);
|
||||
resolve([]);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function dbGetRegattasRange(minDate, maxDate) {
|
||||
return new Promise(async function(resolve) {
|
||||
var regattas = await dbGetData('regattas');
|
||||
var result = [];
|
||||
for (id in regattas) {
|
||||
var regatta = regattas[id];
|
||||
var dateFrom = parseDate(regatta['date']);
|
||||
var dateTo = parseDate(regatta['date']);
|
||||
dateTo.setDate(dateTo.getDate() + parseInt(regatta['length']) - 1);
|
||||
if ((minDate <= dateTo) && (maxDate >= dateFrom)) {
|
||||
regatta['dateFrom'] = dateFrom;
|
||||
regatta['dateTo'] = dateTo;
|
||||
result.push(regatta);
|
||||
}
|
||||
}
|
||||
result.sort(function (a, b) {
|
||||
if (a['date'] < b['date']) return -1;
|
||||
if (a['date'] > b['date']) return 1;
|
||||
return 0;
|
||||
});
|
||||
resolve(result);
|
||||
});
|
||||
}
|
||||
|
||||
var compareResultsRaceCount;
|
||||
function compareResults (a, b) {
|
||||
if (a['netto'] != b['netto']) return (a['netto'] < b['netto']) ? -1 : 1;
|
||||
var tempA = [...a['values']];
|
||||
tempA.sort();
|
||||
var tempB = [...b['values']];
|
||||
tempB.sort();
|
||||
for (var i = 0; i < compareResultsRaceCount; i ++) {
|
||||
if (tempA[i] != tempB[i]) return (tempA[i] < tempB[i]) ? -1 : 1;
|
||||
}
|
||||
for (var i = compareResultsRaceCount - 1; i >= 0; i --) {
|
||||
if (a['values_all'][i] != b['values_all'][i]) return (a['values_all'][i] < b['values_all'][i]) ? -1 : 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function dbGetResultCalculated(regatta) {
|
||||
return new Promise(async function(resolve) {
|
||||
var results = await dbGetDataIndex('results', 'regatta', regatta.id);
|
||||
if (results.length > 0) {
|
||||
|
||||
var gemeldet = results.length;
|
||||
|
||||
for (id in results) {
|
||||
results[id]['finished'] = false;
|
||||
results[id]['values'] = [];
|
||||
results[id]['values_all'] = [];
|
||||
results[id]['texts'] = [];
|
||||
var copy = [];
|
||||
|
||||
for (var i = 0; i < regatta['races']; i ++) {
|
||||
var race = results[id]['race' + (i + 1)].replace(',', '.');
|
||||
|
||||
if (!isNaN(race)) {
|
||||
copy[i] = results[id]['values'][i] = parseFloat(race);
|
||||
results[id]['texts'][i] = race;
|
||||
results[id]['finished'] = true;
|
||||
} else {
|
||||
switch (race.toUpperCase()) {
|
||||
// Nicht gestartet
|
||||
case 'DNC': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Did not come
|
||||
case 'DNS': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Did not started
|
||||
// Startfehler
|
||||
case 'OCS': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // On course site
|
||||
case 'UFD': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Uniform Flag Disqualified (disqu. nach 30.3)
|
||||
case 'BFD': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Black Flag Disqualified (disqu. nach 30.4)
|
||||
// Nicht durch Ziel gegangen
|
||||
case 'DNF': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Did not finish
|
||||
case 'RET': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Retired (Aufgegeben)
|
||||
case 'RAF': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Retired after finish
|
||||
// Disqualifizierun
|
||||
case 'DSQ': results[id]['values'][i] = gemeldet + 1; copy[i] = gemeldet + 1; break; // Disqualified
|
||||
case 'DNE': results[id]['values'][i] = gemeldet + 1; copy[i] = -1; break; // Disqualified, not excludable (disqu. kann nach 90.3(b) nicht gestrichen werden)
|
||||
case 'DGM': results[id]['values'][i] = gemeldet + 1; copy[i] = -2; break; // Disqualification Gross Missconduct (kann nach 69.1(b)(2) nicht gestr. werden, grobes Fehlverhalten)
|
||||
// Unbekannt
|
||||
default: results[id]['values'][i] = 0; copy[i] = 0; break;
|
||||
}
|
||||
|
||||
if (results[id]['values'][i] != 0) {
|
||||
results[id]['texts'][i] = race + ' (' + results[id]['values'][i] + ')';
|
||||
} else {
|
||||
results[id]['texts'][i] = race + ' (Unknown - 0)';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
results[id]['values_all'] = [...results[id]['values']];
|
||||
for (var s = 0; s < regatta['streicher']; s ++) {
|
||||
var max = Math.max(...copy);
|
||||
for (var i = 0; i < regatta['races']; i ++) {
|
||||
if (copy[i] == max) {
|
||||
copy[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var brutto = 0;
|
||||
var netto = 0;
|
||||
for (var i = 0; i < regatta['races']; i ++) {
|
||||
brutto += results[id]['values_all'][i];
|
||||
if (copy[i] == -1) { results[id]['values'][i] = gemeldet + 1; }
|
||||
else if (copy[i] == -2) { results[id]['values'][i] = gemeldet + 1; }
|
||||
else { results[id]['values'][i] = copy[i]; }
|
||||
if (results[id]['values'][i] == 0) {
|
||||
results[id]['texts'][i] = '[' + results[id]['texts'][i] + ']';
|
||||
}
|
||||
netto += results[id]['values'][i];
|
||||
}
|
||||
results[id]['brutto'] = brutto;
|
||||
results[id]['netto'] = netto;
|
||||
}
|
||||
|
||||
compareResultsRaceCount = regatta['races'];
|
||||
|
||||
results.sort(compareResults);
|
||||
|
||||
var place = 1;
|
||||
for (id in results) {
|
||||
if ((id > 0) && (compareResults(results[id], results[id - 1]) == 0)) {
|
||||
results[id]['place'] = results[id - 1]['place'];
|
||||
} else {
|
||||
results[id]['place'] = place;
|
||||
}
|
||||
place ++;
|
||||
}
|
||||
|
||||
resolve(results);
|
||||
|
||||
} else {
|
||||
resolve([]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function updateSyncStatus() { // TODO
|
||||
// var syncStatus = document.getElementById('syncstatus');
|
||||
// var lastSync = await dbGetData('update_times', 'last_sync');
|
||||
// lastSync = new Date(lastSync.time * 1000);
|
||||
// var now = new Date();
|
||||
// var diff = Math.round((now - lastSync) / 1000);
|
||||
// var txt = '';
|
||||
//
|
||||
// if (diff < 30) { // 30 sec
|
||||
// txt = 'jetzt';
|
||||
// } else if (diff < 3600) { // 60 min
|
||||
// diff = Math.round(diff / 60);
|
||||
// txt = 'vor ' + diff + ' ' + (diff == 1 ? 'Minute' : 'Minuten');
|
||||
// } else if (diff < 86400) { // 24 std
|
||||
// diff = Math.round(diff / 3600);
|
||||
// txt = 'vor ' + diff + ' ' + (diff == 1 ? 'Stunde' : 'Stunden');
|
||||
// } else {
|
||||
// diff = Math.round(diff / 86400);
|
||||
// txt = 'vor ' + diff + ' ' + (diff == 1 ? 'Tag' : 'Tagen');
|
||||
// }
|
||||
//
|
||||
// var btn = '<a href="#" onclick="setLoading(true); sync(); return false;"><i class="fas fa-sync"></i> Sync</a>';
|
||||
// syncStatus.innerHTML = 'Zuletzt aktualisiert: ' + txt + btn;
|
||||
}
|
||||
|
||||
async function runPageScript() {
|
||||
if (canUseLocalDB) {
|
||||
updateSyncStatus();
|
||||
}
|
||||
if (typeof updateSyncStatusTimer == 'undefined') { // TODO
|
||||
// var syncStatus = document.getElementById('syncstatus');
|
||||
if (canUseLocalDB) {
|
||||
updateSyncStatusTimer = window.setInterval(updateSyncStatus, 10000);
|
||||
} else {
|
||||
// syncStatus.innerHTML = 'Keine Offline-Nutzung möglich.';
|
||||
updateSyncStatusTimer = null;
|
||||
}
|
||||
// syncStatus.style.display = 'block';
|
||||
}
|
||||
|
||||
if (typeof siteScript === 'function') {
|
||||
siteScript();
|
||||
}
|
||||
hideLoader();
|
||||
}
|
||||
|
||||
function sync() {
|
||||
if (!canUseLocalDB) return false;
|
||||
if (syncInProgress > 0) return false;
|
||||
|
||||
var now = Math.floor(Date.now() / 1000);
|
||||
|
||||
db.transaction('update_times').objectStore('update_times').getAll().onsuccess = function (event) {
|
||||
var localTimes = {};
|
||||
event.target.result.forEach(function (entry) {
|
||||
localTimes[entry['table']] = entry['time'];
|
||||
});
|
||||
|
||||
syncInProgress = 10;
|
||||
var syncOkay = true;
|
||||
console.log("Sync Start");
|
||||
|
||||
var interval = window.setInterval(function () {
|
||||
if (syncInProgress <= 0) {
|
||||
window.clearInterval(interval);
|
||||
if (syncOkay) {
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'last_sync', time: now });
|
||||
}
|
||||
console.log("Sync Stop");
|
||||
|
||||
runPageScript();
|
||||
}
|
||||
}, 100);
|
||||
|
||||
getJSON(QUERY_URL + 'get_update_time', function (code, serverTimes) {
|
||||
if (code == 200) {
|
||||
|
||||
// CLUBS
|
||||
if (localTimes['clubs'] < serverTimes['clubs']) {
|
||||
getJSON(QUERY_URL + 'get_clubs?changer-after=' + localTimes['clubs'], function (code, data) {
|
||||
if (code == 200) {
|
||||
var os = db.transaction('clubs', 'readwrite').objectStore('clubs');
|
||||
console.log(data);
|
||||
data.data.forEach(function (entry) {
|
||||
os.put(entry);
|
||||
});
|
||||
os.openCursor().onsuccess = function (event) {
|
||||
var cursor = event.target.result;
|
||||
if (cursor) {
|
||||
if (!data.keys.includes(parseInt(cursor.key))) {
|
||||
os.delete(cursor.key);
|
||||
}
|
||||
cursor.continue();
|
||||
} else {
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'clubs', time: serverTimes['clubs'] });
|
||||
syncInProgress --;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress --;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
syncInProgress --;
|
||||
}
|
||||
|
||||
// BOATS
|
||||
if (localTimes['boats'] < serverTimes['boats']) {
|
||||
getJSON(QUERY_URL + 'get_boats?changer-after=' + localTimes['boats'], function (code, data) {
|
||||
if (code == 200) {
|
||||
var os = db.transaction('boats', 'readwrite').objectStore('boats');
|
||||
console.log(data);
|
||||
data.data.forEach(function (entry) {
|
||||
os.put(entry);
|
||||
});
|
||||
os.openCursor().onsuccess = function (event) {
|
||||
var cursor = event.target.result;
|
||||
if (cursor) {
|
||||
if (!data.keys.includes(parseInt(cursor.key))) {
|
||||
os.delete(cursor.key);
|
||||
}
|
||||
cursor.continue();
|
||||
} else {
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'boats', time: serverTimes['boats'] });
|
||||
syncInProgress --;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress --;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
syncInProgress --;
|
||||
}
|
||||
|
||||
// SAILORS
|
||||
if (localTimes['sailors'] < serverTimes['sailors']) {
|
||||
getJSON(QUERY_URL + 'get_sailors?changer-after=' + localTimes['sailors'], function (code, data) {
|
||||
if (code == 200) {
|
||||
var os = db.transaction('sailors', 'readwrite').objectStore('sailors');
|
||||
console.log(data);
|
||||
data.data.forEach(function (entry) {
|
||||
os.put(entry);
|
||||
});
|
||||
os.openCursor().onsuccess = function (event) {
|
||||
var cursor = event.target.result;
|
||||
if (cursor) {
|
||||
if (!data.keys.includes(parseInt(cursor.key))) {
|
||||
os.delete(cursor.key);
|
||||
}
|
||||
cursor.continue();
|
||||
} else {
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'sailors', time: serverTimes['sailors'] });
|
||||
syncInProgress --;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress --;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
syncInProgress --;
|
||||
}
|
||||
|
||||
// REGATTAS
|
||||
if (localTimes['regattas'] < serverTimes['regattas']) {
|
||||
getJSON(QUERY_URL + 'get_regattas?changer-after=' + localTimes['regattas'], function (code, data) {
|
||||
if (code == 200) {
|
||||
var os = db.transaction('regattas', 'readwrite').objectStore('regattas');
|
||||
console.log(data);
|
||||
data.data.forEach(function (entry) {
|
||||
os.put(entry);
|
||||
});
|
||||
os.openCursor().onsuccess = async function (event) {
|
||||
var cursor = event.target.result;
|
||||
if (cursor) {
|
||||
if (!data.keys.includes(parseInt(cursor.key))) {
|
||||
os.delete(cursor.key);
|
||||
}
|
||||
cursor.continue();
|
||||
} else {
|
||||
// update years
|
||||
var regattas = await dbGetData('regattas');
|
||||
var years = {};
|
||||
for (id in regattas) {
|
||||
var entry = regattas[id];
|
||||
var date = parseDate(entry['date']);
|
||||
var y = date.getFullYear();
|
||||
years[y] = y;
|
||||
}
|
||||
var osYears = db.transaction('years', 'readwrite').objectStore('years');
|
||||
osYears.clear().onsuccess = function (event) {
|
||||
for (var y in years) {
|
||||
osYears.put({ year: y });
|
||||
}
|
||||
}
|
||||
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'regattas', time: serverTimes['regattas'] });
|
||||
syncInProgress --;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress --;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
syncInProgress --;
|
||||
}
|
||||
|
||||
// RESULTS
|
||||
if (localTimes['results'] < serverTimes['results']) {
|
||||
getJSON(QUERY_URL + 'get_results?changer-after=' + localTimes['results'], function (code, data) {
|
||||
if (code == 200) {
|
||||
var os = db.transaction('results', 'readwrite').objectStore('results');
|
||||
console.log(data);
|
||||
data.data.forEach(function (entry) {
|
||||
os.put(entry);
|
||||
});
|
||||
os.openCursor().onsuccess = function (event) {
|
||||
var cursor = event.target.result;
|
||||
if (cursor) {
|
||||
if (!data.keys.includes(parseInt(cursor.key))) {
|
||||
os.delete(cursor.key);
|
||||
}
|
||||
cursor.continue();
|
||||
} else {
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'results', time: serverTimes['results'] });
|
||||
syncInProgress --;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress --;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
syncInProgress --;
|
||||
}
|
||||
|
||||
// PLANNINGS
|
||||
if (localTimes['plannings'] < serverTimes['plannings']) {
|
||||
getJSON(QUERY_URL + 'get_plannings?changer-after=' + localTimes['plannings'], function (code, data) {
|
||||
if (code == 200) {
|
||||
var os = db.transaction('plannings', 'readwrite').objectStore('plannings');
|
||||
console.log(data);
|
||||
data.data.forEach(function (entry) {
|
||||
os.put(entry);
|
||||
});
|
||||
os.openCursor().onsuccess = function (event) {
|
||||
var cursor = event.target.result;
|
||||
if (cursor) {
|
||||
if (!data.keys.includes(parseInt(cursor.key))) {
|
||||
os.delete(cursor.key);
|
||||
}
|
||||
cursor.continue();
|
||||
} else {
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'plannings', time: serverTimes['plannings'] });
|
||||
syncInProgress --;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress --;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
syncInProgress --;
|
||||
}
|
||||
|
||||
if (isLoggedIn()) {
|
||||
// TRIM_BOATS
|
||||
if (localTimes['trim_boats'] < serverTimes['trim_boats']) {
|
||||
getJSON(QUERY_URL + 'get_trim_boats?changer-after=' + localTimes['trim_boats'], function (code, data) {
|
||||
if (code == 200) {
|
||||
var os = db.transaction('trim_boats', 'readwrite').objectStore('trim_boats');
|
||||
console.log(data);
|
||||
data.data.forEach(function (entry) {
|
||||
os.put(entry);
|
||||
});
|
||||
os.openCursor().onsuccess = function (event) {
|
||||
var cursor = event.target.result;
|
||||
if (cursor) {
|
||||
if (!data.keys.includes(parseInt(cursor.key))) {
|
||||
os.delete(cursor.key);
|
||||
}
|
||||
cursor.continue();
|
||||
} else {
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'trim_boats', time: serverTimes['trim_boats'] });
|
||||
syncInProgress --;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress --;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
syncInProgress --;
|
||||
}
|
||||
|
||||
// TRIM_USERS
|
||||
if (localTimes['trim_users'] < serverTimes['trim_users']) {
|
||||
getJSON(QUERY_URL + 'get_trim_users?changer-after=' + localTimes['trim_users'], function (code, data) {
|
||||
if (code == 200) {
|
||||
var os = db.transaction('trim_users', 'readwrite').objectStore('trim_users');
|
||||
console.log(data);
|
||||
data.data.forEach(function (entry) {
|
||||
os.put(entry);
|
||||
});
|
||||
os.openCursor().onsuccess = function (event) {
|
||||
var cursor = event.target.result;
|
||||
if (cursor) {
|
||||
if (!data.keys.includes(parseInt(cursor.key))) {
|
||||
os.delete(cursor.key);
|
||||
}
|
||||
cursor.continue();
|
||||
} else {
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'trim_users', time: serverTimes['trim_users'] });
|
||||
syncInProgress --;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress --;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
syncInProgress --;
|
||||
}
|
||||
|
||||
// TRIM_TRIMS
|
||||
if (localTimes['trim_trims'] < serverTimes['trim_trims']) {
|
||||
getJSON(QUERY_URL + 'get_trim_trims?changer-after=' + localTimes['trim_trims'], function (code, data) {
|
||||
if (code == 200) {
|
||||
var os = db.transaction('trim_trims', 'readwrite').objectStore('trim_trims');
|
||||
console.log(data);
|
||||
data.data.forEach(function (entry) {
|
||||
os.put(entry);
|
||||
});
|
||||
os.openCursor().onsuccess = function (event) {
|
||||
var cursor = event.target.result;
|
||||
if (cursor) {
|
||||
if (!data.keys.includes(parseInt(cursor.key))) {
|
||||
os.delete(cursor.key);
|
||||
}
|
||||
cursor.continue();
|
||||
} else {
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'trim_trims', time: serverTimes['trim_trims'] });
|
||||
syncInProgress --;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress --;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
syncInProgress --;
|
||||
}
|
||||
|
||||
} else {
|
||||
syncInProgress -= 3;
|
||||
}
|
||||
|
||||
// USERS
|
||||
if (localTimes['users'] < serverTimes['users']) {
|
||||
getJSON(QUERY_URL + 'get_users?changer-after=' + localTimes['users'], function (code, data) {
|
||||
if (code == 200) {
|
||||
var os = db.transaction('users', 'readwrite').objectStore('users');
|
||||
console.log(data);
|
||||
data.data.forEach(function (entry) {
|
||||
os.put(entry);
|
||||
});
|
||||
os.openCursor().onsuccess = function (event) {
|
||||
var cursor = event.target.result;
|
||||
if (cursor) {
|
||||
if (!data.keys.includes(parseInt(cursor.key))) {
|
||||
os.delete(cursor.key);
|
||||
}
|
||||
cursor.continue();
|
||||
} else {
|
||||
var osUpdateTimes = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'users', time: serverTimes['users'] });
|
||||
syncInProgress --;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress --;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
syncInProgress --;
|
||||
}
|
||||
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress = 0;
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function checkSync() {
|
||||
if (!canUseLocalDB) return;
|
||||
var osUpdateTimes = db.transaction('update_times').objectStore('update_times');
|
||||
osUpdateTimes.get('last_sync').onsuccess = function (event) {
|
||||
var lastSync = event.target.result.time;
|
||||
var now = Math.floor(Date.now() / 1000);
|
||||
if ((lastSync + 600) < now) { // sync max all 10 minutes
|
||||
sync();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function initDatabase() {
|
||||
if (window.indexedDB) {
|
||||
var request = window.indexedDB.open('regatten_app_db_' + BOATCLASS, DB_VERSION);
|
||||
request.onerror = function (event) {
|
||||
console.log("Cannot open DB: " + event.target.errorCode);
|
||||
|
||||
runPageScript();
|
||||
};
|
||||
request.onsuccess = function (event) {
|
||||
console.log("Database loaded");
|
||||
db = event.target.result;
|
||||
|
||||
db.onversionchange = function (event) {
|
||||
if (syncTimer != null) window.clearInterval(syncTimer);
|
||||
if (updateSyncStatusTimer != null) window.clearInterval(updateSyncStatusTimer);
|
||||
// TODO document.getElementById('syncstatus').innerHTML = '';
|
||||
canUseLocalDB = false;
|
||||
db.close();
|
||||
location.reload;
|
||||
}
|
||||
|
||||
db.onerror = function (event) {
|
||||
console.log("DB Error: " + event.target.errorCode);
|
||||
};
|
||||
|
||||
canUseLocalDB = true;
|
||||
|
||||
db.transaction('update_times').objectStore('update_times').get('last_sync').onsuccess = function (event) {
|
||||
var lastSync = event.target.result.time;
|
||||
if (lastSync > 0) {
|
||||
runPageScript();
|
||||
}
|
||||
};
|
||||
|
||||
checkSync();
|
||||
|
||||
syncTimer = window.setInterval(checkSync, 300000); // 5 min
|
||||
|
||||
window.ononline = function () {
|
||||
checkSync();
|
||||
}
|
||||
};
|
||||
request.onupgradeneeded = function (event) {
|
||||
var db = event.target.result;
|
||||
var upgradeTransaction = event.target.transaction;
|
||||
var oldVersion = event.oldVersion;
|
||||
var newVersion = event.newVersion;
|
||||
|
||||
console.log("Datenbank Version Upgrade von " + oldVersion + " auf " + newVersion);
|
||||
|
||||
if ((oldVersion < 1) && (newVersion >= 1)) {
|
||||
console.log('to version 1');
|
||||
var osClubs = db.createObjectStore('clubs', { keyPath: 'id' });
|
||||
var osBoats = db.createObjectStore('boats', { keyPath: 'id' });
|
||||
var osSailors = db.createObjectStore('sailors', { keyPath: 'id' });
|
||||
var osRegattas = db.createObjectStore('regattas', { keyPath: 'id' });
|
||||
var osResults = db.createObjectStore('results', { keyPath: 'id' });
|
||||
osResults.createIndex('regatta', 'regatta', { unique: false });
|
||||
var osPlannings = db.createObjectStore('plannings', { keyPath: 'id' });
|
||||
osPlannings.createIndex('user', 'user', { unique: false });
|
||||
osPlannings.createIndex('regatta', 'regatta', { unique: false });
|
||||
var osTrimBoats = db.createObjectStore('trim_boats', { keyPath: 'id' });
|
||||
var osTrimUsers = db.createObjectStore('trim_users', { keyPath: 'id' });
|
||||
osTrimUsers.createIndex('boat', 'boat', { unique: false });
|
||||
var osTrimTrims = db.createObjectStore('trim_trims', { keyPath: 'id' });
|
||||
osTrimTrims.createIndex('boat', 'boat', { unique: false });
|
||||
var osUpdateTimes = db.createObjectStore('update_times', { keyPath: 'table' });
|
||||
osUpdateTimes.add({ table: 'last_sync', time: 0 });
|
||||
osUpdateTimes.add({ table: 'clubs', time: 0 });
|
||||
osUpdateTimes.add({ table: 'boats', time: 0 });
|
||||
osUpdateTimes.add({ table: 'sailors', time: 0 });
|
||||
osUpdateTimes.add({ table: 'regattas', time: 0 });
|
||||
osUpdateTimes.add({ table: 'results', time: 0 });
|
||||
osUpdateTimes.add({ table: 'plannings', time: 0 });
|
||||
osUpdateTimes.add({ table: 'trim_boats', time: 0 });
|
||||
osUpdateTimes.add({ table: 'trim_users', time: 0 });
|
||||
osUpdateTimes.add({ table: 'trim_trims', time: 0 });
|
||||
}
|
||||
|
||||
if ((oldVersion < 2) && (newVersion >= 2)) {
|
||||
console.log('to version 2');
|
||||
var osUsers = db.createObjectStore('users', { keyPath: 'id' });
|
||||
osUsers.createIndex('username', 'username', { unique: true });
|
||||
var osUpdateTimes = upgradeTransaction.objectStore('update_times');
|
||||
osUpdateTimes.add({ table: 'users', time: 0 });
|
||||
}
|
||||
|
||||
if ((oldVersion < 3) && (newVersion >= 3)) {
|
||||
console.log('to version 3');
|
||||
var osYears = db.createObjectStore('years', { keyPath: 'year' });
|
||||
var osUpdateTimes = upgradeTransaction.objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'regattas', time: 0 });
|
||||
}
|
||||
|
||||
var osUpdateTimes = upgradeTransaction.objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'last_sync', time: 0 });
|
||||
}
|
||||
} else {
|
||||
runPageScript();
|
||||
}
|
||||
}
|
||||
87
client/scripts/datetime.js
Normal file
87
client/scripts/datetime.js
Normal file
@@ -0,0 +1,87 @@
|
||||
function parseDate(string) {
|
||||
var year, month, day;
|
||||
if (string.includes('.')) {
|
||||
var split = string.split('.');
|
||||
if (split.length != 3) return null;
|
||||
year = parseInt(split[2]);
|
||||
month = parseInt(split[1]);
|
||||
day = parseInt(split[0]);
|
||||
} else if (string.includes('/')) {
|
||||
var split = string.split('/');
|
||||
if (split.length != 3) return null;
|
||||
year = parseInt(split[2]);
|
||||
month = parseInt(split[0]);
|
||||
day = parseInt(split[1]);
|
||||
} else if (string.includes('-')) {
|
||||
var split = string.split('-');
|
||||
if (split.length != 3) return null;
|
||||
if (split[2].length > 2) {
|
||||
year = parseInt(split[2]);
|
||||
month = parseInt(split[1]);
|
||||
day = parseInt(split[0]);
|
||||
} else {
|
||||
year = parseInt(split[0]);
|
||||
month = parseInt(split[1]);
|
||||
day = parseInt(split[2]);
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isNaN(year) || isNaN(month) || isNaN(day)) return null;
|
||||
if (year.toString().length == 2) year = (year < 70 ? 2000 : 1900) + year;
|
||||
if ((year < 1970) || (year > 3000)) return null;
|
||||
if ((month < 1) || (month > 12)) return null;
|
||||
if ((day < 1) || (day > 31)) return null;
|
||||
|
||||
var date = new Date(Date.UTC(year, month - 1, day));
|
||||
return date;
|
||||
}
|
||||
|
||||
function getToday() {
|
||||
var date = new Date();
|
||||
date = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
|
||||
return date;
|
||||
}
|
||||
|
||||
function formatDate(format, date = null) {
|
||||
if (date === null) {
|
||||
date = new Date();
|
||||
} else {
|
||||
date = new Date(date.valueOf());
|
||||
date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
|
||||
}
|
||||
|
||||
format = format.replace("M", "%1%");
|
||||
format = format.replace("F", "%2%");
|
||||
format = format.replace("D", "%3%");
|
||||
format = format.replace("l", "%4%");
|
||||
|
||||
var tmp = date.getFullYear().toString();
|
||||
var tmp2 = tmp.substr(2);
|
||||
format = format.replace("Y", tmp);
|
||||
format = format.replace('y', tmp2);
|
||||
|
||||
tmp = (date.getMonth() + 1).toString();
|
||||
tmp2 = (tmp.length > 1 ? tmp : ('0' + tmp));
|
||||
format = format.replace('n', tmp);
|
||||
format = format.replace('m', tmp2);
|
||||
|
||||
tmp = date.getDate().toString();
|
||||
tmp2 = (tmp.length > 1 ? tmp : ('0' + tmp));
|
||||
format = format.replace('j', tmp);
|
||||
format = format.replace('d', tmp2);
|
||||
|
||||
tmp = date.getDay();
|
||||
tmp2 = (tmp == 0 ? 7 : tmp);
|
||||
format = format.replace('w', tmp);
|
||||
format = format.replace('N', tmp2);
|
||||
|
||||
format = format.replace('%1%', strings.months_short[date.getMonth()]);
|
||||
format = format.replace('%2%', strings.months_long[date.getMonth()]);
|
||||
|
||||
format = format.replace('%3%', strings.weekdays_short[date.getDay()]);
|
||||
format = format.replace('%4%', strings.weekdays_long[date.getDay()]);
|
||||
|
||||
return format;
|
||||
}
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
?>
|
||||
|
||||
const apiUrl = '<?php echo SERVER_ADDR; ?>/api/';
|
||||
const QUERY_URL = '<?php echo SERVER_ADDR; ?>/api/';
|
||||
const BOATCLASS = '<?php echo BOATCLASS; ?>';
|
||||
|
||||
var randomId = function() { return '_' + Math.random().toString(36).substr(2, 9); }
|
||||
|
||||
@@ -181,33 +182,53 @@ var logout = function() {
|
||||
});
|
||||
}
|
||||
|
||||
var initRegatten = function() {
|
||||
loggedin = (localStorage.getItem('auth_id') !== null);
|
||||
|
||||
if (loggedin) {
|
||||
var auth = {
|
||||
id: localStorage.getItem('auth_id'),
|
||||
hash: localStorage.getItem('auth_hash')
|
||||
}
|
||||
var user = {
|
||||
id: localStorage.getItem('auth_user'),
|
||||
name: localStorage.getItem('auth_username')
|
||||
}
|
||||
if ((auth.hash === null) || (user.id === null) || (user.name === null)) {
|
||||
logoutClearStorage();
|
||||
return;
|
||||
function resetDb() {
|
||||
$('#menu-developer').hideMenu();
|
||||
if (canUseLocalDB) {
|
||||
showLoader();
|
||||
var request = window.indexedDB.deleteDatabase('regatten_app_db_' + BOATCLASS);
|
||||
request.onerror = function (event) {
|
||||
console.log("Cannot open DB: " + event.target.errorCode);
|
||||
toastError('There was an error deleting your database.<br>Please report this to <a href="mailto:dev@regatten.net">dev@regatten.net</a>');
|
||||
hideLoader();
|
||||
};
|
||||
request.onsuccess = function (event) {
|
||||
console.log('DB deleted');
|
||||
toastInfo('The database was deleted. Please reload or close this tab.<br>At the next visit, a new database will be created.');
|
||||
hideLoader();
|
||||
}
|
||||
} else {
|
||||
toastWarn('Your device does not support storing data locally. All data is fetched directly from our server.<br>As a result, you can not reset your database.');
|
||||
}
|
||||
}
|
||||
|
||||
function resetCache() {
|
||||
$('#menu-developer').hideMenu();
|
||||
navigator.serviceWorker.getRegistrations().then(function (registrations) {
|
||||
for (let registration of registrations) {
|
||||
console.log('Unregister sW:', registration);
|
||||
registration.unregister();
|
||||
}
|
||||
});
|
||||
caches.keys().then((keyList) => {
|
||||
return Promise.all(keyList.map((key) => {
|
||||
console.log('Cache deleted:', key);
|
||||
return caches.delete(key);
|
||||
}));
|
||||
});
|
||||
toastInfo('The serviceWorker and the cache were deleted. A new serviceWorker will be generated on the next refresh.');
|
||||
}
|
||||
|
||||
var initRegatten = function() {
|
||||
showLoader();
|
||||
|
||||
if (loggedin) {
|
||||
initDatabase();
|
||||
|
||||
if (isLoggedIn) {
|
||||
$('.show-notloggedin').css('display', 'none');
|
||||
$('.replace-userid-href').attr('href', $('.replace-userid-href').attr('href').replace('%USERID%', user.id));
|
||||
$('.replace-username').html(user.name);
|
||||
$('.replace-userid-href').attr('href', $('.replace-userid-href').attr('href').replace('%USERID%', USER_ID));
|
||||
$('.replace-username').html(USER_NAME);
|
||||
} else {
|
||||
$('.show-loggedin').css('display', 'none');
|
||||
}
|
||||
|
||||
if (typeof siteScript !== 'undefined') {
|
||||
siteScript();
|
||||
}
|
||||
}
|
||||
@@ -8,4 +8,51 @@
|
||||
const strings = {
|
||||
inetMsgOffline: "Keine Internet-Verbindung erkannt",
|
||||
inetMsgOnline: "Du bist wieder online",
|
||||
error_network: "Verbindung fehlgeschlagen.<br>Stelle sicher, dass Du mit dem Internet verbunden bist und versuche es erneut!",
|
||||
months_short: [
|
||||
'Jan.',
|
||||
'Feb.',
|
||||
'März',
|
||||
'Apr.',
|
||||
'Mai',
|
||||
'Juni',
|
||||
'Juli',
|
||||
'Aug.',
|
||||
'Sep.',
|
||||
'Okt.',
|
||||
'Nov.',
|
||||
'Dez.'
|
||||
],
|
||||
months_long: [
|
||||
'Januar',
|
||||
'Februar',
|
||||
'März',
|
||||
'April',
|
||||
'Mai',
|
||||
'Juni',
|
||||
'Juli',
|
||||
'August',
|
||||
'September',
|
||||
'Oktober',
|
||||
'November',
|
||||
'Dezember'
|
||||
],
|
||||
weekdays_short: [
|
||||
'So',
|
||||
'Mo',
|
||||
'Di',
|
||||
'Mi',
|
||||
'Do',
|
||||
'Fr',
|
||||
'Sa'
|
||||
],
|
||||
weekdays_long: [
|
||||
'Sonntag',
|
||||
'Montag',
|
||||
'Dienstag',
|
||||
'Mittwoch',
|
||||
'Donnerstag',
|
||||
'Freitag',
|
||||
'Samstag'
|
||||
],
|
||||
}
|
||||
Reference in New Issue
Block a user