mirror of
https://github.com/GuySandler/CanvasRefined.git
synced 2026-09-23 13:25:09 +02:00
more minor fixes and additions
This commit is contained in:
parent
eaa2a85295
commit
3e6a5927d7
@ -860,6 +860,13 @@
|
|||||||
<span class="sub-text">px</span>
|
<span class="sub-text">px</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="sub-option">
|
||||||
|
<div style="margin-top: 5px;display: flex;gap: 8px;align-items: center">
|
||||||
|
<span class="sub-text" style="width:75px;">Image Roundness</span>
|
||||||
|
<input type="number" id="imageRoundness" class="card-input" min="0" max="50" value="0" style="width:80px;">
|
||||||
|
<span class="sub-text">px</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="sub-option">
|
<div class="sub-option">
|
||||||
<div style="margin-top: 5px;display: flex;gap: 8px;align-items: center">
|
<div style="margin-top: 5px;display: flex;gap: 8px;align-items: center">
|
||||||
<span class="sub-text" style="width:75px;">Extra Card Spacing</span>
|
<span class="sub-text" style="width:75px;">Extra Card Spacing</span>
|
||||||
|
|||||||
@ -57,7 +57,7 @@ chrome.runtime.onInstalled.addListener(function () {
|
|||||||
"full_width": null,
|
"full_width": null,
|
||||||
"remlogo": null,
|
"remlogo": null,
|
||||||
"gpa_calc_bounds": {
|
"gpa_calc_bounds": {
|
||||||
"A+": { "cutoff": 97, "gpa": 4.3 },
|
"A+": { "cutoff": 97, "gpa": 4.0 },
|
||||||
"A": { "cutoff": 93, "gpa": 4 },
|
"A": { "cutoff": 93, "gpa": 4 },
|
||||||
"A-": { "cutoff": 90, "gpa": 3.7 },
|
"A-": { "cutoff": 90, "gpa": 3.7 },
|
||||||
"B+": { "cutoff": 87, "gpa": 3.3 },
|
"B+": { "cutoff": 87, "gpa": 3.3 },
|
||||||
@ -103,9 +103,10 @@ chrome.runtime.onInstalled.addListener(function () {
|
|||||||
"custom_styles": "",
|
"custom_styles": "",
|
||||||
"imageSize": 100,
|
"imageSize": 100,
|
||||||
"cardRoundness": 5,
|
"cardRoundness": 5,
|
||||||
|
"imageRoundness": 0,
|
||||||
'cardSpacing': 0,
|
'cardSpacing': 0,
|
||||||
"cardWidth": 262,
|
"cardWidth": 262,
|
||||||
"cardHeight": 250,
|
"cardHeight": 146,
|
||||||
"customCardStyles": false,
|
"customCardStyles": false,
|
||||||
"customBackgroundLink": "",
|
"customBackgroundLink": "",
|
||||||
"customBackgroundScale": 100,
|
"customBackgroundScale": 100,
|
||||||
|
|||||||
@ -995,6 +995,7 @@ function applyOptionsChanges(changes) {
|
|||||||
break;
|
break;
|
||||||
case "imageSize":
|
case "imageSize":
|
||||||
case "cardRoundness":
|
case "cardRoundness":
|
||||||
|
case "imageRoundness":
|
||||||
case "cardSpacing":
|
case "cardSpacing":
|
||||||
case "cardWidth":
|
case "cardWidth":
|
||||||
case "cardHeight":
|
case "cardHeight":
|
||||||
@ -3572,7 +3573,7 @@ function populateAssignments(iscompleted = false) {
|
|||||||
<div style="width:calc(100% - 40px);height:80%;display:flex;flex-direction:column;gap:5px;padding-left:2px;box-sizing:border-box;overflow:hidden;position:relative;">
|
<div style="width:calc(100% - 40px);height:80%;display:flex;flex-direction:column;gap:5px;padding-left:2px;box-sizing:border-box;overflow:hidden;position:relative;">
|
||||||
<div style="display:flex;flex-direction:column;gap:3px;">
|
<div style="display:flex;flex-direction:column;gap:3px;">
|
||||||
<span style="color:${classNameColor};font-size:12px;margin-top:-2px;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;box-sizing:border-box;padding-right:22px;">${item.context_name}</span>
|
<span style="color:${classNameColor};font-size:12px;margin-top:-2px;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;box-sizing:border-box;padding-right:22px;">${item.context_name}</span>
|
||||||
<a href="${taskHref}" style="color:inherit;text-decoration:none;font-weight:bold;text-overflow:ellipsis;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:-5px;">${item.plannable.title}</a>
|
<a href="${taskHref}" style="color:inherit;text-decoration:none;font-weight:bold;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;box-sizing:border-box;padding-right:28px;margin-top:-5px;">${item.plannable.title}</a>
|
||||||
<span style="color:var(--bctext-0);font-size:12px;margin-top:-5px;">${convertToDueDate(item.plannable_date)}</span>
|
<span style="color:var(--bctext-0);font-size:12px;margin-top:-5px;">${convertToDueDate(item.plannable_date)}</span>
|
||||||
</div>
|
</div>
|
||||||
${editButtonSvg}
|
${editButtonSvg}
|
||||||
@ -4854,14 +4855,24 @@ Dashboard grades
|
|||||||
|
|
||||||
// Map a percentage to a letter grade using the user's configurable GPA
|
// Map a percentage to a letter grade using the user's configurable GPA
|
||||||
// calculator cutoffs (A+ down to F). Returns null when no grade is present.
|
// calculator cutoffs (A+ down to F). Returns null when no grade is present.
|
||||||
|
// Picks the letter with the HIGHEST cutoff the percent meets so the result
|
||||||
|
// doesn't depend on the key order of the stored bounds object — theme imports
|
||||||
|
// can reorder keys (e.g. alphabetically, where "A" precedes "A+"), which made
|
||||||
|
// "+" grades unreachable and displayed e.g. 100% as "A". Cutoffs are coerced
|
||||||
|
// with Number() so string values carried in by imported themes still match.
|
||||||
function percentToLetterGrade(percent) {
|
function percentToLetterGrade(percent) {
|
||||||
const bounds = options.gpa_calc_bounds;
|
const bounds = options.gpa_calc_bounds;
|
||||||
if (!bounds || typeof percent !== "number") return null;
|
if (!bounds || typeof percent !== "number") return null;
|
||||||
|
let best = null;
|
||||||
|
let bestCutoff = -Infinity;
|
||||||
for (const letter of Object.keys(bounds)) {
|
for (const letter of Object.keys(bounds)) {
|
||||||
const cutoff = bounds[letter]?.cutoff;
|
const cutoff = Number(bounds[letter]?.cutoff);
|
||||||
if (typeof cutoff === "number" && percent >= cutoff) return letter;
|
if (Number.isFinite(cutoff) && percent >= cutoff && cutoff > bestCutoff) {
|
||||||
|
best = letter;
|
||||||
|
bestCutoff = cutoff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return best;
|
||||||
}
|
}
|
||||||
|
|
||||||
function insertGrades() {
|
function insertGrades() {
|
||||||
@ -5820,31 +5831,37 @@ function applyAestheticChanges() {
|
|||||||
if (options.customCardStyles === true) {
|
if (options.customCardStyles === true) {
|
||||||
if (options.imageSize !== undefined && options.imageSize !== 100) style.textContent += `.ic-DashboardCard__header_image {transform: scale(${options.imageSize / 100})!important; }`;
|
if (options.imageSize !== undefined && options.imageSize !== 100) style.textContent += `.ic-DashboardCard__header_image {transform: scale(${options.imageSize / 100})!important; }`;
|
||||||
if (options.cardRoundness !== undefined && options.cardRoundness !== 5) style.textContent += `.ic-DashboardCard {border-radius: ${options.cardRoundness}px!important;}`;
|
if (options.cardRoundness !== undefined && options.cardRoundness !== 5) style.textContent += `.ic-DashboardCard {border-radius: ${options.cardRoundness}px!important;}`;
|
||||||
|
// Rounds the header image band. The photo is the background of
|
||||||
|
// .ic-DashboardCard__header_image, and .ic-DashboardCard__header_hero (a
|
||||||
|
// child that covers the full photo with its colored overlay + 1px
|
||||||
|
// border) sits on top of it. border-radius only clips the element it's
|
||||||
|
// on — rounding the parent alone leaves the hero's square overlay
|
||||||
|
// covering the corners, and rounding the hero alone leaves the photo's
|
||||||
|
// square corners behind it — so both elements need the same radius.
|
||||||
|
// Default 0; guard skips the default so stock cards keep square corners.
|
||||||
|
if (options.imageRoundness !== undefined && options.imageRoundness !== 0) style.textContent += `.ic-DashboardCard__header_image, .ic-DashboardCard__header_hero {border-radius: ${options.imageRoundness}px!important;}`;
|
||||||
if (options.cardSpacing !== undefined && options.cardSpacing !== 0) style.textContent += `.ic-DashboardCard {margin-right: ${options.cardSpacing / 2}px!important; margin-bottom: ${options.cardSpacing / 2}px!important;}`;
|
if (options.cardSpacing !== undefined && options.cardSpacing !== 0) style.textContent += `.ic-DashboardCard {margin-right: ${options.cardSpacing / 2}px!important; margin-bottom: ${options.cardSpacing / 2}px!important;}`;
|
||||||
if (options.cardWidth !== undefined && options.cardWidth !== 262) style.textContent += `.ic-DashboardCard {width: ${options.cardWidth}px!important;}`;
|
if (options.cardWidth !== undefined && options.cardWidth !== 262) style.textContent += `.ic-DashboardCard {width: ${options.cardWidth}px!important;}`;
|
||||||
// Always emit a fixed card height when custom card styles are on. The old
|
// Card height sizes the image band via .ic-DashboardCard__header_hero —
|
||||||
// `!== 250` guard silently dropped the height rule when cardHeight matched
|
// the element Canvas pins at 146px that actually drives the header image
|
||||||
// the default, which is exactly what happens after importing a theme that
|
// height (both .ic-DashboardCard and .ic-DashboardCard__header are
|
||||||
// carries the default cardHeight (250) — leaving cards content-sized.
|
// content-sized, so a height on either just clips or adds dead space).
|
||||||
// Content-sized cards plus the dashboard reflow loop trigger Firefox scroll
|
// Everything else — title, actions, and the appended
|
||||||
// anchoring to yank the viewport back up while scrolling. A fixed height
|
// .canvasrefined-card-assignment rows — flows below the hero, so the card
|
||||||
// (even the default 250px) keeps layout stable.
|
// grows with the assignment list and nothing gets clipped. Skipped when
|
||||||
if (options.cardHeight !== undefined && options.cardHeight !== null && options.cardHeight !== "") {
|
// condensed cards is on, since that mode pins the hero at 60px.
|
||||||
style.textContent += `.ic-DashboardCard {height: ${options.cardHeight}px!important;}`;
|
if (options.condensed_cards !== true && options.cardHeight !== undefined && options.cardHeight !== null && options.cardHeight !== "") {
|
||||||
// Canvas sets overflow:hidden on .ic-DashboardCard. With a fixed
|
style.textContent += `.ic-DashboardCard__header_hero {height: ${options.cardHeight}px!important;}`;
|
||||||
// height that clips the appended .canvasrefined-card-assignment area
|
|
||||||
// (the assignment rows live at the bottom of the card), making the
|
|
||||||
// .canvasrefined-assignment-link anchors unclickable for users with
|
|
||||||
// custom card styles enabled. Allow overflow so those rows stay
|
|
||||||
// visible and interactive when card assignments are shown.
|
|
||||||
if (options.assignments_due === true) style.textContent += `.ic-DashboardCard {overflow: visible!important;}`;
|
|
||||||
}
|
}
|
||||||
// Inner card padding. Applied to the whole .ic-DashboardCard box (the
|
// Inner card padding. Applied to the whole .ic-DashboardCard box so the
|
||||||
// element that holds the hero header, title, and action buttons) so the
|
// hero header, title, and action buttons all get breathing room from the
|
||||||
// colored hero header and its content all get consistent breathing room
|
// card's edges. Canvas sizes the card with border-box + a fixed width,
|
||||||
// from the card's edges. Guarded by !== 0 (default).
|
// so padding alone squishes the content area (narrower image/rows)
|
||||||
|
// instead of expanding the card — switch to content-box so the padding
|
||||||
|
// grows the card outward and the content keeps its full width.
|
||||||
|
// Guarded by > 0 (default).
|
||||||
if (options.cardPadding !== undefined && Number(options.cardPadding) > 0) {
|
if (options.cardPadding !== undefined && Number(options.cardPadding) > 0) {
|
||||||
style.textContent += `.ic-DashboardCard {padding: ${options.cardPadding}px!important;}`;
|
style.textContent += `.ic-DashboardCard {padding: ${options.cardPadding}px!important; box-sizing: content-box!important;}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
51
js/popup.js
51
js/popup.js
@ -32,6 +32,7 @@ const syncedSubOptions = [
|
|||||||
"customCardStyles",
|
"customCardStyles",
|
||||||
"imageSize",
|
"imageSize",
|
||||||
"cardRoundness",
|
"cardRoundness",
|
||||||
|
"imageRoundness",
|
||||||
"cardSpacing",
|
"cardSpacing",
|
||||||
"cardWidth",
|
"cardWidth",
|
||||||
"cardHeight",
|
"cardHeight",
|
||||||
@ -54,7 +55,7 @@ const localSwitches = [];
|
|||||||
// Theme export only carries visual settings, never personal productivity data.
|
// Theme export only carries visual settings, never personal productivity data.
|
||||||
const exportDarkSchedule = ["auto_dark", "auto_dark_start", "auto_dark_end", "device_dark"];
|
const exportDarkSchedule = ["auto_dark", "auto_dark_start", "auto_dark_end", "device_dark"];
|
||||||
const exportCardColorToggles = ["gradient_cards", "disable_color_overlay"];
|
const exportCardColorToggles = ["gradient_cards", "disable_color_overlay"];
|
||||||
const exportCardStyles = ["customCardStyles", "imageSize", "cardRoundness", "cardSpacing", "cardWidth", "cardHeight", "cardPadding"];
|
const exportCardStyles = ["customCardStyles", "imageSize", "cardRoundness", "imageRoundness", "cardSpacing", "cardWidth", "cardHeight", "cardPadding"];
|
||||||
const exportLayout = ["full_width", "center_cards", "condensed_cards", "equal_height_cards", "remlogo", "hide_new_canvas", "tab_icons"];
|
const exportLayout = ["full_width", "center_cards", "condensed_cards", "equal_height_cards", "remlogo", "hide_new_canvas", "tab_icons"];
|
||||||
const exportSidebar = ["better_sidebar", "sidebar_scale"];
|
const exportSidebar = ["better_sidebar", "sidebar_scale"];
|
||||||
const exportTodo = ["better_todo", "todo_hide_feedback", "todo_full_height", "todo_confetti", "todo_progress_rings", "todo_timeframe", "todo_hr24", "todo_separate_scrollbar", "todo_alternate_colors", "todo_ignore_card_colors", "todo_remove_icons", "hover_preview"];
|
const exportTodo = ["better_todo", "todo_hide_feedback", "todo_full_height", "todo_confetti", "todo_progress_rings", "todo_timeframe", "todo_hr24", "todo_separate_scrollbar", "todo_alternate_colors", "todo_ignore_card_colors", "todo_remove_icons", "hover_preview"];
|
||||||
@ -135,7 +136,7 @@ const defaultOptions = {
|
|||||||
"full_width": null,
|
"full_width": null,
|
||||||
"remlogo": null,
|
"remlogo": null,
|
||||||
"gpa_calc_bounds": {
|
"gpa_calc_bounds": {
|
||||||
"A+": { "cutoff": 97, "gpa": 4.3 },
|
"A+": { "cutoff": 97, "gpa": 4.0 },
|
||||||
"A": { "cutoff": 93, "gpa": 4 },
|
"A": { "cutoff": 93, "gpa": 4 },
|
||||||
"A-": { "cutoff": 90, "gpa": 3.7 },
|
"A-": { "cutoff": 90, "gpa": 3.7 },
|
||||||
"B+": { "cutoff": 87, "gpa": 3.3 },
|
"B+": { "cutoff": 87, "gpa": 3.3 },
|
||||||
@ -173,9 +174,10 @@ const defaultOptions = {
|
|||||||
"card_limit": 25,
|
"card_limit": 25,
|
||||||
"imageSize": 100,
|
"imageSize": 100,
|
||||||
"cardRoundness": 5,
|
"cardRoundness": 5,
|
||||||
|
"imageRoundness": 0,
|
||||||
"cardSpacing": 0,
|
"cardSpacing": 0,
|
||||||
"cardWidth": 262,
|
"cardWidth": 262,
|
||||||
"cardHeight": 250,
|
"cardHeight": 146,
|
||||||
"cardPadding": 0,
|
"cardPadding": 0,
|
||||||
"customCardStyles": false,
|
"customCardStyles": false,
|
||||||
"customBackgroundLink": "",
|
"customBackgroundLink": "",
|
||||||
@ -401,6 +403,14 @@ function setupCardRoundnessInput(initial) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setupImageRoundnessInput(initial) {
|
||||||
|
let el = document.querySelector("#imageRoundness");
|
||||||
|
el.value = initial;
|
||||||
|
el.addEventListener("input", (e) => {
|
||||||
|
debouncedCardStyleSet("imageRoundness", e.target.value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function setupCardSpacingInput(initial) {
|
function setupCardSpacingInput(initial) {
|
||||||
let el = document.querySelector("#cardSpacing");
|
let el = document.querySelector("#cardSpacing");
|
||||||
el.value = initial;
|
el.value = initial;
|
||||||
@ -1056,6 +1066,10 @@ function setup() {
|
|||||||
identifier: "cardRoundness",
|
identifier: "cardRoundness",
|
||||||
setup: (initial) => setupCardRoundnessInput(initial),
|
setup: (initial) => setupCardRoundnessInput(initial),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
identifier: "imageRoundness",
|
||||||
|
setup: (initial) => setupImageRoundnessInput(initial),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
identifier: "cardSpacing",
|
identifier: "cardSpacing",
|
||||||
setup: (initial) => setupCardSpacingInput(initial),
|
setup: (initial) => setupCardSpacingInput(initial),
|
||||||
@ -1534,7 +1548,7 @@ function setup() {
|
|||||||
"A-": { "cutoff": 90, "gpa": 4.0 },
|
"A-": { "cutoff": 90, "gpa": 4.0 },
|
||||||
"B+": { "cutoff": 87, "gpa": 3.0 },
|
"B+": { "cutoff": 87, "gpa": 3.0 },
|
||||||
"B": { "cutoff": 83, "gpa": 3.0 },
|
"B": { "cutoff": 83, "gpa": 3.0 },
|
||||||
"B-": { "cutoff": 89, "gpa": 3.0 },
|
"B-": { "cutoff": 80, "gpa": 3.0 },
|
||||||
"C+": { "cutoff": 77, "gpa": 2.0 },
|
"C+": { "cutoff": 77, "gpa": 2.0 },
|
||||||
"C": { "cutoff": 73, "gpa": 2.0 },
|
"C": { "cutoff": 73, "gpa": 2.0 },
|
||||||
"C-": { "cutoff": 70, "gpa": 2.0 },
|
"C-": { "cutoff": 70, "gpa": 2.0 },
|
||||||
@ -1545,8 +1559,9 @@ function setup() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Note: the card-style number inputs (imageSize, cardRoundness, cardSpacing,
|
// Note: the card-style number inputs (imageSize, cardRoundness,
|
||||||
// cardWidth, cardHeight, cardPadding) are wired via their setup*Input
|
// imageRoundness, cardSpacing, cardWidth, cardHeight, cardPadding) are wired
|
||||||
|
// via their setup*Input
|
||||||
// handlers in menu.special above, which debounce the storage writes. The
|
// handlers in menu.special above, which debounce the storage writes. The
|
||||||
// duplicate listeners that used to live here referenced nonexistent
|
// duplicate listeners that used to live here referenced nonexistent
|
||||||
// #*Value spans (threw on every input) and double-wrote to storage, which
|
// #*Value spans (threw on every input) and double-wrote to storage, which
|
||||||
@ -1619,11 +1634,9 @@ async function getExport(storage, options) {
|
|||||||
case "custom_cards":
|
case "custom_cards":
|
||||||
let arr = [];
|
let arr = [];
|
||||||
Object.keys(storage["custom_cards"]).forEach(key => {
|
Object.keys(storage["custom_cards"]).forEach(key => {
|
||||||
if (storage["custom_cards"][key].img !== "") arr.push(storage["custom_cards"][key].img);
|
const img = storage["custom_cards"][key].img;
|
||||||
|
if (img && img !== "none" && img.trim() !== "") arr.push(img);
|
||||||
});
|
});
|
||||||
if (arr.length === 0) {
|
|
||||||
arr = ["none"];
|
|
||||||
}
|
|
||||||
final["custom_cards"] = arr;
|
final["custom_cards"] = arr;
|
||||||
break;
|
break;
|
||||||
case "card_colors":
|
case "card_colors":
|
||||||
@ -1767,6 +1780,7 @@ function saveCurrentTheme() {
|
|||||||
"sidebar_scale": current["sidebar_scale"],
|
"sidebar_scale": current["sidebar_scale"],
|
||||||
"imageSize": current["imageSize"],
|
"imageSize": current["imageSize"],
|
||||||
"cardRoundness": current["cardRoundness"],
|
"cardRoundness": current["cardRoundness"],
|
||||||
|
"imageRoundness": current["imageRoundness"],
|
||||||
"cardSpacing": current["cardSpacing"],
|
"cardSpacing": current["cardSpacing"],
|
||||||
"cardWidth": current["cardWidth"],
|
"cardWidth": current["cardWidth"],
|
||||||
"cardHeight": current["cardHeight"],
|
"cardHeight": current["cardHeight"],
|
||||||
@ -1867,7 +1881,7 @@ function displaySavedThemes() {
|
|||||||
let title = makeElement("p", btn, { "className": "theme-button-title", "textContent": `Theme ${index + 1}`});
|
let title = makeElement("p", btn, { "className": "theme-button-title", "textContent": `Theme ${index + 1}`});
|
||||||
let date = makeElement("p", btn, { "className": "theme-button-creator", "textContent": `${getRelativeDate(created).time} ago` });
|
let date = makeElement("p", btn, { "className": "theme-button-creator", "textContent": `${getRelativeDate(created).time} ago` });
|
||||||
let remove = makeElement("div", btn, { "className": "theme-button-remove", "textContent": "x" });
|
let remove = makeElement("div", btn, { "className": "theme-button-remove", "textContent": "x" });
|
||||||
btn.style.backgroundImage = `linear-gradient(rgba(0, 0, 0, 0.44), rgba(0, 0, 0, 0.44)), url(${local["saved_themes"][key]["custom_cards"][0]})`;
|
btn.style.backgroundImage = `linear-gradient(rgba(0, 0, 0, 0.44), rgba(0, 0, 0, 0.44)), url(${local["saved_themes"][key]["custom_cards"]?.[0] || ""})`;
|
||||||
btn.addEventListener("click", () => {
|
btn.addEventListener("click", () => {
|
||||||
importTheme(local["saved_themes"][key]);
|
importTheme(local["saved_themes"][key]);
|
||||||
});
|
});
|
||||||
@ -1906,16 +1920,23 @@ function importTheme(theme) {
|
|||||||
case "card_colors":
|
case "card_colors":
|
||||||
sendFromPopup("setcolors", theme["card_colors"]);
|
sendFromPopup("setcolors", theme["card_colors"]);
|
||||||
break;
|
break;
|
||||||
case "custom_cards":
|
case "custom_cards": {
|
||||||
|
// "none" is a legacy placeholder meaning "this theme has
|
||||||
|
// no custom card images" — treat it as such instead of
|
||||||
|
// writing the literal string into every card (which hides
|
||||||
|
// the card image on the dashboard). Fall back to "" so
|
||||||
|
// cards keep their default Canvas images.
|
||||||
|
const themeImgs = (theme["custom_cards"] || []).filter(u => u && u !== "none" && u.trim() !== "");
|
||||||
if (theme["custom_cards"].length > 0) {
|
if (theme["custom_cards"].length > 0) {
|
||||||
let pos = 0;
|
let pos = 0;
|
||||||
Object.keys(sync["custom_cards"]).forEach(key => {
|
Object.keys(sync["custom_cards"]).forEach(key => {
|
||||||
sync["custom_cards"][key].img = theme["custom_cards"][pos];
|
sync["custom_cards"][key].img = themeImgs.length ? themeImgs[pos] : "";
|
||||||
pos = (pos === theme["custom_cards"].length - 1) ? 0 : pos + 1;
|
pos = (pos === themeImgs.length - 1) ? 0 : pos + 1;
|
||||||
});
|
});
|
||||||
|
final["custom_cards"] = sync["custom_cards"];
|
||||||
}
|
}
|
||||||
final["custom_cards"] = sync["custom_cards"];
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
final[key] = theme[key];
|
final[key] = theme[key];
|
||||||
break;
|
break;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user