Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion css/layout.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
/* Layout and columns */
html.ydd-startup-hold body {
visibility: hidden !important;
}

html.ydd-startup-fading #sample-dark-background {
transition: none !important;
}

body {
font-family: var(--ydd-font-family, "Outfit", system-ui, sans-serif);
background-color: var(--bg-primary);
Expand Down Expand Up @@ -40,7 +48,7 @@ body:not(.loaded) {
width: 100%;
height: 100%;
padding: 2rem 4rem;
gap: 20rem;
gap: clamp(12rem, calc(100vw - 1078px), 20rem);
overflow-y: auto;
overscroll-behavior: contain;
}
Expand Down
22 changes: 20 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
/>
<title>New Tab</title>

<script src="src/theme-init.js"></script>
<link rel="icon" type="image/png" href="assets/icons/icon32.png" />
<link rel="stylesheet" href="css/main.css" />
<script src="src/theme-init.js"></script>
</head>
<!-- Dashboard interface -->
<body>
Expand Down Expand Up @@ -448,7 +448,7 @@ <h2 id="apps-popup-title" class="visually-hidden">Google Apps</h2>

<!-- Mini settings -->
<div id="settings-popup" class="popup-container" role="dialog"
aria-labelledby="settings-popup-title" aria-hidden="true">
aria-labelledby="settings-popup-title" aria-hidden="true" inert>
<div style="position: relative; text-align: center; margin-bottom: 1rem">
<button
id="info-btn"
Expand Down Expand Up @@ -770,6 +770,24 @@ <h2 id="apps-popup-title" class="visually-hidden">Google Apps</h2>
aria-label="Remove custom background">Remove</button>
</div>
</div>
<div class="setting-row">
<div class="label">
<span>Startup Fade</span><small>Fade from the startup color into your theme or wallpaper.</small>
</div>
<label class="toggle-switch">
<input type="checkbox" id="startup-fade-toggle"
aria-label="Fade startup background" checked />
<span class="slider"></span>
</label>
</div>
<div class="setting-row" id="startup-canvas-color-row">
<div class="label">
<span>Startup BG</span><small>Choose the color shown before your theme or wallpaper appears.</small>
</div>
<input type="color" id="startup-canvas-color-picker"
class="color-picker" aria-label="Startup background color"
value="#ffffff" />
</div>
<div class="setting-row">
<div class="label">
<span class="mini-random-bg-label">
Expand Down
25 changes: 19 additions & 6 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class SampleDarkBackground {
this.particles = [];
this.frameId = 0;
this.isAnimating = false;
this.active = false;
this.pointer = { x: -1000, y: -1000, active: false };
this.reduceMotion = Boolean(
window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches,
Expand Down Expand Up @@ -135,16 +136,28 @@ class SampleDarkBackground {

const active = this.isActive();
this.container.classList.toggle("is-active", active);
this.stop();

if (!active) {
this.clear();
if (this.active) {
this.stop();
this.clear();
}
this.active = false;
return;
}

this.resize();
if (this.shouldAnimate()) this.start();
else this.drawFrame(false);
if (!this.active) {
this.active = true;
this.resize();
this.drawFrame(false);
}

if (this.shouldAnimate()) {
this.start();
} else {
this.stop();
this.drawFrame(false);
}
}

makeParticle() {
Expand Down Expand Up @@ -434,7 +447,7 @@ document.addEventListener("DOMContentLoaded", () => {
});
}

setTimeout(() => document.body.classList.add("loaded"), 100);
requestAnimationFrame(() => document.body.classList.add("loaded"));
});

// Welcome popup
Expand Down
2 changes: 2 additions & 0 deletions src/modules/keyboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,13 +184,15 @@ export class KeyboardManager {
const miniButton = document.getElementById("settings-toggle-button");
if (miniPopup?.classList.contains("visible")) {
miniPopup.classList.remove("visible");
miniPopup.inert = true;
miniPopup.setAttribute("aria-hidden", "true");
miniButton?.setAttribute("aria-expanded", "false");
state.set("lastSettingsView", "mini");
return true;
}
if (fullModal?.isOpen) fullModal.close();
if (!miniPopup) return false;
miniPopup.inert = false;
miniPopup.classList.add("visible");
miniPopup.setAttribute("aria-hidden", "false");
miniButton?.setAttribute("aria-expanded", "true");
Expand Down
36 changes: 35 additions & 1 deletion src/modules/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
makeKeyboardInteractive,
playNotificationSound,
showCustomModal,
syncStartupCanvasAvailability,
} from "../utils.js";
import { secondStorage } from "../secondStorage.js";
import {
Expand Down Expand Up @@ -1144,6 +1145,8 @@ export class SettingsManager {
uploadBg: document.getElementById("upload-bg-button"),
bgInput: document.getElementById("bg-file-input"),
removeBg: document.getElementById("remove-bg-button"),
startupCanvasColor: document.getElementById("startup-canvas-color-picker"),
startupFade: document.getElementById("startup-fade-toggle"),
randomBgFreeze: document.getElementById("random-bg-freeze-btn"),
randomBgRnd: document.getElementById("random-bg-rnd-btn"),
randomBgSchedule: document.getElementById("random-bg-schedule-select"),
Expand Down Expand Up @@ -1381,6 +1384,18 @@ export class SettingsManager {
}
if (this.els.locInput) this.els.locInput.value = state.get("yd_city") || "";

if (this.els.startupCanvasColor) {
const startupCanvasColor = localStorage.getItem("startupCanvasColor");
if (/^#[\da-f]{6}$/i.test(startupCanvasColor || "")) {
this.els.startupCanvasColor.value = startupCanvasColor;
}
}
if (this.els.startupFade) {
this.els.startupFade.checked =
localStorage.getItem("startupFadeEnabled") !== "false";
}
syncStartupCanvasAvailability();

if (this.els.bgBlurSelect) {
const savedBlur = state.get("bgBlurIntensity") || "0";
this.els.bgBlurSelect.value = savedBlur;
Expand Down Expand Up @@ -1441,7 +1456,7 @@ export class SettingsManager {
document.body.classList.add("has-custom-bg");
document.body.style.backgroundImage = `url(${bg})`;
if (this.els.removeBg) this.els.removeBg.classList.remove("hidden");
} else {
} else if (localStorage.getItem("has_idb_bg") !== "true") {
document.body.classList.remove("has-custom-bg");
}

Expand Down Expand Up @@ -1693,6 +1708,7 @@ export class SettingsManager {
state.set("lastSettingsView", "full");
} else if (isMiniOpen) {
this.els.popup.classList.remove("visible");
this.els.popup.inert = true;
this.els.btn.setAttribute("aria-expanded", "false");
this.els.popup.setAttribute("aria-hidden", "true");
state.set("lastSettingsView", "mini");
Expand All @@ -1701,6 +1717,7 @@ export class SettingsManager {
if (lastView === "full" && fullModal) {
fullModal.open();
} else {
this.els.popup.inert = false;
this.els.popup.classList.add("visible");
this.els.btn.setAttribute("aria-expanded", "true");
this.els.popup.setAttribute("aria-hidden", "false");
Expand All @@ -1720,6 +1737,22 @@ export class SettingsManager {
setTimeout(() => this.els.btn.classList.remove("animating"), 400);
});

if (this.els.startupCanvasColor) {
this.els.startupCanvasColor.addEventListener("input", (e) => {
localStorage.setItem("startupCanvasColor", e.target.value);
const fullPicker = document.getElementById("fs-startup-canvas-color");
if (fullPicker) fullPicker.value = e.target.value;
});
}
if (this.els.startupFade) {
this.els.startupFade.addEventListener("change", (e) => {
localStorage.setItem("startupFadeEnabled", String(e.target.checked));
const fullToggle = document.getElementById("fs-startup-fade-toggle");
if (fullToggle) fullToggle.checked = e.target.checked;
syncStartupCanvasAvailability();
});
}

if (this.els.bgBlurSelect) {
this.els.bgBlurSelect.addEventListener("change", (e) => {
const val = e.target.value;
Expand Down Expand Up @@ -1762,6 +1795,7 @@ export class SettingsManager {
!this.els.btn.contains(e.target)
) {
this.els.popup.classList.remove("visible");
this.els.popup.inert = true;
this.els.btn.setAttribute("aria-expanded", "false");
this.els.popup.setAttribute("aria-hidden", "true");
state.set("lastSettingsView", "mini");
Expand Down
52 changes: 52 additions & 0 deletions src/modules/settingsModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
makeKeyboardInteractive,
playNotificationSound,
showCustomModal,
syncStartupCanvasAvailability,
} from "../utils.js";
import {
CONFIG,
Expand Down Expand Up @@ -1010,6 +1011,18 @@ export class FullSettingsModal {
const bgControls = this._el("div", { className: "background-controls" });
bgControls.append(uploadBtn, bgFileInput, removeBtn);

const startupCanvasColor = this._el("input", {
type: "color",
id: "fs-startup-canvas-color",
className: "color-picker",
value: "#ffffff",
});
startupCanvasColor.setAttribute("aria-label", "Startup background color");
this.els.fsStartupCanvasColor = startupCanvasColor;
const startupFade = this._toggle("fs-startup-fade-toggle");
startupFade.input.setAttribute("aria-label", "Fade startup background");
this.els.fsStartupFade = startupFade.input;

const freezeBtn = this._el("button", {
className: "settings-button hidden",
id: "fs-freeze-btn",
Expand Down Expand Up @@ -1066,9 +1079,23 @@ export class FullSettingsModal {
);
this.els.fsBlurRow = blurRow;

const startupCanvasRow = this._row(
"Startup BG",
"Choose the color shown before your theme or wallpaper appears.",
startupCanvasColor,
);
startupCanvasRow.id = "fs-startup-canvas-color-row";
this.els.fsStartupCanvasRow = startupCanvasRow;

pane.appendChild(
this._section("Background", [
this._row("Custom BG", "Upload an image.", bgControls),
this._row(
"Startup Fade",
"Fade from the startup color into your theme or wallpaper.",
startupFade.wrapper,
),
startupCanvasRow,
this._row(randomBgLabel, "Fetch image from Lorem Picsum.", rndControls),
blurRow,
]),
Expand Down Expand Up @@ -1404,6 +1431,7 @@ export class FullSettingsModal {
state.set("lastSettingsView", "mini");
const sm = this._sm();
if (sm && sm.els.popup) {
sm.els.popup.inert = false;
sm.els.popup.classList.add("visible");
sm.els.popup.setAttribute("aria-hidden", "false");
sm.els.btn?.setAttribute("aria-expanded", "true");
Expand Down Expand Up @@ -1601,6 +1629,18 @@ export class FullSettingsModal {
}
});

this.els.fsStartupCanvasColor.addEventListener("input", (e) => {
localStorage.setItem("startupCanvasColor", e.target.value);
const miniPicker = document.getElementById("startup-canvas-color-picker");
if (miniPicker) miniPicker.value = e.target.value;
});
this.els.fsStartupFade.addEventListener("change", (e) => {
localStorage.setItem("startupFadeEnabled", String(e.target.checked));
const miniToggle = document.getElementById("startup-fade-toggle");
if (miniToggle) miniToggle.checked = e.target.checked;
syncStartupCanvasAvailability();
});

this.els.fsBlurSelect.addEventListener("change", (e) => {
state.set("bgBlurIntensity", e.target.value);
const blurMap = { 0: 0, 10: 2, 20: 4, 30: 6, 40: 8, 50: 10 };
Expand Down Expand Up @@ -2034,6 +2074,13 @@ export class FullSettingsModal {
this.els.fsScPosition.value = state.get("shortcutsPosition") || "bottom";
this.els.fsLocInput.value = state.get("yd_city") || "";
this.els.fsBlurSelect.value = state.get("bgBlurIntensity") || "0";
const startupCanvasColor = localStorage.getItem("startupCanvasColor");
if (/^#[\da-f]{6}$/i.test(startupCanvasColor || "")) {
this.els.fsStartupCanvasColor.value = startupCanvasColor;
}
this.els.fsStartupFade.checked =
localStorage.getItem("startupFadeEnabled") !== "false";
syncStartupCanvasAvailability();
this.els.fsRandomBgSchedule.value = state.get("randomBgSchedule") || "1m";

const isAnalog = state.get("clockType") === "analog";
Expand Down Expand Up @@ -2061,6 +2108,11 @@ export class FullSettingsModal {

const miniPopup = document.getElementById("settings-popup");
if (miniPopup) {
const focused = document.activeElement;
if (focused instanceof HTMLElement && miniPopup.contains(focused)) {
focused.blur();
}
miniPopup.inert = true;
miniPopup.classList.remove("visible");
miniPopup.setAttribute("aria-hidden", "true");
document.getElementById("settings-toggle-button")?.setAttribute(
Expand Down
12 changes: 12 additions & 0 deletions src/modules/zenMode.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ export class ZenModeController {

// Border UI cleanup
closeBorderUi() {
const settingsPopup = document.getElementById("settings-popup");
if (settingsPopup?.classList.contains("visible")) {
settingsPopup.classList.remove("visible");
settingsPopup.inert = true;
settingsPopup.setAttribute("aria-hidden", "true");
document.getElementById("settings-toggle-button")?.setAttribute(
"aria-expanded",
"false",
);
state.set("lastSettingsView", "mini");
}

document
.querySelectorAll(".popup-container.visible")
.forEach((popup) => popup.classList.remove("visible"));
Expand Down
12 changes: 11 additions & 1 deletion src/storageKeys.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ const EXTRA_STORAGE_KEYS = [
"randomBgSchedule",
"randomBgTime",
"savedBgUrl",
"startupCanvasColor",
"startupFadeEnabled",
"showDate",
"showEditableText",
"showShortcuts",
Expand All @@ -73,6 +75,8 @@ const RAW_STORAGE_KEYS = new Set([
"has_idb_bg",
"hideGpsConsent",
"lowResBg",
"startupCanvasColor",
"startupFadeEnabled",
]);

const INTERNAL_STORAGE_KEYS = new Set(["ydd_daily_greeting"]);
Expand Down Expand Up @@ -206,11 +210,17 @@ export function validateYddStorageEntries(entries) {
throw new TypeError("Invalid active tool tab.");
}
if (
["has_idb_bg", "hideGpsConsent"].includes(key) &&
["has_idb_bg", "hideGpsConsent", "startupFadeEnabled"].includes(key) &&
!["true", "false"].includes(rawValue)
) {
throw new TypeError(`Invalid stored flag for ${key}.`);
}
if (
key === "startupCanvasColor" &&
!/^#[\da-f]{6}$/i.test(rawValue)
) {
throw new TypeError("Invalid startup background color.");
}
if (!RAW_STORAGE_KEYS.has(key) && !key.startsWith("welcomeShown_")) {
const parsedValue = JSON.parse(rawValue);
if (shouldNormalizeImportedValue(key)) {
Expand Down
Loading