diff --git a/src/manifest.json b/src/manifest.json index 8902a972b..858ca3f28 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -65,7 +65,7 @@ } ], - "minimum_chrome_version": "89", + "minimum_chrome_version": "90", "browser_specific_settings": { "gecko": { "strict_min_version": "89.0a1" diff --git a/src/scripts/tweaks.json b/src/scripts/tweaks.json index 39e0eea54..146994f6c 100644 --- a/src/scripts/tweaks.json +++ b/src/scripts/tweaks.json @@ -53,6 +53,11 @@ "default": false, "inherit": "tweaks.preferences.subtle_follow" }, + "subtle_activity_mutuals": { + "type": "checkbox", + "label": "Make following/mutuals indicators on notifications more subtle", + "default": false + }, "hide_activity_mutuals": { "type": "checkbox", "label": "Hide following/mutuals indicators on notifications", diff --git a/src/scripts/tweaks/subtle_activity_mutuals.js b/src/scripts/tweaks/subtle_activity_mutuals.js new file mode 100644 index 000000000..996e056a9 --- /dev/null +++ b/src/scripts/tweaks/subtle_activity_mutuals.js @@ -0,0 +1,67 @@ +import { pageModifications } from '../../util/mutations.js'; +import { keyToCss } from '../../util/css_map.js'; +import { buildStyle } from '../../util/interface.js'; +import { dom } from '../../util/dom.js'; + +const labelSelector = keyToCss('followingBadgeContainer', 'mutualsBadgeContainer'); + +const spanClass = 'xkit-tweaks-subtle-activity-span'; + +const styleElement = buildStyle(` +.${spanClass} { + display: inline-block; + overflow-x: clip; + + width: var(--rendered-width); +} + +a:not(:hover) .${spanClass} { + width: 0; +} + +a:not(:hover) ${labelSelector} > svg { + margin-left: 0; +} +`); + +const transitionStyleElement = buildStyle(` +.${spanClass} { + transition: width 0.2s ease; +} +${labelSelector} > svg { + transition: margin 0.2s ease; +} +`); + +const processLabels = labels => labels.forEach(label => { + const textNode = label.firstChild; + if (textNode.nodeName !== '#text') return; + + const span = dom('span', null, null, [textNode.textContent]); + label.insertBefore(span, textNode); + textNode.textContent = ''; + + span.style.setProperty('--rendered-width', `${span.getBoundingClientRect().width}px`); + span.classList.add(spanClass); +}); + +const waitForRender = () => + new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve))); + +export const main = async function () { + pageModifications.register(labelSelector, processLabels); + + document.documentElement.append(styleElement); + waitForRender().then(() => document.documentElement.append(transitionStyleElement)); +}; + +export const clean = async function () { + pageModifications.unregister(processLabels); + styleElement.remove(); + transitionStyleElement.remove(); + + [...document.querySelectorAll(`.${spanClass}`)].forEach(span => { + const textNode = document.createTextNode(span.textContent); + span.parentNode.replaceChild(textNode, span); + }); +};