add minute to notification scheduling & fix a bug, plus other tweaks

This commit is contained in:
2024-11-15 20:39:08 -07:00
parent f06eb27ba0
commit 2c0c7ac256
6 changed files with 106 additions and 22 deletions

View File

@@ -260,9 +260,16 @@
<span class="mt-2">Yes, tell me at: </span>
<input
type="number"
@change="checkHourInput"
class="rounded-l border border-r-0 border-slate-400 ml-2 mt-2 px-2 py-2 text-center w-20"
v-model="hourInput"
/>
<input
type="number"
@change="checkMinuteInput"
class="border border-slate-400 mt-2 px-2 py-2 text-center w-20"
v-model="minuteInput"
/>
<span
class="rounded-r border border-slate-400 bg-slate-200 text-center text-blue-500 mt-2 px-2 py-2 w-20"
@click="hourAm = !hourAm"
@@ -377,7 +384,7 @@ import axios from "axios";
import { Vue, Component } from "vue-facing-decorator";
import { DEFAULT_PUSH_SERVER, NotificationIface } from "@/constants/app";
import { retrieveSettingsForActiveAccount } from "@/db/index";
import { addLogMessage, retrieveSettingsForActiveAccount } from "@/db/index";
import * as libsUtil from "@/libs/util";
import { urlBase64ToUint8Array } from "@/libs/crypto/vc/util";
@@ -405,7 +412,8 @@ interface VapidResponse {
}
interface PushSubscriptionWithTime extends PushSubscriptionJSON {
notifyTime: { utcHour: number };
notifyTime: { utcHour: number; minute: number };
notifyType: string;
}
@Component
@@ -416,6 +424,7 @@ export default class App extends Vue {
b64 = "";
hourAm = true;
hourInput = "8";
minuteInput = "00";
serviceWorkerReady = true;
async mounted() {
@@ -429,14 +438,19 @@ export default class App extends Vue {
if (pushUrl.startsWith("http://localhost")) {
console.log("Not checking for VAPID in this local environment.");
} else {
let responseData = "";
await axios
.get(pushUrl + "/web-push/vapid")
.then((response: VapidResponse) => {
this.b64 = response.data?.vapidKey || "";
console.log("Got vapid key:", this.b64);
navigator.serviceWorker.addEventListener("controllerchange", () => {
console.log("New service worker is now controlling the page");
});
responseData = JSON.stringify(response.data);
navigator.serviceWorker?.addEventListener(
"controllerchange",
() => {
console.log("New service worker is now controlling the page");
},
);
});
if (!this.b64) {
this.$notify(
@@ -446,7 +460,11 @@ export default class App extends Vue {
title: "Error Setting Notifications",
text: "Could not set notifications.",
},
-1,
5000,
);
await addLogMessage(
"Error Setting Notifications: web push server response didn't have vapidKey: " +
responseData,
);
}
}
@@ -462,7 +480,11 @@ export default class App extends Vue {
title: "Error Setting Notifications",
text: "Got an error setting notifications.",
},
-1,
5000,
);
await addLogMessage(
"Error Setting Notifications: some error occurred: " +
JSON.stringify(error),
);
}
}
@@ -476,7 +498,7 @@ export default class App extends Vue {
message: ServiceWorkerMessage,
): Promise<unknown> {
return new Promise((resolve, reject) => {
if (navigator.serviceWorker.controller) {
if (navigator.serviceWorker?.controller) {
const messageChannel = new MessageChannel();
messageChannel.port1.onmessage = (event: MessageEvent) => {
@@ -487,7 +509,7 @@ export default class App extends Vue {
}
};
navigator.serviceWorker.controller.postMessage(message, [
navigator.serviceWorker?.controller.postMessage(message, [
messageChannel.port2,
]);
} else {
@@ -498,7 +520,9 @@ export default class App extends Vue {
private askPermission(): Promise<NotificationPermission> {
console.log("Requesting permission for notifications:", navigator);
if (!("serviceWorker" in navigator && navigator.serviceWorker.controller)) {
if (
!("serviceWorker" in navigator && navigator.serviceWorker?.controller)
) {
return Promise.reject("Service worker not available.");
}
@@ -548,6 +572,36 @@ export default class App extends Vue {
});
}
private checkHourInput() {
const hourNum = parseInt(this.hourInput);
if (isNaN(hourNum)) {
this.hourInput = "12";
} else if (hourNum < 1) {
this.hourInput = "12";
this.hourAm = !this.hourAm;
} else if (hourNum > 12) {
this.hourInput = "1";
this.hourAm = !this.hourAm;
} else {
this.hourInput = hourNum.toString();
}
}
private checkMinuteInput() {
const minuteNum = parseInt(this.minuteInput);
if (isNaN(minuteNum)) {
this.minuteInput = "00";
} else if (minuteNum < 0) {
this.minuteInput = "59";
} else if (minuteNum < 10) {
this.minuteInput = "0" + minuteNum;
} else if (minuteNum > 59) {
this.minuteInput = "00";
} else {
this.minuteInput = minuteNum.toString();
}
}
// this allows us to show an error without closing the dialog
checkHour() {
if (!libsUtil.isNumeric(this.hourInput)) {
@@ -617,14 +671,29 @@ export default class App extends Vue {
);
// we already checked that this is a valid hour number
const rawHourNum = libsUtil.numberOrZero(this.hourInput);
const adjHourNum = rawHourNum + (this.hourAm ? 0 : 12);
const hourNum = adjHourNum % 24;
const adjHourNum = this.hourAm
? // If it's AM, then we'll change it to 0 for 12 AM but otherwise use rawHourNum
rawHourNum === 12
? 0
: rawHourNum
: // Otherwise it's PM, so keep a 12 but otherwise add 12
rawHourNum === 12
? 12
: rawHourNum + 12;
const hourNum = adjHourNum % 24; // probably unnecessary now
const utcHour =
hourNum + Math.round(new Date().getTimezoneOffset() / 60);
const finalUtcHour = (utcHour + (utcHour < 0 ? 24 : 0)) % 24;
console.log("utc hour:", utcHour, "final utc:", finalUtcHour);
const minuteNum = libsUtil.numberOrZero(this.minuteInput);
const utcMinute =
minuteNum + Math.round(new Date().getTimezoneOffset() % 60);
const finalUtcMinute =
(utcMinute + (utcMinute < 0 ? 60 : 0)) % 60;
const subscriptionWithTime: PushSubscriptionWithTime = {
notifyTime: { utcHour: finalUtcHour },
notifyTime: { utcHour: finalUtcHour, minute: finalUtcMinute },
notifyType: "DAILY_CHECK",
...subscription.toJSON(),
};
await this.sendSubscriptionToServer(subscriptionWithTime);
@@ -687,7 +756,7 @@ export default class App extends Vue {
applicationServerKey: applicationServerKey,
};
navigator.serviceWorker.ready
navigator.serviceWorker?.ready
.then((registration) => {
return registration.pushManager.subscribe(options);
})