Add comments shortcode.
This commit is contained in:
parent
811fa02a41
commit
049822a72a
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,71 @@
|
|||
/* globals MastodonAPI */
|
||||
|
||||
function fetch_mastodon_api_comments(instance, status_id)
|
||||
{
|
||||
const root = document.getElementById("mastodon-api-comments_" + status_id);
|
||||
|
||||
let api = new MastodonAPI(
|
||||
{
|
||||
instance: "https://" + instance,
|
||||
api_user_token: ""
|
||||
});
|
||||
|
||||
// Get the URL of the status and write the intro.
|
||||
api.get("statuses/" + status_id, function(data)
|
||||
{
|
||||
root.appendChild(comments_intro(data.url));
|
||||
});
|
||||
|
||||
// Get all the replies to the status and write them to the page.
|
||||
api.get("statuses/" + status_id + "/context", function(data)
|
||||
{
|
||||
write_comments(root, data);
|
||||
});
|
||||
}
|
||||
|
||||
function comments_intro(url)
|
||||
{
|
||||
const p = document.createElement("p");
|
||||
const a = document.createElement("a");
|
||||
p.appendChild(document.createTextNode("You can "));
|
||||
p.setAttribute("class", "mastodon-api-comment-intro");
|
||||
a.setAttribute("href", url);
|
||||
a.appendChild(
|
||||
document.createTextNode("comment on this post in the Fediverse"));
|
||||
p.appendChild(a);
|
||||
p.appendChild(document.createTextNode("."));
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
function write_comments(root, data)
|
||||
{
|
||||
for (const status of data.descendants)
|
||||
{
|
||||
let content = status.content;
|
||||
for (const emoji of status.emojis)
|
||||
{
|
||||
content = content.replace(
|
||||
':' + emoji.shortcode + ':',
|
||||
'<img style="height: 1em;" src="' + emoji.url + '">');
|
||||
}
|
||||
|
||||
const p = document.createElement("p");
|
||||
p.setAttribute("class", "mastodon-api-comment");
|
||||
p.appendChild(author_html(status.account));
|
||||
p.innerHTML += content;
|
||||
root.appendChild(p);
|
||||
}
|
||||
}
|
||||
|
||||
function author_html(account)
|
||||
{
|
||||
const p = document.createElement("p");
|
||||
p.setAttribute("class", "mastodon-api-comment-author");
|
||||
const strong = document.createElement("strong");
|
||||
strong.appendChild(document.createTextNode(account.display_name));
|
||||
p.appendChild(strong);
|
||||
p.appendChild(document.createTextNode(" (" + account.acct + ") wrote:"));
|
||||
return p;
|
||||
}
|
|
@ -0,0 +1,223 @@
|
|||
// mastodon javascript lib
|
||||
// by @kirschn@pleasehug.me 2017
|
||||
// no fucking copyright
|
||||
// do whatever you want with it
|
||||
// but please don't hurt it (and keep this header)
|
||||
|
||||
|
||||
var MastodonAPI = function (config) {
|
||||
var apiBase = config.instance + "/api/v1/";
|
||||
|
||||
function checkArgs(args) {
|
||||
var checkedArgs;
|
||||
if (typeof args[1] === "function") {
|
||||
checkedArgs = { data: {}, callback: args[1] };
|
||||
} else {
|
||||
checkedArgs = { data: args[1], callback: args[2] };
|
||||
}
|
||||
|
||||
return checkedArgs;
|
||||
}
|
||||
|
||||
function addAuthorizationHeader(headers, token) {
|
||||
if (token) {
|
||||
headers.Authorization = "Bearer " + token;
|
||||
}
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
||||
function onAjaxSuccess(url, op, callback, logData) {
|
||||
return function (data, textStatus, xhr) {
|
||||
console.log("Successful " + op + " API request to " + url,
|
||||
", status: " + textStatus,
|
||||
", HTTP status: " + xhr.status,
|
||||
", data: " + (logData ? JSON.stringify(data) : "<skipped>"));
|
||||
|
||||
if (typeof callback !== "undefined") {
|
||||
callback(data, textStatus);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function onAjaxError(url, op) {
|
||||
return function (xhr, textStatus, errorThrown) {
|
||||
console.error("Failed " + op + " API request to " + url,
|
||||
", status: " + textStatus,
|
||||
", error: " + errorThrown,
|
||||
", HTTP status: " + xhr.status,
|
||||
", response JSON: " + JSON.stringify(xhr.responseJSON));
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
setConfig: function (key, value) {
|
||||
// modify initial config afterwards
|
||||
config[key] = value;
|
||||
},
|
||||
getConfig: function (key) {
|
||||
// get config key
|
||||
return config[key];
|
||||
},
|
||||
get: function (endpoint) {
|
||||
// for GET API calls
|
||||
// can be called with two or three parameters
|
||||
// endpoint, callback
|
||||
// or
|
||||
// endpoint, queryData, callback
|
||||
// where queryData is an object { paramname1: "paramvalue1", paramname2: paramvalue2 }
|
||||
|
||||
var args = checkArgs(arguments);
|
||||
var queryData = args.data;
|
||||
var callback = args.callback;
|
||||
var url = apiBase + endpoint;
|
||||
|
||||
// ajax function
|
||||
return $.ajax({
|
||||
url: url,
|
||||
type: "GET",
|
||||
data: queryData,
|
||||
headers: addAuthorizationHeader({}, config.api_user_token),
|
||||
success: onAjaxSuccess(url, "GET", callback, false),
|
||||
error: onAjaxError(url, "GET")
|
||||
});
|
||||
},
|
||||
patch: function (endpoint) {
|
||||
// for PATCH API calls
|
||||
var args = checkArgs(arguments);
|
||||
var postData = args.data;
|
||||
var callback = args.callback;
|
||||
var url = apiBase + endpoint;
|
||||
|
||||
return $.ajax({
|
||||
url: url,
|
||||
type: "PATCH",
|
||||
data: postData,
|
||||
headers: addAuthorizationHeader({}, config.api_user_token),
|
||||
success: onAjaxSuccess(url, "POST", callback, false),
|
||||
error: onAjaxError(url, "POST")
|
||||
});
|
||||
},
|
||||
post: function (endpoint) {
|
||||
// for POST API calls
|
||||
var args = checkArgs(arguments);
|
||||
var postData = args.data;
|
||||
var callback = args.callback;
|
||||
var url = apiBase + endpoint;
|
||||
|
||||
return $.ajax({
|
||||
url: url,
|
||||
type: "POST",
|
||||
data: postData,
|
||||
headers: addAuthorizationHeader({}, config.api_user_token),
|
||||
success: onAjaxSuccess(url, "POST", callback, false),
|
||||
error: onAjaxError(url, "POST")
|
||||
});
|
||||
},
|
||||
postMedia: function (endpoint) {
|
||||
// for POST API calls
|
||||
var args = checkArgs(arguments);
|
||||
var postData = args.data;
|
||||
var callback = args.callback;
|
||||
var url = apiBase + endpoint;
|
||||
|
||||
return $.ajax({
|
||||
url: url,
|
||||
type: "POST",
|
||||
data: postData,
|
||||
contentType: false,
|
||||
processData: false,
|
||||
headers: addAuthorizationHeader({}, config.api_user_token),
|
||||
success: onAjaxSuccess(url, "POST MEDIA", callback, false),
|
||||
error: onAjaxError(url, "POST MEDIA")
|
||||
});
|
||||
},
|
||||
delete: function (endpoint, callback) {
|
||||
// for DELETE API calls.
|
||||
var url = apiBase + endpoint;
|
||||
return $.ajax({
|
||||
url: url,
|
||||
type: "DELETE",
|
||||
headers: addAuthorizationHeader({}, config.api_user_token),
|
||||
success: onAjaxSuccess(url, "DELETE", callback, false),
|
||||
error: onAjaxError(url, "DELETE")
|
||||
});
|
||||
},
|
||||
stream: function (streamType, onData) {
|
||||
// Event Stream Support
|
||||
// websocket streaming is undocumented. i had to reverse engineer the fucking web client.
|
||||
// streamType is either
|
||||
// user for your local home TL and notifications
|
||||
// public for your federated TL
|
||||
// public:local for your home TL
|
||||
// hashtag&tag=fuckdonaldtrump for the stream of #fuckdonaldtrump
|
||||
// callback gets called whenever new data ist recieved
|
||||
// callback { event: (eventtype), payload: {mastodon object as described in the api docs} }
|
||||
// eventtype could be notification (=notification) or update (= new toot in TL)
|
||||
var es = new WebSocket("wss://" + apiBase.substr(8)
|
||||
+ "streaming?access_token=" + config.api_user_token + "&stream=" + streamType);
|
||||
var listener = function (event) {
|
||||
console.log("Got Data from Stream " + streamType);
|
||||
event = JSON.parse(event.data);
|
||||
event.payload = JSON.parse(event.payload);
|
||||
onData(event);
|
||||
};
|
||||
es.onmessage = listener;
|
||||
},
|
||||
registerApplication: function (client_name, redirect_uri, scopes, website, callback) {
|
||||
// register a new application
|
||||
|
||||
// OAuth Auth flow:
|
||||
// First register the application
|
||||
// 2) get a access code from a user (using the link, generation function below!)
|
||||
// 3) insert the data you got from the application and the code from the user into
|
||||
// getAccessTokenFromAuthCode. Note: scopes has to be an array, every time!
|
||||
// For example ["read", "write"]
|
||||
|
||||
// determine which parameters we got
|
||||
if (website === null) {
|
||||
website = "";
|
||||
}
|
||||
// build scope array to string for the api request
|
||||
if (typeof scopes !== "string") {
|
||||
scopes = scopes.join(" ");
|
||||
}
|
||||
var url = apiBase + "apps";
|
||||
return $.ajax({
|
||||
url: url,
|
||||
type: "POST",
|
||||
data: {
|
||||
client_name: client_name,
|
||||
redirect_uris: redirect_uri,
|
||||
scopes: scopes,
|
||||
website: website
|
||||
},
|
||||
success: onAjaxSuccess(url, "REGISTER", callback, true),
|
||||
error: onAjaxError(url, "REGISTER")
|
||||
});
|
||||
},
|
||||
generateAuthLink: function (client_id, redirect_uri, responseType, scopes) {
|
||||
return config.instance + "/oauth/authorize?client_id=" + client_id + "&redirect_uri=" + redirect_uri +
|
||||
"&response_type=" + responseType + "&scope=" + scopes.join("+");
|
||||
},
|
||||
getAccessTokenFromAuthCode: function (client_id, client_secret, redirect_uri, code, callback) {
|
||||
var url = config.instance + "/oauth/token";
|
||||
return $.ajax({
|
||||
url: url,
|
||||
type: "POST",
|
||||
data: {
|
||||
client_id: client_id,
|
||||
client_secret: client_secret,
|
||||
redirect_uri: redirect_uri,
|
||||
grant_type: "authorization_code",
|
||||
code: code
|
||||
},
|
||||
success: onAjaxSuccess(url, "TOKEN", callback, true),
|
||||
error: onAjaxError(url, "TOKEN")
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
// node.js
|
||||
if (typeof module !== "undefined") { module.exports = MastodonAPI; }
|
|
@ -0,0 +1,3 @@
|
|||
<script type="application/javascript" src="/scripts/jquery-3.4.1.min.js"></script>
|
||||
<script type="application/javascript" src="/scripts/mastodon.js"></script>
|
||||
<script type="application/javascript" src="/scripts/mastodon-api-comments.js"></script>
|
|
@ -0,0 +1,8 @@
|
|||
{{ $instance := .Get "instance" | default "false" }}
|
||||
{{ $status_id := .Get "status_id" | default "false" }}
|
||||
|
||||
{{ partial "mastodon-api-comments-scripts.html" . }}
|
||||
<p id="mastodon-api-comments_{{ $status_id }}" class="mastodon-api-comments"></p>
|
||||
<script type="application/javascript">
|
||||
fetch_mastodon_api_comments("{{ $instance }}", "{{ $status_id }}");
|
||||
</script>
|
|
@ -73,6 +73,10 @@ for file in style.css style-compat.css; do
|
|||
sed -i 's/$/.right{float:right}/' tastytea/static/assets/${file}
|
||||
sed -i 's/$/.left{float:left}/' tastytea/static/assets/${file}
|
||||
|
||||
sed -i 's/$/.mastodon-api-comment{margin-left: 1em;border:0.1em solid black;padding:0.1em 1em;}/' tastytea/static/assets/${file}
|
||||
sed -i 's/$/.mastodon-api-comment:nth-child(even){background-color:#0402}/' tastytea/static/assets/${file}
|
||||
sed -i 's/$/.mastodon-api-comment:nth-child(odd){background-color:#2402}/' tastytea/static/assets/${file}
|
||||
|
||||
# Make CSS more readable
|
||||
sed -i 's/}/}\n/g' tastytea/static/assets/${file}
|
||||
sed -i 's/{/ {/g' tastytea/static/assets/${file}
|
||||
|
|
|
@ -301,3 +301,6 @@ div.tip td.icon {color:var(--blue)}
|
|||
div.important td.icon {color:var(--yellow)}
|
||||
.right {float:right}
|
||||
.left {float:left}
|
||||
.mastodon-api-comment {margin-left: 1em; border:0.1em solid black; padding:0.1em 1em; }
|
||||
.mastodon-api-comment:nth-child(even) {background-color:#0402}
|
||||
.mastodon-api-comment:nth-child(odd) {background-color:#2402}
|
||||
|
|
|
@ -334,3 +334,6 @@ div.tip td.icon {color:var(--blue)}
|
|||
div.important td.icon {color:var(--yellow)}
|
||||
.right {float:right}
|
||||
.left {float:left}
|
||||
.mastodon-api-comment {margin-left: 1em; border:0.1em solid black; padding:0.1em 1em; }
|
||||
.mastodon-api-comment:nth-child(even) {background-color:#0402}
|
||||
.mastodon-api-comment:nth-child(odd) {background-color:#2402}
|
||||
|
|
Loading…
Reference in New Issue