Last active
January 26, 2018 07:07
-
-
Save unarist/6579b9e78e842c03b734560c844c717d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Akane Gallery Ex | |
// @namespace https://github.com/unarist/ | |
// @version 0.1 | |
// @author unarist | |
// @match https://akane.blue/gallery/ | |
// @downloadURL https://gist.github.com/unarist/6579b9e78e842c03b734560c844c717d/raw/akane-gallery-ex.user.js | |
// @grant none | |
// ==/UserScript== | |
/* | |
todo: | |
* login via OAuth | |
* hide buttons while no token is specified | |
*/ | |
(function() { | |
'use strict'; | |
const tag = (name, props = {}, children = []) => { | |
const e = Object.assign(document.createElement(name), props); | |
if (typeof props.style === "object") Object.assign(e.style, props.style); | |
children.forEach(c => e.appendChild(c)); | |
return e; | |
}; | |
const textNode = t => document.createTextNode(t); | |
let refs = {}; | |
let cache = {}; | |
const getToken = () => new Promise((resolve, reject) => refs.token.value ? resolve(refs.token.value) : reject('no token')); | |
const api = (path, method = 'get') => | |
getToken() | |
.then(token => fetch(`https://${refs.domain.value}${path}`, { method, headers: { authorization: 'Bearer ' + token } })) | |
.then(resp => { if (!resp.ok) throw new Error(new URL(resp.url).pathname + ' ' + resp.status); return resp.json(); }); | |
const searchStatus = url => cache[[refs.domain.value,url]] ? Promise.resolve(cache[[refs.domain.value,url]]) : api('/api/v1/search?q=' + url).then(json => json.statuses[0]), | |
doFavourite = status => api('/api/v1/statuses/' + status.id + '/favourite', 'post'), | |
doReblog = status => api('/api/v1/statuses/' + status.id + '/reblog', 'post'); | |
document.head.appendChild(tag('style', { textContent: ` | |
/* icomoon icon-star-full */ | |
.gallery-ex-favourite { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cpath fill='red' d='M32 12.408l-11.056-1.607L16 .783l-4.944 10.018L0 12.408l8 7.798-1.889 11.011L16 26.018l9.889 5.199L24 20.206l8-7.798z'/%3E%3C/svg%3E"); } | |
/* icomoon icon-loop */ | |
.gallery-ex-reblog { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cpath fill='red' d='M4 10h20v6l8-8-8-8v6H0v12h4zm24 12H8v-6l-8 8 8 8v-6h24V14h-4z'/%3E%3C/svg%3E"); } | |
.gallery-ex-favourite, .gallery-ex-reblog { display: inline-block; width: 1em; height: 1em; margin-right: .2em; background-size: contain; filter: grayscale(1) brightness(2); cursor: pointer; } | |
.gallery-ex-favourite:hover, .gallery-ex-reblog:hover { opacity: 0.8; } | |
.gallery-ex-favourite.active { filter: hue-rotate(70deg) saturate(1.1) brightness(2.2); /*color: #2b90d9;*/ } | |
.gallery-ex-reblog.active { filter: hue-rotate(205deg) saturate(0.7) brightness(1.5); /*color: #ca8f04;*/ } | |
` })); | |
document.querySelector('.container > p').appendChild( | |
tag('div', {}, [ | |
tag('label', {}, [ textNode('domain: '), refs.domain = tag('input', { value: 'mstdn.maud.io' }) ]), | |
tag('label', {}, [ textNode('access_token: '), refs.token = tag('input') ]), | |
]) | |
); | |
let i = 0; | |
for (const card of document.querySelectorAll('.card')) { | |
const posturl = card.querySelector('.card-text a').href; | |
const cardText = card.querySelector('.card-text'); | |
const favButton = cardText.appendChild(tag('i', { | |
className: 'gallery-ex-favourite', | |
onclick: e => searchStatus(posturl).then(doFavourite).then(() => e.target.classList.add('active')) | |
})); | |
const reblogButton = cardText.appendChild(tag('i', { | |
className: 'gallery-ex-reblog', | |
onclick: e => searchStatus(posturl).then(doReblog).then(() => e.target.classList.add('active')) | |
})); | |
let synced = false; | |
let mouseover = false; | |
card.addEventListener('mouseover', () => (mouseover = true, synced || setTimeout(() => { | |
if (!mouseover) return; | |
searchStatus(posturl).then(status => { | |
if (status.favourited) favButton.classList.add('active'); | |
if (status.reblogged) reblogButton.classList.add('active'); | |
synced = true; | |
}); | |
}, 200))); | |
card.addEventListener('mouseleave', () => mouseover = false); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment