From c7b9fc5d7fca45fb147d028500a2bb001d12050a Mon Sep 17 00:00:00 2001 From: smpl Date: Tue, 3 May 2022 03:34:37 +0200 Subject: [PATCH] ENERGIZE! --- buttons/mastodon-follow-dark.svg | 24 + buttons/mastodon-follow-light.svg | 24 + buttons/mastodon-share-dark.svg | 38 ++ buttons/mastodon-share-light.svg | 38 ++ embed/index.html | 754 ++++++++++++++++++++++++++++++ mastodon-interact.js | 292 ++++++++++++ 6 files changed, 1170 insertions(+) create mode 100644 buttons/mastodon-follow-dark.svg create mode 100644 buttons/mastodon-follow-light.svg create mode 100644 buttons/mastodon-share-dark.svg create mode 100644 buttons/mastodon-share-light.svg create mode 100644 embed/index.html create mode 100644 mastodon-interact.js diff --git a/buttons/mastodon-follow-dark.svg b/buttons/mastodon-follow-dark.svg new file mode 100644 index 0000000..43b9316 --- /dev/null +++ b/buttons/mastodon-follow-dark.svg @@ -0,0 +1,24 @@ + + + + + + + diff --git a/buttons/mastodon-follow-light.svg b/buttons/mastodon-follow-light.svg new file mode 100644 index 0000000..eb32a59 --- /dev/null +++ b/buttons/mastodon-follow-light.svg @@ -0,0 +1,24 @@ + + + + + + + diff --git a/buttons/mastodon-share-dark.svg b/buttons/mastodon-share-dark.svg new file mode 100644 index 0000000..8fa3698 --- /dev/null +++ b/buttons/mastodon-share-dark.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + diff --git a/buttons/mastodon-share-light.svg b/buttons/mastodon-share-light.svg new file mode 100644 index 0000000..d1a411e --- /dev/null +++ b/buttons/mastodon-share-light.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + diff --git a/embed/index.html b/embed/index.html new file mode 100644 index 0000000..004f75d --- /dev/null +++ b/embed/index.html @@ -0,0 +1,754 @@ + + + + + + + Mastodon Interact Widget | Embed + + + + + + + + + + + + +
+

Mastodon Interact embedding

+ +

Enter your Mastodon account, pick your settings and click on + generate. This page will generate a script to be embedded in + the <head> section of your page and two HTML + snippets you can insert where you want each button on your + page. Also remember to download the icon files for the buttons + unless you supply your own.

+ +

You can easily tweak the script after download. The settings + and strings are in the beginning of the script. In the HTML + snippets you can modify the size of the button in the + style attribute of the <img> tag, which + is set to height: 32px and change the src + attribute to adjust the path to the button image. You can also + adjust the fallback links, but you can't remove the + <a> tags.

+
+ + + + + + + + + + + + + +
Mastodon handle + +
Language + +
Theme + +
+ +
+ +
+ +
+

Script

+
Download script
+ +

Follow Embed

+
Download icon
+ +

Share Embed

+
Download icon
+ +
+
+

Copyright (C) 2022 smpl <smpl@slamkode.ml>

+ Source code +
+ + diff --git a/mastodon-interact.js b/mastodon-interact.js new file mode 100644 index 0000000..7c80d8e --- /dev/null +++ b/mastodon-interact.js @@ -0,0 +1,292 @@ +/* SPDX-License-Identifier: Zlib + Copyright (C) 2022 smpl */ + +const MastodonInteract = function() { + settings = { + "account": "superman@localhost", + "portal": "https://localhost/users/superman/remote_follow", + "width": "256px", + "theme": "light" + }; + strings = { + "share": { + "title": "Enter your Mastodon handle", + "button": "Share", + "text": window.location + }, + "follow": { + "title": "Enter your Mastodon handle", + "button": "Follow" + }, + "common": { + "create": "Create account", + "create_url": "https://joinmastodon.org/communities", + "error": { + "handle": "Invalid handle" + } + } + }; + + var widget = { + style: null, + dialogs: { + follow: null, + share: null + }, + buttons: { + follow: null, + share: null + } + }; + var CreateStyle = function() { + widget.style = document.createElement('style'); + widget.style.id = "mastodon-widget-style"; + + widget.style.innerHTML = + ".mastodon-widget-container {" + +// "display: block;" + + "z-index: 1;" + + "border: 0;" + + "border-radius: 5px;" + + "position: absolute;" + + "top:110%;" + + "left: 0;" + + "width: " + settings.width + ";" + + 'font-family: "Roboto",Roboto,sans-serif;' + + "margin: 0 auto;" + + "padding: 20px;" + + "font-weight: 400;" + + "font-size: 13px;" + + "line-height: 18px;" + + "}" + + ".mastodon-widget-container.light {" + + "background: #d9e1e8;" + + "color: #282c37;" + + "}" + + ".mastodon-widget-container.dark {" + + "background: #282c37;" + + "color: #9baec8;" + + "}" + + ".mastodon-widget-title {" + + "text-align: center;" + + "font-size: 18px;" + + "font-weight: 500;" + + "margin: 0;" + + "}" + + ".mastodon-widget-title.light {" + + "color: #282c37;" + + "}" + + ".mastodon-widget-title.dark {" + + "color: #fff;" + + "}" + + ".mastodon-widget-input {" + + "border: 0;" + + "border-radius: 4px;" + + "margin-top: 20px;" + + "padding: 10px;" + + "width: 100%;" + + "box-sizing: border-box;" + + "font-family: inherit;" + + "font-weight: 500;" + + "font-size: 18px;" + + "}" + + ".mastodon-widget-input.light {" + + "background: #f9fafb;" + + "color: #000;" + + "}" + + ".mastodon-widget-input.dark {" + + "background: #131419;" + + "color: #fff;" + + "}" + + ".mastodon-widget-input::placeholder {" + + "color: #c83737;" + + "}" + + ".mastodon-widget-button {" + + "display: block;" + + "width: 100%;" + + "border: 0;" + + "border-radius: 4px;" + + "margin-right: 10px;" + + "margin-top: 20px;" + + "padding: 10px;" + + "background: #2b90d9;" + + "font-family: inherit;" + + "font-weight: 500;" + + "font-size: 18px;" + + "color: #fff;" + + "line-height: inherit;" + + "text-align: center;" + + "text-transform: uppercase;" + + "box-sizing: border-box;" + + "cursor: pointer;" + + "}"; + document.head.appendChild(widget.style); + }; + var CreateDialog = function(o) { + var t; + if(o === widget.buttons.follow) + t = strings.follow; + else if(o === widget.buttons.share) + t = strings.share; + + obj = document.createElement('div'); + obj.setAttribute('class', 'mastodon-widget-container ' + settings.theme); + + var title = document.createElement('p'); + title.setAttribute('class', 'mastodon-widget-title ' + settings.theme); + title.innerHTML = t.title; + + var input = document.createElement('input'); + input.setAttribute('name', 'mastodon-handle'); + input.setAttribute('type', 'text'); + input.setAttribute('class', 'mastodon-widget-input ' + settings.theme); + + var button = document.createElement('button'); + button.innerHTML = t.button; + button.setAttribute('class', 'mastodon-widget-button'); + button.onclick = cbAction; + + var create_div = document.createElement('div'); + create_div.style = "text-align: right;"; + var create_a = document.createElement('a'); + create_a.setAttribute('href', strings.common.create_url); + create_a.innerHTML = strings.common.create; + create_div.appendChild(create_a); + + obj.appendChild(title); + obj.appendChild(input); + obj.appendChild(button); + obj.appendChild(create_div); + return obj; + }; + var cbCreateDialog = function(e) { + var dialog; + if(widget.style == null) + CreateStyle(); + dialog = CreateDialog(e.target); + e.target.parentElement.appendChild(dialog); + e.target.onclick = cbToggle; + if(widget.buttons.share && e.target === widget.buttons.share) { + widget.dialogs.share = dialog; + } else if(widget.buttons.follow && e.target === widget.buttons.follow) { + widget.dialogs.follow = dialog; + } + window.addEventListener('click', cbHide, true); + }; + var cbHide = function(e) { + if(widget.dialogs.follow) { + if( e.target === widget.buttons.follow || + e.target === widget.dialogs.follow || + e.target.parentNode === widget.dialogs.follow ) { + return; + } + widget.dialogs.follow.style.display = 'none'; + } + if(widget.dialogs.share) { + if( e.target === widget.buttons.share || + e.target === widget.dialogs.share || + e.target.parentNode === widget.dialogs.share ) { + return; + } + widget.dialogs.share.style.display = 'none'; + } + window.removeEventListener('click', cbHide, true); + } + var cbToggle = function(e) { + if(e.target === widget.buttons.follow) { + if(widget.dialogs.follow.style.display === 'none') { + widget.dialogs.follow.style.display = ''; + if(widget.dialogs.share) + widget.dialogs.share.style.display = 'none'; + window.addEventListener('click', cbHide, true); + } else { + widget.dialogs.follow.style.display = 'none'; + } + } else if(e.target === widget.buttons.share) { + if(widget.dialogs.share.style.display === 'none') { + widget.dialogs.share.style.display = ''; + if(widget.dialogs.follow) + widget.dialogs.follow.style.display = 'none'; + window.addEventListener('click', cbHide, true); + } else { + widget.dialogs.share.style.display = 'none'; + } + } + }; + var cbAction = function(e) { + var input = e.target.parentNode.querySelector('input[name="mastodon-handle"]'); + var handle = input.value; + + // remove any initial @ + if(handle.charAt(0) == '@') { + handle = handle.substring(1); + } + + // split into nick and host + var uriparts = handle.split('@'); + if(uriparts.length < 2) { + input.value = ''; + input.setAttribute('placeholder', strings.common.error.handle); + return; + } + + if(e.target.parentNode === widget.dialogs.follow) { + var oReq = new XMLHttpRequest(); + oReq.addEventListener("loadend", cbQueryResponse); + oReq.open("GET", "https://" + uriparts[1] + "/.well-known/webfinger?resource=acct:" + encodeURIComponent(handle)); + oReq.send(); + } else if(e.target.parentNode === widget.dialogs.share) { + window.location = "https://" + uriparts[1] + "/share?text=" + encodeURIComponent(strings.share.text); + } + }; + // follow only + var cbQueryResponse = function(e) { + var data; + if (e.readyState === e.DONE) { + if (e.status === 200) { + try { + data = JSON.parse(e.responseText); + } catch { + window.location = settings.portal; + return; + } + + data.links.forEach( function(l) { + if(l.rel === "http://ostatus.org/schema/1.0/subscribe") { + window.location = l.template.replace('{uri}', encodeURIComponent(settings.account)); + return; + } + }); + } + } + window.location = settings.portal; + return; + }; + + widget.buttons.follow = document.getElementById('mastodon-widget-follow'); + widget.buttons.share = document.getElementById('mastodon-widget-share'); + + if(widget.buttons.follow) { + widget.buttons.follow.onclick = cbCreateDialog; + widget.buttons.follow.style.cursor = "pointer"; + let a = widget.buttons.follow.parentNode; + let div = a.parentNode; + div.appendChild(widget.buttons.follow); + a.remove(); + } + if(widget.buttons.share) { + widget.buttons.share.onclick = cbCreateDialog; + widget.buttons.share.style.cursor = "pointer"; + let a = widget.buttons.share.parentNode; + let div = a.parentNode; + div.appendChild(widget.buttons.share); + a.remove(); + } + + return this; +}; + +var mastodon_widget; +window.addEventListener("load", function(e) { + mastodon_widget = MastodonInteract(); +});