Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Mastodon - Mobile Composer
// ==UserScript==
// @name Mastodon - Mobile Composer
// @namespace https://github.com/unarist/
// @version 0.6
// @description add composer to page bottom
// @author unarist
// @downloadURL https://gist.github.com/unarist/08f56c49986d3b1775fe88bc918cac50/raw/mastodon-mobile-composer.user.js
// @match https://*/web/*
// @grant GM_setValue
// @grant GM_getValue
// ==/UserScript==
/*
v0.5から、現在のカラムに関わらずpublicがデフォルト、Shift押下でunlistedになっています。
元の挙動に戻したい場合はalwaysPublicを無効化してください。
F12で開発者コンソールを開いて、こう、▼や(...)をぽちぽちクリックして展開していくと設定ができます。わかりにくいね。
https://user-images.githubusercontent.com/705555/30266537-a75cf660-971a-11e7-85a3-896222578c60.png
*/
(function() {
'use strict';
const tag = (name, props = {}, children = '') => {
const e = Object.assign(document.createElement(name), props);
Object.assign(e.style, props.style);
if (children.forEach) children.forEach(c => e.appendChild(c));
else e.textContent = children;
return e;
};
// migration
if (GM_getValue('alwaysPublic') === undefined)
GM_setValue('alwaysPublic', false);
const config = {
get alwaysPublic() { return GM_getValue('alwaysPublic', true); },
set alwaysPublic(v) { GM_setValue('alwaysPublic', v); }
};
document.head.appendChild(tag('style', {}, `
@media (min-width: 1025px) {
.mobile-composer { display: none }
}
.mobile-composer {
position: unset;
height: auto;
flex: 0 0 auto;
padding: 5px;
}
.mobile-composer .spoiler-input__input,
.mobile-composer .autosuggest-textarea__textarea {
margin-bottom: 5px;
font-size: 14px;
padding: 0.5em;
border-radius: 4px;
}
.mobile-composer .autosuggest-textarea__textarea {
min-height: unset;
height: 5em !important;
}
.mobile-composer__buttons {
display: flex;
justify-content: flex-end;
}
.mobile-composer__button {
padding: 0 1em;
height: 2em;
line-height: 2em;
margin-left: 5px;
}
`));
const refs = {};
const button = (t, onclick) =>
tag('button', {
className: 'button mobile-composer__button',
onclick
}, t);
const target = document.querySelector('.ui');
const initialState = JSON.parse(document.querySelector('#initial-state').textContent);
const api = (method, url, body) =>
fetch(url, {
method,
headers: {
'Authorization': 'Bearer ' + initialState.meta.access_token,
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
const clear = () => {
[refs.cw, refs.body].forEach(e => e.value = '');
refs.body.focus();
};
const post = (visibility) => {
if (!refs.body.value) return;
refs.buttons.style.display = 'none';
api('post', '/api/v1/statuses', {
status: refs.body.value,
spoiler_text: refs.cw.value,
visibility: visibility
})
.then(resp => resp.ok ? clear() : Promise.reject(resp.statusText))
.catch(window.alert)
.then(() => refs.buttons.style.display = null);
};
const getVisibility = (alternative = false) =>
config.alwaysPublic ?
(alternative ? 'unlisted' : 'public') :
(!!location.pathname.match(/\/home$/) ^ alternative ? 'unlisted' : 'public');
refs.root = tag('div', { className: 'drawer__inner mobile-composer' }, [
refs.cw = tag('input', {
type: 'text',
placeholder: 'CW',
className: 'spoiler-input__input'
}),
refs.body = tag('textarea', {
className: 'autosuggest-textarea__textarea',
onkeydown: e => void(e.keyCode == 13 && e.ctrlKey && post(getVisibility(e.shiftKey))),
oninput: e => void(refs.body.style.backgroundColor = (e.target.value.length > 500 ? 'pink' : null))
}),
refs.buttons = tag('div', { className: 'mobile-composer__buttons' }, [
button('×', clear),
button('DM', post.bind(null, 'direct')),
button('非公開', post.bind(null, 'private')),
button('未収載', post.bind(null, 'unlisted')),
button('公開', post.bind(null, 'public'))
])
]);
target.appendChild(refs.root);
const showSettings = () => {
console.log('MobileComposer settings:');
console.log({
get alwaysPublic() {
return {
current: config.alwaysPublic,
get enable() { config.alwaysPublic = true; },
get disable() { config.alwaysPublic = false; }
};
},
get showSettingsAgain() { showSettings(); }
});
};
showSettings();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment