// ==UserScript==
// @name Show all comments
// @version 1.2
// @match https://www.patreon.com/posts/*
// @grant none
// @icon https://c5.patreon.com/external/favicon/favicon-32x32.png
// @updateURL https://github.com/stepanhakobyan/custom-user-scripts/raw/master/Patreon/patreon-show-all-comments.user.js
// @downloadURL https://github.com/stepanhakobyan/custom-user-scripts/raw/master/Patreon/patreon-show-all-comments.user.js
// @homepageURL https://github.com/stepanhakobyan/custom-user-scripts/tree/master/Patreon
// ==/UserScript==
window.addEventListener("load", ()=> {
const wrapper = document.getElementById("renderPageContentWrapper");
const mainDiv = wrapper.firstChild;
const div = document.createElement("div");
mainDiv.prepend(div);
const allComments = document.createElement("div");
allComments.innerHTML = ""
+ ""
+ ""
+ "";
div.append(allComments);
const newScript = document.createElement("script");
newScript.textContent = showAllComments.toString()
+ showAllCommentsFlat.toString();
div.append(newScript);
});
function showAllComments(showInNewWindow) {
const loc = document.location.href;
const postId = loc.substring(loc.lastIndexOf("-")+1); //36881796
const longUrl = "https://www.patreon.com/api/posts/" + postId + "/comments"
+ "?include=commenter.campaign.null%2Ccommenter.flairs.campaign%2Cparent%2Cpost%2Cfirst_reply.commenter.campaign.null%2Cfirst_reply.parent%2Cfirst_reply.post%2Cexclude_replies%2Con_behalf_of_campaign.null%2Cfirst_reply.on_behalf_of_campaign.null"
+ "&fields[comment]=body%2Ccreated%2Cdeleted_at%2Cis_by_patron%2Cis_by_creator%2Cvote_sum%2Ccurrent_user_vote%2Creply_count"
+ "&fields[post]=comment_count"
+ "&fields[user]=image_url%2Cfull_name%2Curl"
+ "&fields[flair]=image_tiny_url%2Cname"
+ "&page[count]=10000"
+ "&sort=created"
+ "&json-api-use-default-includes=false"
+ "&json-api-version=1.0";
// const shortUrl = "https://www.patreon.com/api/posts/" + postId + "/comments?page[count]=1000&sort=created"
// + "&" + "json-api-use-default-includes=false"
// + "&" + "include=commenter.campaign.null%2Ccommenter.flairs.campaign.null%2Cparent%2Cpost%2Con_behalf_of_campaign.null";
//https://www.patreon.com/api/posts/36473589/comments?page[count]=10000&sort=created&json-api-use-default-includes=false&include=commenter.campaign.null%2Ccommenter.flairs.campaign.null%2Cparent%2Cpost%2Con_behalf_of_campaign.null
//https://www.patreon.com/api/posts/36881796/comments?page[count]=1000&sort=created&include=commenter.campaign.null%2Ccommenter.flairs.campaign.null%2Cparent%2Cpost%2Con_behalf_of_campaign.null&json-api-use-default-includes=false
//&include=commenter.campaign.null%2Ccommenter.flairs.campaign.null%2Cparent%2Cpost%2Con_behalf_of_campaign.null&
//replies
//https://www.patreon.com/api/comments/36574431/replies
//https://www.patreon.com/api/comments/36342081/replies?include=commenter.campaign.null%2Ccommenter.flairs.campaign.null%2Cparent%2Cpost%2Con_behalf_of_campaign.null&fields[comment]=body%2Ccreated%2Cdeleted_at%2Cis_by_patron%2Cis_by_creator%2Cvote_sum%2Ccurrent_user_vote&fields[flair]=image_tiny_url%2Cname&fields[post]=comment_count&fields[user]=image_url%2Cfull_name%2Curl&json-api-use-default-includes=false&json-api-version=1.0
//https://www.patreon.com/api/comments/36355620/replies?include=commenter.campaign.null%2Ccommenter.flairs.campaign.null%2Cparent%2Cpost%2Con_behalf_of_campaign.null&fields[comment]=body%2Ccreated%2Cdeleted_at%2Cis_by_patron%2Cis_by_creator%2Cvote_sum%2Ccurrent_user_vote&fields[flair]=image_tiny_url%2Cname&fields[post]=comment_count&fields[user]=image_url%2Cfull_name%2Curl&json-api-use-default-includes=false&json-api-version=1.0
//https://www.patreon.com/api/comments/36355620/replies
fetch(longUrl)
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(myJson);
let win = null
if (showInNewWindow) {
win = window.open("", "All Comments " + Math.random().toString());
} else {
win = window;
win.document.body.innerHTML = "";
}
if (win) {
const winHead = win.document.head;
let style = win.document.createElement("style");
style.innerText = "table, th, td { border: 1px solid lightgray; border-spacing: 0px; border-collapse: collapse; } "
+ "td { padding: 5px; vertical-align: top; } "
+ "#mainContainer { padding: 25px; } "
+ "a { text-decoration: none; font-weight: 700; color: black; } "
+ "a:hover { text-decoration: underline; } "
+ "html { font-family: sans-serif; } "
+ " "
+ "@media print { "
+ " #mainContainer { padding: 0px; }"
+ "} "
+ " ";
winHead.append(style);
let title = win.document.createElement("title");
title.innerText = "Show All Comments";
winHead.append(title);
const winBody = win.document.body;
const mainContainer = win.document.createElement("div");
mainContainer.id = "mainContainer";
winBody.append(mainContainer);
let table = win.document.createElement("table");
mainContainer.append(table);
let thead = win.document.createElement("thead");
table.append(thead);
let theadtr = win.document.createElement("tr");
thead.append(theadtr);
let th = win.document.createElement("th");
th.innerText = "type";
theadtr.append(th);
th = win.document.createElement("th");
th.innerText = "icon";
theadtr.append(th);
th = win.document.createElement("th");
th.innerText = "name";
theadtr.append(th);
th = win.document.createElement("th");
th.innerText = "comment";
theadtr.append(th);
th = win.document.createElement("th");
th.innerText = "date";
theadtr.append(th);
let tbody = win.document.createElement("tbody");
table.append(tbody);
const converterArea = win.document.createElement("textarea");
const convertHtml = (encodedText) => {
converterArea.innerHTML = encodedText;
return converterArea.value;
}
const repliedCommentIds = [];
const addRowDetails = (item, tbodytr, myJson, commentType) => {
let itemUser = null;
if (item.relationships.commenter.data.type == "user") {
for (let user of myJson.included) {
if (user.id == item.relationships.commenter.data.id && user.type == "user") {
itemUser = user;
break;
}
}
}
let td = win.document.createElement("td");
td.innerText = commentType;
tbodytr.append(td);
td = win.document.createElement("td");
if (itemUser == null) {
td.innerText = "icon";
} else {
const img = win.document.createElement("img");
img.src = itemUser.attributes.image_url;
img.width = 32;
img.height = 32;
td.append(img);
}
tbodytr.append(td);
td = win.document.createElement("td");
if (itemUser == null) {
td.innerText = "name";
} else {
const link = win.document.createElement("a");
link.href = itemUser.attributes.url;
link.innerText = itemUser.attributes.full_name;
td.append(link);
}
tbodytr.append(td);
td = win.document.createElement("td");
tbodytr.append(td);
let span = win.document.createElement("span");
span.innerText = convertHtml(item.attributes.body)
td.append(span);
td = win.document.createElement("td");
tbodytr.append(td);
td.innerText = (new Date(item.attributes.created)).toLocaleString();
};
for (let item of myJson.data) {
if (item.type == "comment") {
let tbodytr = win.document.createElement("tr");
tbodytr.id = "tr" + item.id;
tbody.append(tbodytr);
addRowDetails(item, tbodytr, myJson, "");
if (item.attributes.reply_count > 1) {
repliedCommentIds.push(item.id);
}
}
}
for (let item of myJson.included) {
if (item.type == "comment") {
if (!repliedCommentIds.includes(item.relationships.parent.data.id)) {
let tbodytr = win.document.createElement("tr");
tbodytr.id = "tr" + item.id;
let prevTr = win.document.getElementById("tr" + item.relationships.parent.data.id);
prevTr.parentNode.insertBefore(tbodytr, prevTr.nextSibling);
addRowDetails(item, tbodytr, myJson, "reply");
}
}
}
for (let id of repliedCommentIds) {
//console.log(id);
const replayLongUrl = "https://www.patreon.com/api/comments/" + id + "/replies"
+ "?include=commenter.campaign.null%2Ccommenter.flairs.campaign.null%2Cparent%2Cpost%2Con_behalf_of_campaign.null"
+ "&fields[comment]=body%2Ccreated%2Cdeleted_at%2Cis_by_patron%2Cis_by_creator%2Cvote_sum%2Ccurrent_user_vote"
+ "&fields[flair]=image_tiny_url%2Cname"
+ "&fields[post]=comment_count"
+ "&fields[user]=image_url%2Cfull_name%2Curl"
+ "&json-api-use-default-includes=false"
+ "&json-api-version=1.0";
fetch(replayLongUrl)
.then(function(replyResponse) {
return replyResponse.json();
})
.then(function(replyJson) {
console.log(replyJson);
for (let i = replyJson.data.length - 1; i >= 0; i--) {
let item = replyJson.data[i];
if (item.type == "comment") {
if (win.document.getElementById("tr" + item.id)) {
//reply is already in
} else {
let tbodytr = win.document.createElement("tr");
tbodytr.id = "tr" + item.id;
let prevTr = win.document.getElementById("tr" + item.relationships.parent.data.id);
prevTr.parentNode.insertBefore(tbodytr, prevTr.nextSibling);
addRowDetails(item, tbodytr, replyJson, "reply");
}
}
}
});
}
}
});
}
function showAllCommentsFlat(showInNewWindow) {
const loc = document.location.href;
const postId = loc.substring(loc.lastIndexOf("-")+1); //36881796
const longUrl = "https://www.patreon.com/api/posts/" + postId + "/comments"
+ "?include=commenter.campaign.null%2Ccommenter.flairs.campaign%2Cparent%2Cpost%2Cfirst_reply.commenter.campaign.null%2Cfirst_reply.parent%2Cfirst_reply.post%2Cexclude_replies%2Con_behalf_of_campaign.null%2Cfirst_reply.on_behalf_of_campaign.null"
+ "&fields[comment]=body%2Ccreated%2Cdeleted_at%2Cis_by_patron%2Cis_by_creator%2Cvote_sum%2Ccurrent_user_vote%2Creply_count"
+ "&fields[post]=comment_count"
+ "&fields[user]=image_url%2Cfull_name%2Curl"
+ "&fields[flair]=image_tiny_url%2Cname"
+ "&page[count]=10000"
+ "&sort=created"
+ "&json-api-use-default-includes=false"
+ "&json-api-version=1.0";
// const shortUrl = "https://www.patreon.com/api/posts/" + postId + "/comments?page[count]=1000&sort=created"
// + "&" + "json-api-use-default-includes=false"
// + "&" + "include=commenter.campaign.null%2Ccommenter.flairs.campaign.null%2Cparent%2Cpost%2Con_behalf_of_campaign.null";
//https://www.patreon.com/api/posts/36473589/comments?page[count]=10000&sort=created&json-api-use-default-includes=false&include=commenter.campaign.null%2Ccommenter.flairs.campaign.null%2Cparent%2Cpost%2Con_behalf_of_campaign.null
//https://www.patreon.com/api/posts/36881796/comments?page[count]=1000&sort=created&include=commenter.campaign.null%2Ccommenter.flairs.campaign.null%2Cparent%2Cpost%2Con_behalf_of_campaign.null&json-api-use-default-includes=false
//&include=commenter.campaign.null%2Ccommenter.flairs.campaign.null%2Cparent%2Cpost%2Con_behalf_of_campaign.null&
//replies
//https://www.patreon.com/api/comments/36574431/replies
//https://www.patreon.com/api/comments/36342081/replies?include=commenter.campaign.null%2Ccommenter.flairs.campaign.null%2Cparent%2Cpost%2Con_behalf_of_campaign.null&fields[comment]=body%2Ccreated%2Cdeleted_at%2Cis_by_patron%2Cis_by_creator%2Cvote_sum%2Ccurrent_user_vote&fields[flair]=image_tiny_url%2Cname&fields[post]=comment_count&fields[user]=image_url%2Cfull_name%2Curl&json-api-use-default-includes=false&json-api-version=1.0
//https://www.patreon.com/api/comments/36355620/replies?include=commenter.campaign.null%2Ccommenter.flairs.campaign.null%2Cparent%2Cpost%2Con_behalf_of_campaign.null&fields[comment]=body%2Ccreated%2Cdeleted_at%2Cis_by_patron%2Cis_by_creator%2Cvote_sum%2Ccurrent_user_vote&fields[flair]=image_tiny_url%2Cname&fields[post]=comment_count&fields[user]=image_url%2Cfull_name%2Curl&json-api-use-default-includes=false&json-api-version=1.0
//https://www.patreon.com/api/comments/36355620/replies
fetch(longUrl)
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(myJson);
let win = null
if (showInNewWindow) {
win = window.open("", "All Comments " + Math.random().toString());
} else {
win = window;
win.document.body.innerHTML = "";
}
if (win) {
const winHead = win.document.head;
let style = win.document.createElement("style");
style.innerText = "table, th, td { border-spacing: 0px; border-collapse: collapse; } "
+ "table { margin-top: 25px; } "
+ "td { padding: 5px; vertical-align: top; padding-bottom: 25px; } "
+ "#mainContainer { padding: 25px; } "
+ "a { text-decoration: none; font-weight: 700; color: black; } "
+ "a:hover { text-decoration: underline; } "
+ "html { font-family: sans-serif; } "
+ " "
+ "@media print { "
+ " #mainContainer { padding: 0px; }"
+ "} "
+ " ";
winHead.append(style);
let title = win.document.createElement("title");
title.innerText = "Show All Comments";
winHead.append(title);
const winBody = win.document.body;
const mainContainer = win.document.createElement("div");
mainContainer.id = "mainContainer";
winBody.append(mainContainer);
let table = win.document.createElement("table");
mainContainer.append(table);
let tbody = win.document.createElement("tbody");
table.append(tbody);
const converterArea = win.document.createElement("textarea");
const convertHtml = (encodedText) => {
converterArea.innerHTML = encodedText;
return converterArea.value;
}
const repliedCommentIds = [];
const addRowDetails = (item, tbodytr, myJson, commentType) => {
let itemUser = null;
if (item.relationships.commenter.data.type == "user") {
for (let user of myJson.included) {
if (user.id == item.relationships.commenter.data.id && user.type == "user") {
itemUser = user;
break;
}
}
}
let td;
td = win.document.createElement("td");
if (itemUser == null) {
td.innerText = "icon";
} else {
const img = win.document.createElement("img");
img.src = itemUser.attributes.image_url;
img.width = 32;
img.height = 32;
td.append(img);
}
tbodytr.append(td);
let userName = "name";
let userUrl = "";
if (itemUser != null) {
userName = itemUser.attributes.full_name;
userUrl = itemUser.attributes.url;
}
td = win.document.createElement("td");
tbodytr.append(td);
const userP = win.document.createElement("div");
td.append(userP);
const link = win.document.createElement("a");
link.href = userUrl;
link.innerText = userName;
userP.append(link);
const commentP = win.document.createElement("div");
td.append(commentP);
let span = win.document.createElement("span");
span.innerText = convertHtml(item.attributes.body)
commentP.append(span);
if (item.attributes.reply_count > 0) {
const repliesDiv = win.document.createElement("div");
td.append(repliesDiv);
const repliesTable = win.document.createElement("table");
repliesTable.id = "replies" + item.id;
td.append(repliesTable);
}
};
for (let item of myJson.data) {
if (item.type == "comment") {
let tbodytr = win.document.createElement("tr");
tbodytr.id = "tr" + item.id;
tbody.append(tbodytr);
addRowDetails(item, tbodytr, myJson, "");
if (item.attributes.reply_count > 1) {
repliedCommentIds.push(item.id);
}
}
}
for (let item of myJson.included) {
if (item.type == "comment") {
if (!repliedCommentIds.includes(item.relationships.parent.data.id)) {
let tbodytr = win.document.createElement("tr");
tbodytr.id = "tr" + item.id;
let repliesTable = win.document.getElementById("replies" + item.relationships.parent.data.id);
repliesTable.append(tbodytr);
addRowDetails(item, tbodytr, myJson, "reply");
}
}
}
for (let id of repliedCommentIds) {
//console.log(id);
const replayLongUrl = "https://www.patreon.com/api/comments/" + id + "/replies"
+ "?include=commenter.campaign.null%2Ccommenter.flairs.campaign.null%2Cparent%2Cpost%2Con_behalf_of_campaign.null"
+ "&fields[comment]=body%2Ccreated%2Cdeleted_at%2Cis_by_patron%2Cis_by_creator%2Cvote_sum%2Ccurrent_user_vote"
+ "&fields[flair]=image_tiny_url%2Cname"
+ "&fields[post]=comment_count"
+ "&fields[user]=image_url%2Cfull_name%2Curl"
+ "&json-api-use-default-includes=false"
+ "&json-api-version=1.0";
fetch(replayLongUrl)
.then(function(replyResponse) {
return replyResponse.json();
})
.then(function(replyJson) {
console.log(replyJson);
for (let item of replyJson.data) {
if (item.type == "comment") {
if (win.document.getElementById("tr" + item.id)) {
//reply is already in
} else {
let tbodytr = win.document.createElement("tr");
tbodytr.id = "tr" + item.id;
let repliesTable = win.document.getElementById("replies" + item.relationships.parent.data.id);
repliesTable.append(tbodytr);
addRowDetails(item, tbodytr, replyJson, "reply");
}
}
}
});
}
}
});
}
console.log("Show all comments");