Skip to content

Instantly share code, notes, and snippets.

@karasugawasu
Last active January 31, 2023 12:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save karasugawasu/d84015f1bc3709283cef5397b105a20b to your computer and use it in GitHub Desktop.
Save karasugawasu/d84015f1bc3709283cef5397b105a20b to your computer and use it in GitHub Desktop.
タグ固定するやつ

タグ固定するやつ

MastodonのWebUIでハッシュタグ付き投稿をする際、
何回も打ち直すことなく固定して投稿できるようにするものです。
(使い勝手微妙だけどゆるして・・・・)
demo.gif

1.4.xのタグテンプレートリストは試験的なものです。

機能

  • タグボタンを押すことで固定文を挿入するかしないか切り替えられます
  • 文章を固定できるので様々な使い方ができます
  • 最後に使用した固定文は保存されます
  • 簡単なテンプレートリストを作成可能です

タグテンプレートリスト

Ctrl + Homeを押すと編集モードに入ります(またはEditアイコン)
画像のように、リストをテキストエリアに入力してください(改行で区切ります)
image.png

Ctrl+Endで編集を終了します(またはEditアイコン)

あとは切り替えキーを押すだけです
demo2.gif

ショートカットキー

ショートカットキーはタグ固定するやつテキストエリア内にカーソルがいる場合にのみ有効です

  • 上 = テンプレートリスト切り替え
  • 下 = テンプレートリスト切り替え
  • Ctrl + Home = テンプレートリスト編集開始
  • Ctrl + End = テンプレートリスト編集終了

キー設定は迷走中です。

動作環境

ユーザースクリプトですので、それを利用できる拡張機能を入れてください

Androidで使う場合

Firefoxの拡張機能、USIを使用してください(Tampermonkeyでは動きません)
Yandexの場合はChrome拡張 Tampermonkeyを使用します

インストール

Tampermonkeyを導入済みの場合、こちらからユーザースクリプトをインストールできます

インストール後、設定の「include/exclude」の「ユーザーによる match」へ自身の利用しているMastodonサーバーのURLを入れてください

変更履歴

1.4.5

  • Mastodon v4.0.2に対応

1.4.4

  • Mastodon v3.0.1に対応
// ==UserScript==
// @name タグ固定するやつ
// @namespace https://md.korako.me/@karasu_sue
// @version 1.4.5
// @description タグ固定するやつ
// @author Sue Karasugawa https://md.korako.me/@karasu_sue
// @match https://md.korako.me/*
// @grant GM_addStyle
// @updateURL https://gist.githubusercontent.com/karasugawasu/d84015f1bc3709283cef5397b105a20b/raw/%25E3%2582%25BF%25E3%2582%25B0%25E5%259B%25BA%25E5%25AE%259A%25E3%2581%2599%25E3%2582%258B%25E3%2582%2584%25E3%2581%25A4.user.js
// @downloadURL https://gist.githubusercontent.com/karasugawasu/d84015f1bc3709283cef5397b105a20b/raw/%25E3%2582%25BF%25E3%2582%25B0%25E5%259B%25BA%25E5%25AE%259A%25E3%2581%2599%25E3%2582%258B%25E3%2582%2584%25E3%2581%25A4.user.js
// @supportURL https://gist.github.com/karasugawasu/d84015f1bc3709283cef5397b105a20b
// ==/UserScript==
(function() {
'use strict';
var koteitag_list_index = 0;
var template_list;
window.addEventListener("load", function() {
if (window.innerWidth > 630) {
Init();
}else{
if(window.location.pathname == '/web/statuses/new'){
Init();
}
document.querySelector('body').addEventListener('click', function(){
setTimeout(function() {
if(document.querySelector('div.columns-area .drawer') != null){
if(document.querySelector('.koteitag-input') == null){
Init();
}
}
},100);
});
}
});
function Init(){
if(document.querySelector('.compose-form')){
addKoteitagInput();
addKoteitagButton();
addActionButton();
setEvents();
}
if(localStorage.getItem('karasu_koteitag_list') == null){
localStorage.setItem('karasu_koteitag_list', document.querySelector('.koteitag-input__input').value + ",#precure_fun");
}
template_list = localStorage.getItem('karasu_koteitag_list').split(",");
var css = `
.koteitag-input {
position: relative;
height: 0;
transform-origin: bottom;
opacity: 0.0;
transition: height 0.4s ease, opacity 0.4s ease;
}
.koteitag-input--visible {
height: 47px;
opacity: 1.0;
}
.koteitag-input__input {
display: block !important;
box-sizing: border-box !important;
width: 100%;
padding: 10px;
resize: vertical;
outline: 0;
border-radius: 0 0 4px 4px;
}
`;
GM_addStyle(css)
if(localStorage.getItem('karasu_koteitag') != "" && document.querySelector('.koteitag-input__input') != null ){
document.querySelector('.koteitag-input__input').value = localStorage.getItem('karasu_koteitag');
}
}
function addKoteitagInput(){
var koteitag = document.createElement('div');
koteitag.classList.add('koteitag-input');
koteitag.appendChild(document.createElement('label'));
var koteistyle = document.createElement('span');
//koteistyle.setAttribute('style', 'display: none;');
koteitag.querySelector('label').appendChild(koteistyle);
var koteiinput = document.createElement('input');
koteiinput.classList.add('setting-text');
koteiinput.classList.add('koteitag-input__input');
koteiinput.setAttribute('placeholder', 'ここに固定したいハッシュタグを記載');
koteiinput.setAttribute('tabindex', '-1');
koteiinput.setAttribute('type', 'text');
koteiinput.setAttribute('id', 'koteitag-input');
koteiinput.addEventListener('change', savekoteitag);
koteiinput.addEventListener('keyup', selectTags);
koteitag.querySelector('label').appendChild(koteiinput);
document.querySelector('div.compose-form__buttons-wrapper').after(koteitag);
}
function addKoteitagButton(){
var koteitag = document.createElement('div');
koteitag.classList.add('compose-form__tag-button');
koteitag.addEventListener('click', clicktagbutton);
var koteibutton = document.createElement('div');
koteibutton.classList.add('text-icon-button');
koteibutton.setAttribute('title', '固定タグが設定されていません');
koteibutton.setAttribute('aria-controls', 'koteitag-input');
koteitag.appendChild(koteibutton);
var koteiicon = document.createElement('i');
koteiicon.classList.add('fa', 'fa-fw', 'fa-hashtag');
koteiicon.setAttribute('aria-hidden', 'true');
koteitag.querySelector('div').appendChild(koteiicon);
document.querySelector('.compose-form__buttons').appendChild(koteitag);
}
function addActionButton(){
var ab = document.createElement('nav');
ab.classList.add('koteitag__action-button')
var ab_up = document.createElement('a');
ab_up.classList.add('text-icon-button');
ab_up.classList.add('button_up');
ab_up.setAttribute('title', 'リスト上');
ab_up.setAttribute('aria-label', 'リスト上');
ab_up.addEventListener('click', selectTagUp);
var ab_up_i = document.createElement('i')
ab_up_i.classList.add('fa', 'fa-fw', 'fa-angle-up');
ab_up_i.setAttribute('role', 'img');
ab_up.appendChild(ab_up_i);
ab.appendChild(ab_up);
var ab_down = document.createElement('a');
ab_down.classList.add('text-icon-button');
ab_down.classList.add('button_down');
ab_down.setAttribute('title', 'リスト下');
ab_down.setAttribute('aria-label', 'リスト下');
ab_down.addEventListener('click', selectTagDown);
var ab_down_i = document.createElement('i')
ab_down_i.classList.add('fa', 'fa-fw', 'fa-angle-down');
ab_down_i.setAttribute('role', 'img');
ab_down.appendChild(ab_down_i);
ab.appendChild(ab_down);
var ab_edit = document.createElement('a');
ab_edit.classList.add('text-icon-button');
ab_edit.classList.add('button_edit');
ab_edit.setAttribute('title', '編集');
ab_edit.setAttribute('aria-label', '編集');
ab_edit.addEventListener('click', tagListEdit);
var ab_edit_i = document.createElement('i')
ab_edit_i.classList.add('fa', 'fa-fw', 'fa-edit');
ab_edit_i.setAttribute('role', 'img');
ab_edit.appendChild(ab_edit_i);
ab.appendChild(ab_edit);
document.querySelector('.koteitag-input label').after(ab);
}
function setEvents(){
document.querySelector('div.compose-form__publish-button-wrapper .button').addEventListener('click', setkoteitag);
document.querySelector('.autosuggest-textarea__textarea').addEventListener('keydown', pressed_keyconfirm);
}
function pressed_keyconfirm() {
if(event.ctrlKey){
if(event.keyCode === 13){
setkoteitag();
return false;
}
}
}
function tagListSet(){
localStorage.setItem('karasu_koteitag_list', document.querySelector('.autosuggest-textarea__textarea').value.replace(/\r?\n/g, ','));
setTextAreaText('');
template_list = localStorage.getItem('karasu_koteitag_list').split(",");
alert('タグ固定するやつリストを更新しました');
}
function tagListEdit(){
if(document.querySelector('.koteitag__action-button .text-icon-button.button_edit').getAttribute('title') == "編集"){
alert('タグ固定するやつリストを作成します、テキストエリアに改行で入力します');
setTextAreaText(localStorage.getItem('karasu_koteitag_list').replace(/,/g, '\n'));
document.querySelector('.koteitag__action-button .text-icon-button.button_edit').setAttribute('title','編集完了');
document.querySelector('.koteitag__action-button .text-icon-button.button_edit').classList.add('active');
}else{
tagListSet();
document.querySelector('.koteitag__action-button .text-icon-button.button_edit').setAttribute('title','編集');
document.querySelector('.koteitag__action-button .text-icon-button.button_edit').classList.remove('active');
}
}
function selectTagUp(){
if(koteitag_list_index >= template_list.length - 1){
koteitag_list_index = 0;
}else{
koteitag_list_index++;
}
document.querySelector('.koteitag-input__input').value = template_list[koteitag_list_index];
}
function selectTagDown(){
if(koteitag_list_index === 0 ){
koteitag_list_index = template_list.length - 1;
}else{
koteitag_list_index--;
}
document.querySelector('.koteitag-input__input').value = template_list[koteitag_list_index];
}
function selectTags(){
if(event.ctrlKey){
if(event.keyCode === 35){
tagListSet();
}else if(event.keyCode === 36){
tagListEdit();
}
}
if(localStorage.getItem('karasu_koteitag_list') == null){
alert('ハッシュタグリストを作成します');
document.querySelector('.autosuggest-textarea__textarea').placeholder = '改行しながらリストを作成してください、完了後にCtrl+Endをおしてください';
return;
}
if(template_list == null || template_list == ""){
template_list = localStorage.getItem('karasu_koteitag_list').split(",");
}else{
if(event.keyCode === 38){
selectTagUp();
}else if(event.keyCode === 40){
selectTagDown();
}
}
}
function setkoteitag() {
if(document.querySelector('.compose-form__tag-button .text-icon-button').getAttribute('title') == "固定タグが設定されています"){
const drawer = document.querySelector('.drawer');
const textarea = drawer.querySelector('.autosuggest-textarea__textarea');
const statusValue = String(textarea.value);
const koteitag = String(document.querySelector('.koteitag-input__input').value);
if(koteitag != ""){
setTextAreaText(statusValue + "\n" + koteitag + " ");
savekoteitag();
}
}
}
function setTextAreaText(value){
const drawer = document.querySelector('.drawer');
const textarea = drawer.querySelector('.autosuggest-textarea__textarea');
Object.getOwnPropertyDescriptor(Object.getPrototypeOf(textarea), 'value').set
.call(textarea, value);
textarea.dispatchEvent(new Event('input', { bubbles: true }));
}
function savekoteitag() {
localStorage.setItem('karasu_koteitag', String(document.querySelector('.koteitag-input__input').value));
}
function clicktagbutton(){
if (document.querySelector('.compose-form__tag-button .text-icon-button').getAttribute('title') == "固定タグが設定されていません") {
document.querySelector('.compose-form__tag-button .text-icon-button').setAttribute('title','固定タグが設定されています');
document.querySelector('.compose-form__tag-button .text-icon-button').classList.add('active');
document.querySelector('.koteitag-input__input').setAttribute('tabindex','1');
document.querySelector('.koteitag-input').classList.add('koteitag-input--visible');
document.querySelector('.koteitag-input__input').focus();
} else {
document.querySelector('.compose-form__tag-button .text-icon-button').setAttribute('title','固定タグが設定されていません');
document.querySelector('.compose-form__tag-button .text-icon-button').classList.remove('active');
document.querySelector('.koteitag-input__input').setAttribute('tabindex','-1');
document.querySelector('.koteitag-input').classList.remove('koteitag-input--visible');
document.querySelector('.autosuggest-textarea__textarea').focus();
}
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment