Skip to content

Instantly share code, notes, and snippets.

@pacochi
Last active December 12, 2022 09:28
Show Gist options
  • Save pacochi/d466d481fa9aa982c2f206815765fd53 to your computer and use it in GitHub Desktop.
Save pacochi/d466d481fa9aa982c2f206815765fd53 to your computer and use it in GitHub Desktop.
Mastodon の静的ページに⭐🔃した人のアイコンを表示します。
// ==UserScript==
// @name [Mastodon] show ⭐🔃 on static pages
// @namespace hen.acho.co
// @include /^https?:\/\/[^\/]+\/(?:@\w+|users\/\w+\/(?:statuses|updates))\/\d+/
// @version 1.221212
// @description add favoriter or booster icons next to counts
// @downloadURL https://gist.github.com/pacochi/d466d481fa9aa982c2f206815765fd53/raw/mastodon_show_faboo.user.js
// @run-at document-idle
// @grant none
// ==/UserScript==
(async () => {
'use strict';
const mastodon = document.querySelector('#mastodon');
const isReady = (parent = document) => parent.querySelector('.detailed-status__meta');
if (mastodon && !isReady()) await new Promise(resolve => {
new MutationObserver((mutations, observer) => {
if (mutations.reduce((nodes, mutation) => nodes.concat(Array.from(mutation.addedNodes)), []).find(node => isReady(node))) {
observer.disconnect();
resolve();
}
}).observe(mastodon, { childList: true, subtree: true });
});
const reactions = [...document.querySelectorAll(
'a.detailed-status__datetime, .detailed-status__meta>span, a.absolute-time, span.engagement, .detailed-status__reblogs, .detailed-status__favorites'
)].filter(node => !['detailed-status__link', 'detailed-status__visibility-icon'].includes(node.className) && !/reply/.test(node.parentNode.firstChild.className)) || [ { href: '' } ];
const statId = reactions[0].href.replace(
/^(.+?\/)@.+?(\/\d+)/, '$1api/v1/statuses$2'
);
if (reactions.length == 3 && statId)
['/reblogged_by', '/favourited_by']
.map(by => `${statId}${by}?limit=80`)
.forEach(async (url, i) => {
const node = reactions[i + 1];
while (url) {
await fetch(url)
.then(response => ((
url = response.headers.has('Link')
? (response.headers.get('Link').match(/<(.+?)>; rel="next"/) || [])[1]
: null
), response.json()))
.catch(error => ((url = null), console.error(error)))
.then(accounts => Array.isArray(accounts) && accounts.forEach(account =>
node.parentNode.insertBefore(Object.assign(document.createElement('a'), {
href: account.url, title: account.display_name
}), node.nextSibling)
.appendChild(Object.assign(document.createElement('img'), {
src: account.avatar, style: 'width: 20px; height: 20px; margin: 0 2px;'
}))
));
await new Promise(resolve => setTimeout(resolve, 1000));
}
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment