From f168193e64793621652a86a3b2f238fe153f5b65 Mon Sep 17 00:00:00 2001 From: "(quasar) nebula" Date: Mon, 20 Jan 2025 10:39:07 -0400 Subject: userstuff: initial commit Userscripts and userstyles. Extension/platform-agnostic. At the moment we're using the macOS 'Userscripts' app (from the app store), which we've configured to point to a folder in iCloud Documents, 'Userscripts Folder'. 'Userscripts Folder' is flat and each file is hardlinked with the appropriate placement in userstuff, though we haven't checked if the Userscripts app breaks hardlinks or not. --- .../discord/Highlight hovered message.user.css | 10 ++ userstuff/e621/Search their favorites!.user.js | 152 +++++++++++++++++++++ userstuff/google-docs/Banish Gemini.user.css | 9 ++ .../youtube/Copy YouTube chat messages.user.js | 18 +++ 4 files changed, 189 insertions(+) create mode 100644 userstuff/discord/Highlight hovered message.user.css create mode 100644 userstuff/e621/Search their favorites!.user.js create mode 100644 userstuff/google-docs/Banish Gemini.user.css create mode 100644 userstuff/youtube/Copy YouTube chat messages.user.js diff --git a/userstuff/discord/Highlight hovered message.user.css b/userstuff/discord/Highlight hovered message.user.css new file mode 100644 index 0000000..fe9d89b --- /dev/null +++ b/userstuff/discord/Highlight hovered message.user.css @@ -0,0 +1,10 @@ +/* ==UserStyle== +@name Highlight hovered message +@description Adds a background and underline to the Discord message under the mouse cursor +@match https://discord.com/* +==/UserStyle== */ + +div[class*=cozyMessage]:hover { + background-color: #ccc1; + box-shadow: 0 1px 0px #eee5; +} diff --git a/userstuff/e621/Search their favorites!.user.js b/userstuff/e621/Search their favorites!.user.js new file mode 100644 index 0000000..e34f4ee --- /dev/null +++ b/userstuff/e621/Search their favorites!.user.js @@ -0,0 +1,152 @@ +// ==UserScript== +// @name Search their favorites! +// @description This is your new file, start writing code +// @match https://e621.net/posts/*/favorites +// ==/UserScript== + +const settings = { + normalHoverInfoDelay: 400, + fastHoveringInfoDelay: 150, + endFastHoveringDelay: 500, + + focusInfoDelay: 750, + + hideTooltipDelay: 500, +}; + +const state = { + hoverTimeout: null, + focusTimeout: null, + + fastHovering: false, + endFastHoveringTimeout: false, + + showing: false, + justHidden: false, + + row: null, +}; + +const thumb = document.querySelector('#a-index .thumbnail'); + +const container = document.createElement('div'); + +const tagLabel = document.createElement('label'); +const tagInput = document.createElement('input'); +tagLabel.appendChild(document.createTextNode('Search these tags: ')); +tagLabel.appendChild(tagInput); +container.appendChild(tagLabel); + +let hoverTimeout = null; +for (const a of document.querySelectorAll('#a-index td a[href^="/favorites"]')) { + a.addEventListener('mouseover', event => { + const hoverTimeoutDelay = + (state.fastHovering + ? settings.fastHoveringInfoDelay + : settings.normalHoverInfoDelay); + + state.hoverTimeout = setTimeout(() => { + state.hoverTimeout = null; + state.fastHovering = true; + show(a); + }, hoverTimeoutDelay); + + if (state.endFastHoveringTimeout) { + clearTimeout(state.endFastHoveringTimeout); + state.endFastHoveringTimeout = null; + } + + if (state.hideTimeout) { + clearTimeout(state.hideTimeout); + state.hideTimeout = null; + } + }); + + a.addEventListener('mouseleave', event => { + if (state.hoverTimeout) { + clearTimeout(state.hoverTimeout); + state.hoverTimeout = null; + } + + if (state.fastHovering && !state.endFastHoveringTimeout) { + state.endFastHoveringTimeout = setTimeout(() => { + state.endFastHoveringTimeout = null; + state.fastHovering = false; + }, settings.endFastHoveringDelay); + } + }); + + a.closest('tr').addEventListener('mouseleave', event => { + if (state.showing && !state.hideTimeout) { + state.hideTimeout = setTimeout(() => { + state.hideTimeout = null; + hide(); + }, settings.hideTooltipDelay); + } + }); + + a.addEventListener('focus', event => { + state.focusTimeout = setTimeout(() => { + state.focusTimeout = null; + show(a); + }, settings.focusInfoDelay); + + if (state.justHidden) { + clearTimeout(state.focusTimeout); + state.focusTimeout = null; + show(a); + } + }) +} + +function show(a) { + hide(); + + const tr = document.createElement('tr'); + const td = document.createElement('td'); + const aa = document.createElement('a'); + aa.href = '#'; + aa.appendChild(document.createTextNode('Hiya')); + td.appendChild(aa); + tr.appendChild(td); + + state.showing = true; + state.row = tr; + + tr.addEventListener('mouseenter', event => { + if (state.hideTimeout) { + clearTimeout(state.hideTimeout); + state.hideTimeout = null; + } + }); + + tr.addEventListener('focusin', event => { + if (state.hideTimeout) { + clearTimeout(state.hideTimeout); + state.hideTimeout = null; + } + }); + + tr.addEventListener('focusout', event => { + hide(); + }); + + a.closest('tr').after(tr); +} + +function hide() { + if (!state.showing) return; + if (!state.row) return; + + state.row.remove(); + + state.showing = false; + state.row = null; + + state.justHidden = true; + setTimeout(() => { + state.justHiden = false; + }); +} + +thumb.after(container); diff --git a/userstuff/google-docs/Banish Gemini.user.css b/userstuff/google-docs/Banish Gemini.user.css new file mode 100644 index 0000000..04f78cc --- /dev/null +++ b/userstuff/google-docs/Banish Gemini.user.css @@ -0,0 +1,9 @@ +/* ==UserStyle== +@name Banish Gemini +@description Removes Gemini promo button from Google Docs, etc +@match https://docs.google.com/* +==/UserStyle== */ + +#docs-sidekick-gen-ai-promo-button-container { + display: none; +} \ No newline at end of file diff --git a/userstuff/youtube/Copy YouTube chat messages.user.js b/userstuff/youtube/Copy YouTube chat messages.user.js new file mode 100644 index 0000000..9665e12 --- /dev/null +++ b/userstuff/youtube/Copy YouTube chat messages.user.js @@ -0,0 +1,18 @@ +// ==UserScript== +// @name Copy YouTube chat messages +// @description Copies the text of a message when you click it (no emotes, sorry) +// @match https://www.youtube.com/live_chat_replay* +// ==/UserScript== + +document.body.addEventListener('click', event => { + const mouseElem = document.elementFromPoint(event.clientX, event.clientY); + if (!mouseElem) return; + const rendererElem = mouseElem.closest('yt-live-chat-text-message-renderer'); + if (!rendererElem) return; + const messageElem = rendererElem.querySelector('#message'); + if (!messageElem) { + console.warn(`Couldn't find message in message renderer`); + return; + } + navigator.clipboard.writeText(messageElem.innerText.trim()); +}); -- cgit 1.3.0-6-gf8a5