mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-08-28 17:21:05 +00:00
feat: tweak calendar and clean it up
This commit is contained in:
@@ -16,10 +16,20 @@ import {
|
||||
readGoogleCalendarState,
|
||||
writeGoogleCalendarState,
|
||||
} from "@/seqta/utils/googleCalendar/storage";
|
||||
import {
|
||||
clampSyncWeeks,
|
||||
getAutoSyncWeekly,
|
||||
getSyncWeeksAhead,
|
||||
} from "@/seqta/utils/googleCalendar/syncSettings";
|
||||
import type {
|
||||
GoogleCalendarStatus,
|
||||
GoogleCalendarSyncResult,
|
||||
} from "@/seqta/utils/googleCalendar/types";
|
||||
import {
|
||||
clearWeeklySyncAlarm,
|
||||
ensureWeeklySyncAlarm,
|
||||
registerWeeklySyncAlarmListener,
|
||||
} from "./googleCalendarWeekly";
|
||||
|
||||
function base64UrlEncode(buffer: ArrayBuffer): string {
|
||||
const bytes = new Uint8Array(buffer);
|
||||
@@ -197,6 +207,8 @@ async function connectGoogleCalendar(): Promise<GoogleCalendarSyncResult> {
|
||||
connectedAt: Date.now(),
|
||||
});
|
||||
|
||||
await ensureWeeklySyncAlarm();
|
||||
|
||||
return { success: true, configured: true, connected: true };
|
||||
} catch (err) {
|
||||
return {
|
||||
@@ -209,11 +221,16 @@ async function connectGoogleCalendar(): Promise<GoogleCalendarSyncResult> {
|
||||
|
||||
async function getGoogleCalendarStatus(): Promise<GoogleCalendarStatus> {
|
||||
const state = await readGoogleCalendarState();
|
||||
const syncWeeksAhead = await getSyncWeeksAhead();
|
||||
const autoSyncWeekly = await getAutoSyncWeekly();
|
||||
return {
|
||||
configured: isGoogleCalendarConfigured(),
|
||||
connected: !!(state.refreshToken || state.accessToken),
|
||||
lastSyncAt: state.lastSyncAt,
|
||||
lastWeeklySyncAt: state.lastWeeklySyncAt,
|
||||
lastSyncOrigin: state.lastSyncOrigin,
|
||||
syncWeeksAhead,
|
||||
autoSyncWeekly,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -222,6 +239,7 @@ export async function handleGoogleCalendarConnect(): Promise<GoogleCalendarSyncR
|
||||
}
|
||||
|
||||
export async function handleGoogleCalendarDisconnect(): Promise<{ success: boolean }> {
|
||||
await clearWeeklySyncAlarm();
|
||||
await clearGoogleCalendarState();
|
||||
return { success: true };
|
||||
}
|
||||
@@ -298,4 +316,50 @@ export function registerGoogleCalendarMessageHandlers(
|
||||
});
|
||||
return true;
|
||||
};
|
||||
|
||||
handlers.googleCalendarEnsureWeeklyAlarm = (_req, sendResponse, sender) => {
|
||||
if (rejectUntrusted(sendResponse, sender)) return false;
|
||||
void ensureWeeklySyncAlarm()
|
||||
.then(() => sendResponse({ success: true }))
|
||||
.catch((err) => {
|
||||
sendResponse({
|
||||
success: false,
|
||||
error: err instanceof Error ? err.message : "Could not schedule weekly sync",
|
||||
});
|
||||
});
|
||||
return true;
|
||||
};
|
||||
|
||||
handlers.googleCalendarUpdateSyncSettings = (request, sendResponse, sender) => {
|
||||
if (rejectUntrusted(sendResponse, sender)) return false;
|
||||
void (async () => {
|
||||
const body = request as {
|
||||
syncWeeksAhead?: number;
|
||||
autoSyncWeekly?: boolean;
|
||||
};
|
||||
const patch: Record<string, unknown> = {};
|
||||
if (body.syncWeeksAhead != null) {
|
||||
patch.syncWeeksAhead = clampSyncWeeks(body.syncWeeksAhead);
|
||||
}
|
||||
if (body.autoSyncWeekly != null) {
|
||||
patch.autoSyncWeekly = !!body.autoSyncWeekly;
|
||||
}
|
||||
if (Object.keys(patch).length > 0) {
|
||||
await writeGoogleCalendarState(patch);
|
||||
}
|
||||
await ensureWeeklySyncAlarm();
|
||||
sendResponse({ success: true, ...(await getGoogleCalendarStatus()) });
|
||||
})().catch((err) => {
|
||||
sendResponse({
|
||||
success: false,
|
||||
error: err instanceof Error ? err.message : "Could not update sync settings",
|
||||
});
|
||||
});
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
export function initGoogleCalendarBackground(): void {
|
||||
registerWeeklySyncAlarmListener();
|
||||
void ensureWeeklySyncAlarm();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
import browser from "webextension-polyfill";
|
||||
import { verboseLog } from "@/utils/verboseLog";
|
||||
import {
|
||||
getAutoSyncWeekly,
|
||||
GOOGLE_CALENDAR_WEEKLY_ALARM,
|
||||
markWeeklySyncPending,
|
||||
} from "@/seqta/utils/googleCalendar/syncSettings";
|
||||
import { readGoogleCalendarState } from "@/seqta/utils/googleCalendar/storage";
|
||||
|
||||
const WEEKLY_PERIOD_MINUTES = 7 * 24 * 60;
|
||||
|
||||
function isSeqtaTab(tab: browser.Tabs.Tab): boolean {
|
||||
const title = tab.title ?? "";
|
||||
return title.includes("SEQTA Learn") || title.includes("SEQTA Engage");
|
||||
}
|
||||
|
||||
async function isCalendarConnected(): Promise<boolean> {
|
||||
const state = await readGoogleCalendarState();
|
||||
return !!(state.refreshToken || state.accessToken);
|
||||
}
|
||||
|
||||
export async function ensureWeeklySyncAlarm(): Promise<void> {
|
||||
const connected = await isCalendarConnected();
|
||||
const enabled = await getAutoSyncWeekly();
|
||||
if (!connected || !enabled) {
|
||||
await browser.alarms.clear(GOOGLE_CALENDAR_WEEKLY_ALARM);
|
||||
return;
|
||||
}
|
||||
|
||||
const existing = await browser.alarms.get(GOOGLE_CALENDAR_WEEKLY_ALARM);
|
||||
if (!existing) {
|
||||
await browser.alarms.create(GOOGLE_CALENDAR_WEEKLY_ALARM, {
|
||||
periodInMinutes: WEEKLY_PERIOD_MINUTES,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function clearWeeklySyncAlarm(): Promise<void> {
|
||||
await browser.alarms.clear(GOOGLE_CALENDAR_WEEKLY_ALARM);
|
||||
}
|
||||
|
||||
export async function triggerWeeklySyncOnSeqtaTabs(): Promise<boolean> {
|
||||
const tabs = await browser.tabs.query({});
|
||||
const seqtaTabs = tabs.filter((tab) => tab.id != null && isSeqtaTab(tab));
|
||||
if (seqtaTabs.length === 0) return false;
|
||||
|
||||
let delivered = false;
|
||||
for (const tab of seqtaTabs) {
|
||||
if (tab.id == null) continue;
|
||||
try {
|
||||
await browser.tabs.sendMessage(tab.id, { type: "googleCalendarRunWeeklySync" });
|
||||
delivered = true;
|
||||
} catch (err) {
|
||||
verboseLog("[BetterSEQTA+] Weekly calendar sync message failed for tab:", tab.id, err);
|
||||
}
|
||||
}
|
||||
return delivered;
|
||||
}
|
||||
|
||||
export async function handleWeeklySyncAlarm(): Promise<void> {
|
||||
if (!(await isCalendarConnected()) || !(await getAutoSyncWeekly())) return;
|
||||
|
||||
const delivered = await triggerWeeklySyncOnSeqtaTabs();
|
||||
if (!delivered) {
|
||||
await markWeeklySyncPending();
|
||||
}
|
||||
}
|
||||
|
||||
export function registerWeeklySyncAlarmListener(): void {
|
||||
browser.alarms.onAlarm.addListener((alarm) => {
|
||||
if (alarm.name !== GOOGLE_CALENDAR_WEEKLY_ALARM) return;
|
||||
void handleWeeklySyncAlarm();
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user