fixing bugs, centering, links, theme comparability

This commit is contained in:
Guy Sandler 2026-08-15 17:51:55 -07:00
parent 0325b38a82
commit fdaa2754b8
18 changed files with 342 additions and 31 deletions

View File

@ -68,6 +68,8 @@ Canvas Refined adds more with more to come!
- Markdown in dashboard notes
- Smaller additions:
- Equal height cards for card assignments
- Center cards
- Hide new dashbaord button
## Planned Features (by priority)
- auto rotate theme + theme history + fix theme submissions

View File

@ -238,5 +238,17 @@
},
"fix_dm_text": {
"message": "Der Fixer wird automatisch auf diesen Seiten ausgeführt:"
},
"hide_links": {
"message": "Links ausblenden"
},
"show_links": {
"message": "Links einblenden"
},
"center_cards": {
"message": "Karten zentrieren"
},
"hide_new_canvas": {
"message": "Neues Canvas ausblenden"
}
}

View File

@ -250,5 +250,17 @@
},
"fix_dm_text": {
"message": "The Fixer Is Automatically Running On These Pages:"
},
"hide_links": {
"message": "Hide links"
},
"show_links": {
"message": "Show links"
},
"center_cards": {
"message": "Center Cards"
},
"hide_new_canvas": {
"message": "Hide New Canvas"
}
}

View File

@ -238,5 +238,17 @@
},
"fix_dm_text": {
"message": "El reparador se ejecuta automáticamente en estas páginas:"
},
"hide_links": {
"message": "Ocultar enlaces"
},
"show_links": {
"message": "Mostrar enlaces"
},
"center_cards": {
"message": "Centrar tarjetas"
},
"hide_new_canvas": {
"message": "Ocultar nuevo Canvas"
}
}

View File

@ -238,5 +238,17 @@
},
"fix_dm_text": {
"message": "Le fixateur s'exécute automatiquement sur ces pages :"
},
"hide_links": {
"message": "Masquer les liens"
},
"show_links": {
"message": "Afficher les liens"
},
"center_cards": {
"message": "Centrer les cartes"
},
"hide_new_canvas": {
"message": "Masquer le nouveau Canvas"
}
}

View File

@ -238,5 +238,17 @@
},
"fix_dm_text": {
"message": "Il fissatore viene eseguito automaticamente su queste pagine:"
},
"hide_links": {
"message": "Nascondi link"
},
"show_links": {
"message": "Mostra link"
},
"center_cards": {
"message": "Centra schede"
},
"hide_new_canvas": {
"message": "Nascondi nuovo Canvas"
}
}

View File

@ -238,5 +238,17 @@
},
"fix_dm_text": {
"message": "Fixer はこれらのページで自動的に実行されます:"
},
"hide_links": {
"message": "リンクを非表示"
},
"show_links": {
"message": "リンクを表示"
},
"center_cards": {
"message": "カードを中央配置"
},
"hide_new_canvas": {
"message": "新しい Canvas を非表示"
}
}

View File

@ -238,5 +238,17 @@
},
"fix_dm_text": {
"message": "O Fixer está sendo executado automaticamente nestas páginas:"
},
"hide_links": {
"message": "Ocultar ligações"
},
"show_links": {
"message": "Mostrar ligações"
},
"center_cards": {
"message": "Centrar cartões"
},
"hide_new_canvas": {
"message": "Ocultar novo Canvas"
}
}

View File

@ -238,5 +238,17 @@
},
"fix_dm_text": {
"message": "Fixer автоматически запускается на этих страницах:"
},
"hide_links": {
"message": "Скрыть ссылки"
},
"show_links": {
"message": "Показать ссылки"
},
"center_cards": {
"message": "Центрировать карточки"
},
"hide_new_canvas": {
"message": "Скрыть новый Canvas"
}
}

View File

@ -238,5 +238,17 @@
},
"fix_dm_text": {
"message": "Fixern körs automatiskt på dessa sidor:"
},
"hide_links": {
"message": "Dölj länkar"
},
"show_links": {
"message": "Visa länkar"
},
"center_cards": {
"message": "Centrera kort"
},
"hide_new_canvas": {
"message": "Dölj ny Canvas"
}
}

View File

@ -238,5 +238,17 @@
},
"fix_dm_text": {
"message": "修复程序会自动在这些页面上运行:"
},
"hide_links": {
"message": "隐藏链接"
},
"show_links": {
"message": "显示链接"
},
"center_cards": {
"message": "居中卡片"
},
"hide_new_canvas": {
"message": "隐藏新版 Canvas"
}
}

View File

@ -238,5 +238,17 @@
},
"fix_dm_text": {
"message": "修复程序会自动在这些页面上运行:"
},
"hide_links": {
"message": "隱藏連結"
},
"show_links": {
"message": "顯示連結"
},
"center_cards": {
"message": "置中卡片"
},
"hide_new_canvas": {
"message": "隱藏新版 Canvas"
}
}

View File

@ -68,6 +68,18 @@ h2 {margin-top: 20px;font-weight:600}
#advanced-settings, #gpa-bounds-btn, #custom-font-btn, #customize-dark-btn, #card-colors-btn {width: 100%;}
.back-btn {width: 120px;height:100%;margin-top:0}
.big-button {border: none;border-radius: 7px;background: var(--containerbg);color: #fff;font-family: inherit;padding: 12px 10px;font-weight:600}
.social-buttons {display: flex;gap: 8px;margin-top: 8px;}
.social-buttons a {flex: 1;box-sizing: border-box;}
.discord-button {display: flex;align-items: center;justify-content: center;gap: 8px;padding: 12px 10px;border: none;border-radius: 7px;background: #5865F2;color: #fff;font-family: inherit;font-size: 14px;font-weight: 600;text-decoration: none;transition: .15s background}
.discord-button:hover {background: #4752c4;cursor: pointer}
.discord-button:active {filter: brightness(85%)}
.github-button {display: flex;align-items: center;justify-content: center;gap: 8px;padding: 12px 10px;border: none;border-radius: 7px;background: #30363d;color: #fff;font-family: inherit;font-size: 14px;font-weight: 600;text-decoration: none;transition: .15s background}
.github-button:hover {background: #21262d;cursor: pointer}
.github-button:active {filter: brightness(85%)}
.discord-button svg, .github-button svg {flex-shrink: 0}
.social-toggle {text-align: center;font-size: 12px;color: #9a9a9a;margin-top: 6px;cursor: pointer;user-select: none;transition: .15s color;text-decoration: none}
.social-toggle:hover {color: #e2e2e2}
.social-buttons.hidden {display: none}
#setSingleColor, #setGradientColor {padding: 8px 20px;margin-top:5px;}
.gpa-bounds-input {font-size: 14px;background: var(--inputbg); border: none;padding:6px;color: #e2e2e2;margin-top: 6px;border-radius: 6px; font-family: inherit; width: 55px; box-sizing: border-box;text-align: right}
.gpa-bounds span {font-size: 16px; width: 25px;display: inline-block}
@ -141,7 +153,7 @@ textarea {resize: vertical}
.sidebar-changer {display: flex;gap: 10px;}
.custom-key { margin-right: 5px; }
.options-presets .customization-button {padding:9px 14px}
#export-output {margin: 0; height: 100%;}
#export-output {margin: 0; height: calc(100% - 46px);}
input[type="checkbox"] { appearance: none; background: var(--inputbg); margin: 0; width: 16px; height: 16px; border: 1px solid #1a1a1a;;border-radius: 4px; display: grid; place-content: center;}
input[type="checkbox"]::before { content: ""; width: 10px; height: 10px; transform: scale(0); box-shadow: inset 1em 1em #323232; transform-origin: center; clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);}
input[type="checkbox"]:checked::before {transform: scale(1);}

View File

@ -190,6 +190,17 @@
<span class="option-name" data-i18n="todo_remind">Todo Reminders</span>
</div>
</div>
<div class="social-buttons">
<a class="discord-button" href="https://discord.gg/GjFh4JA3wh" target="_blank" rel="noopener noreferrer" title="Join our Discord">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M20.317 4.369a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.331c-1.182 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/></svg>
<span>Discord</span>
</a>
<a class="github-button" href="https://github.com/GuySandler/CanvasRefined" target="_blank" rel="noopener noreferrer" title="View on GitHub">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>
<span>GitHub</span>
</a>
</div>
<div class="social-toggle" id="social-toggle" role="button" tabindex="0"></div>
</div>
<div class="options-right">
@ -267,6 +278,15 @@
</div>
</div>
<div class="option-container" style="display:flex;flex-direction:column;gap:6px;">
<div class="option" id="center_cards">
<input type="radio" id="off" name="center_cards">
<input type="radio" id="on" name="center_cards">
<div class="slider">
<div class="sliderknob"></div>
<div class="sliderbg"></div>
</div>
<span class="option-name" data-i18n="center_cards">Center Cards</span>
</div>
<div class="option" id="dashboard_notes">
<input type="radio" id="off" name="dashboard_notes">
<input type="radio" id="on" name="dashboard_notes">
@ -325,6 +345,14 @@
<div class="sliderbg"></div>
</div><span class="option-name" data-i18n="tab_icons">Color coded tab icons</span>
</div>
<div class="option" id="hide_new_canvas">
<input type="radio" id="off" name="hide_new_canvas">
<input type="radio" id="on" name="hide_new_canvas">
<div class="slider">
<div class="sliderknob"></div>
<div class="sliderbg"></div>
</div><span class="option-name" data-i18n="hide_new_canvas">Hide New Canvas</span>
</div>
</div>
<div class="option-container">
<div class="customDomain">
@ -479,6 +507,10 @@
<input type="checkbox" id="export-dark" />
<span>Dark mode</span>
</div>
<div class="sub-option">
<input type="checkbox" id="export-dark-schedule" />
<span>Dark mode schedule</span>
</div>
<div class="sub-option">
<input type="checkbox" id="export-cards" />
<span>Card images</span>
@ -487,6 +519,10 @@
<input type="checkbox" id="export-colors" />
<span>Card colors</span>
</div>
<div class="sub-option">
<input type="checkbox" id="export-card-styles" />
<span>Card styles</span>
</div>
<div class="sub-option">
<input type="checkbox" id="export-font" />
<span>Custom font</span>
@ -495,13 +531,25 @@
<input type="checkbox" id="export-toggles" />
<span>On/off toggles</span>
</div>
<div class="sub-option">
<input type="checkbox" id="export-layout" />
<span>Layout</span>
</div>
<div class="sub-option">
<input type="checkbox" id="export-sidebar" />
<span>Sidebar</span>
</div>
<div class="sub-option">
<input type="checkbox" id="export-todo" />
<span>Todo list</span>
</div>
<div class="sub-option">
<input type="checkbox" id="export-gpa" />
<span>GPA settings</span>
</div>
<div class="sub-option">
<input type="checkbox" id="export-customStyles" />
<span>Custom card styles</span>
<span>Custom CSS</span>
</div>
<div class="sub-option">
<input type="checkbox" id="export-background" />
@ -510,6 +558,7 @@
</div>
<div style="flex: 1">
<textarea class="card-input" id="export-output" placeholder="Output"></textarea>
<button type="button" id="export-copy" class="customization-button" style="display:block;margin-top:8px;width:100%;">Copy</button>
</div>
</div>
</div>

View File

@ -38,7 +38,7 @@ chrome.runtime.onInstalled.addListener(function () {
"dashboard_notes": false,
"dashboard_notes_text": "",
"dashboard_notes_mode": "edit",
"better_todo": false,
"better_todo": true,
"todo_hr24": false,
"todo_separate_scrollbar": false,
"better_sidebar": false,
@ -75,6 +75,7 @@ chrome.runtime.onInstalled.addListener(function () {
"relative_dues": false,
"equal_height_cards": false,
"hide_feedback": false,
"hide_new_canvas": true,
"dark_mode_fix": [],
"assignment_states": {},
"tab_icons": false,

View File

@ -46,6 +46,7 @@ function getSubmissionAssignmentLink() {
let submissionPageButtonObserver = null;
let profileLogoutButtonObserver = null;
let newCanvasButtonObserver = null;
function addSubmissionPageButton() {
const assignmentLink = getSubmissionAssignmentLink();
@ -158,6 +159,30 @@ function watchSubmissionPageButton() {
}, 10000);
}
function removeNewCanvasButton() {
document.querySelectorAll('[data-testid="switch-to-new-dashboard-button"]').forEach(btn => btn.remove());
}
function watchNewCanvasButton() {
if (newCanvasButtonObserver) {
newCanvasButtonObserver.disconnect();
newCanvasButtonObserver = null;
}
if (options.hide_new_canvas !== true) return;
removeNewCanvasButton();
newCanvasButtonObserver = new MutationObserver(() => {
if (options.hide_new_canvas !== true) {
if (newCanvasButtonObserver) {
newCanvasButtonObserver.disconnect();
newCanvasButtonObserver = null;
}
return;
}
removeNewCanvasButton();
});
newCanvasButtonObserver.observe(document.documentElement, { childList: true, subtree: true });
}
async function getActiveCustomBackground() {
const syncOpts = await chrome.storage.sync.get([
"customBackgroundDaily",
@ -510,6 +535,7 @@ function startExtension() {
checkDashboardReady();
loadCustomFont();
applyAestheticChanges();
watchNewCanvasButton();
changeFavicon();
updateReminders();
applyCustomBackground();
@ -625,9 +651,13 @@ function applyOptionsChanges(changes) {
case "condensed_cards":
case "hide_feedback":
case "full_width":
case "center_cards":
case "custom_styles":
applyAestheticChanges();
break;
case "hide_new_canvas":
watchNewCanvasButton();
break;
case "customBackgroundScale":
applyCustomBackground();
break;
@ -4043,6 +4073,7 @@ function applyAestheticChanges() {
if (options.disable_color_overlay === true) style.textContent += ".ic-DashboardCard__header_hero{opacity: 0!important} .ic-DashboardCard__header-button-bg{opacity: 1!important}";
if (options.hide_feedback === true) style.textContent += ".recent_feedback {display: none}";
if (options.full_width === true) style.textContent += "#wrapper,.ic-Layout-wrapper{max-width:100%!important}";
if (options.center_cards === true) style.textContent += ".ic-DashboardCard__box__container{display:flex!important;flex-wrap:wrap!important;justify-content:center!important;align-items:flex-start!important}";
if (options.customCardStyles === true) {
if (options.imageSize !== undefined && options.imageSize !== 100) style.textContent += `.ic-DashboardCard__header_image {transform: scale(${options.imageSize / 100})!important; }`;

View File

@ -1,14 +1,17 @@
const syncedSwitches = ['remind', 'tab_icons', 'hide_feedback', 'dark_mode', 'remlogo', 'full_width', 'auto_dark', 'assignments_due', 'gpa_calc', 'gradient_cards', 'disable_color_overlay', 'dashboard_grades', 'dashboard_notes', 'better_todo', 'better_sidebar', 'condensed_cards'];
const syncedSwitches = ['remind', 'tab_icons', 'hide_feedback', 'dark_mode', 'remlogo', 'full_width', 'auto_dark', 'assignments_due', 'gpa_calc', 'gradient_cards', 'disable_color_overlay', 'dashboard_grades', 'dashboard_notes', 'better_todo', 'better_sidebar', 'condensed_cards', 'hide_new_canvas', 'center_cards'];
const syncedSubOptions = [
"todo_hide_feedback",
"todo_full_height",
"todo_confetti",
"todo_progress_rings",
"device_dark",
"relative_dues",
"card_overdues",
"equal_height_cards",
// "todo_overdues",
"gpa_calc_prepend",
"gpa_calc_cumulative",
"gpa_calc_weighted",
"auto_dark",
"auto_dark_start",
"auto_dark_end",
@ -34,6 +37,22 @@ const syncedSubOptions = [
"sidebar_scale",
];
const localSwitches = [];
// Theme export categories. Only visual/appearance settings belong in a
// shared theme; personal productivity features (reminders, dashboard notes,
// the card-assignments list and its display prefs, card grades, item counts)
// are intentionally excluded so exported themes never carry personal stuff.
const exportDarkSchedule = ["auto_dark", "auto_dark_start", "auto_dark_end", "device_dark"];
const exportCardColorToggles = ["gradient_cards", "disable_color_overlay"];
const exportCardStyles = ["customCardStyles", "imageSize", "cardRoundness", "cardSpacing", "cardWidth", "cardHeight"];
const exportLayout = ["full_width", "center_cards", "condensed_cards", "equal_height_cards", "remlogo", "hide_new_canvas", "hide_feedback", "tab_icons"];
const exportSidebar = ["better_sidebar", "sidebar_scale"];
const exportTodo = ["better_todo", "todo_hide_feedback", "todo_full_height", "todo_confetti", "todo_progress_rings", "todo_hr24", "todo_separate_scrollbar"];
const exportGpa = ["gpa_calc", "gpa_calc_prepend", "gpa_calc_cumulative", "gpa_calc_weighted"];
const exportBackground = ["customBackgroundLink", "customBackgroundScale", "customBackgroundDaily", "customBackgroundNasaDaily", "fitImageToScreen"];
// Master "On/off toggles" = every visual toggle (no GPA, no dark-mode schedule,
// no personal productivity features).
const exportToggles = ["dark_mode"].concat(exportCardColorToggles, exportLayout, exportSidebar, exportTodo);
const fontsDropdownStateKey = "fonts_dropdown_open";
const apiurl = "none";
@ -74,12 +93,13 @@ const defaultOptions = {
"dashboard_notes": false,
"dashboard_notes_text": "",
"dashboard_notes_mode": "edit",
"better_todo": false,
"better_todo": true,
"better_sidebar": false,
"sidebar_scale": 100,
"todo_hr24": false,
"todo_separate_scrollbar": false,
"condensed_cards": false,
"center_cards": false,
"custom_cards": {},
"custom_cards_2": {},
"custom_cards_3": {},
@ -112,6 +132,7 @@ const defaultOptions = {
"relative_dues": false,
"equal_height_cards": false,
"hide_feedback": false,
"hide_new_canvas": true,
"dark_mode_fix": [],
"assignment_states": {},
"tab_icons": false,
@ -184,6 +205,28 @@ function displayDarkModeFixUrls() {
document.addEventListener("DOMContentLoaded", setup);
// toggle visibility of the Discord/GitHub social links (persists locally)
document.addEventListener("DOMContentLoaded", () => {
const toggle = document.getElementById("social-toggle");
const buttons = document.querySelector(".social-buttons");
if (!toggle || !buttons) return;
const KEY = "hide_socials";
const render = (hidden) => {
buttons.classList.toggle("hidden", hidden);
toggle.textContent = chrome.i18n.getMessage(hidden ? "show_links" : "hide_links");
};
chrome.storage.local.get(KEY, (res) => render(!!res[KEY]));
const flip = () => chrome.storage.local.get(KEY, (res) => {
const next = !res[KEY];
chrome.storage.local.set({ [KEY]: next });
render(next);
});
toggle.addEventListener("click", flip);
toggle.addEventListener("keydown", (e) => {
if (e.key === "Enter" || e.key === " ") { e.preventDefault(); flip(); }
});
});
function setupAssignmentsSlider(initial) {
let el = document.querySelector('#numAssignmentsSlider');
el.value = initial;
@ -929,7 +972,9 @@ function setup() {
// give everything the appropirate i18n text
document.querySelectorAll('[data-i18n]').forEach(text => {
text.innerText = chrome.i18n.getMessage(text.dataset.i18n);
const msg = chrome.i18n.getMessage(text.dataset.i18n);
// keep the in-HTML fallback text when a key is missing instead of blanking it
if (msg) text.innerText = msg;
});
document.querySelectorAll('[data-i18n-placeholder]').forEach(el => {
const msg = chrome.i18n.getMessage(el.dataset.i18nPlaceholder);
@ -1006,38 +1051,70 @@ function setup() {
importTheme(obj);
});
// copy export output to clipboard
document.querySelector("#export-copy").addEventListener("click", async () => {
const output = document.querySelector("#export-output");
const btn = document.querySelector("#export-copy");
const text = output.value;
if (!text) { displayAlert(true, "Nothing to copy — select what to export first."); return; }
const flash = () => { const old = btn.textContent; btn.textContent = "Copied!"; setTimeout(() => { btn.textContent = old; }, 1200); };
try {
await navigator.clipboard.writeText(text);
flash();
} catch (e) {
output.select();
document.execCommand("copy");
flash();
}
});
// activate export checkbox
document.querySelectorAll(".export-details input").forEach(input => {
input.addEventListener("change", () => {
chrome.storage.sync.get(syncedSwitches.concat(syncedSubOptions).concat(["dark_preset", "custom_cards", "custom_font", "gpa_calc_bounds"]), async storage => {
chrome.storage.sync.get(syncedSwitches.concat(syncedSubOptions).concat(["dark_preset", "custom_cards", "custom_font", "gpa_calc_bounds", "custom_styles"]), async storage => {
let final = {};
for await (item of document.querySelectorAll(".export-details input")) {
if (item.checked) {
switch (item.id) {
case "export-toggles":
final = { ...final, ...(await getExport(storage, syncedSwitches.concat(syncedSubOptions))) };
final = { ...final, ...(await getExport(storage, exportToggles)) };
break;
case "export-dark":
final = { ...final, ...(await getExport(storage, ["dark_preset"])) };
final = { ...final, ...(await getExport(storage, ["dark_preset", "dark_mode"])) };
break;
case "export-dark-schedule":
final = { ...final, ...(await getExport(storage, exportDarkSchedule)) };
break;
case "export-cards":
final = { ...final, ...(await getExport(storage, ["custom_cards"])) };
break;
case "export-colors":
final = { ...final, ...(await getExport(storage, ["card_colors", ...exportCardColorToggles])) };
break;
case "export-card-styles":
final = { ...final, ...(await getExport(storage, exportCardStyles)) };
break;
case "export-customStyles":
final = { ...final, ...(await getExport(storage, ["custom_styles"])) };
break;
case "export-font":
final = { ...final, ...(await getExport(storage, ["custom_font"])) };
break;
case "export-colors":
final = { ...final, ...(await getExport(storage, ["card_colors"])) }
case "export-background":
final = { ...final, ...(await getExport(storage, exportBackground)) };
break;
case "export-layout":
final = { ...final, ...(await getExport(storage, exportLayout)) };
break;
case "export-sidebar":
final = { ...final, ...(await getExport(storage, exportSidebar)) };
break;
case "export-todo":
final = { ...final, ...(await getExport(storage, exportTodo)) };
break;
case "export-gpa":
final = { ...final, ...(await getExport(storage, ["gpa_calc_bounds"])) }
final = { ...final, ...(await getExport(storage, [...exportGpa, "gpa_calc_bounds"])) };
break;
case "export-customStyles":
final = { ...final, ...(await getExport(storage, ["custom_styles"])) };
break;
case "export-background":
final = { ...final, ...(await getExport(storage, ["customBackgroundLink", "customBackgroundScale", "customBackgroundDaily", "fitImageToScreen"])) };
break;
}
}
}
@ -1348,12 +1425,7 @@ async function getExport(storage, options) {
}
break;
case "custom_styles":
final["customCardStyles"] = storage["customCardStyles"];
final["imageSize"] = storage["imageSize"];
final["cardRoundness"] = storage["cardRoundness"];
final["cardSpacing"] = storage["cardSpacing"];
final["cardWidth"] = storage["cardWidth"];
final["cardHeight"] = storage["cardHeight"];
final["custom_styles"] = storage["custom_styles"];
break;
default:
final[option] = storage[option];
@ -1458,7 +1530,7 @@ let fallback = false;
function saveCurrentTheme() {
const allOptions = syncedSwitches.concat(syncedSubOptions).concat(["dark_preset", "custom_cards", "custom_font", "gpa_calc_bounds", "card_colors"]);
const allOptions = syncedSwitches.concat(syncedSubOptions).concat(["dark_preset", "custom_cards", "custom_font", "gpa_calc_bounds", "card_colors", "custom_styles"]);
chrome.storage.local.get("saved_themes", local => {
chrome.storage.sync.get(allOptions, async sync => {
let current = await getExport(sync, allOptions);
@ -1473,10 +1545,10 @@ function saveCurrentTheme() {
"better_todo": current["better_todo"],
"todo_hide_feedback": current["todo_hide_feedback"],
"todo_full_height": current["todo_full_height"],
"todo_confetti": current["todo_confetti"],
"todo_progress_rings": current["todo_progress_rings"],
"todo_hr24": current["todo_hr24"],
"todo_separate_scrollbar": current["todo_separate_scrollbar"],
"num_todo_items": current["num_todo_items"],
"hover_preview": current["hover_preview"],
"better_sidebar": current["better_sidebar"],
"sidebar_scale": current["sidebar_scale"],
"imageSize": current["imageSize"],
@ -1484,9 +1556,13 @@ function saveCurrentTheme() {
"cardSpacing": current["cardSpacing"],
"cardWidth": current["cardWidth"],
"cardHeight": current["cardHeight"],
"custom_styles": current["custom_styles"],
"customCardStyles": current["customCardStyles"],
"customBackgroundLink": current["customBackgroundLink"],
"customBackgroundScale": current["customBackgroundScale"],
"customBackgroundDaily": current["customBackgroundDaily"],
"customBackgroundNasaDaily": current["customBackgroundNasaDaily"],
"fitImageToScreen": current["fitImageToScreen"],
}
const now = new Date();
local["saved_themes"][now.getTime()] = trimmed;
@ -1498,7 +1574,15 @@ function saveCurrentTheme() {
}
async function displayThemeList(direction = 0) {
function displayThemeList(direction = 0) {
// render the full sorted theme list (filtered by any active search).
// Previously this was an empty stub, so the browser showed nothing
// until the search box fired displayThemeSearchList directly.
let themesToShow = allThemes;
if (searchFor) {
themesToShow = allThemes.filter(theme => theme.title.toLowerCase().includes(searchFor.toLowerCase()));
}
displayThemeSearchList(themesToShow, direction);
}
@ -1507,7 +1591,7 @@ function displayThemeSearchList(themesToShow, pageDir = 0) {
const perPage = 24;
const maxPage = Math.ceil(themesToShow.length / perPage);
if (pageDir == -1 && current_page_num > 1) current_page_num--;
if (pageDir == 1 && curren_page_num < maxPage) current_page_num++;
if (pageDir == 1 && current_page_num < maxPage) current_page_num++;
let container = document.getElementById("premade-themes");
container.textContent = "";
let start = (current_page_num - 1) * perPage, end = start + perPage;
@ -1520,7 +1604,7 @@ function displayThemeSearchList(themesToShow, pageDir = 0) {
makeElement("p", themeBtn, {"className": "theme-button-title", "textContent": split[0] });
makeElement("p", themeBtn, {"className": "theme-button-creator", "textContent": split[1] });
themeBtn.addEventListener("click", () => {
const allOptions = syncedSwitches.concat(syncedSubOptions).concat(["dark_preset", "custom_cards", "custom_font", "gpa_calc_bounds", "card_colors"]);
const allOptions = syncedSwitches.concat(syncedSubOptions).concat(["dark_preset", "custom_cards", "custom_font", "gpa_calc_bounds", "card_colors", "custom_styles"]);
chrome.storage.sync.get(allOptions, sync => {
chrome.storage.local.get(["previous_theme"], async local => {
if (local["previous_theme"] === null) {

View File

@ -1,6 +1,6 @@
{
"manifest_version": 3,
"name": "CanvasRefined",
"name": "Canvas Refined",
"description": "Even More Feature packed extension for Canvas.",
"version": "6.2.61",
"icons": {