mirror of
https://github.com/BetterSEQTA/BetterSEQTA-Plus.git
synced 2026-06-06 03:34:40 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fcc856e798 | |||
| a0038ac871 | |||
| 49824e9eab |
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "betterseqtaplus",
|
"name": "betterseqtaplus",
|
||||||
"version": "3.6.1",
|
"version": "3.6.3",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"description": "Enhance SEQTA Learn's usability and aesthetics! A fork of BetterSEQTA to continue development and add heaps more features!",
|
"description": "Enhance SEQTA Learn's usability and aesthetics! A fork of BetterSEQTA to continue development and add heaps more features!",
|
||||||
"browserslist": "> 0.5%, last 2 versions, not dead",
|
"browserslist": "> 0.5%, last 2 versions, not dead",
|
||||||
|
|||||||
@@ -59,6 +59,10 @@ async function init() {
|
|||||||
IsSEQTAPage = true;
|
IsSEQTAPage = true;
|
||||||
console.info("[BetterSEQTA+] Verified SEQTA Page");
|
console.info("[BetterSEQTA+] Verified SEQTA Page");
|
||||||
|
|
||||||
|
if (typeof window !== "undefined" && window === window.top) {
|
||||||
|
void browser.runtime.sendMessage({ type: "cloudSettingsPoll" }).catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
registerFetchSeqtaAppLinkListener();
|
registerFetchSeqtaAppLinkListener();
|
||||||
|
|
||||||
const documentLoadStyle = document.createElement("style");
|
const documentLoadStyle = document.createElement("style");
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ export const CLOUD_SUMMARY_URL = `${ACCOUNTS_BASE}/api/user/cloud-summary`;
|
|||||||
const CLOUD_SETTINGS_SYNC_URL = `${ACCOUNTS_BASE}/api/bsplus/settings/sync`;
|
const CLOUD_SETTINGS_SYNC_URL = `${ACCOUNTS_BASE}/api/bsplus/settings/sync`;
|
||||||
const REFRESH_URL = `${ACCOUNTS_BASE}/api/bsplus/refresh`;
|
const REFRESH_URL = `${ACCOUNTS_BASE}/api/bsplus/refresh`;
|
||||||
|
|
||||||
const ALARM_NAME = "bsplus_cloud_settings_auto_sync";
|
|
||||||
const PERIOD_MINUTES = 60;
|
|
||||||
const UPLOAD_DEBOUNCE_MS = 2000;
|
const UPLOAD_DEBOUNCE_MS = 2000;
|
||||||
|
const POLL_THROTTLE_MS = 24 * 60 * 60 * 1000;
|
||||||
|
const POLL_THROTTLE_KEY = "bsplus_lastCloudPoll";
|
||||||
|
|
||||||
type CloudSummaryResponse = {
|
type CloudSummaryResponse = {
|
||||||
desqta?: unknown;
|
desqta?: unknown;
|
||||||
@@ -323,6 +323,9 @@ export function runCloudSettingsPoll(): Promise<void> {
|
|||||||
if (pollInFlight) return pollInFlight;
|
if (pollInFlight) return pollInFlight;
|
||||||
pollInFlight = (async () => {
|
pollInFlight = (async () => {
|
||||||
try {
|
try {
|
||||||
|
const { [POLL_THROTTLE_KEY]: last } = await browser.storage.local.get(POLL_THROTTLE_KEY);
|
||||||
|
if (Date.now() - (Number(last) || 0) < POLL_THROTTLE_MS) return;
|
||||||
|
await browser.storage.local.set({ [POLL_THROTTLE_KEY]: Date.now() });
|
||||||
await runCloudSettingsPollInner();
|
await runCloudSettingsPollInner();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error("[BS+ cloud sync] Poll error:", e);
|
console.error("[BS+ cloud sync] Poll error:", e);
|
||||||
@@ -360,14 +363,11 @@ async function runDebouncedUploadJob(): Promise<void> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function syncAlarmWithStorage(): Promise<void> {
|
async function syncAutoUploadWithStorage(): Promise<void> {
|
||||||
const all = (await browser.storage.local.get()) as Record<string, unknown>;
|
const all = (await browser.storage.local.get()) as Record<string, unknown>;
|
||||||
if (!isAutoCloudSyncEnabled(all)) {
|
if (!isAutoCloudSyncEnabled(all)) {
|
||||||
await browser.alarms.clear(ALARM_NAME);
|
|
||||||
clearUploadDebounce();
|
clearUploadDebounce();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
await browser.alarms.create(ALARM_NAME, { periodInMinutes: PERIOD_MINUTES });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onStorageChanged(
|
function onStorageChanged(
|
||||||
@@ -377,7 +377,7 @@ function onStorageChanged(
|
|||||||
if (area !== "local") return;
|
if (area !== "local") return;
|
||||||
|
|
||||||
if (Object.prototype.hasOwnProperty.call(changes, "autoCloudSettingsSync")) {
|
if (Object.prototype.hasOwnProperty.call(changes, "autoCloudSettingsSync")) {
|
||||||
void syncAlarmWithStorage();
|
void syncAutoUploadWithStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
const keys = Object.keys(changes);
|
const keys = Object.keys(changes);
|
||||||
@@ -392,15 +392,8 @@ function onStorageChanged(
|
|||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
function onAlarm(alarm: browser.Alarms.Alarm): void {
|
|
||||||
if (alarm.name !== ALARM_NAME) return;
|
|
||||||
void runCloudSettingsPoll();
|
|
||||||
}
|
|
||||||
|
|
||||||
export function initCloudSettingsAutoSync(deps: { reloadSeqtaPages: () => void }): void {
|
export function initCloudSettingsAutoSync(deps: { reloadSeqtaPages: () => void }): void {
|
||||||
reloadSeqtaPagesFn = deps.reloadSeqtaPages;
|
reloadSeqtaPagesFn = deps.reloadSeqtaPages;
|
||||||
browser.alarms.onAlarm.addListener(onAlarm);
|
|
||||||
browser.storage.onChanged.addListener(onStorageChanged);
|
browser.storage.onChanged.addListener(onStorageChanged);
|
||||||
void syncAlarmWithStorage();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
"64": "resources/icons/icon-64.png"
|
"64": "resources/icons/icon-64.png"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"permissions": ["tabs", "notifications", "storage", "alarms"],
|
"permissions": ["tabs", "notifications", "storage"],
|
||||||
"host_permissions": ["https://newsapi.org/", "https://betterseqta.org/", "https://accounts.betterseqta.org/", "*://*/*"],
|
"host_permissions": ["https://newsapi.org/", "https://betterseqta.org/", "https://accounts.betterseqta.org/", "*://*/*"],
|
||||||
"background": {
|
"background": {
|
||||||
"service_worker": "background.ts"
|
"service_worker": "background.ts"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import type { Plugin } from "../../core/types";
|
import type { Plugin } from "../../core/types";
|
||||||
import { waitForElm } from "@/seqta/utils/waitForElm";
|
import { waitForElm } from "@/seqta/utils/waitForElm";
|
||||||
import { getAssessmentsData } from "./api";
|
import { getAssessmentsData } from "./api";
|
||||||
import { renderErrorState, renderSkeletonLoader } from "./ui";
|
import { renderErrorState, renderGrid, renderSkeletonLoader } from "./ui";
|
||||||
import styles from "./styles.css?inline";
|
import styles from "./styles.css?inline";
|
||||||
import { delay } from "@/seqta/utils/delay";
|
import { delay } from "@/seqta/utils/delay";
|
||||||
import { isSeqtaEngageExperience } from "@/seqta/utils/isSeqtaEngage";
|
import { isSeqtaEngageExperience } from "@/seqta/utils/isSeqtaEngage";
|
||||||
@@ -68,7 +68,6 @@ const assessmentsOverviewPlugin: Plugin<{}> = {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const data = await getAssessmentsData();
|
const data = await getAssessmentsData();
|
||||||
const { renderGrid } = await import("./ui");
|
|
||||||
renderGrid(container, data);
|
renderGrid(container, data);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Failed to load assessments:", err);
|
console.error("Failed to load assessments:", err);
|
||||||
|
|||||||
@@ -34,7 +34,10 @@ export function OpenWhatsNewPopup(onDismissed?: () => void) {
|
|||||||
const text = stringToHTML(/* html */ `
|
const text = stringToHTML(/* html */ `
|
||||||
<div class="whatsnewTextContainer" style="height: 50%;overflow-y: auto;">
|
<div class="whatsnewTextContainer" style="height: 50%;overflow-y: auto;">
|
||||||
|
|
||||||
<h1>3.6.1 - Cloud backup, various fixes & SEQTA Engage support</h1>
|
<h1>3.6.3 - Assessment overview fix</h1>
|
||||||
|
<li>Fixed assessments overview failing to load.</li>
|
||||||
|
|
||||||
|
<h1>3.6.2 - Cloud backup, various fixes & SEQTA Engage support</h1>
|
||||||
<li>BetterSEQTA Cloud: back up and restore extension settings from your account (General settings).</li>
|
<li>BetterSEQTA Cloud: back up and restore extension settings from your account (General settings).</li>
|
||||||
<li>Optional automatic cloud sync if signed in (on by default).</li>
|
<li>Optional automatic cloud sync if signed in (on by default).</li>
|
||||||
<li>Option to use cloud profile photo as the local SEQTA profile picture</li>
|
<li>Option to use cloud profile photo as the local SEQTA profile picture</li>
|
||||||
|
|||||||
@@ -36,7 +36,10 @@ export const SENSITIVE_DEVICE_STORAGE_KEYS_EXACT = [
|
|||||||
/** e.g. any future `plugin.global-search.storage.*` keys in chrome.storage */
|
/** e.g. any future `plugin.global-search.storage.*` keys in chrome.storage */
|
||||||
export const SENSITIVE_DEVICE_STORAGE_KEY_PREFIXES = ["plugin.global-search.storage."] as const;
|
export const SENSITIVE_DEVICE_STORAGE_KEY_PREFIXES = ["plugin.global-search.storage."] as const;
|
||||||
|
|
||||||
const CLIENT_ONLY_CLOUD_KEYS_EXACT = [BSPLUS_CLOUD_KNOWN_REMOTE_UPDATED_AT_KEY] as const;
|
const CLIENT_ONLY_CLOUD_KEYS_EXACT = [
|
||||||
|
BSPLUS_CLOUD_KNOWN_REMOTE_UPDATED_AT_KEY,
|
||||||
|
"bsplus_lastCloudPoll",
|
||||||
|
] as const;
|
||||||
|
|
||||||
/** After restoring from cloud, keep local session so the user stays signed in. */
|
/** After restoring from cloud, keep local session so the user stays signed in. */
|
||||||
const AUTH_KEYS_TO_PRESERVE = [
|
const AUTH_KEYS_TO_PRESERVE = [
|
||||||
|
|||||||
Reference in New Issue
Block a user