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.1
// @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 none
// ==/UserScript==
(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;
};
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 = null) => {
refs.buttons.style.display = 'none';
api('post', '/api/v1/statuses', {
status: refs.body.value,
spoiler_text: refs.cw.value,
visibility: visibility || (location.pathname.match(/\/\w+$/)[0] == '/home' ? 'unlisted' : 'public')
})
.then(resp => resp.ok ? clear() : Promise.reject(resp.statusText))
.catch(window.alert)
.then(() => refs.buttons.style.display = null);
};
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',
onkeypress: e => void(e.keyCode == 10 && e.ctrlKey && post())
}),
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);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment