Browse Source

allow notifications even without an ID

kb/add-usage-guide
Trent Larson 11 months ago
parent
commit
44cfe0d88e
  1. 5
      project.task.yaml
  2. 7
      src/views/HelpNotificationsView.vue
  3. 140
      sw_scripts/safari-notifications.js

5
project.task.yaml

@ -4,6 +4,11 @@ tasks:
- 08 notifications : - 08 notifications :
- get the rest of our Android devices to work... and insert tooling (exportable logs?) so that we can see problems and troubleshoot as we onboard - get the rest of our Android devices to work... and insert tooling (exportable logs?) so that we can see problems and troubleshoot as we onboard
- get an error registering notifications on Firefox and subscription info is null - get an error registering notifications on Firefox and subscription info is null
- if navigator.serviceWorker is null, then tell the user to wait
- Android DuckDuckGo asked for my permissions, got error, won't download DB
- Android Chrome won't ask permission, will download log but always empty
-
- Chrome will get notification permissions but still complain when I reload (maybe I reload too soon?)
- prompt user to install on their home screen https://benborgers.com/posts/pwa-detect-installed - prompt user to install on their home screen https://benborgers.com/posts/pwa-detect-installed
- warn if they're using the web (android only?) - warn if they're using the web (android only?)
https://developer.mozilla.org/en-US/docs/Web/API/Navigator/getInstalledRelatedApps https://developer.mozilla.org/en-US/docs/Web/API/Navigator/getInstalledRelatedApps

7
src/views/HelpNotificationsView.vue

@ -22,7 +22,7 @@
</div> </div>
<div> <div>
<p>Here are things to try to get notifications working.</p> <p>Here are things to get notifications working.</p>
<h2 class="text-xl font-semibold">Test</h2> <h2 class="text-xl font-semibold">Test</h2>
<p>Somehow call the service-worker self.showNotification</p> <p>Somehow call the service-worker self.showNotification</p>
@ -54,7 +54,10 @@
<div>Make sure your OS (above) supports it.</div> <div>Make sure your OS (above) supports it.</div>
<h3 class="text-lg font-semibold">Mobile Phone - Android</h3> <h3 class="text-lg font-semibold">Mobile Phone - Android</h3>
<div>Chrome requires version 50.</div> <div>
Chrome requires version 50. Hold icon, select "App info", and enable
notifications.
</div>
</div> </div>
</div> </div>

140
sw_scripts/safari-notifications.js

@ -461,10 +461,10 @@ function updateRecord(store, data) {
async function fetchAllAccounts() { async function fetchAllAccounts() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let openRequest = indexedDB.open("TimeSafariAccounts"); const openRequest = indexedDB.open("TimeSafariAccounts");
openRequest.onupgradeneeded = function (event) { openRequest.onupgradeneeded = function (event) {
let db = event.target.result; const db = event.target.result;
if (!db.objectStoreNames.contains("accounts")) { if (!db.objectStoreNames.contains("accounts")) {
db.createObjectStore("accounts", { keyPath: "id" }); db.createObjectStore("accounts", { keyPath: "id" });
} }
@ -474,10 +474,10 @@ async function fetchAllAccounts() {
}; };
openRequest.onsuccess = function (event) { openRequest.onsuccess = function (event) {
let db = event.target.result; const db = event.target.result;
let transaction = db.transaction("accounts", "readonly"); const transaction = db.transaction("accounts", "readonly");
let objectStore = transaction.objectStore("accounts"); const objectStore = transaction.objectStore("accounts");
let getAllRequest = objectStore.getAll(); const getAllRequest = objectStore.getAll();
getAllRequest.onsuccess = function () { getAllRequest.onsuccess = function () {
resolve(getAllRequest.result); resolve(getAllRequest.result);
@ -494,76 +494,78 @@ async function fetchAllAccounts() {
} }
async function getNotificationCount() { async function getNotificationCount() {
let secret = null;
let accounts = []; let accounts = [];
let result = null; let result = null;
if ("secret" in self) { // 1 is our master settings ID; see MASTER_SETTINGS_KEY
secret = self.secret; const settings = await getSettingById(1);
const secretUint8Array = self.decodeBase64(secret); let lastNotifiedClaimId = null;
// 1 is our master settings ID; see MASTER_SETTINGS_KEY if ("lastNotifiedClaimId" in settings) {
const settings = await getSettingById(1); lastNotifiedClaimId = settings["lastNotifiedClaimId"];
let lastNotifiedClaimId = null; }
if ("lastNotifiedClaimId" in settings) { const activeDid = settings["activeDid"];
lastNotifiedClaimId = settings["lastNotifiedClaimId"]; console.log("safari-not getNotificationsCount last", lastNotifiedClaimId);
accounts = await fetchAllAccounts();
let activeAccount = null;
for (let i = 0; i < accounts.length; i++) {
if (accounts[i]["did"] == activeDid) {
activeAccount = accounts[i];
break;
} }
const activeDid = settings["activeDid"]; }
accounts = await fetchAllAccounts();
let did = null; const headers = {
for (var i = 0; i < accounts.length; i++) { "Content-Type": "application/json",
let account = accounts[i]; };
let did = account["did"];
if (did == activeDid) { const identity = activeAccount && activeAccount["identity"];
let publicKeyHex = account["publicKeyHex"]; if (identity && "secret" in self) {
let identity = account["identity"]; const secret = self.secret;
const messageWithNonceAsUint8Array = self.decodeBase64(identity); const secretUint8Array = self.decodeBase64(secret);
const nonce = messageWithNonceAsUint8Array.slice(0, 24); const messageWithNonceAsUint8Array = self.decodeBase64(identity);
const message = messageWithNonceAsUint8Array.slice(24, identity.length); const nonce = messageWithNonceAsUint8Array.slice(0, 24);
const decoder = new TextDecoder("utf-8"); const message = messageWithNonceAsUint8Array.slice(24, identity.length);
const decrypted = self.secretbox.open(message, nonce, secretUint8Array); const decoder = new TextDecoder("utf-8");
const decrypted = self.secretbox.open(message, nonce, secretUint8Array);
const msg = decoder.decode(decrypted); const msg = decoder.decode(decrypted);
const identifier = JSON.parse(JSON.parse(msg)); const identifier = JSON.parse(JSON.parse(msg));
const headers = { headers["Authorization"] = "Bearer " + (await accessToken(identifier));
"Content-Type": "application/json", }
};
console.log("safari-not getNotificationsCount fetch", headers);
headers["Authorization"] = "Bearer " + (await accessToken(identifier)); const response = await fetch(
settings["apiServer"] + "/api/v2/report/claims",
let response = await fetch( {
settings["apiServer"] + "/api/v2/report/claims", method: "GET",
{ headers: headers,
method: "GET", },
headers: headers, );
}, console.log("safari-not getNotificationsCount json", response);
); if (response.status == 200) {
if (response.status == 200) { const json = await response.json();
let json = await response.json(); console.log("safari-not getNotificationsCount json", json);
let claims = json["data"]; const claims = json["data"];
let newClaims = 0; let newClaims = 0;
for (var i = 0; i < claims.length; i++) { for (let i = 0; i < claims.length; i++) {
let claim = claims[i]; const claim = claims[i];
if (claim["id"] === lastNotifiedClaimId) { if (claim["id"] === lastNotifiedClaimId) {
break;
}
newClaims++;
}
if (newClaims > 0) {
result = `There are ${newClaims} new activities on TimeSafari`;
}
const most_recent_notified = claims[0]["id"];
await setMostRecentNotified(most_recent_notified);
} else {
console.error(
"safari-notifications getNotificationsCount got a bad response status when fetching claims",
response.status,
response,
);
}
break; break;
} }
newClaims++;
}
if (newClaims > 0) {
result = `There are ${newClaims} new activities on Time Safari`;
} }
const most_recent_notified = claims[0]["id"];
await setMostRecentNotified(most_recent_notified);
} else {
console.error(
"safari-notifications getNotificationsCount got a bad response status when fetching claims",
response.status,
response,
);
} }
return result; return result;
} }

Loading…
Cancel
Save