From 876776eb5b08ddb2c093cb8c46d95412f3194960 Mon Sep 17 00:00:00 2001 From: Timon Ostertun Date: Sun, 27 Sep 2020 21:54:43 +0200 Subject: [PATCH] Added notifications --- client/scripts/database.js | 35 +++++++- client/scripts/regatten.js.php | 52 ++++++------ service-worker.js.php | 141 ++++++++++++++++++++++++++++++++- 3 files changed, 202 insertions(+), 26 deletions(-) diff --git a/client/scripts/database.js b/client/scripts/database.js index b29666f..c0a50d9 100644 --- a/client/scripts/database.js +++ b/client/scripts/database.js @@ -1,4 +1,4 @@ -const DB_VERSION = 4; +const DB_VERSION = 5; 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'); @@ -878,6 +904,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 +981,11 @@ 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' }); + } + var osUpdateTimes = upgradeTransaction.objectStore('update_times'); osUpdateTimes.put({ table: 'last_sync', time: 0 }); } diff --git a/client/scripts/regatten.js.php b/client/scripts/regatten.js.php index f22786b..5061132 100644 --- a/client/scripts/regatten.js.php +++ b/client/scripts/regatten.js.php @@ -295,28 +295,28 @@ function pushesUpdateServerSubscription(subscription, enabled) { }); } -function initPushSettings() { +async function initPushSettings() { var items = [ - ['regatten_app_' + BOATCLASS + '_notify_channel_news', true], - ['regatten_app_' + BOATCLASS + '_notify_channel_regatta_changed_my', true], - ['regatten_app_' + BOATCLASS + '_notify_channel_regatta_changed_all', false], - ['regatten_app_' + BOATCLASS + '_notify_channel_result_ready_my', true], - ['regatten_app_' + BOATCLASS + '_notify_channel_result_ready_all', true], - ['regatten_app_' + BOATCLASS + '_notify_channel_meldeschluss', true] + ['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 (localStorage.getItem(item[0]) === null) localStorage.setItem(item[0], item[1]); + if ((await dbSettingsGet(item[0])) == null) dbSettingsSet(item[0], item[1]); } } -function updatePushSwitches() { - $('#switch-pushes-news').prop('checked', 'true' == localStorage.getItem('regatten_app_' + BOATCLASS + '_notify_channel_news')); - $('#switch-pushes-regatta-changed-my').prop('checked', 'true' == localStorage.getItem('regatten_app_' + BOATCLASS + '_notify_channel_regatta_changed_my')); - $('#switch-pushes-regatta-changed-all').prop('checked', 'true' == localStorage.getItem('regatten_app_' + BOATCLASS + '_notify_channel_regatta_changed_all')); - $('#switch-pushes-result-ready-my').prop('checked', 'true' == localStorage.getItem('regatten_app_' + BOATCLASS + '_notify_channel_result_ready_my')); - $('#switch-pushes-result-ready-all').prop('checked', 'true' == localStorage.getItem('regatten_app_' + BOATCLASS + '_notify_channel_result_ready_all')); - $('#switch-pushes-meldeschluss').prop('checked', 'true' == localStorage.getItem('regatten_app_' + BOATCLASS + '_notify_channel_meldeschluss')); +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(); @@ -337,12 +337,12 @@ function pushesSubscribeClicked() { } function pushesChannelClicked() { - localStorage.setItem('regatten_app_' + BOATCLASS + '_notify_channel_news', $('#switch-pushes-news').prop('checked')); - localStorage.setItem('regatten_app_' + BOATCLASS + '_notify_channel_regatta_changed_my', $('#switch-pushes-regatta-changed-my').prop('checked')); - localStorage.setItem('regatten_app_' + BOATCLASS + '_notify_channel_regatta_changed_all', $('#switch-pushes-regatta-changed-all').prop('checked')); - localStorage.setItem('regatten_app_' + BOATCLASS + '_notify_channel_result_ready_my', $('#switch-pushes-result-ready-my').prop('checked')); - localStorage.setItem('regatten_app_' + BOATCLASS + '_notify_channel_result_ready_all', $('#switch-pushes-result-ready-all').prop('checked')); - localStorage.setItem('regatten_app_' + BOATCLASS + '_notify_channel_meldeschluss', $('#switch-pushes-meldeschluss').prop('checked')); + 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() { @@ -398,16 +398,20 @@ var initRegatten = function() { } // Pushes - initPushSettings(); $('#a-switch-pushes').click(pushesSubscribeClicked); $('.a-switch-pushes-channel').click(pushesChannelClicked); } var onServiceWorkerLoaded = function() { - if (swRegistration !== null) { + if ((swRegistration !== null) && canUseLocalDB) { pushesPossible = true; updatePushBadge(); } else { $('#badge-pushes').removeClass('bg-green2-dark').addClass('bg-red2-dark').text('NOT SUPPORTED'); } -} \ No newline at end of file +} + +var onDatabaseLoaded = function() { + onServiceWorkerLoaded(); + initPushSettings(); +} diff --git a/service-worker.js.php b/service-worker.js.php index 297810c..2caaedf 100644 --- a/service-worker.js.php +++ b/service-worker.js.php @@ -104,4 +104,143 @@ workbox.routing.registerRoute( //Learn more about Service Workers and Configurations -//https://developers.google.com/web/tools/workbox/ \ No newline at end of file +//https://developers.google.com/web/tools/workbox/ + + +// DB + +var db = null; +if (indexedDB) { + var request = indexedDB.open('regatten_app_db_'); + 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_'); + 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__news')) okay = true; + break; + case 'regatta_changed': + if (await dbSettingsGet('notify_channel__regatta_changed_all')) okay = true; + else if (await dbSettingsGet('notify_channel__regatta_changed_my')) { + if (await isMyRegatta(getEntry(data, 'id', ''))) okay = true; + } + break; + case 'result_ready': + if (await dbSettingsGet('notify_channel__result_ready_all')) okay = true; + else if (await dbSettingsGet('notify_channel__result_ready_my')) { + if (await isMyRegatta(getEntry(data, 'id', ''))) okay = true; + } + break; + case 'meldeschluss': + if (await dbSettingsGet('notify_channel__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', '/client/app/icons/icon-512x512.png'), + badge: '/client/app/icons/icon-96x96.png', + vibrate: [500,100,500] + }; + if ((image = getEntry(data, 'image', null)) !== null) { + options.image = image; + } + + 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 = '' + getEntry(data, 'url', ''); + + event.waitUntil( + clients.openWindow(url) + ); +}); \ No newline at end of file