Skip to content

Instantly share code, notes, and snippets.

@pacochi
Last active March 2, 2022 06:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pacochi/ca65a42509080210ddb12ec650fbe995 to your computer and use it in GitHub Desktop.
Save pacochi/ca65a42509080210ddb12ec650fbe995 to your computer and use it in GitHub Desktop.
書き込み欄上部(モバイル版ではタブバー)にアカウント表示ボタンを追加します。新規リストに表示させたいアカウントを追加して、リスト番号を指定してください。
// ==UserScript==
// @name [Mastodon] profile shortcut
// @namespace hen.acho.co
// @include https://*/web/*
// @version 1.220302
// @description jump to your favorite account easily
// @downloadURL https://gist.github.com/pacochi/ca65a42509080210ddb12ec650fbe995/raw/mastodon_profile_shortcut.user.js
// @run-at document-idle
// @grant none
// ==/UserScript==
// 監視対象が一定しないので雑に五秒後につけることにした
setTimeout((() => {
let profileListId = localStorage.getItem('profileListId');
const accessToken = JSON.parse(
(document.querySelector('#initial-state') || {}
).textContent || '{ "meta": {} }').meta.access_token;
// 自分が使ってない機能のとこ置き換えてる
if (!accessToken) return;
const E = (name, attr = {}) => Object.assign(document.createElement(name), attr);
if (!document.getElementById('profile-shortcut-css')) document.head.appendChild(
E('style', { id: 'profile-shortcut-css', textContent: `
.tabs-bar {
overflow: visible;
}
.profile-shortcut {
position: relative;
display: block;
width: 40px;
height: 40px;
min-height: 40px;
line-height: 40px;
z-index: 0;
text-align: center;
margin: -12px auto -10px auto;
}
.navigation-bar .profile-shortcut {
margin: 0;
}
.profile-shortcut .profile-shortcut-icons{
display: none;
position: absolute;
top: 40px;
left: 0;
width: 40px;
}
.profile-shortcut:focus-within {
z-index: 4;
}
.profile-shortcut:focus-within .profile-shortcut-icons {
display: block;
}
.profile-shortcut-icon {
width: 40px;
height: 40px;
background-size: 40px 40px;
cursor: pointer;
border: 0;
margin: 0;
padding: 0;
}
.profile-shortcut-setting {
color: #fff;
background-color: transparent;
cursor: pointer;
border: 0;
margin: 0;
padding: 0;
}
`
})
);
// https://gist.github.com/unarist/a5998d24c5bcb207376ab22c05f24e5c からもらってきた
const getHistory = () => {
const rootContainer = document.getElementById('mastodon')._reactRootContainer;
let current_node = (rootContainer._internalRoot || rootContainer).current.child;
while (current_node) {
const history = current_node.memoizedProps.history;
if (history) return history;
current_node = current_node.child;
}
};
const changedLink = document.querySelector('[data-preview-title-id="pawoo.column.suggested_accounts"], [data-preview-title-id="column.public"], [data-preview-title-id="column.community"]');
const fromPC = !document.querySelector('.columns-area__panels') || getComputedStyle(document.querySelector('.tabs-bar') || {})?.display == 'none';
const parentElm = fromPC ? document.querySelector('.navigation-bar')
: E('strong', { className: 'tabs-bar__link' });
if (!parentElm) console.log('[profile-shortcut] no parentElm', fromPC);
if (!fromPC && changedLink) changedLink.replaceWith(parentElm);
const container = parentElm.appendChild(E('strong', { className: 'profile-shortcut' }));
const setting = container.appendChild(E('button', {
className: 'profile-shortcut-setting'
}));
const settingIcon = setting.appendChild(E('i', { className: 'fa fa-fw fa-plus-square' }));
const icons = container.appendChild(E('span', { className: 'profile-shortcut-icons' }));
const addIcon = account => {
const icon = icons.appendChild(E('button', {
style: `background-image: url('${account.avatar}');`,
className: 'profile-shortcut-icon',
title: account.acct
}));
icon.addEventListener('click', e => {
getHistory().push('/accounts/' + account.id); // + '/with_replies');
e.target.blur();
e.preventDefault();
});
};
const getProfiles = profileListId => {
if (!profileListId || !accessToken) return;
const profileEndpoint = `/api/v1/lists/${profileListId}/accounts?limit=0`;
document.querySelectorAll('.profile-shortcut-icon').forEach(icon => icon.remove());
settingIcon.className = 'fa fa-fw fa-heart';
fetch(profileEndpoint, {
headers: { Authorization: 'Bearer ' + accessToken }
}).then(r => r.json()).then(json => json.forEach(account => addIcon(account)));
};
setting.addEventListener('contextmenu', e => {
profileListId = parseInt(prompt('リストの ID', ''));
if (profileListId) localStorage.setItem('profileListId', profileListId);
getProfiles(profileListId);
e.preventDefault();
});
getProfiles(profileListId);
}), 5000);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment