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:
@@ -25,7 +25,7 @@ html.rt-enabled .thing.link .flat-list li:has(> .comments) {
|
||||
}
|
||||
|
||||
.rt-badge:hover {
|
||||
filter: brightness(0.9);
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
|
||||
/* --- Subreddit badge: relative for gear positioning --- */
|
||||
@@ -316,6 +316,96 @@ html.rt-enabled .thing.link .flat-list li:has(> .comments) {
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
/* --- Preset badges --- */
|
||||
.rt-popover-presets {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 8px 0;
|
||||
border-top: 1px solid #eee;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.rt-preset-list {
|
||||
display: flex;
|
||||
gap: 4px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.rt-preset-badge {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
border: 1px solid;
|
||||
border-radius: 3px;
|
||||
padding: 2px 6px;
|
||||
font-size: 10px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
line-height: 1.4;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.rt-preset-badge:hover {
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
|
||||
.rt-preset-delete {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
right: -6px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
background: #d9534f;
|
||||
color: white;
|
||||
border-radius: 50%;
|
||||
font-size: 10px;
|
||||
line-height: 14px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.rt-preset-badge:hover .rt-preset-delete {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.rt-preset-add {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border: 1px dashed #ccc;
|
||||
border-radius: 3px;
|
||||
background: none;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.rt-preset-add:hover {
|
||||
border-color: #999;
|
||||
color: #666;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.rt-color-popover.rt-dark .rt-popover-presets {
|
||||
border-top-color: #444;
|
||||
}
|
||||
|
||||
.rt-color-popover.rt-dark .rt-preset-add {
|
||||
border-color: #555;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.rt-color-popover.rt-dark .rt-preset-add:hover {
|
||||
border-color: #888;
|
||||
color: #ccc;
|
||||
background: #333;
|
||||
}
|
||||
|
||||
/* --- Color Picker Widget --- */
|
||||
.rt-color-picker {
|
||||
margin: 8px 0;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user