Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b1176b952 | ||
|
|
00c1c93b80 | ||
|
|
876776eb5b | ||
|
|
a92dc45bb7 |
@@ -1,4 +1,4 @@
|
||||
const DB_VERSION = 4;
|
||||
const DB_VERSION = 6;
|
||||
|
||||
const USER_ID = localStorage.getItem('auth_user');
|
||||
const USER_NAME = localStorage.getItem('auth_username');
|
||||
@@ -397,6 +397,26 @@ function dbGetRanking(minDate, maxDate, jugend, jugstrict) {
|
||||
});
|
||||
}
|
||||
|
||||
function dbSettingsGet(key) {
|
||||
return new Promise(function(resolve) {
|
||||
if (canUseLocalDB) {
|
||||
var request = db.transaction('settings').objectStore('settings').get(key);
|
||||
request.onsuccess = function (event) {
|
||||
resolve(typeof request.result != 'undefined' ? request.result.value : null);
|
||||
}
|
||||
} else {
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function dbSettingsSet(key, value) {
|
||||
if (canUseLocalDB) {
|
||||
var os = db.transaction('settings', 'readwrite').objectStore('settings');
|
||||
os.put({ key: key, value: value});
|
||||
}
|
||||
}
|
||||
|
||||
async function updateSyncStatus() { // TODO
|
||||
// var syncStatus = document.getElementById('syncstatus');
|
||||
// var lastSync = await dbGetData('update_times', 'last_sync');
|
||||
@@ -433,6 +453,12 @@ async function runPageScript() {
|
||||
}
|
||||
};
|
||||
updateSyncStatus();
|
||||
|
||||
if (isLoggedIn()) {
|
||||
var plannings = await dbGetDataIndex('plannings', 'user', USER_ID);
|
||||
plannings = plannings.map(function (e) { return e.regatta; });
|
||||
dbSettingsSet('myregattas_' + BOATCLASS, plannings);
|
||||
}
|
||||
}
|
||||
if (typeof updateSyncStatusTimer == 'undefined') { // TODO
|
||||
// var syncStatus = document.getElementById('syncstatus');
|
||||
@@ -465,7 +491,7 @@ function sync() {
|
||||
localTimes[entry['table']] = entry['time'];
|
||||
});
|
||||
|
||||
syncInProgress = 10;
|
||||
syncInProgress = 11;
|
||||
var syncOkay = true;
|
||||
console.log("Sync Start");
|
||||
$('#i-sync').addClass('fa-spin');
|
||||
@@ -798,6 +824,38 @@ function sync() {
|
||||
syncInProgress -= 3;
|
||||
}
|
||||
|
||||
// NEWS
|
||||
if (localTimes['news'] < serverTimes['news']) {
|
||||
getJSON(QUERY_URL + 'get_news?changed-after=' + localTimes['news'], function (code, data) {
|
||||
if (code == 200) {
|
||||
var os = db.transaction('news', 'readwrite').objectStore('news');
|
||||
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: 'news', time: serverTimes['news'] });
|
||||
syncInProgress --;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log("Something went wrong (HTTP " + code + ")");
|
||||
syncOkay = false;
|
||||
syncInProgress --;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
syncInProgress --;
|
||||
}
|
||||
|
||||
// USERS
|
||||
if (localTimes['users'] < serverTimes['users']) {
|
||||
getJSON(QUERY_URL + 'get_users?changed-after=' + localTimes['users'], function (code, data) {
|
||||
@@ -878,6 +936,8 @@ function initDatabase() {
|
||||
|
||||
canUseLocalDB = true;
|
||||
|
||||
if (typeof onDatabaseLoaded == 'function') onDatabaseLoaded();
|
||||
|
||||
db.transaction('update_times').objectStore('update_times').get('last_sync').onsuccess = function (event) {
|
||||
var lastSync = event.target.result.time;
|
||||
if (lastSync > 0) {
|
||||
@@ -953,6 +1013,18 @@ function initDatabase() {
|
||||
osUpdateTimes.add({ table: 'loggedin', status: isLoggedIn() });
|
||||
}
|
||||
|
||||
if ((oldVersion < 5) && (newVersion >= 5)) {
|
||||
console.log('to version 5');
|
||||
var osPushes = db.createObjectStore('settings', { keyPath: 'key' });
|
||||
}
|
||||
|
||||
if ((oldVersion < 6) && (newVersion >= 6)) {
|
||||
console.log('to version 6');
|
||||
var osNews = db.createObjectStore('news', { keyPath: 'id' });
|
||||
var osUpdateTimes = upgradeTransaction.objectStore('update_times');
|
||||
osUpdateTimes.add({ table: 'news', time: 0 });
|
||||
}
|
||||
|
||||
var osUpdateTimes = upgradeTransaction.objectStore('update_times');
|
||||
osUpdateTimes.put({ table: 'last_sync', time: 0 });
|
||||
}
|
||||
@@ -976,6 +1048,7 @@ function resetDb(silent = true) {
|
||||
osUpdateTimes.put({ table: 'trim_boats', time: 0 });
|
||||
osUpdateTimes.put({ table: 'trim_users', time: 0 });
|
||||
osUpdateTimes.put({ table: 'trim_trims', time: 0 });
|
||||
osUpdateTimes.put({ table: 'news', time: 0 });
|
||||
osUpdateTimes.put({ table: 'users', time: 0 });
|
||||
console.log('DB update times reset');
|
||||
if (!silent)
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
|
||||
?>
|
||||
//Loading the Service Worker
|
||||
var swRegistration = null;
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', function() {
|
||||
navigator.serviceWorker.register('<?php echo SERVER_ADDR; ?>/service-worker.js.php');
|
||||
window.addEventListener('load', async function() {
|
||||
swRegistration = await navigator.serviceWorker.register('<?php echo SERVER_ADDR; ?>/service-worker.js.php');
|
||||
if (typeof onServiceWorkerLoaded === 'function') onServiceWorkerLoaded();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ const BOATCLASS = '<?php echo BOATCLASS; ?>';
|
||||
const LINK_PRE = '<?php echo SERVER_ADDR; ?>/';
|
||||
const YOUTH_AGE = '<?php echo $_CLASS['youth-age']; ?>';
|
||||
const YOUTH_GERMAN_NAME = '<?php echo $_CLASS['youth-german-name']; ?>';
|
||||
const PUSH_SERVER_KEY = '<?php echo PUSH_SERVER_KEY; ?>';
|
||||
|
||||
var randomId = function() { return '_' + Math.random().toString(36).substr(2, 9); }
|
||||
|
||||
@@ -219,6 +220,166 @@ function resetCache() {
|
||||
toastInfo('The serviceWorker and the cache were deleted. A new serviceWorker will be generated on the next refresh.');
|
||||
}
|
||||
|
||||
var pushesPossible = false;
|
||||
|
||||
function urlB64ToUint8Array(base64String) {
|
||||
const padding = '='.repeat((4 - base64String.length % 4) % 4);
|
||||
const base64 = (base64String + padding)
|
||||
.replace(/\-/g, '+')
|
||||
.replace(/_/g, '/');
|
||||
|
||||
const rawData = window.atob(base64);
|
||||
const outputArray = new Uint8Array(rawData.length);
|
||||
|
||||
for (let i = 0; i < rawData.length; ++i) {
|
||||
outputArray[i] = rawData.charCodeAt(i);
|
||||
}
|
||||
return outputArray;
|
||||
}
|
||||
|
||||
function pushesSubscribe() {
|
||||
console.log('Subscribing');
|
||||
const applicationServerKey = urlB64ToUint8Array(PUSH_SERVER_KEY);
|
||||
swRegistration.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
applicationServerKey: applicationServerKey
|
||||
})
|
||||
.then(function(subscription) {
|
||||
pushesUpdateServerSubscription(subscription, true);
|
||||
updatePushSwitches();
|
||||
updatePushBadge();
|
||||
})
|
||||
.catch(function(err) {
|
||||
console.log('Failed to subscribe the user: ', err);
|
||||
toastError('Da ist leider etwas schief gelaufen. Bitte stelle sicher, dass Du mit dem Internet verbunden bist und versuche es erneut.', 5000);
|
||||
pushesUnSubscribe(true);
|
||||
});
|
||||
}
|
||||
|
||||
function pushesUnSubscribe(silent = false) {
|
||||
console.log('Unsubscribing');
|
||||
swRegistration.pushManager.getSubscription()
|
||||
.then(function(subscription) {
|
||||
if (subscription) {
|
||||
pushesUpdateServerSubscription(subscription, false);
|
||||
subscription.unsubscribe();
|
||||
$('#menu-pushes').hideMenu();
|
||||
updatePushBadge();
|
||||
hideLoader();
|
||||
}
|
||||
})
|
||||
.catch(function(error) {
|
||||
console.log('Error unsubscribing', error);
|
||||
$('#menu-pushes').hideMenu();
|
||||
if (!silent) toastError('Da ist leider etwas schief gelaufen. Bitte versuche es erneut oder wende Dich an unseren Support.', 5000);
|
||||
updatePushBadge();
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
function pushesUpdateServerSubscription(subscription, enabled) {
|
||||
console.log('updateServer', enabled, subscription);
|
||||
$.ajax({
|
||||
url: QUERY_URL + (enabled ? 'add' : 'remove') + '_subscription',
|
||||
type: 'POST',
|
||||
data: { subscription: JSON.stringify(subscription) },
|
||||
success: function (data, textStatus, jqXHR) {
|
||||
if (!enabled) {
|
||||
toastOk('Du erhältst ab sofort keine Benachrichtigungen mehr von uns.');
|
||||
}
|
||||
hideLoader();
|
||||
},
|
||||
error: function (jqXHR, textStatus, errorThrown) {
|
||||
throw 'Cannot update server subscription';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function initPushSettings() {
|
||||
var items = [
|
||||
['notify_channel_' + BOATCLASS + '_news', true],
|
||||
['notify_channel_' + BOATCLASS + '_regatta_changed_my', true],
|
||||
['notify_channel_' + BOATCLASS + '_regatta_changed_all', false],
|
||||
['notify_channel_' + BOATCLASS + '_result_ready_my', true],
|
||||
['notify_channel_' + BOATCLASS + '_result_ready_all', true],
|
||||
['notify_channel_' + BOATCLASS + '_meldeschluss', true]
|
||||
];
|
||||
for (var i in items) {
|
||||
var item = items[i];
|
||||
if ((await dbSettingsGet(item[0])) == null) dbSettingsSet(item[0], item[1]);
|
||||
}
|
||||
}
|
||||
|
||||
async function updatePushSwitches() {
|
||||
$('#switch-pushes-news').prop('checked', await dbSettingsGet('notify_channel_' + BOATCLASS + '_news'));
|
||||
$('#switch-pushes-regatta-changed-my').prop('checked', await dbSettingsGet('notify_channel_' + BOATCLASS + '_regatta_changed_my'));
|
||||
$('#switch-pushes-regatta-changed-all').prop('checked', await dbSettingsGet('notify_channel_' + BOATCLASS + '_regatta_changed_all'));
|
||||
$('#switch-pushes-result-ready-my').prop('checked', await dbSettingsGet('notify_channel_' + BOATCLASS + '_result_ready_my'));
|
||||
$('#switch-pushes-result-ready-all').prop('checked', await dbSettingsGet('notify_channel_' + BOATCLASS + '_result_ready_all'));
|
||||
$('#switch-pushes-meldeschluss').prop('checked', await dbSettingsGet('notify_channel_' + BOATCLASS + '_meldeschluss'));
|
||||
|
||||
if ($('#switch-pushes').prop('checked')) {
|
||||
$('#p-pushes-info').show();
|
||||
$('.a-switch-pushes-channel').show();
|
||||
} else {
|
||||
$('#p-pushes-info').hide();
|
||||
$('.a-switch-pushes-channel').hide();
|
||||
}
|
||||
}
|
||||
|
||||
function pushesSubscribeClicked() {
|
||||
showLoader();
|
||||
if ($('#switch-pushes').prop('checked')) {
|
||||
pushesSubscribe();
|
||||
} else {
|
||||
pushesUnSubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
function pushesChannelClicked() {
|
||||
dbSettingsSet('notify_channel_' + BOATCLASS + '_news', $('#switch-pushes-news').prop('checked'));
|
||||
dbSettingsSet('notify_channel_' + BOATCLASS + '_regatta_changed_my', $('#switch-pushes-regatta-changed-my').prop('checked'));
|
||||
dbSettingsSet('notify_channel_' + BOATCLASS + '_regatta_changed_all', $('#switch-pushes-regatta-changed-all').prop('checked'));
|
||||
dbSettingsSet('notify_channel_' + BOATCLASS + '_result_ready_my', $('#switch-pushes-result-ready-my').prop('checked'));
|
||||
dbSettingsSet('notify_channel_' + BOATCLASS + '_result_ready_all', $('#switch-pushes-result-ready-all').prop('checked'));
|
||||
dbSettingsSet('notify_channel_' + BOATCLASS + '_meldeschluss', $('#switch-pushes-meldeschluss').prop('checked'));
|
||||
}
|
||||
|
||||
function pushesOpenMenu() {
|
||||
$('#menu-settings').hideMenu();
|
||||
if (!pushesPossible) {
|
||||
toastWarn('Dein Browser unterstützt leider keine Benachrichtigungen.', 5000);
|
||||
return;
|
||||
}
|
||||
if (Notification.permission == 'denied') {
|
||||
toastWarn('Benachrichtigungen werden von Deinem Browser blockiert.', 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
swRegistration.pushManager.getSubscription().then(function(subscription) {
|
||||
var isSub = (subscription !== null);
|
||||
$('#switch-pushes').prop('checked', isSub);
|
||||
updatePushSwitches();
|
||||
$('#menu-pushes').showMenu();
|
||||
});
|
||||
}
|
||||
|
||||
function updatePushBadge() {
|
||||
if (!pushesPossible) return;
|
||||
if (Notification.permission == 'denied') {
|
||||
$('#badge-pushes').removeClass('bg-green2-dark').addClass('bg-red2-dark').text('BLOCKED');
|
||||
return;
|
||||
}
|
||||
swRegistration.pushManager.getSubscription().then(function(subscription) {
|
||||
var isSub = (subscription !== null);
|
||||
if (isSub) {
|
||||
$('#badge-pushes').removeClass('bg-red2-dark').addClass('bg-green2-dark').text('AN');
|
||||
} else {
|
||||
$('#badge-pushes').removeClass('bg-green2-dark').addClass('bg-red2-dark').text('AUS');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var initRegatten = function() {
|
||||
showLoader();
|
||||
|
||||
@@ -235,4 +396,22 @@ var initRegatten = function() {
|
||||
$('.show-loggedin').hide();
|
||||
$('.show-notloggedin').show();
|
||||
}
|
||||
|
||||
// Pushes
|
||||
$('#a-switch-pushes').click(pushesSubscribeClicked);
|
||||
$('.a-switch-pushes-channel').click(pushesChannelClicked);
|
||||
}
|
||||
|
||||
var onServiceWorkerLoaded = function() {
|
||||
if ((swRegistration !== null) && canUseLocalDB) {
|
||||
pushesPossible = true;
|
||||
updatePushBadge();
|
||||
} else {
|
||||
$('#badge-pushes').removeClass('bg-green2-dark').addClass('bg-red2-dark').text('NOT SUPPORTED');
|
||||
}
|
||||
}
|
||||
|
||||
var onDatabaseLoaded = function() {
|
||||
onServiceWorkerLoaded();
|
||||
initPushSettings();
|
||||
}
|
||||
@@ -173,6 +173,13 @@
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/*** BLOCKQUOTE ***/
|
||||
blockquote {
|
||||
border-left: 0.5em solid rgba(0, 0, 0, 0.125);
|
||||
font-style: italic;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
/*** BLINKING ICONS ***/
|
||||
@keyframes fa-blink {
|
||||
0% { opacity: 1; }
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
define('QUERY_URL', 'http://' . $_SERVER['SERVER_NAME'] . '/api/' . BOATCLASS . '/'); // url to api backend
|
||||
define('LOGGING_APIKEY', 'xxx'); // Apikey for Logging API -> get from ostertun.net/logging
|
||||
|
||||
// PUSH
|
||||
define('PUSH_SERVER_KEY', '');
|
||||
|
||||
// BOAT CLASS
|
||||
$_CLASS = array(
|
||||
'name' => 'Pirat',
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
<?php
|
||||
|
||||
// TODO: Create site
|
||||
|
||||
$sp['title'] = 'Seite noch nicht unterstuuml;tzt - Regatten.net ' . $_CLASS['name'];
|
||||
$sp['title'] = 'News - Regatten.net ' . $_CLASS['name'];
|
||||
$sp['backbutton'] = true;
|
||||
$sp['activenav'] = 5;
|
||||
|
||||
$content = $tpl->load('error', ['404', 'Seite existiert noch nicht']);
|
||||
$content .= '<p>';
|
||||
$content .= 'Die gesuchte Seite ist leider noch nicht verfügbar.<br>';
|
||||
$content .= 'Wir arbeiten daran, sie schnellstmöglich zur Verfügung zu stellen.<br>';
|
||||
$content .= 'Wie wäre es mit der Homepage?';
|
||||
$content .= '</p>';
|
||||
$content .= $tpl->load('button', ['Zur Startseite', LINK_PRE . 'index', 'css-class' => 'mb-3']);
|
||||
$content .= $tpl->load('button', ['Kontakt', LINK_PRE . 'contact']);
|
||||
// Title
|
||||
$content = "<h1>Neuigkeiten</h1>";
|
||||
$content .= '<p>Aktuelles der letzten zwölf Monate</p>';
|
||||
|
||||
$sp['output'] = $tpl->load('card', [$content, 'css-class' => 'text-center pt-3']);
|
||||
$sp['output'] .= $tpl->load('card', [$content]);
|
||||
|
||||
// Menu
|
||||
$sp['menus'] .= $tpl->load('menu/modal', ['html-id' => 'menu-news', 'title' => 'Details']);
|
||||
|
||||
$cardTemplate = $tpl->load('card', ['%CONTENT%', 'html-id' => '%ID%', 'css-class' => 'card-news']);
|
||||
$cardTemplate = str_replace("\n", '', $cardTemplate);
|
||||
$cardTemplate = str_replace("\r", '', $cardTemplate);
|
||||
$sp['scripts'] .= "<script>const cardTemplate = '" . $cardTemplate . "';</script>";
|
||||
$sp['scripts'] .= $scripts->load('news');
|
||||
|
||||
?>
|
||||
@@ -92,7 +92,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="menu-settings" class="menu menu-box-bottom menu-box-detached rounded-m" data-menu-height="270">
|
||||
<div id="menu-settings" class="menu menu-box-bottom menu-box-detached rounded-m" data-menu-height="310">
|
||||
<div class="menu-title"><h1>Einstellungen</h1><p class="color-highlight"> </p><a href="#" class="close-menu"><i class="fa fa-times"></i></a></div>
|
||||
<div class="divider divider-margins mb-n2"></div>
|
||||
<div class="content">
|
||||
@@ -110,7 +110,7 @@
|
||||
<span>Login</span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
<a href="#" data-menu="menu-signup" class="show-notloggedin border-0">
|
||||
<a href="#" data-menu="menu-signup" class="show-notloggedin">
|
||||
<i class="fa font-14 fa-user-plus rounded-s bg-highlight color-white"></i>
|
||||
<span>Registrieren</span>
|
||||
<span class="badge bg-red2-dark color-white">FREE</span>
|
||||
@@ -120,11 +120,88 @@
|
||||
<span>Account</span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
<a href="#" onclick="logout();" class="show-loggedin border-0">
|
||||
<a href="#" onclick="logout();" class="show-loggedin">
|
||||
<i class="fa font-14 fa-sign-out-alt rounded-s bg-highlight color-white"></i>
|
||||
<span>Logout</span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
<a href="#" onclick="pushesOpenMenu()" class="border-0">
|
||||
<i class="fa font-14 fa-bell rounded-s bg-highlight color-white"></i>
|
||||
<span>Benachrichtigungen</span>
|
||||
<span id="badge-pushes" class="badge color-white"></span>
|
||||
<i class="fa fa-angle-right"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="menu-pushes" class="menu menu-box-bottom menu-box-detached rounded-m" data-menu-height="500">
|
||||
<div class="menu-title"><h1>Benachrichtigungen</h1><p class="color-highlight">Bleibe immer auf dem aktuellen Stand</p><a href="#" class="close-menu"><i class="fa fa-times"></i></a></div>
|
||||
<div class="divider divider-margins mb-n2"></div>
|
||||
<div class="content">
|
||||
<div class="list-group list-custom-small">
|
||||
<a id="a-switch-pushes" href="#" data-trigger-switch="switch-pushes" class="pb-2">
|
||||
<i class="fa font-14 fa-bell rounded-s bg-highlight color-white"></i>
|
||||
<span>Benachrichtigungen aktivieren</span>
|
||||
<div class="custom-control scale-switch ios-switch">
|
||||
<input type="checkbox" class="ios-input" id="switch-pushes">
|
||||
<label class="custom-control-label" for="switch-pushes"></label>
|
||||
</div>
|
||||
</a>
|
||||
<div class="divider"></div>
|
||||
<p style="line-height: 1.5em;" id="p-pushes-info">
|
||||
Wähle hier, über was Du informiert werden möchtest.<br>
|
||||
(meine) bezieht sich auf die Regatten, die in Deiner Saison-Planung sind,<br>
|
||||
(alle) informiert Dich über alle Regatten
|
||||
</p>
|
||||
<a href="#" data-trigger-switch="switch-pushes-news" class="pb-2 a-switch-pushes-channel">
|
||||
<i class="fa font-14 fa-newspaper rounded-s bg-highlight color-white"></i>
|
||||
<span>Neuigkeiten</span>
|
||||
<div class="custom-control scale-switch ios-switch">
|
||||
<input type="checkbox" class="ios-input" id="switch-pushes-news">
|
||||
<label class="custom-control-label" for="switch-pushes-news"></label>
|
||||
</div>
|
||||
</a>
|
||||
<a href="#" data-trigger-switch="switch-pushes-regatta-changed-my" class="pb-2 a-switch-pushes-channel">
|
||||
<i class="fa font-14 fa-calendar-check rounded-s bg-highlight color-white"></i>
|
||||
<span>Regatta verschoben (meine)</span>
|
||||
<div class="custom-control scale-switch ios-switch">
|
||||
<input type="checkbox" class="ios-input" id="switch-pushes-regatta-changed-my">
|
||||
<label class="custom-control-label" for="switch-pushes-regatta-changed-my"></label>
|
||||
</div>
|
||||
</a>
|
||||
<a href="#" data-trigger-switch="switch-pushes-regatta-changed-all" class="pb-2 a-switch-pushes-channel">
|
||||
<i class="fa font-14 fa-calendar-check rounded-s bg-highlight color-white"></i>
|
||||
<span>Regatta verschoben (alle)</span>
|
||||
<div class="custom-control scale-switch ios-switch">
|
||||
<input type="checkbox" class="ios-input" id="switch-pushes-regatta-changed-all">
|
||||
<label class="custom-control-label" for="switch-pushes-regatta-changed-all"></label>
|
||||
</div>
|
||||
</a>
|
||||
<a href="#" data-trigger-switch="switch-pushes-result-ready-my" class="pb-2 a-switch-pushes-channel">
|
||||
<i class="fa font-14 fa-poll rounded-s bg-highlight color-white"></i>
|
||||
<span>Ergebnisse verfügbar (meine)</span>
|
||||
<div class="custom-control scale-switch ios-switch">
|
||||
<input type="checkbox" class="ios-input" id="switch-pushes-result-ready-my">
|
||||
<label class="custom-control-label" for="switch-pushes-result-ready-my"></label>
|
||||
</div>
|
||||
</a>
|
||||
<a href="#" data-trigger-switch="switch-pushes-result-ready-all" class="pb-2 a-switch-pushes-channel">
|
||||
<i class="fa font-14 fa-poll rounded-s bg-highlight color-white"></i>
|
||||
<span>Ergebnisse verfügbar (alle)</span>
|
||||
<div class="custom-control scale-switch ios-switch">
|
||||
<input type="checkbox" class="ios-input" id="switch-pushes-result-ready-all">
|
||||
<label class="custom-control-label" for="switch-pushes-result-ready-all"></label>
|
||||
</div>
|
||||
</a>
|
||||
<a href="#" data-trigger-switch="switch-pushes-meldeschluss" class="pb-2 a-switch-pushes-channel">
|
||||
<i class="fa font-14 fa-file-signature rounded-s bg-highlight color-white"></i>
|
||||
<span>Melde-Erinnerungen</span>
|
||||
<div class="custom-control scale-switch ios-switch">
|
||||
<input type="checkbox" class="ios-input" id="switch-pushes-meldeschluss">
|
||||
<label class="custom-control-label" for="switch-pushes-meldeschluss"></label>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
44
server/scripts/news.js
Normal file
44
server/scripts/news.js
Normal file
@@ -0,0 +1,44 @@
|
||||
async function onNewsClicked(id) {
|
||||
var newsEntry = await dbGetData('news', id);
|
||||
if (newsEntry == null) return;
|
||||
|
||||
$('#menu-news').css('height', '80%');
|
||||
$('#menu-news').css('width', '90%');
|
||||
$('#menu-news').find('.menu-title').find('p').text(newsEntry.title);
|
||||
$('#menu-news').find('.content').addClass('pb-3');
|
||||
$('#menu-news').find('.content').html(newsEntry.html);
|
||||
|
||||
$('#menu-news').showMenu();
|
||||
}
|
||||
|
||||
function addCard(newsEntry) {
|
||||
console.log(newsEntry);
|
||||
var content = '<h2>' + newsEntry.title + '</h2>';
|
||||
content += '<p class="mb-2"><i>' + formatDate('d.m.Y', newsEntry.date) + '</i></p>';
|
||||
content += '<p class="mb-0">' + newsEntry.description.replace('\n', '<br>') + '</p>';
|
||||
if (newsEntry.html != '') {
|
||||
content += '<a class="btn btn-full rounded-s text-uppercase font-900 shadow-m bg-highlight mt-3" href="#" onclick="onNewsClicked(' + newsEntry.id + '); return false;">Mehr lesen</a>';
|
||||
}
|
||||
|
||||
$('.page-content').append(cardTemplate.replace('%ID%', 'card-news-' + newsEntry.id).replace('%CONTENT%', content));
|
||||
}
|
||||
|
||||
var siteScript = async function() {
|
||||
$('.card-news').remove();
|
||||
var news = await dbGetData('news');
|
||||
news.sort(function (a,b) {
|
||||
return b.date.localeCompare(a.date);
|
||||
});
|
||||
var today = getToday();
|
||||
var lastYear = new Date(today);
|
||||
lastYear.setFullYear(lastYear.getFullYear() - 1);
|
||||
console.log(today, lastYear);
|
||||
for (var n in news) {
|
||||
var newsEntry = news[n];
|
||||
newsEntry.date = parseDate(newsEntry.date.substring(0, 10));
|
||||
if (newsEntry.date > today) continue;
|
||||
if (newsEntry.date < lastYear) break;
|
||||
addCard(newsEntry);
|
||||
}
|
||||
hideLoader();
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
|
||||
define('PWA_VERSION', '1.5');
|
||||
define('PWA_VERSION', '1.6');
|
||||
|
||||
?>
|
||||
@@ -105,3 +105,146 @@ workbox.routing.registerRoute(
|
||||
|
||||
//Learn more about Service Workers and Configurations
|
||||
//https://developers.google.com/web/tools/workbox/
|
||||
|
||||
|
||||
// DB
|
||||
|
||||
var db = null;
|
||||
if (indexedDB) {
|
||||
var request = indexedDB.open('regatten_app_db_<?php echo BOATCLASS; ?>');
|
||||
request.onerror = function (e) {
|
||||
console.log('[sW] Cannot open DB:', e.target.errorCode);
|
||||
};
|
||||
request.onupgradeneeded = function (e) {
|
||||
console.log('[sW] DB does not exist');
|
||||
e.target.transaction.abort();
|
||||
};
|
||||
request.onsuccess = function (e) {
|
||||
console.log('[sW] DB loaded');
|
||||
db = e.target.result;
|
||||
db.onerror = function (e) {
|
||||
console.log('[sW] DB Error:', e)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function dbSettingsGet(key) {
|
||||
return new Promise(function(resolve) {
|
||||
if (db != null) {
|
||||
var request = db.transaction('settings').objectStore('settings').get(key);
|
||||
request.onsuccess = function (event) {
|
||||
resolve(typeof request.result != 'undefined' ? request.result.value : null);
|
||||
}
|
||||
} else {
|
||||
resolve(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function dbSettingsSet(key, value) {
|
||||
if (db != null) {
|
||||
var os = db.transaction('settings', 'readwrite').objectStore('settings');
|
||||
os.put({ key: key, value: value});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// PUSHES
|
||||
|
||||
function getEntry(data, index, defaultValue) {
|
||||
return ((typeof data[index] !== "undefined") ? data[index] : defaultValue);
|
||||
}
|
||||
|
||||
function isMyRegatta(id) {
|
||||
return new Promise(async function (resolve) {
|
||||
var regattas = await dbSettingsGet('myregattas_<?php echo BOATCLASS; ?>');
|
||||
if (regattas == null) resolve(false);
|
||||
else resolve(regattas.includes(id.toString()));
|
||||
});
|
||||
}
|
||||
|
||||
self.addEventListener('push', async function(event) {
|
||||
console.log('[sW] Push received:', event.data.text());
|
||||
|
||||
var data;
|
||||
try {
|
||||
data = JSON.parse(event.data.text());
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
data = undefined;
|
||||
}
|
||||
|
||||
if (typeof data.type !== "undefined") {
|
||||
switch (data.type) {
|
||||
case 'notification':
|
||||
if (typeof data.title === "undefined") break;
|
||||
if (typeof data.body === "undefined") break;
|
||||
if (typeof data.channel === "undefined") break;
|
||||
|
||||
// check channel
|
||||
var okay = false;
|
||||
switch (data.channel) {
|
||||
case 'news':
|
||||
if (await dbSettingsGet('notify_channel_<?php echo BOATCLASS; ?>_news')) okay = true;
|
||||
break;
|
||||
case 'regatta_changed':
|
||||
if (await dbSettingsGet('notify_channel_<?php echo BOATCLASS; ?>_regatta_changed_all')) okay = true;
|
||||
else if (await dbSettingsGet('notify_channel_<?php echo BOATCLASS; ?>_regatta_changed_my')) {
|
||||
if (await isMyRegatta(getEntry(data, 'id', ''))) okay = true;
|
||||
}
|
||||
break;
|
||||
case 'result_ready':
|
||||
if (await dbSettingsGet('notify_channel_<?php echo BOATCLASS; ?>_result_ready_all')) okay = true;
|
||||
else if (await dbSettingsGet('notify_channel_<?php echo BOATCLASS; ?>_result_ready_my')) {
|
||||
if (await isMyRegatta(getEntry(data, 'id', ''))) okay = true;
|
||||
}
|
||||
break;
|
||||
case 'meldeschluss':
|
||||
if (await dbSettingsGet('notify_channel_<?php echo BOATCLASS; ?>_meldeschluss')) {
|
||||
if (await isMyRegatta(getEntry(data, 'id', ''))) okay = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console.log('Unknown channel:', data.channel);
|
||||
break;
|
||||
}
|
||||
if (!okay) {
|
||||
console.log('Notification channel not subscribed');
|
||||
return;
|
||||
}
|
||||
|
||||
const options = {
|
||||
data: data,
|
||||
body: data.body,
|
||||
icon: getEntry(data, 'icon', '<?php echo SERVER_ADDR; ?>/client/app/icons/icon-512x512.png'),
|
||||
badge: '<?php echo SERVER_ADDR; ?>/client/app/icons/icon-96x96.png',
|
||||
vibrate: [500,100,500]
|
||||
};
|
||||
if ((image = getEntry(data, 'image', null)) !== null) {
|
||||
options.image = image;
|
||||
}
|
||||
|
||||
// Force refresh on next app open
|
||||
var os = db.transaction('update_times', 'readwrite').objectStore('update_times');
|
||||
os.put({ table: 'last_sync', time: 0 });
|
||||
|
||||
console.log('Showing notification');
|
||||
self.registration.showNotification(data.title, options);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
self.addEventListener('notificationclick', function(event) {
|
||||
var data = event.notification.data;
|
||||
|
||||
event.notification.close();
|
||||
|
||||
var url = '<?php echo SERVER_ADDR; ?>' + getEntry(data, 'url', '');
|
||||
|
||||
event.waitUntil(
|
||||
clients.openWindow(url)
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user