Last active
March 31, 2023 19:12
-
-
Save saschanaz/701908eb329af5991061f8813b5bf4bc to your computer and use it in GitHub Desktop.
Mastodon redirector (Click the "Raw" button)
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 Mastodon Redirector | |
// @namespace http://saschanaz.github.io/ | |
// @version 0.1.11 | |
// @description Redirects to your home server when applicable | |
// @author Kagami Rosylight | |
// @match https://*/* | |
// @icon https://mastodon.social/favicon.ico | |
// @grant GM_xmlhttpRequest | |
// @grant GM_registerMenuCommand | |
// @grant GM_getValue | |
// @grant GM_setValue | |
// @run-at document-end | |
// @updateURL https://gist.github.com/saschanaz/701908eb329af5991061f8813b5bf4bc/raw/mastodon-redirector.user.js | |
// @downloadURL https://gist.github.com/saschanaz/701908eb329af5991061f8813b5bf4bc/raw/mastodon-redirector.user.js | |
// @supportURL https://gist.github.com/saschanaz/701908eb329af5991061f8813b5bf4bc | |
// ==/UserScript== | |
(() => { | |
'use strict'; | |
const homeServers = GM_getValue("homeServers", ["https://mozilla.social"]); | |
GM_registerMenuCommand("Set home servers", () => { | |
const dialog = createDialog(` | |
<form style="padding: 15px;"> | |
Type home servers below, line by line. | |
<p> | |
<textarea | |
id="saschanaz-redirector-textarea" | |
placeholder="Example:\nhttps://fosstodon.org/\nhttps://mastodon.social/" | |
style="width: 100%; font-size: 0.8em; font-family: sans-serif;" | |
rows="3" | |
></textarea> | |
</p> | |
<button id="saschanaz-redirector-button" type="button">Save</button> | |
</form> | |
`); | |
const button = dialog.querySelector("#saschanaz-redirector-button"); | |
const textarea = dialog.querySelector("#saschanaz-redirector-textarea"); | |
textarea.value = homeServers.join("\n"); | |
button.addEventListener("click", ev => { | |
const servers = textarea.value.split("\n"); | |
GM_setValue("homeServers", servers); | |
dialog.close(); | |
}); | |
button.focus({ focusVisible: false }); | |
}); | |
if (homeServers.includes(new URL(location.href).origin)) { | |
return; | |
} | |
const link = document.querySelector("link[rel=alternate][type='application/activity+json']"); | |
if (!link) { | |
return; | |
} | |
popover(); | |
function resolve(server) { | |
const url = new URL("api/v2/search", server); | |
url.searchParams.set("q", link.href); | |
url.searchParams.set("resolve", "true"); | |
GM_xmlhttpRequest({ | |
method: "GET", | |
url: url.toString(), | |
headers: { | |
"Content-Type": "application/json" | |
}, | |
onload: function(response) { | |
const body = JSON.parse(response.response); | |
if (body.accounts[0]) { | |
location.href = new URL(`@${body.accounts[0].acct}`, server); | |
} else if (body.statuses[0]) { | |
location.href = new URL(`@${body.statuses[0].account.acct}/${body.statuses[0].id}`, server); | |
} | |
}, | |
}); | |
} | |
function popover() { | |
// TODO: try popover when implemented | |
const dialog = createDialog(` | |
<form id="saschanaz-redirector-form" style="padding: 15px;"> | |
Redirect to: | |
<p id="saschanaz-redirector-list" style="margin: 1em 0; display: flex; flex-direction: column;"></p> | |
<button id="saschanaz-redirector-button" type="button">Redirect</button> | |
</form> | |
`); | |
const servers = homeServers.map(server => { | |
return document.createRange().createContextualFragment(` | |
<label><input type="radio" name="server" value="${server}"> ${new URL(server).hostname}</label> | |
`).children[0]; | |
}); | |
dialog.querySelector("#saschanaz-redirector-list").append(...servers); | |
const button = dialog.querySelector("#saschanaz-redirector-button"); | |
const form = dialog.querySelector("#saschanaz-redirector-form"); | |
if (form.elements.server) { | |
(form.elements.server[0] ?? form.elements.server).checked = true; | |
} | |
button.addEventListener("click", ev => { | |
const homeServer = form.elements.server.value; | |
if (!homeServer) { | |
return; | |
} | |
button.disabled = true; | |
resolve(homeServer); | |
}); | |
button.focus({ focusVisible: false }); | |
} | |
function createDialog(content) { | |
const dialog = document.createElement("dialog"); | |
dialog.style = "background: #fff8; color: #444; backdrop-filter: blur(15px); padding: 0; border: 0; border-radius: 15px; top: 100px; bottom: initial; font-size: 20px; font-family: sans-serif; text-shadow: white 0 0 10px; line-height: 1.2em;"; | |
dialog.innerHTML = content; | |
dialog.addEventListener("click", ev => { | |
if (ev.target === dialog) { | |
dialog.close(); | |
} | |
}); | |
dialog.addEventListener("close", ev => { | |
dialog.remove(); | |
}); | |
document.body.append(dialog); | |
dialog.showModal(); | |
return dialog; | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment