293 lines
8.0 KiB
JavaScript
293 lines
8.0 KiB
JavaScript
/* SPDX-License-Identifier: Zlib
|
|
Copyright (C) 2022 smpl <smpl@slamkode.ml> */
|
|
|
|
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();
|
|
});
|