mirror of
https://github.com/GuySandler/CanvasRefined.git
synced 2026-09-22 04:54:53 +02:00
background work + bugfixes
daily backgrounds + some smaller fixes and some UI changes
This commit is contained in:
parent
25ff281bf9
commit
2c65b5ab17
@ -254,7 +254,16 @@
|
|||||||
<span class="option-name" data-i18n="better_sidebar">Better Sidebar</span>
|
<span class="option-name" data-i18n="better_sidebar">Better Sidebar</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="sub-options">
|
<div class="sub-options">
|
||||||
<div style="margin-top: 5px">
|
<div class="option" id="remlogo" style="margin-top:2px">
|
||||||
|
<input type="radio" id="off" name="remlogo">
|
||||||
|
<input type="radio" id="on" name="remlogo">
|
||||||
|
<div class="slider">
|
||||||
|
<div class="sliderknob"></div>
|
||||||
|
<div class="sliderbg"></div>
|
||||||
|
</div>
|
||||||
|
<span class="option-name" data-i18n="remlogo">Remove sidebar logo</span>
|
||||||
|
</div>
|
||||||
|
<div style="margin-top: 5px" id="sidebarScaleSub">
|
||||||
<span class="sub-text">Sidebar scale: </span><span id="sidebarScaleValue"></span><span class="sub-text">%</span>
|
<span class="sub-text">Sidebar scale: </span><span id="sidebarScaleValue"></span><span class="sub-text">%</span>
|
||||||
<input type="range" min="70" max="150" id="sidebarScaleSlider">
|
<input type="range" min="70" max="150" id="sidebarScaleSlider">
|
||||||
</div>
|
</div>
|
||||||
@ -303,14 +312,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<span class="option-name" data-i18n="full_width">Full Width Fix</span>
|
<span class="option-name" data-i18n="full_width">Full Width Fix</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="option" id="remlogo">
|
|
||||||
<input type="radio" id="off" name="remlogo">
|
|
||||||
<input type="radio" id="on" name="remlogo">
|
|
||||||
<div class="slider">
|
|
||||||
<div class="sliderknob"></div>
|
|
||||||
<div class="sliderbg"></div>
|
|
||||||
</div><span class="option-name" data-i18n="remlogo">Remove sidebar logo</span>
|
|
||||||
</div>
|
|
||||||
<div class="option" id="hide_feedback">
|
<div class="option" id="hide_feedback">
|
||||||
<input type="radio" id="off" name="hide_feedback">
|
<input type="radio" id="off" name="hide_feedback">
|
||||||
<input type="radio" id="on" name="hide_feedback">
|
<input type="radio" id="on" name="hide_feedback">
|
||||||
@ -941,16 +942,30 @@
|
|||||||
<div class="custom-font option-container">
|
<div class="custom-font option-container">
|
||||||
<h3 class="header-small">Custom Background</h3>
|
<h3 class="header-small">Custom Background</h3>
|
||||||
<p>Pick a preset or use your own image url.</p>
|
<p>Pick a preset or use your own image url.</p>
|
||||||
<div class="background-preset-grid" id="background-presets"></div>
|
<div id="customBackgroundManualControls">
|
||||||
<div class="background-scale-row">
|
<div class="background-preset-grid" id="background-presets"></div>
|
||||||
<div style="display:flex;justify-content:space-between;gap:10px;align-items:center;margin-top:10px;">
|
<div class="background-scale-row">
|
||||||
<span class="sub-text" style="font-weight:600; color:#e2e2e2;">Image scale</span>
|
<div style="display:flex;justify-content:space-between;gap:10px;align-items:center;margin-top:10px;">
|
||||||
<span class="sub-text" id="customBackgroundScaleValue">100%</span>
|
<span class="sub-text" style="font-weight:600; color:#e2e2e2;">Image scale</span>
|
||||||
|
<span class="sub-text" id="customBackgroundScaleValue">100%</span>
|
||||||
|
</div>
|
||||||
|
<input type="range" min="50" max="200" step="1" id="customBackgroundScale">
|
||||||
</div>
|
</div>
|
||||||
<input type="range" min="50" max="200" step="1" id="customBackgroundScale">
|
<input style="width:85%;" class="card-input" id="customBackgroundLink" placeholder="https://...">
|
||||||
|
<button id="clearCustomBackground" class="big-button" style="margin-top: 8px;">Clear Background</button>
|
||||||
|
</div>
|
||||||
|
<div class="sub-option" style="margin-top:10px;">
|
||||||
|
<input type="checkbox" id="customBackgroundDaily" name="customBackgroundDaily">
|
||||||
|
<label for="customBackgroundDaily" class="sub-text">Daily Random Image</label>
|
||||||
|
</div>
|
||||||
|
<div class="sub-option" style="margin-top:6px;">
|
||||||
|
<input type="checkbox" id="customBackgroundNasaDaily" name="customBackgroundNasaDaily">
|
||||||
|
<label for="customBackgroundNasaDaily" class="sub-text">NASA Astronomy Picture of the Day</label>
|
||||||
|
</div>
|
||||||
|
<div class="sub-option" style="margin-top:8px;">
|
||||||
|
<input type="checkbox" id="fitImageToScreen" name="fitImageToScreen">
|
||||||
|
<label for="fitImageToScreen" class="sub-text">Fit image to screen</label>
|
||||||
</div>
|
</div>
|
||||||
<input style="width:85%;" class="card-input" id="customBackgroundLink" placeholder="https://...">
|
|
||||||
<button id="clearCustomBackground" class="big-button" style="margin-top: 8px;">Clear Background</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -104,6 +104,10 @@ chrome.runtime.onInstalled.addListener(function () {
|
|||||||
"customCardStyles": false,
|
"customCardStyles": false,
|
||||||
"customBackgroundLink": "",
|
"customBackgroundLink": "",
|
||||||
"customBackgroundScale": 100,
|
"customBackgroundScale": 100,
|
||||||
|
"customBackgroundDaily": false,
|
||||||
|
"customBackgroundNasaDaily": false,
|
||||||
|
"nasaInfoOverlay": false,
|
||||||
|
"fitImageToScreen": false,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -122,6 +126,11 @@ chrome.runtime.onInstalled.addListener(function () {
|
|||||||
newLocalOptions[option] = default_options["local"][option];
|
newLocalOptions[option] = default_options["local"][option];
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// migrate old setting name
|
||||||
|
if (sync["nasaFitToScreen"] !== undefined && sync["fitImageToScreen"] === undefined) {
|
||||||
|
newSyncOptions["fitImageToScreen"] = sync["nasaFitToScreen"];
|
||||||
|
}
|
||||||
|
|
||||||
if (Object.keys(newLocalOptions).length > 0) {
|
if (Object.keys(newLocalOptions).length > 0) {
|
||||||
chrome.storage.local.set(newLocalOptions);
|
chrome.storage.local.set(newLocalOptions);
|
||||||
}
|
}
|
||||||
@ -139,4 +148,90 @@ chrome.runtime.onInstalled.addListener(function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// The NASA APOD API with the demo key is limited to 30 requests/hour and 50/day.
|
||||||
|
// All calls are serialized through this worker and gated against those limits.
|
||||||
|
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||||
|
if (message?.type === "getNasaBackground") {
|
||||||
|
getNasaBackground().then(sendResponse);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let nasaRequestQueue = Promise.resolve();
|
||||||
|
function queuedNasaTask(task) {
|
||||||
|
const run = nasaRequestQueue.then(task, task);
|
||||||
|
nasaRequestQueue = run.catch(() => {});
|
||||||
|
return run;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getNasaBackground() {
|
||||||
|
return queuedNasaTask(async () => {
|
||||||
|
const date = new Date();
|
||||||
|
for (let i = 0; i < 7; i++) {
|
||||||
|
const dateStr = date.toISOString().slice(0, 10);
|
||||||
|
const cacheKey = `nasa_apod_${dateStr}`;
|
||||||
|
const metadataKey = `nasa_apod_meta_${dateStr}`;
|
||||||
|
const cached = await chrome.storage.local.get([cacheKey, metadataKey]);
|
||||||
|
if (cached[cacheKey]) return cached[cacheKey];
|
||||||
|
|
||||||
|
// Don't re-probe dates the API already told us don't exist
|
||||||
|
const missingKey = `nasa_apod_missing_${dateStr}`;
|
||||||
|
const missing = await chrome.storage.local.get(missingKey);
|
||||||
|
if (missing[missingKey]) {
|
||||||
|
date.setDate(date.getDate() - 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await callNasaApi(dateStr);
|
||||||
|
if (data === "ratelimited" || data === null) return null;
|
||||||
|
if (data === "missing") {
|
||||||
|
await chrome.storage.local.set({ [missingKey]: true });
|
||||||
|
date.setDate(date.getDate() - 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = data.thumbnail_url || data.hdurl || data.url;
|
||||||
|
if (!url) return null;
|
||||||
|
const result = { url, scale: 100, date: dateStr };
|
||||||
|
await chrome.storage.local.set({ [cacheKey]: result });
|
||||||
|
await chrome.storage.local.set({ [metadataKey]: { title: data.title || "", date: data.date || dateStr, copyright: data.copyright || "", explanation: data.explanation || "" } });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function callNasaApi(dateStr) {
|
||||||
|
const now = Date.now();
|
||||||
|
const { nasa_api_calls = [] } = await chrome.storage.local.get("nasa_api_calls");
|
||||||
|
const lastHour = nasa_api_calls.filter(t => now - t < 3600 * 1000);
|
||||||
|
const lastDay = nasa_api_calls.filter(t => now - t < 24 * 3600 * 1000);
|
||||||
|
if (lastHour.length >= 30 || lastDay.length >= 50) {
|
||||||
|
console.warn("[CanvasRefined] NASA API rate limit reached, skipping request");
|
||||||
|
return "ratelimited";
|
||||||
|
}
|
||||||
|
|
||||||
|
let response;
|
||||||
|
try {
|
||||||
|
response = await fetch(`https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY&thumbs=true&date=${dateStr}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("[CanvasRefined] Failed to fetch NASA APOD:", error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The request was made, so it counts against the quota
|
||||||
|
await chrome.storage.local.set({ nasa_api_calls: [...lastDay, now] });
|
||||||
|
|
||||||
|
if (response.status === 429) return "ratelimited";
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorData = await response.json().catch(() => ({}));
|
||||||
|
if (errorData.code === 404 && (errorData.msg || "").toLowerCase().includes("no data available")) {
|
||||||
|
return "missing";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return await response.json().catch(() => null);
|
||||||
|
}
|
||||||
|
|
||||||
// chrome.runtime.setUninstallURL("https://diditupe.dev/canvasrefined/goodbye");
|
// chrome.runtime.setUninstallURL("https://diditupe.dev/canvasrefined/goodbye");
|
||||||
|
|||||||
386
js/content.js
386
js/content.js
@ -30,6 +30,10 @@ function isConversationsPage() {
|
|||||||
return /^\/conversations(?:\/|$)/.test(current_page);
|
return /^\/conversations(?:\/|$)/.test(current_page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isAccountsPage() {
|
||||||
|
return /^\/accounts(?:\/|$)/.test(current_page);
|
||||||
|
}
|
||||||
|
|
||||||
function isProfilePage() {
|
function isProfilePage() {
|
||||||
return /^\/profile(?:\/|$)/.test(current_page);
|
return /^\/profile(?:\/|$)/.test(current_page);
|
||||||
}
|
}
|
||||||
@ -58,72 +62,6 @@ function addSubmissionPageButton() {
|
|||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
let sequenceFooterObserver = null;
|
|
||||||
|
|
||||||
function isAssignmentPage() {
|
|
||||||
return /^\/courses\/\d+\/assignments(?:\/\d+)?(?:\/|$)/.test(current_page);
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeSequenceFooter() {
|
|
||||||
if (!isAssignmentPage()) return false;
|
|
||||||
const sequenceFooter = document.getElementById("sequence_footer");
|
|
||||||
if (!sequenceFooter) return false;
|
|
||||||
sequenceFooter.remove();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function watchSequenceFooter() {
|
|
||||||
if (!isAssignmentPage()) return;
|
|
||||||
if (removeSequenceFooter()) return;
|
|
||||||
if (sequenceFooterObserver) return;
|
|
||||||
|
|
||||||
sequenceFooterObserver = new MutationObserver(() => {
|
|
||||||
if (removeSequenceFooter() && sequenceFooterObserver) {
|
|
||||||
sequenceFooterObserver.disconnect();
|
|
||||||
sequenceFooterObserver = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
sequenceFooterObserver.observe(document.documentElement, { childList: true, subtree: true });
|
|
||||||
setTimeout(() => {
|
|
||||||
if (sequenceFooterObserver) {
|
|
||||||
sequenceFooterObserver.disconnect();
|
|
||||||
sequenceFooterObserver = null;
|
|
||||||
}
|
|
||||||
}, 10000);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureSubmissionPageButton() {
|
|
||||||
const assignmentLink = getSubmissionAssignmentLink();
|
|
||||||
if (!assignmentLink) return false;
|
|
||||||
const content = document.getElementById("content");
|
|
||||||
if (!content) return false;
|
|
||||||
if (content.querySelector("#canvasrefined-assignment-return")) return true;
|
|
||||||
addSubmissionPageButton();
|
|
||||||
return Boolean(content.querySelector("#canvasrefined-assignment-return"));
|
|
||||||
}
|
|
||||||
|
|
||||||
function watchSubmissionPageButton() {
|
|
||||||
if (!getSubmissionAssignmentLink()) return;
|
|
||||||
if (ensureSubmissionPageButton()) return;
|
|
||||||
if (submissionPageButtonObserver) return;
|
|
||||||
|
|
||||||
submissionPageButtonObserver = new MutationObserver(() => {
|
|
||||||
if (ensureSubmissionPageButton() && submissionPageButtonObserver) {
|
|
||||||
submissionPageButtonObserver.disconnect();
|
|
||||||
submissionPageButtonObserver = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
submissionPageButtonObserver.observe(document.documentElement, { childList: true, subtree: true });
|
|
||||||
setTimeout(() => {
|
|
||||||
if (submissionPageButtonObserver) {
|
|
||||||
submissionPageButtonObserver.disconnect();
|
|
||||||
submissionPageButtonObserver = null;
|
|
||||||
}
|
|
||||||
}, 10000);
|
|
||||||
}
|
|
||||||
|
|
||||||
function addProfileLogoutPageButton() {
|
function addProfileLogoutPageButton() {
|
||||||
if (!isProfilePage()) return;
|
if (!isProfilePage()) return;
|
||||||
const content = document.getElementById("content");
|
const content = document.getElementById("content");
|
||||||
@ -168,6 +106,194 @@ function watchProfileLogoutPageButton() {
|
|||||||
}, 10000);
|
}, 10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ensureSubmissionPageButton() {
|
||||||
|
const assignmentLink = getSubmissionAssignmentLink();
|
||||||
|
if (!assignmentLink) return false;
|
||||||
|
const content = document.getElementById("content");
|
||||||
|
if (!content) return false;
|
||||||
|
if (content.querySelector("#canvasrefined-assignment-return")) return true;
|
||||||
|
addSubmissionPageButton();
|
||||||
|
return Boolean(content.querySelector("#canvasrefined-assignment-return"));
|
||||||
|
}
|
||||||
|
|
||||||
|
function watchSequenceFooter() {
|
||||||
|
if (!isAssignmentPage()) return;
|
||||||
|
if (removeSequenceFooter()) return;
|
||||||
|
if (sequenceFooterObserver) return;
|
||||||
|
|
||||||
|
sequenceFooterObserver = new MutationObserver(() => {
|
||||||
|
if (removeSequenceFooter() && sequenceFooterObserver) {
|
||||||
|
sequenceFooterObserver.disconnect();
|
||||||
|
sequenceFooterObserver = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
sequenceFooterObserver.observe(document.documentElement, { childList: true, subtree: true });
|
||||||
|
setTimeout(() => {
|
||||||
|
if (sequenceFooterObserver) {
|
||||||
|
sequenceFooterObserver.disconnect();
|
||||||
|
sequenceFooterObserver = null;
|
||||||
|
}
|
||||||
|
}, 10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function watchSubmissionPageButton() {
|
||||||
|
if (!getSubmissionAssignmentLink()) return;
|
||||||
|
if (ensureSubmissionPageButton()) return;
|
||||||
|
if (submissionPageButtonObserver) return;
|
||||||
|
|
||||||
|
submissionPageButtonObserver = new MutationObserver(() => {
|
||||||
|
if (ensureSubmissionPageButton() && submissionPageButtonObserver) {
|
||||||
|
submissionPageButtonObserver.disconnect();
|
||||||
|
submissionPageButtonObserver = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
submissionPageButtonObserver.observe(document.documentElement, { childList: true, subtree: true });
|
||||||
|
setTimeout(() => {
|
||||||
|
if (submissionPageButtonObserver) {
|
||||||
|
submissionPageButtonObserver.disconnect();
|
||||||
|
submissionPageButtonObserver = null;
|
||||||
|
}
|
||||||
|
}, 10000);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getActiveCustomBackground() {
|
||||||
|
const syncOpts = await chrome.storage.sync.get([
|
||||||
|
"customBackgroundDaily",
|
||||||
|
"customBackgroundNasaDaily",
|
||||||
|
"customBackgroundLink",
|
||||||
|
"customBackgroundScale",
|
||||||
|
]);
|
||||||
|
|
||||||
|
console.log("[CanvasRefined] getActiveCustomBackground:", syncOpts);
|
||||||
|
|
||||||
|
if (syncOpts.customBackgroundNasaDaily === true) {
|
||||||
|
console.log("[CanvasRefined] Using NASA APOD");
|
||||||
|
return await getNasaDailyBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (syncOpts.customBackgroundDaily === true) {
|
||||||
|
console.log("[CanvasRefined] Using Wikimedia Featured");
|
||||||
|
const dailyPreset = await getDailyBackgroundPreset();
|
||||||
|
if (dailyPreset) {
|
||||||
|
console.log("[CanvasRefined] Wikimedia URL:", dailyPreset.url);
|
||||||
|
return {
|
||||||
|
url: dailyPreset.url,
|
||||||
|
scale: dailyPreset.scale,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
console.log("[CanvasRefined] Wikimedia returned null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (syncOpts.customBackgroundLink && syncOpts.customBackgroundLink !== "") {
|
||||||
|
console.log("[CanvasRefined] Using custom link");
|
||||||
|
return {
|
||||||
|
url: syncOpts.customBackgroundLink,
|
||||||
|
scale: syncOpts.customBackgroundScale || 100,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("[CanvasRefined] No custom background");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getDailyBackgroundPreset() {
|
||||||
|
const today = new Date();
|
||||||
|
const dateStr = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, "0")}-${String(today.getDate()).padStart(2, "0")}`;
|
||||||
|
const cacheKey = `picsum_daily_${dateStr}`;
|
||||||
|
const cached = await chrome.storage.local.get(cacheKey);
|
||||||
|
if (cached[cacheKey]) return cached[cacheKey];
|
||||||
|
|
||||||
|
const url = `https://picsum.photos/seed/${dateStr}/1920/1080`;
|
||||||
|
const result = { url, scale: 100 };
|
||||||
|
await chrome.storage.local.set({ [cacheKey]: result });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getNasaDailyBackground() {
|
||||||
|
try {
|
||||||
|
return await chrome.runtime.sendMessage({ type: "getNasaBackground" });
|
||||||
|
} catch (error) {
|
||||||
|
console.error("[CanvasRefined] Failed to fetch NASA APOD:", error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let nasaInfoOverlayEl = null;
|
||||||
|
|
||||||
|
function isDashboardPage() {
|
||||||
|
return !!document.querySelector("#DashboardCard_Container");
|
||||||
|
}
|
||||||
|
|
||||||
|
function createNasaInfoOverlay() {
|
||||||
|
if (options.customBackgroundNasaDaily !== true) return;
|
||||||
|
if (nasaInfoOverlayEl || !isDashboardPage()) return;
|
||||||
|
|
||||||
|
const contentMain = document.querySelector("#content.ic-Layout-contentMain, .ic-Layout-contentMain");
|
||||||
|
if (!contentMain) return;
|
||||||
|
if (getComputedStyle(contentMain).position === "static") {
|
||||||
|
contentMain.style.position = "relative";
|
||||||
|
}
|
||||||
|
|
||||||
|
nasaInfoOverlayEl = document.createElement("div");
|
||||||
|
nasaInfoOverlayEl.id = "canvasrefined-nasa-info-overlay";
|
||||||
|
nasaInfoOverlayEl.style.cssText = "position:absolute;right:24px;bottom:24px;z-index:9999;";
|
||||||
|
nasaInfoOverlayEl.innerHTML = `
|
||||||
|
<div id="nasa-info-icon" style="display:flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:50%;background:rgba(30,30,30,0.85);border:1px solid rgba(255,255,255,0.15);cursor:pointer;box-shadow:0 2px 8px rgba(0,0,0,0.4);">
|
||||||
|
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#e2e2e2" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<circle cx="12" cy="12" r="10"></circle>
|
||||||
|
<line x1="12" y1="16" x2="12" y2="12"></line>
|
||||||
|
<line x1="12" y1="8" x2="12.01" y2="8"></line>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div id="nasa-info-panel" style="display:none;position:absolute;bottom:calc(100% + 10px);right:0;background:#1e1e1e;border:1px solid #3c3c3c;border-radius:8px;padding:14px 18px;width:340px;max-width:calc(100vw - 40px);box-shadow:0 4px 16px rgba(0,0,0,0.4);">
|
||||||
|
<div id="nasa-info-title" style="font-weight:600;font-size:14px;margin-bottom:4px;color:#f5f5f5;"></div>
|
||||||
|
<div id="nasa-info-date" style="font-size:12px;color:#ababab;margin-bottom:4px;"></div>
|
||||||
|
<div id="nasa-info-credit" style="font-size:12px;color:#dfa581;margin-bottom:8px;"></div>
|
||||||
|
<div id="nasa-info-explanation" style="font-size:12px;color:#e2e2e2;line-height:1.5;max-height:200px;overflow-y:auto;white-space:pre-wrap;"></div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const icon = nasaInfoOverlayEl.querySelector("#nasa-info-icon");
|
||||||
|
const panel = nasaInfoOverlayEl.querySelector("#nasa-info-panel");
|
||||||
|
|
||||||
|
const showPanel = async () => {
|
||||||
|
const dateStr = new Date().toISOString().slice(0, 10);
|
||||||
|
const cacheKey = `nasa_apod_${dateStr}`;
|
||||||
|
const cached = await chrome.storage.local.get(cacheKey);
|
||||||
|
const metaDate = cached[cacheKey]?.date || dateStr;
|
||||||
|
const metadataKey = `nasa_apod_meta_${metaDate}`;
|
||||||
|
const metadata = await chrome.storage.local.get(metadataKey);
|
||||||
|
const meta = metadata[metadataKey];
|
||||||
|
if (meta) {
|
||||||
|
document.getElementById("nasa-info-title").textContent = meta.title || "";
|
||||||
|
document.getElementById("nasa-info-date").textContent = `Date: ${meta.date}`;
|
||||||
|
document.getElementById("nasa-info-credit").textContent = meta.copyright ? `Credit: ${meta.copyright}` : "";
|
||||||
|
document.getElementById("nasa-info-explanation").textContent = meta.explanation || "No description available.";
|
||||||
|
panel.style.display = "block";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const hidePanel = () => {
|
||||||
|
panel.style.display = "none";
|
||||||
|
};
|
||||||
|
|
||||||
|
icon.addEventListener("mouseenter", showPanel);
|
||||||
|
icon.addEventListener("mouseleave", hidePanel);
|
||||||
|
panel.addEventListener("mouseenter", showPanel);
|
||||||
|
panel.addEventListener("mouseleave", hidePanel);
|
||||||
|
|
||||||
|
contentMain.appendChild(nasaInfoOverlayEl);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeNasaInfoOverlay() {
|
||||||
|
if (nasaInfoOverlayEl) {
|
||||||
|
nasaInfoOverlayEl.remove();
|
||||||
|
nasaInfoOverlayEl = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getSidebarStateMode(mode = getSidebarLayoutMode()) {
|
function getSidebarStateMode(mode = getSidebarLayoutMode()) {
|
||||||
return mode === "course" ? "course" : "dashboard";
|
return mode === "course" ? "course" : "dashboard";
|
||||||
}
|
}
|
||||||
@ -348,6 +474,7 @@ async function reminderWatch() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateReminders() {
|
function updateReminders() {
|
||||||
|
if (!assignments || typeof assignments.then !== "function") return;
|
||||||
const fiveDays = 1000 * 60 * 60 * 24 * 5;
|
const fiveDays = 1000 * 60 * 60 * 24 * 5;
|
||||||
const now = (new Date()).getTime();
|
const now = (new Date()).getTime();
|
||||||
const list = [];
|
const list = [];
|
||||||
@ -438,6 +565,17 @@ function isDomainCanvasPage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function startExtension() {
|
function startExtension() {
|
||||||
|
// Remove footer robustly - run first so a crash below can't block it
|
||||||
|
const removeFooter = () => {
|
||||||
|
const footer = document.querySelector('footer#footer.ic-app-footer, footer#footer');
|
||||||
|
if (footer) footer.remove();
|
||||||
|
};
|
||||||
|
removeFooter();
|
||||||
|
const footerObserver = new MutationObserver(() => {
|
||||||
|
removeFooter();
|
||||||
|
});
|
||||||
|
footerObserver.observe(document.documentElement, { childList: true, subtree: true });
|
||||||
|
|
||||||
toggleDarkMode();
|
toggleDarkMode();
|
||||||
|
|
||||||
chrome.storage.sync.get(["better_sidebar", "sidebar_scale"], result => {
|
chrome.storage.sync.get(["better_sidebar", "sidebar_scale"], result => {
|
||||||
@ -463,7 +601,6 @@ function startExtension() {
|
|||||||
|
|
||||||
//getClassAverages();
|
//getClassAverages();
|
||||||
|
|
||||||
setTimeout(() => document.getElementById("footer")?.remove(), 800);
|
|
||||||
setTimeout(() => runDarkModeFixer(false), 800);
|
setTimeout(() => runDarkModeFixer(false), 800);
|
||||||
setTimeout(() => runDarkModeFixer(false), 4500);
|
setTimeout(() => runDarkModeFixer(false), 4500);
|
||||||
});
|
});
|
||||||
@ -567,6 +704,21 @@ function applyOptionsChanges(changes) {
|
|||||||
applyAestheticChanges();
|
applyAestheticChanges();
|
||||||
break;
|
break;
|
||||||
case "customBackgroundScale":
|
case "customBackgroundScale":
|
||||||
|
applyCustomBackground();
|
||||||
|
break;
|
||||||
|
case "customBackgroundDaily":
|
||||||
|
applyCustomBackground();
|
||||||
|
removeNasaInfoOverlay();
|
||||||
|
break;
|
||||||
|
case "customBackgroundNasaDaily":
|
||||||
|
applyCustomBackground();
|
||||||
|
if (options.customBackgroundNasaDaily === true) {
|
||||||
|
createNasaInfoOverlay();
|
||||||
|
} else {
|
||||||
|
removeNasaInfoOverlay();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "fitImageToScreen":
|
||||||
applyCustomBackground();
|
applyCustomBackground();
|
||||||
break;
|
break;
|
||||||
// case "show_updates":
|
// case "show_updates":
|
||||||
@ -674,22 +826,31 @@ function ensureBetterSidebar() {
|
|||||||
setupBetterSidebar(getSidebarLayoutMode());
|
setupBetterSidebar(getSidebarLayoutMode());
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyCustomBackground() {
|
async function applyCustomBackground() {
|
||||||
// let style = document.querySelector("#DashboardCard_Container")
|
// let style = document.querySelector("#DashboardCard_Container")
|
||||||
let style = document.querySelector("#canvasrefined-background") || document.createElement('style');
|
let style = document.querySelector("#canvasrefined-background") || document.createElement('style');
|
||||||
style.id = "canvasrefined-background";
|
style.id = "canvasrefined-background";
|
||||||
|
|
||||||
if (options.customBackgroundLink && options.customBackgroundLink !== "") {
|
const activeBackground = await getActiveCustomBackground();
|
||||||
const backgroundScale = Number(options.customBackgroundScale) || 100;
|
console.log("[CanvasRefined] activeBackground:", activeBackground);
|
||||||
style.textContent = `
|
if (!activeBackground) {
|
||||||
|
if (style.isConnected) style.remove();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const backgroundScale = Number(activeBackground.scale) || 100;
|
||||||
|
const backgroundUrl = JSON.stringify(activeBackground.url);
|
||||||
|
const fitToScreen = options.fitImageToScreen === true;
|
||||||
|
console.log("[CanvasRefined] Applying background:", activeBackground.url, "fitToScreen:", fitToScreen);
|
||||||
|
style.textContent = `
|
||||||
#wrapper {
|
#wrapper {
|
||||||
background-image: url('${options.customBackgroundLink}') !important;
|
background-image: url(${backgroundUrl}) !important;
|
||||||
background-repeat: no-repeat !important;
|
background-repeat: no-repeat !important;
|
||||||
background-position: center center !important;
|
background-position: center center !important;
|
||||||
background-attachment: fixed !important;
|
background-attachment: fixed !important;
|
||||||
}
|
}
|
||||||
@media (orientation: landscape) {
|
@media (orientation: landscape) {
|
||||||
#wrapper { background-size: ${backgroundScale}% auto !important; }
|
#wrapper { background-size: ${fitToScreen ? 'cover' : backgroundScale + '% auto'} !important; }
|
||||||
}
|
}
|
||||||
@media (orientation: portrait) {
|
@media (orientation: portrait) {
|
||||||
#wrapper { background-size: cover !important; }
|
#wrapper { background-size: cover !important; }
|
||||||
@ -698,6 +859,20 @@ function applyCustomBackground() {
|
|||||||
background: none !important;
|
background: none !important;
|
||||||
/* backdrop-filter: blur(10px) !important; */
|
/* backdrop-filter: blur(10px) !important; */
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
padding-left: 20px !important;
|
||||||
|
}
|
||||||
|
#dashboard_header_container {
|
||||||
|
margin-left: -35px !important;
|
||||||
|
margin-right: -35px !important;
|
||||||
|
box-sizing: border-box !important;
|
||||||
|
background-color: color-mix(in srgb, var(--bcbackground-0), transparent 20%) !important;
|
||||||
|
border: 1px solid color-mix(in srgb, var(--bcborders) 60%, transparent) !important;
|
||||||
|
border-radius: 10px !important;
|
||||||
|
position: sticky !important;
|
||||||
|
top: 0 !important;
|
||||||
|
z-index: 1000 !important;
|
||||||
|
backdrop-filter: blur(8px) saturate(120%) !important;
|
||||||
|
-webkit-backdrop-filter: blur(8px) saturate(120%) !important;
|
||||||
}
|
}
|
||||||
#right-side-wrapper {
|
#right-side-wrapper {
|
||||||
// backdrop-filter: blur(10px) !important;
|
// backdrop-filter: blur(10px) !important;
|
||||||
@ -837,8 +1012,7 @@ function applyCustomBackground() {
|
|||||||
tr.student_assignment.assignment_graded.editable > * {
|
tr.student_assignment.assignment_graded.editable > * {
|
||||||
border:none!important
|
border:none!important
|
||||||
}`;
|
}`;
|
||||||
// TODO: liquid glass?
|
// TODO: liquid glass?
|
||||||
}
|
|
||||||
|
|
||||||
document.documentElement.appendChild(style);
|
document.documentElement.appendChild(style);
|
||||||
}
|
}
|
||||||
@ -903,6 +1077,7 @@ function checkDashboardReady() {
|
|||||||
loadDashboardNotes();
|
loadDashboardNotes();
|
||||||
setupGPACalc();
|
setupGPACalc();
|
||||||
showUpdateMsg();
|
showUpdateMsg();
|
||||||
|
createNasaInfoOverlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
const rightSide = document.querySelector("#right-side");
|
const rightSide = document.querySelector("#right-side");
|
||||||
@ -942,7 +1117,7 @@ function recieveMessage(request, sender, sendResponse) {
|
|||||||
case ("getcolors"): sendResponse(getCardColors()); break;
|
case ("getcolors"): sendResponse(getCardColors()); break;
|
||||||
case ("inspect"): sendResponse(inspectDarkMode(true)); break;
|
case ("inspect"): sendResponse(inspectDarkMode(true)); break;
|
||||||
case ("fixdm"): sendResponse(runDarkModeFixer(true)); break;
|
case ("fixdm"): sendResponse(runDarkModeFixer(true)); break;
|
||||||
case ("updateBackground"): clearCustomBackground(); sendResponse(true); break;
|
case ("updateBackground"): applyCustomBackground(); sendResponse(true); break;
|
||||||
default: sendResponse(true);
|
default: sendResponse(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2442,8 +2617,13 @@ async function setupBetterSidebar(mode = getSidebarLayoutMode()) {
|
|||||||
const contentMain = document.querySelector(".ic-Layout-contentMain");
|
const contentMain = document.querySelector(".ic-Layout-contentMain");
|
||||||
contentMain?.style.setProperty("flex", "1 1 auto");
|
contentMain?.style.setProperty("flex", "1 1 auto");
|
||||||
contentMain?.style.setProperty("min-width", "0");
|
contentMain?.style.setProperty("min-width", "0");
|
||||||
|
const notRightSide = document.getElementById("not_right_side");
|
||||||
|
if (notRightSide && isAccountsPage()) {
|
||||||
|
notRightSide.style.setProperty("width", "100%");
|
||||||
|
notRightSide.style.setProperty("max-width", "100%");
|
||||||
|
notRightSide.style.setProperty("min-width", "0");
|
||||||
|
}
|
||||||
if (layoutMode === "course" && leftSide) {
|
if (layoutMode === "course" && leftSide) {
|
||||||
const notRightSide = document.getElementById("not_right_side");
|
|
||||||
const rightSideWrapper = document.getElementById("right-side-wrapper");
|
const rightSideWrapper = document.getElementById("right-side-wrapper");
|
||||||
const sectionTabs = document.getElementById("section-tabs");
|
const sectionTabs = document.getElementById("section-tabs");
|
||||||
leftSide.style.setProperty("padding-top", "0", "important");
|
leftSide.style.setProperty("padding-top", "0", "important");
|
||||||
@ -3790,7 +3970,7 @@ function setupGPACalc() {
|
|||||||
grades?.then(result => {
|
grades?.then(result => {
|
||||||
|
|
||||||
const sortableContainer = document.querySelector(".ic-DashboardCard__box__container");
|
const sortableContainer = document.querySelector(".ic-DashboardCard__box__container");
|
||||||
const dashboardContainer = document.querySelector("#DashboardCard_Container");
|
const dashboardContainer = sortableContainer || document.querySelector("#DashboardCard_Container");
|
||||||
if (!dashboardContainer) return;
|
if (!dashboardContainer) return;
|
||||||
|
|
||||||
let container2 = document.querySelector(".canvasrefined-gpa-card");
|
let container2 = document.querySelector(".canvasrefined-gpa-card");
|
||||||
@ -3850,17 +4030,15 @@ function setupGPACalc() {
|
|||||||
if (cumulative) cumulative.style.display = options.gpa_calc_cumulative ? "block" : "none";
|
if (cumulative) cumulative.style.display = options.gpa_calc_cumulative ? "block" : "none";
|
||||||
|
|
||||||
const shouldPrepend = options.gpa_calc_prepend === true;
|
const shouldPrepend = options.gpa_calc_prepend === true;
|
||||||
const firstCard = shouldPrepend ? container : container2;
|
if (shouldPrepend) {
|
||||||
const secondCard = shouldPrepend ? container2 : container;
|
if (dashboardContainer.children[0] !== container || dashboardContainer.children[1] !== container2) {
|
||||||
|
dashboardContainer.insertBefore(container, dashboardContainer.firstChild);
|
||||||
if (firstCard.parentElement !== dashboardContainer) {
|
dashboardContainer.insertBefore(container2, container.nextSibling);
|
||||||
dashboardContainer.prepend(firstCard);
|
}
|
||||||
}
|
} else {
|
||||||
if (secondCard.parentElement !== dashboardContainer) {
|
if (dashboardContainer.lastElementChild !== container || container2.nextElementSibling !== container) {
|
||||||
if (shouldPrepend) {
|
dashboardContainer.appendChild(container2);
|
||||||
dashboardContainer.prepend(secondCard);
|
dashboardContainer.appendChild(container);
|
||||||
} else {
|
|
||||||
dashboardContainer.appendChild(secondCard);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4013,23 +4191,39 @@ function changeFullWidth() {
|
|||||||
function changeGradientCards() {
|
function changeGradientCards() {
|
||||||
if (options.gradient_cards === true) {
|
if (options.gradient_cards === true) {
|
||||||
let cardheads = document.querySelectorAll('.ic-DashboardCard__header_hero');
|
let cardheads = document.querySelectorAll('.ic-DashboardCard__header_hero');
|
||||||
let cardcss = document.querySelector("#gradientcss") || document.createElement('style');
|
|
||||||
cardcss.id = "gradientcss";
|
|
||||||
cardcss.textContent = "";
|
|
||||||
document.documentElement.appendChild(cardcss);
|
|
||||||
|
|
||||||
|
// Only create + append the style once; never re-append an already-
|
||||||
|
// attached element, since appending to <html> triggers the
|
||||||
|
// MutationObserver in checkDashboardReady() and re-runs this function.
|
||||||
|
let cardcss = document.querySelector("#gradientcss");
|
||||||
|
if (!cardcss) {
|
||||||
|
cardcss = document.createElement('style');
|
||||||
|
cardcss.id = "gradientcss";
|
||||||
|
document.documentElement.appendChild(cardcss);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the full CSS into a string first, then only touch the DOM
|
||||||
|
// if the content actually changed. This keeps #gradientcss from being
|
||||||
|
// cleared/rewritten on every observer tick.
|
||||||
|
let css = "";
|
||||||
for (let i = 0; i < cardheads.length; i++) {
|
for (let i = 0; i < cardheads.length; i++) {
|
||||||
let colorone = cardheads[i].style.backgroundColor.split(',');
|
let colorone = cardheads[i].style.backgroundColor.split(',');
|
||||||
let [r, g, b] = [parseInt(colorone[0].split('(')[1]), parseInt(colorone[1]), parseInt(colorone[2])];
|
let [r, g, b] = [parseInt(colorone[0].split('(')[1]), parseInt(colorone[1]), parseInt(colorone[2])];
|
||||||
let [h, s, l] = [rgbToHsl(r, g, b)[0], rgbToHsl(r, g, b)[1], rgbToHsl(r, g, b)[2]];
|
let [h, s, l] = [rgbToHsl(r, g, b)[0], rgbToHsl(r, g, b)[1], rgbToHsl(r, g, b)[2]];
|
||||||
let degree = ((h % 60) / 60) >= .66 ? 30 : ((h % 60) / 60) <= .33 ? -30 : 15;
|
let degree = ((h % 60) / 60) >= .66 ? 30 : ((h % 60) / 60) <= .33 ? -30 : 15;
|
||||||
let newh = h > 300 ? (360 - (h + 65)) + (65 + degree) : h + 65 + degree;
|
let newh = h > 300 ? (360 - (h + 65)) + (65 + degree) : h + 65 + degree;
|
||||||
cardcss.textContent += ".ic-DashboardCard:nth-of-type(" + (i + 1) + ") .ic-DashboardCard__header_hero{background: linear-gradient(115deg, hsl(" + h + "deg," + s + "%," + l + "%) 5%, hsl(" + newh + "deg," + s + "%," + l + "%) 100%)!important}";
|
css += ".ic-DashboardCard:nth-of-type(" + (i + 1) + ") .ic-DashboardCard__header_hero{background: linear-gradient(115deg, hsl(" + h + "deg," + s + "%," + l + "%) 5%, hsl(" + newh + "deg," + s + "%," + l + "%) 100%)!important}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cardcss.textContent !== css) {
|
||||||
|
cardcss.textContent = css;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
let cardcss = document.querySelector("#gradientcss");
|
let cardcss = document.querySelector("#gradientcss");
|
||||||
if (cardcss) cardcss.textContent = "";
|
if (cardcss && cardcss.textContent !== "") {
|
||||||
|
cardcss.textContent = "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
91
js/popup.js
91
js/popup.js
@ -29,6 +29,9 @@ const syncedSubOptions = [
|
|||||||
"cardHeight",
|
"cardHeight",
|
||||||
"customBackgroundLink",
|
"customBackgroundLink",
|
||||||
"customBackgroundScale",
|
"customBackgroundScale",
|
||||||
|
"customBackgroundDaily",
|
||||||
|
"customBackgroundNasaDaily",
|
||||||
|
"fitImageToScreen",
|
||||||
"sidebar_scale",
|
"sidebar_scale",
|
||||||
];
|
];
|
||||||
const localSwitches = [];
|
const localSwitches = [];
|
||||||
@ -133,6 +136,9 @@ const defaultOptions = {
|
|||||||
"customCardStyles": false,
|
"customCardStyles": false,
|
||||||
"customBackgroundLink": "",
|
"customBackgroundLink": "",
|
||||||
"customBackgroundScale": 100,
|
"customBackgroundScale": 100,
|
||||||
|
"customBackgroundDaily": false,
|
||||||
|
"customBackgroundNasaDaily": false,
|
||||||
|
"fitImageToScreen": false,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -315,9 +321,41 @@ function setupCustomBackgroundScale(initial) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getDailyBackgroundPreset() {
|
||||||
|
if (typeof backgroundPresets === "undefined" || !Array.isArray(backgroundPresets) || backgroundPresets.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const today = new Date();
|
||||||
|
const dayNumber = Math.floor(Date.UTC(today.getFullYear(), today.getMonth(), today.getDate()) / 86400000);
|
||||||
|
return backgroundPresets[Math.abs(dayNumber) % backgroundPresets.length];
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncCustomBackgroundDailyState(isDaily) {
|
||||||
|
const manualControls = document.getElementById("customBackgroundManualControls");
|
||||||
|
if (manualControls) {
|
||||||
|
manualControls.style.opacity = isDaily ? "0.45" : "1";
|
||||||
|
manualControls.style.pointerEvents = isDaily ? "none" : "auto";
|
||||||
|
manualControls.style.filter = isDaily ? "grayscale(1)" : "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
["customBackgroundLink", "customBackgroundScale", "clearCustomBackground"].forEach(id => {
|
||||||
|
const el = document.getElementById(id);
|
||||||
|
if (el) el.disabled = isDaily;
|
||||||
|
});
|
||||||
|
|
||||||
|
document.querySelectorAll(".background-preset-card").forEach(button => {
|
||||||
|
button.disabled = isDaily;
|
||||||
|
});
|
||||||
|
|
||||||
|
renderBackgroundPresetSelection();
|
||||||
|
}
|
||||||
|
|
||||||
function renderBackgroundPresetSelection() {
|
function renderBackgroundPresetSelection() {
|
||||||
const currentLink = document.querySelector("#customBackgroundLink")?.value || "";
|
const isDaily = document.querySelector("#customBackgroundDaily")?.checked === true || document.querySelector("#customBackgroundNasaDaily")?.checked === true;
|
||||||
const currentScale = String(document.querySelector("#customBackgroundScale")?.value || "100");
|
const dailyPreset = isDaily ? getDailyBackgroundPreset() : null;
|
||||||
|
const currentLink = isDaily ? (dailyPreset?.url || "") : (document.querySelector("#customBackgroundLink")?.value || "");
|
||||||
|
const currentScale = isDaily ? String(dailyPreset?.scale || "100") : String(document.querySelector("#customBackgroundScale")?.value || "100");
|
||||||
document.querySelectorAll(".background-preset-card").forEach(button => {
|
document.querySelectorAll(".background-preset-card").forEach(button => {
|
||||||
const matchesLink = button.dataset.backgroundUrl === currentLink;
|
const matchesLink = button.dataset.backgroundUrl === currentLink;
|
||||||
const matchesScale = button.dataset.backgroundScale === currentScale;
|
const matchesScale = button.dataset.backgroundScale === currentScale;
|
||||||
@ -349,6 +387,29 @@ function displayBackgroundPresets() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
renderBackgroundPresetSelection();
|
renderBackgroundPresetSelection();
|
||||||
|
syncCustomBackgroundDailyState(document.querySelector("#customBackgroundDaily")?.checked === true || document.querySelector("#customBackgroundNasaDaily")?.checked === true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleBetterSidebarSubOptions(betterSidebarOn) {
|
||||||
|
const remlogoEl = document.getElementById("remlogo");
|
||||||
|
if (remlogoEl) {
|
||||||
|
remlogoEl.style.display = betterSidebarOn ? "none" : "flex";
|
||||||
|
}
|
||||||
|
const sidebarScaleEl = document.getElementById("sidebarScaleSub");
|
||||||
|
if (sidebarScaleEl) {
|
||||||
|
sidebarScaleEl.style.display = betterSidebarOn ? "block" : "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// When the Better Todo List is on, its own "Hide Recent Feedback" sub-option
|
||||||
|
// (todo_hide_feedback) replaces the standalone "Hide recent feedback" toggle,
|
||||||
|
// so hide the big #hide_feedback toggle to avoid showing two controls for the
|
||||||
|
// same thing. Mirrors toggleBetterSidebarSubOptions.
|
||||||
|
function toggleBetterTodoSubOptions(betterTodoOn) {
|
||||||
|
const hideFeedbackEl = document.getElementById("hide_feedback");
|
||||||
|
if (hideFeedbackEl) {
|
||||||
|
hideFeedbackEl.style.display = betterTodoOn ? "none" : "flex";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setup() {
|
function setup() {
|
||||||
@ -376,6 +437,9 @@ function setup() {
|
|||||||
"grade_hover",
|
"grade_hover",
|
||||||
// "hide_completed",
|
// "hide_completed",
|
||||||
"hover_preview",
|
"hover_preview",
|
||||||
|
"customBackgroundDaily",
|
||||||
|
"customBackgroundNasaDaily",
|
||||||
|
"fitImageToScreen",
|
||||||
// "scheduledReminder",
|
// "scheduledReminder",
|
||||||
"customCardStyles",
|
"customCardStyles",
|
||||||
],
|
],
|
||||||
@ -493,8 +557,16 @@ function setup() {
|
|||||||
if (option === "auto_dark") {
|
if (option === "auto_dark") {
|
||||||
toggleDarkModeDisable(status);
|
toggleDarkModeDisable(status);
|
||||||
}
|
}
|
||||||
|
if (option === "better_sidebar") {
|
||||||
|
toggleBetterSidebarSubOptions(status);
|
||||||
|
}
|
||||||
|
if (option === "better_todo") {
|
||||||
|
toggleBetterTodoSubOptions(status);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
toggleBetterSidebarSubOptions(sync["better_sidebar"] === true);
|
||||||
|
toggleBetterTodoSubOptions(sync["better_todo"] === true);
|
||||||
});
|
});
|
||||||
|
|
||||||
chrome.storage.sync.get(menu.checkboxes, sync => {
|
chrome.storage.sync.get(menu.checkboxes, sync => {
|
||||||
@ -503,11 +575,21 @@ function setup() {
|
|||||||
if (!checkbox) {console.log(option); return;}
|
if (!checkbox) {console.log(option); return;}
|
||||||
checkbox.addEventListener("change", function (e) {
|
checkbox.addEventListener("change", function (e) {
|
||||||
let status = this.checked;
|
let status = this.checked;
|
||||||
chrome.storage.sync.set(JSON.parse(`{"${option}": ${status}}`));
|
if (option === "customBackgroundDaily" && status) {
|
||||||
|
document.querySelector("#customBackgroundNasaDaily").checked = false;
|
||||||
|
chrome.storage.sync.set({ "customBackgroundDaily": true, "customBackgroundNasaDaily": false });
|
||||||
|
} else if (option === "customBackgroundNasaDaily" && status) {
|
||||||
|
document.querySelector("#customBackgroundDaily").checked = false;
|
||||||
|
chrome.storage.sync.set({ "customBackgroundNasaDaily": true, "customBackgroundDaily": false });
|
||||||
|
} else {
|
||||||
|
chrome.storage.sync.set(JSON.parse(`{"${option}": ${status}}`));
|
||||||
|
}
|
||||||
|
syncCustomBackgroundDailyState(document.querySelector("#customBackgroundDaily")?.checked === true || document.querySelector("#customBackgroundNasaDaily")?.checked === true);
|
||||||
});
|
});
|
||||||
const value = sync[option] !== undefined ? sync[option] : defaultOptions.sync[option];
|
const value = sync[option] !== undefined ? sync[option] : defaultOptions.sync[option];
|
||||||
document.querySelector("#" + option).checked = value;
|
document.querySelector("#" + option).checked = value;
|
||||||
});
|
});
|
||||||
|
syncCustomBackgroundDailyState(sync.customBackgroundDaily === true || sync.customBackgroundNasaDaily === true);
|
||||||
/*
|
/*
|
||||||
document.querySelector('#autodark_start').value = result.auto_dark_start["hour"] + ":" + result.auto_dark_start["minute"];
|
document.querySelector('#autodark_start').value = result.auto_dark_start["hour"] + ":" + result.auto_dark_start["minute"];
|
||||||
document.querySelector('#autodark_end').value = result.auto_dark_end["hour"] + ":" + result.auto_dark_end["minute"];
|
document.querySelector('#autodark_end').value = result.auto_dark_end["hour"] + ":" + result.auto_dark_end["minute"];
|
||||||
@ -662,7 +744,7 @@ function setup() {
|
|||||||
final = { ...final, ...(await getExport(storage, ["custom_styles"])) };
|
final = { ...final, ...(await getExport(storage, ["custom_styles"])) };
|
||||||
break;
|
break;
|
||||||
case "export-background":
|
case "export-background":
|
||||||
final = { ...final, ...(await getExport(storage, ["customBackgroundLink", "customBackgroundScale"])) };
|
final = { ...final, ...(await getExport(storage, ["customBackgroundLink", "customBackgroundScale", "customBackgroundDaily", "fitImageToScreen"])) };
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1270,6 +1352,7 @@ function saveCurrentTheme() {
|
|||||||
"cardHeight": current["cardHeight"],
|
"cardHeight": current["cardHeight"],
|
||||||
"customBackgroundLink": current["customBackgroundLink"],
|
"customBackgroundLink": current["customBackgroundLink"],
|
||||||
"customBackgroundScale": current["customBackgroundScale"],
|
"customBackgroundScale": current["customBackgroundScale"],
|
||||||
|
"customBackgroundDaily": current["customBackgroundDaily"],
|
||||||
}
|
}
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
local["saved_themes"][now.getTime()] = trimmed;
|
local["saved_themes"][now.getTime()] = trimmed;
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
"content_scripts": [
|
"content_scripts": [
|
||||||
{
|
{
|
||||||
"matches": ["https://*/*"],
|
"matches": ["https://*/*"],
|
||||||
"js": ["css/darkmodecss.js", "js/content.js"],
|
"js": ["css/darkmodecss.js", "js/backgrounds.js", "js/content.js"],
|
||||||
"css": ["css/content.css"],
|
"css": ["css/content.css"],
|
||||||
"run_at": "document_start"
|
"run_at": "document_start"
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user