feat: add color presets + fix badge hover effect

- Add global color presets: save/apply/delete sets of {bg, border, text}
  colors as reusable presets, shown as mini badges in their own colors.
- Popover: preset badges under preview with + to save, click to apply,
  × on hover to delete.
- Popup: dedicated Color Presets section with same functionality,
  applying to light subreddit badge colors.
- Storage: colorPresets array added to settings defaults.
- Fix badge hover: change brightness(0.9) to brightness(1.1) so hover
  brightens (activates) instead of dimming.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-26 18:00:54 -04:00
parent fb0c03d46a
commit 48db2fc70e
9 changed files with 2053 additions and 23 deletions

View File

@@ -105,6 +105,21 @@
var previewSection = el.querySelector(".rt-popover-preview");
el.insertBefore(picker.el, previewSection);
var presetsDiv = document.createElement("div");
presetsDiv.className = "rt-popover-presets";
var presetList = document.createElement("div");
presetList.className = "rt-preset-list";
var presetAddBtn = document.createElement("button");
presetAddBtn.className = "rt-preset-add";
presetAddBtn.type = "button";
presetAddBtn.textContent = "+";
presetAddBtn.title = "Save current colors as preset";
presetAddBtn.addEventListener("click", saveAsPreset);
presetsDiv.appendChild(presetList);
presetsDiv.appendChild(presetAddBtn);
el.querySelector(".rt-popover-footer").insertAdjacentElement("beforebegin", presetsDiv);
els.presetList = presetList;
els.closeBtn.addEventListener("click", close);
els.cancelBtn.addEventListener("click", close);
els.saveBtn.addEventListener("click", save);
@@ -234,6 +249,73 @@
els.preview.style.color = text;
}
function renderPresets(presets) {
els.presetList.innerHTML = "";
for (var i = 0; i < presets.length; i++) {
(function (index) {
var p = presets[index];
var badge = document.createElement("span");
badge.className = "rt-preset-badge";
badge.style.background = p.bg;
badge.style.borderColor = p.border;
badge.style.color = p.text;
badge.textContent = "Aa";
badge.title = "Click to apply";
badge.addEventListener("click", function () {
applyPreset(p);
});
var del = document.createElement("span");
del.className = "rt-preset-delete";
del.textContent = "\u00d7";
del.addEventListener("click", function (e) {
e.stopPropagation();
removePreset(index);
});
badge.appendChild(del);
els.presetList.appendChild(badge);
})(i);
}
}
function applyPreset(p) {
markModeDirty(selectedMode);
var props = ["bg", "border", "text"];
for (var i = 0; i < props.length; i++) {
var prop = props[i];
els.rows[prop].swatch.style.backgroundColor = p[prop];
els.rows[prop].hex.value = p[prop];
els.rows[prop].hex.classList.remove("rt-input-error");
}
updatePreview();
if (picker && picker.isOpen() && activeProp) {
picker.setColor(els.rows[activeProp].hex.value);
}
}
async function saveAsPreset() {
var preset = {
bg: els.rows.bg.hex.value,
border: els.rows.border.hex.value,
text: els.rows.text.hex.value,
};
var settings = await window.RedditTweaks.loadSettings();
var presets = settings.colorPresets || [];
presets.push(preset);
settings.colorPresets = presets;
await window.RedditTweaks.saveSettings(settings);
renderPresets(presets);
}
async function removePreset(index) {
var settings = await window.RedditTweaks.loadSettings();
var presets = settings.colorPresets || [];
presets.splice(index, 1);
settings.colorPresets = presets;
await window.RedditTweaks.saveSettings(settings);
renderPresets(presets);
}
function positionPopover(anchorEl) {
var rect = anchorEl.getBoundingClientRect();
var gap = 6;
@@ -311,6 +393,7 @@
applyDarkModeToPopover(settings);
loadModeIntoInputs();
updatePreview();
renderPresets(settings.colorPresets || []);
positionPopover(badgeEl);
}