mirror of
https://github.com/GuySandler/CanvasRefined.git
synced 2026-11-03 22:07:18 +01:00
stuff 2: electric boogaloo
This commit is contained in:
parent
9bb1441c83
commit
1c140c7153
@ -281,6 +281,15 @@
|
||||
"custom_background": {
|
||||
"message": "Benutzerdefinierter Hintergrund"
|
||||
},
|
||||
"solid_color": {
|
||||
"message": "Einfarbiger Hintergrund"
|
||||
},
|
||||
"solid_color_hex": {
|
||||
"message": "#1e2a38"
|
||||
},
|
||||
"bg_transparency": {
|
||||
"message": "Transparente Elemente"
|
||||
},
|
||||
"custom_background_desc": {
|
||||
"message": "Wähle eine Voreinstellung oder verwende deine eigene Bild-URL."
|
||||
},
|
||||
|
||||
@ -281,6 +281,15 @@
|
||||
"custom_background": {
|
||||
"message": "Custom Background"
|
||||
},
|
||||
"solid_color": {
|
||||
"message": "Solid color"
|
||||
},
|
||||
"solid_color_hex": {
|
||||
"message": "#1e2a38"
|
||||
},
|
||||
"bg_transparency": {
|
||||
"message": "Transparent elements"
|
||||
},
|
||||
"custom_background_desc": {
|
||||
"message": "Pick a preset or use your own image url."
|
||||
},
|
||||
|
||||
@ -281,6 +281,15 @@
|
||||
"custom_background": {
|
||||
"message": "Fondo personalizado"
|
||||
},
|
||||
"solid_color": {
|
||||
"message": "Color sólido"
|
||||
},
|
||||
"solid_color_hex": {
|
||||
"message": "#1e2a38"
|
||||
},
|
||||
"bg_transparency": {
|
||||
"message": "Elementos transparentes"
|
||||
},
|
||||
"custom_background_desc": {
|
||||
"message": "Elige un preajuste o usa la URL de tu propia imagen."
|
||||
},
|
||||
|
||||
@ -281,6 +281,15 @@
|
||||
"custom_background": {
|
||||
"message": "Arrière-plan personnalisé"
|
||||
},
|
||||
"solid_color": {
|
||||
"message": "Couleur unie"
|
||||
},
|
||||
"solid_color_hex": {
|
||||
"message": "#1e2a38"
|
||||
},
|
||||
"bg_transparency": {
|
||||
"message": "Éléments transparents"
|
||||
},
|
||||
"custom_background_desc": {
|
||||
"message": "Choisissez un préréglage ou utilisez l'URL de votre propre image."
|
||||
},
|
||||
|
||||
@ -281,6 +281,15 @@
|
||||
"custom_background": {
|
||||
"message": "Sfondo personalizzato"
|
||||
},
|
||||
"solid_color": {
|
||||
"message": "Colore pieno"
|
||||
},
|
||||
"solid_color_hex": {
|
||||
"message": "#1e2a38"
|
||||
},
|
||||
"bg_transparency": {
|
||||
"message": "Elementi trasparenti"
|
||||
},
|
||||
"custom_background_desc": {
|
||||
"message": "Scegli un preset o usa l'URL della tua immagine."
|
||||
},
|
||||
|
||||
@ -281,6 +281,15 @@
|
||||
"custom_background": {
|
||||
"message": "カスタム背景"
|
||||
},
|
||||
"solid_color": {
|
||||
"message": "単色"
|
||||
},
|
||||
"solid_color_hex": {
|
||||
"message": "#1e2a38"
|
||||
},
|
||||
"bg_transparency": {
|
||||
"message": "要素を透過"
|
||||
},
|
||||
"custom_background_desc": {
|
||||
"message": "プリセットを選ぶか、自分の画像URLを使用してください。"
|
||||
},
|
||||
|
||||
@ -281,6 +281,15 @@
|
||||
"custom_background": {
|
||||
"message": "Fundo personalizado"
|
||||
},
|
||||
"solid_color": {
|
||||
"message": "Cor sólida"
|
||||
},
|
||||
"solid_color_hex": {
|
||||
"message": "#1e2a38"
|
||||
},
|
||||
"bg_transparency": {
|
||||
"message": "Elementos transparentes"
|
||||
},
|
||||
"custom_background_desc": {
|
||||
"message": "Escolhe uma predefinição ou usa o URL da tua própria imagem."
|
||||
},
|
||||
|
||||
@ -281,6 +281,15 @@
|
||||
"custom_background": {
|
||||
"message": "Свой фон"
|
||||
},
|
||||
"solid_color": {
|
||||
"message": "Сплошной цвет"
|
||||
},
|
||||
"solid_color_hex": {
|
||||
"message": "#1e2a38"
|
||||
},
|
||||
"bg_transparency": {
|
||||
"message": "Прозрачные элементы"
|
||||
},
|
||||
"custom_background_desc": {
|
||||
"message": "Выберите пресет или используйте свою ссылку на изображение."
|
||||
},
|
||||
|
||||
@ -281,6 +281,15 @@
|
||||
"custom_background": {
|
||||
"message": "Anpassad bakgrund"
|
||||
},
|
||||
"solid_color": {
|
||||
"message": "Enfärgad"
|
||||
},
|
||||
"solid_color_hex": {
|
||||
"message": "#1e2a38"
|
||||
},
|
||||
"bg_transparency": {
|
||||
"message": "Genomskinliga element"
|
||||
},
|
||||
"custom_background_desc": {
|
||||
"message": "Välj en förinställning eller använd din egen bild-URL."
|
||||
},
|
||||
|
||||
@ -281,6 +281,15 @@
|
||||
"custom_background": {
|
||||
"message": "自定义背景"
|
||||
},
|
||||
"solid_color": {
|
||||
"message": "纯色"
|
||||
},
|
||||
"solid_color_hex": {
|
||||
"message": "#1e2a38"
|
||||
},
|
||||
"bg_transparency": {
|
||||
"message": "元素透明"
|
||||
},
|
||||
"custom_background_desc": {
|
||||
"message": "选择预设,或使用你自己的图片 URL。"
|
||||
},
|
||||
|
||||
@ -281,6 +281,15 @@
|
||||
"custom_background": {
|
||||
"message": "自訂背景"
|
||||
},
|
||||
"solid_color": {
|
||||
"message": "純色"
|
||||
},
|
||||
"solid_color_hex": {
|
||||
"message": "#1e2a38"
|
||||
},
|
||||
"bg_transparency": {
|
||||
"message": "元素透明"
|
||||
},
|
||||
"custom_background_desc": {
|
||||
"message": "選擇預設背景,或使用你自己的圖片網址。"
|
||||
},
|
||||
|
||||
@ -179,6 +179,11 @@ h2 {margin-top: 20px;font-weight:600}
|
||||
.theme-button-creator {font-size:10px;white-space:nowrap}
|
||||
.theme-button-title {font-weight: 600;font-size:12px;white-space:nowrap;}
|
||||
.background-preset-grid {display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; margin-top: 10px;}
|
||||
/* a solid colour outranks the presets, so they are inert until it is cleared */
|
||||
.background-preset-grid.is-disabled {opacity: .45; filter: grayscale(1); pointer-events: none;}
|
||||
.background-color-picker {width: 38px; height: 30px; padding: 0; border: none; border-radius: 7px; background: var(--inputbg); cursor: pointer;}
|
||||
.background-color-picker::-webkit-color-swatch-wrapper {padding: 2px;}
|
||||
.background-color-picker::-webkit-color-swatch {border: none; border-radius: 5px;}
|
||||
.background-preset-card {min-height: 96px; display: flex; flex-direction: column; justify-content: flex-end; align-items: flex-start; border-radius: 8px;}
|
||||
.background-preset-card.selected {outline: 2px solid #56Caf0; outline-offset: 2px;}
|
||||
.background-preset-scale {font-size:10px;white-space:nowrap;opacity:0.9;}
|
||||
|
||||
@ -1485,6 +1485,22 @@
|
||||
<input type="range" min="50" max="200" step="1" id="customBackgroundScale">
|
||||
</div>
|
||||
<input style="width:85%;" class="card-input" id="customBackgroundLink" placeholder="https://...">
|
||||
<!-- Solid colour: when set it wins over the presets and the image URL -->
|
||||
<div id="customBackgroundSolidRow" style="margin-top:12px;">
|
||||
<span class="sub-text" style="font-weight:600; color:#e2e2e2;" data-i18n="solid_color">Solid color</span>
|
||||
<div style="display:flex;align-items:center;gap:8px;margin-top:6px;">
|
||||
<input type="color" id="customBackgroundColorPicker" class="background-color-picker" value="#1e2a38" data-i18n-title="solid_color" title="Solid color">
|
||||
<input class="card-input" id="customBackgroundColorHex" maxlength="7" style="width:110px;margin:0;" data-i18n-placeholder="solid_color_hex" placeholder="#1e2a38">
|
||||
<button type="button" class="opacity-reset-btn" id="clearCustomBackgroundColor" title="Clear" data-i18n-title="clear_background">
|
||||
<svg viewBox="0 0 24 24" width="11" height="11" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Only meaningful with a colour set -->
|
||||
<div class="sub-option" id="customBackgroundColorTransparencyRow" style="margin-top:8px;display:none;">
|
||||
<input type="checkbox" id="customBackgroundColorTransparent" name="customBackgroundColorTransparent">
|
||||
<label for="customBackgroundColorTransparent" class="sub-text" data-i18n="bg_transparency">Background transparency</label>
|
||||
</div>
|
||||
<button id="clearCustomBackground" class="big-button" style="margin-top: 8px;" data-i18n="clear_background">Clear Background</button>
|
||||
</div>
|
||||
<div class="sub-option" style="margin-top:10px;">
|
||||
|
||||
@ -150,6 +150,8 @@ chrome.runtime.onInstalled.addListener(function () {
|
||||
"cardHeight": 146,
|
||||
"customCardStyles": false,
|
||||
"customBackgroundLink": "",
|
||||
"customBackgroundColor": "",
|
||||
"customBackgroundColorTransparent": false,
|
||||
"customBackgroundScale": 100,
|
||||
"customBackgroundDaily": false,
|
||||
"customBackgroundNasaDaily": false,
|
||||
|
||||
@ -492,8 +492,16 @@ async function getActiveCustomBackground() {
|
||||
"customBackgroundNasaDaily",
|
||||
"customBackgroundLink",
|
||||
"customBackgroundScale",
|
||||
"customBackgroundColor",
|
||||
"customBackgroundColorTransparent",
|
||||
]);
|
||||
|
||||
// A solid colour always wins over the image sources.
|
||||
const color = normalizeBackgroundColor(syncOpts.customBackgroundColor);
|
||||
if (color) {
|
||||
return { color, transparent: syncOpts.customBackgroundColorTransparent === true };
|
||||
}
|
||||
|
||||
if (syncOpts.customBackgroundNasaDaily === true) {
|
||||
return await getNasaDailyBackground();
|
||||
}
|
||||
@ -518,6 +526,16 @@ async function getActiveCustomBackground() {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Accepts "#1e2a38", "1e2a38" or "#abc"; anything else is "no colour".
|
||||
function normalizeBackgroundColor(value) {
|
||||
const hex = String(value || "").trim().replace(/^#/, "");
|
||||
if (/^[0-9a-f]{3}$/i.test(hex)) {
|
||||
return "#" + hex.split("").map(c => c + c).join("").toLowerCase();
|
||||
}
|
||||
if (/^[0-9a-f]{6}$/i.test(hex)) return "#" + hex.toLowerCase();
|
||||
return "";
|
||||
}
|
||||
|
||||
async function getDailyBackgroundPreset() {
|
||||
const today = new Date();
|
||||
const dateStr = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, "0")}-${String(today.getDate()).padStart(2, "0")}`;
|
||||
@ -1431,6 +1449,8 @@ function applyOptionsChanges(changes) {
|
||||
debouncedApplyAestheticChanges();
|
||||
break;
|
||||
case "customBackgroundLink":
|
||||
case "customBackgroundColor":
|
||||
case "customBackgroundColorTransparent":
|
||||
applyCustomBackground();
|
||||
break;
|
||||
case "bg_opacity":
|
||||
@ -1583,19 +1603,30 @@ async function applyCustomBackground() {
|
||||
const cardOpacity = Math.max(0, Math.min(100, Number(options.card_opacity ?? 80)));
|
||||
const cardBlur = Math.max(0, Math.min(30, Number(options.card_blur ?? 8)));
|
||||
const cardTransparent = 100 - cardOpacity;
|
||||
style.textContent = `
|
||||
#wrapper {
|
||||
background-image: url(${backgroundUrl}) !important;
|
||||
// Solid colour: one flat fill, no image rules. The transparency opt-in is not
|
||||
// about the colour — it decides whether the page's surfaces turn see-through over
|
||||
// it (the glass treatment an image background always gets).
|
||||
const solid = activeBackground.color || "";
|
||||
const surfaceTransparent = solid
|
||||
? (activeBackground.transparent ? bgTransparent : 0)
|
||||
: bgTransparent;
|
||||
const wrapperBackground = solid
|
||||
? `background-image: none !important;
|
||||
background-color: ${solid} !important;`
|
||||
: `background-image: url(${backgroundUrl}) !important;
|
||||
background-repeat: no-repeat !important;
|
||||
background-position: center center !important;
|
||||
background-attachment: fixed !important;
|
||||
background-attachment: fixed !important;`;
|
||||
style.textContent = `
|
||||
#wrapper {
|
||||
${wrapperBackground}
|
||||
}
|
||||
@media (orientation: landscape) {
|
||||
${solid ? "" : `@media (orientation: landscape) {
|
||||
#wrapper { background-size: ${fitToScreen ? 'cover' : backgroundScale + '% auto'} !important; }
|
||||
}
|
||||
@media (orientation: portrait) {
|
||||
#wrapper { background-size: cover !important; }
|
||||
}
|
||||
}`}
|
||||
.ic-Dashboard-header__layout {
|
||||
background: none !important;
|
||||
border-radius: 5px;
|
||||
@ -1605,7 +1636,7 @@ async function applyCustomBackground() {
|
||||
margin-left: -35px !important;
|
||||
margin-right: -35px !important;
|
||||
box-sizing: border-box !important;
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${bgTransparent}%) !important;
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${surfaceTransparent}%) !important;
|
||||
border: 1px solid color-mix(in srgb, var(--bcborders) 60%, transparent) !important;
|
||||
border-radius: 10px !important;
|
||||
position: sticky !important;
|
||||
@ -1617,7 +1648,7 @@ async function applyCustomBackground() {
|
||||
/* glass day groups so a background image shows through between day cards */
|
||||
#dashboard-planner .planner-day,
|
||||
#dashboard-planner .planner-empty-days {
|
||||
background: color-mix(in srgb, var(--bcbackground-0), transparent ${bgTransparent}%) !important;
|
||||
background: color-mix(in srgb, var(--bcbackground-0), transparent ${surfaceTransparent}%) !important;
|
||||
backdrop-filter: blur(${bgBlur}px) !important;
|
||||
-webkit-backdrop-filter: blur(${bgBlur}px) !important;
|
||||
border-radius: 12px !important;
|
||||
@ -1644,14 +1675,14 @@ async function applyCustomBackground() {
|
||||
#right-side-wrapper {
|
||||
backdrop-filter: blur(${bgBlur}px) !important;
|
||||
-webkit-backdrop-filter: blur(${bgBlur}px) !important;
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${bgTransparent}%);
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${surfaceTransparent}%);
|
||||
border-radius: 5px;
|
||||
}
|
||||
/* tint the whole #left-side column (the inner frame only wraps the links) */
|
||||
#left-side {
|
||||
backdrop-filter: blur(${bgBlur}px) !important;
|
||||
-webkit-backdrop-filter: blur(${bgBlur}px) !important;
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${bgTransparent}%) !important;
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${surfaceTransparent}%) !important;
|
||||
}
|
||||
/* #right-side sub-text keeps Canvas gray in light mode; recolor for contrast */
|
||||
.recent_feedback .event-details {
|
||||
@ -1736,14 +1767,14 @@ async function applyCustomBackground() {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
#assignments.ui-tabs-panel {
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${bgTransparent}%) !important;
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${surfaceTransparent}%) !important;
|
||||
backdrop-filter: blur(${bgBlur}px) !important;
|
||||
-webkit-backdrop-filter: blur(${bgBlur}px) !important;
|
||||
border-radius: 5px !important;
|
||||
}
|
||||
/* InstUI flex View ships an opaque surface; give it the glass treatment */
|
||||
.css-fiozi7-view--flex-flex {
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${bgTransparent}%) !important;
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${surfaceTransparent}%) !important;
|
||||
backdrop-filter: blur(${bgBlur}px) !important;
|
||||
-webkit-backdrop-filter: blur(${bgBlur}px) !important;
|
||||
border-radius: 5px !important;
|
||||
@ -1770,7 +1801,7 @@ async function applyCustomBackground() {
|
||||
}
|
||||
/* threads toolbar sits under the header panel; same glass treatment */
|
||||
.css-1n94jrf-view {
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${bgTransparent}%) !important;
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${surfaceTransparent}%) !important;
|
||||
backdrop-filter: blur(${bgBlur}px) !important;
|
||||
-webkit-backdrop-filter: blur(${bgBlur}px) !important;
|
||||
border-radius: 5px !important;
|
||||
@ -1786,7 +1817,7 @@ async function applyCustomBackground() {
|
||||
#content {
|
||||
margin: 36px 48px 48px !important;
|
||||
padding: 10px !important;
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${bgTransparent}%) !important;
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${surfaceTransparent}%) !important;
|
||||
backdrop-filter: blur(${bgBlur}px) !important;
|
||||
-webkit-backdrop-filter: blur(${bgBlur}px) !important;
|
||||
border-radius: 5px !important;
|
||||
@ -1797,7 +1828,7 @@ async function applyCustomBackground() {
|
||||
#content {
|
||||
margin: 36px 48px 48px !important;
|
||||
padding: 10px !important;
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${bgTransparent}%) !important;
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${surfaceTransparent}%) !important;
|
||||
backdrop-filter: blur(${bgBlur}px) !important;
|
||||
-webkit-backdrop-filter: blur(${bgBlur}px) !important;
|
||||
border-radius: 5px !important;
|
||||
@ -1809,7 +1840,7 @@ async function applyCustomBackground() {
|
||||
.ic-Layout-contentMain {
|
||||
margin: 26px 38px 38px !important;
|
||||
padding: 10px !important;
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${bgTransparent}%) !important;
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${surfaceTransparent}%) !important;
|
||||
backdrop-filter: blur(${bgBlur}px) !important;
|
||||
-webkit-backdrop-filter: blur(${bgBlur}px) !important;
|
||||
border-radius: 10px !important;
|
||||
@ -1822,7 +1853,7 @@ async function applyCustomBackground() {
|
||||
it" signal -- and without it the tint above never lands, leaving dark
|
||||
text straight on the background image. */
|
||||
#content:not(.ic-Layout-contentMain) {
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${bgTransparent}%) !important;
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${surfaceTransparent}%) !important;
|
||||
backdrop-filter: blur(${bgBlur}px) !important;
|
||||
-webkit-backdrop-filter: blur(${bgBlur}px) !important;
|
||||
border-radius: 10px !important;
|
||||
@ -1838,7 +1869,7 @@ async function applyCustomBackground() {
|
||||
}
|
||||
${isConversationsPage() ? `
|
||||
.css-1nh4pc4-view-flexItem {
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${bgTransparent}%) !important;
|
||||
background-color: color-mix(in srgb, var(--bcbackground-0), transparent ${surfaceTransparent}%) !important;
|
||||
backdrop-filter: blur(${bgBlur}px) !important;
|
||||
-webkit-backdrop-filter: blur(${bgBlur}px) !important;
|
||||
border-radius: 5px !important;
|
||||
|
||||
84
js/popup.js
84
js/popup.js
@ -219,7 +219,7 @@ const exportLayout = ["full_width", "center_cards", "condensed_cards", "equal_he
|
||||
const exportSidebar = ["better_sidebar", "sidebar_scale"];
|
||||
const exportTodo = ["better_todo", "todo_hide_feedback", "todo_hide_read", "todo_full_height", "todo_celebrations_enabled", "todo_celebrations", "todo_celebration_amount", "todo_progress_rings", "todo_timeframe", "todo_timeframe_custom_past", "todo_timeframe_custom_future", "todo_hr24", "todo_separate_scrollbar", "todo_alternate_colors", "todo_ignore_card_colors", "todo_remove_icons", "todo_show_scores", "hover_preview"];
|
||||
const exportGpa = ["gpa_calc", "gpa_calc_prepend", "gpa_calc_cumulative", "gpa_calc_weighted", "gpa_calc_show_on_hover"];
|
||||
const exportBackground = ["customBackgroundLink", "customBackgroundScale", "customBackgroundDaily", "customBackgroundNasaDaily", "fitImageToScreen", "card_transparency", "bg_opacity", "sidebar_opacity", "bg_blur", "sidebar_blur", "card_opacity", "card_blur"];
|
||||
const exportBackground = ["customBackgroundLink", "customBackgroundScale", "customBackgroundDaily", "customBackgroundNasaDaily", "customBackgroundColor", "customBackgroundColorTransparent", "fitImageToScreen", "card_transparency", "bg_opacity", "sidebar_opacity", "bg_blur", "sidebar_blur", "card_opacity", "card_blur"];
|
||||
// Master "On/off toggles": every visual toggle, minus GPA/schedule/productivity.
|
||||
const exportToggles = ["dark_mode", "quiz_safe_mode", "grade_analytics", "grade_analytics_zones"].concat(exportCardColorToggles, exportLayout, exportSidebar, exportTodo);
|
||||
const fontsDropdownStateKey = "fonts_dropdown_open";
|
||||
@ -401,6 +401,8 @@ const defaultOptions = {
|
||||
"card_grid_flex": false,
|
||||
"customCardStyles": false,
|
||||
"customBackgroundLink": "",
|
||||
"customBackgroundColor": "",
|
||||
"customBackgroundColorTransparent": false,
|
||||
"customBackgroundScale": 100,
|
||||
"customBackgroundDaily": false,
|
||||
"customBackgroundNasaDaily": false,
|
||||
@ -1106,6 +1108,73 @@ function setupCustomBackgroundLink(initial) {
|
||||
});
|
||||
}
|
||||
|
||||
// Accepts "#1e2a38", "1e2a38" or "#abc"; anything else means "no colour".
|
||||
function normalizeBackgroundColor(value) {
|
||||
const hex = String(value || "").trim().replace(/^#/, "");
|
||||
if (/^[0-9a-f]{3}$/i.test(hex)) return "#" + hex.split("").map(c => c + c).join("").toLowerCase();
|
||||
if (/^[0-9a-f]{6}$/i.test(hex)) return "#" + hex.toLowerCase();
|
||||
return "";
|
||||
}
|
||||
|
||||
function currentBackgroundColor() {
|
||||
return normalizeBackgroundColor(document.querySelector("#customBackgroundColorHex")?.value || "");
|
||||
}
|
||||
|
||||
// Solid colour area: hex field + picker, either one sets it. The colour outranks the
|
||||
// presets and the image URL, so those are greyed out while it is set.
|
||||
function setupCustomBackgroundColor(initial) {
|
||||
const hexEl = document.querySelector("#customBackgroundColorHex");
|
||||
const picker = document.querySelector("#customBackgroundColorPicker");
|
||||
const clearBtn = document.querySelector("#clearCustomBackgroundColor");
|
||||
const transparency = document.querySelector("#customBackgroundColorTransparent");
|
||||
if (!hexEl || !picker) return;
|
||||
|
||||
const initialColor = normalizeBackgroundColor(initial);
|
||||
if (initialColor) {
|
||||
hexEl.value = initialColor;
|
||||
picker.value = initialColor;
|
||||
}
|
||||
chrome.storage.sync.get("customBackgroundColorTransparent", sync => {
|
||||
if (transparency) transparency.checked = sync.customBackgroundColorTransparent === true;
|
||||
});
|
||||
|
||||
const commit = (raw, { writeField = false } = {}) => {
|
||||
const color = normalizeBackgroundColor(raw);
|
||||
if (color) {
|
||||
if (writeField || !hexEl.value) hexEl.value = color;
|
||||
picker.value = color;
|
||||
} else if (writeField) {
|
||||
hexEl.value = "";
|
||||
}
|
||||
chrome.storage.sync.set({ "customBackgroundColor": color });
|
||||
syncSolidBackgroundState();
|
||||
toggleOpacityOptions();
|
||||
};
|
||||
|
||||
hexEl.addEventListener("input", (e) => commit(e.target.value));
|
||||
hexEl.addEventListener("blur", (e) => commit(e.target.value, { writeField: true }));
|
||||
picker.addEventListener("input", (e) => commit(e.target.value, { writeField: true }));
|
||||
clearBtn?.addEventListener("click", () => {
|
||||
hexEl.value = "";
|
||||
chrome.storage.sync.set({ "customBackgroundColor": "" });
|
||||
syncSolidBackgroundState();
|
||||
toggleOpacityOptions();
|
||||
});
|
||||
transparency?.addEventListener("change", function () {
|
||||
chrome.storage.sync.set({ "customBackgroundColorTransparent": this.checked });
|
||||
});
|
||||
syncSolidBackgroundState();
|
||||
}
|
||||
|
||||
// Grey the presets out while a colour is set, and only offer transparency with one.
|
||||
function syncSolidBackgroundState() {
|
||||
const hasColor = currentBackgroundColor() !== "";
|
||||
const presets = document.getElementById("background-presets");
|
||||
if (presets) presets.classList.toggle("is-disabled", hasColor);
|
||||
const transparencyRow = document.getElementById("customBackgroundColorTransparencyRow");
|
||||
if (transparencyRow) transparencyRow.style.display = hasColor ? "flex" : "none";
|
||||
}
|
||||
|
||||
function setupCustomBackgroundScale(initial) {
|
||||
const el = document.querySelector("#customBackgroundScale");
|
||||
const output = document.querySelector("#customBackgroundScaleValue");
|
||||
@ -1139,7 +1208,7 @@ function syncCustomBackgroundDailyState(isDaily) {
|
||||
manualControls.style.filter = isDaily ? "grayscale(1)" : "none";
|
||||
}
|
||||
|
||||
["customBackgroundLink", "customBackgroundScale", "clearCustomBackground"].forEach(id => {
|
||||
["customBackgroundLink", "customBackgroundScale", "clearCustomBackground", "customBackgroundColorHex", "customBackgroundColorPicker", "clearCustomBackgroundColor"].forEach(id => {
|
||||
const el = document.getElementById(id);
|
||||
if (el) el.disabled = isDaily;
|
||||
});
|
||||
@ -1152,6 +1221,7 @@ function syncCustomBackgroundDailyState(isDaily) {
|
||||
}
|
||||
|
||||
function renderBackgroundPresetSelection() {
|
||||
syncSolidBackgroundState();
|
||||
const isDaily = document.querySelector("#customBackgroundDaily")?.checked === true || document.querySelector("#customBackgroundNasaDaily")?.checked === true;
|
||||
const dailyPreset = isDaily ? getDailyBackgroundPreset() : null;
|
||||
const currentLink = isDaily ? (dailyPreset?.url || "") : (document.querySelector("#customBackgroundLink")?.value || "");
|
||||
@ -1211,7 +1281,7 @@ function customBackgroundActive() {
|
||||
const link = document.querySelector("#customBackgroundLink");
|
||||
const daily = document.querySelector("#customBackgroundDaily");
|
||||
const nasa = document.querySelector("#customBackgroundNasaDaily");
|
||||
return (link && link.value.trim() !== "") || (daily && daily.checked) || (nasa && nasa.checked);
|
||||
return (currentBackgroundColor() !== "") || (link && link.value.trim() !== "") || (daily && daily.checked) || (nasa && nasa.checked);
|
||||
}
|
||||
|
||||
function toggleOpacityOptions() {
|
||||
@ -2127,6 +2197,10 @@ async function setup() {
|
||||
{
|
||||
identifier: "customBackgroundScale",
|
||||
setup: (initial) => setupCustomBackgroundScale(initial),
|
||||
},
|
||||
{
|
||||
identifier: "customBackgroundColor",
|
||||
setup: (initial) => setupCustomBackgroundColor(initial),
|
||||
},
|
||||
{
|
||||
identifier: "todo_celebrations",
|
||||
@ -2795,8 +2869,10 @@ async function setup() {
|
||||
|
||||
|
||||
document.getElementById("clearCustomBackground").addEventListener("click", () => {
|
||||
chrome.storage.sync.set({ "customBackgroundLink": "", "customBackgroundScale": 100 });
|
||||
chrome.storage.sync.set({ "customBackgroundLink": "", "customBackgroundScale": 100, "customBackgroundColor": "" });
|
||||
document.querySelector("#customBackgroundLink").value = "";
|
||||
document.querySelector("#customBackgroundColorHex").value = "";
|
||||
syncSolidBackgroundState();
|
||||
document.querySelector("#customBackgroundScale").value = 100;
|
||||
document.querySelector("#customBackgroundScaleValue").textContent = "100%";
|
||||
renderBackgroundPresetSelection();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user