removeddit/static/script.js
2017-08-26 00:39:41 +02:00

332 lines
No EOL
9.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
const markdown = SnuOwnd.getParser();
const thread_url = `https://oauth.reddit.com/r/${subreddit}/comments/${thread_id}`;
const morechildren_url = `https://oauth.reddit.com/api/morechildren?link_id=t3_${thread_id}&children=`;
const single_comment_url = `https://oauth.reddit.com/r/${subreddit}/api/info/?id=t1_`;
const removed_comments_url = "/comments/?c=";
const main_div = document.getElementById("main");
const loading_comments = document.getElementById("loading-comments");
const comment_ids = new Set();
const comment_lookup = new Map();
const comments_to_generate = [];
const comments_to_generate_ids = new Set();
let ajax_calls_left = 0;
let total_comments;
get_multiple([single_comment_url+"dlg744z",single_comment_url+"dlu05ei",single_comment_url+"dlu08gp"],
response => console.log(response),
() => console.log("done with all")
);
/*
get(thread_url, response => {
const json = JSON.parse(response);
generate_thread(json[0].data.children[0].data);
get_comment_ids(json[1].data.children);
});*/
function generate_thread(thread) {
const thread_div = document.createElement("div");
thread_div.id = "thread";
const thread_string = `
<div id="thread-score-box">
<div class="vote upvote"></div>
<div id="thread-score">${pretty_score(thread.score)}</div>
<div class="vote downvote"></div>
</div>
<div id="thumbnail"></div>
<div id="thread-content">
${thread.link_flair_text !== null ? '<span class="link-flair">'+thread.link_flair_text+'</span>' : ''}
<a id="thread-title" href="${thread.url}">${thread.title}</a>
<span id="domain">(${thread.domain})</span>
<div id="thread-info">
submitted <span id="thread-time">${pretty_date(thread.created_utc)}</span> by
<a id="thread-author" class="user-link" href="https://www.reddit.com/user/${thread.author}">${thread.author}</a> to
<a id="subreddit-link" href="https://reddit.com/r/${subreddit}">/r/${subreddit}</a>
</div>
${thread.selftext !== '' ? '<div id="thread-selftext" class="user-text">'+markdown.render(thread.selftext)+'</div>':''}
</div>
`;
thread_div.innerHTML = thread_string;
main_div.insertBefore(thread_div, loading_comments);
total_comments = thread.num_comments;
}
function get_comment_ids(comments) {
comments.forEach(comment => extract_id_from_comment(comment));
if(ajax_calls_left == 0) {
get_all_comment_ids();
}
}
function extract_id_from_comment(comment) {
// "Show more"-comments
if(comment.kind == "more") {
const children = comment.data.children;
// Some "show more"-comments were missing, need to do more ajax-calls
if(children.length < comment.data.count){
ajax_calls_left++;
get(morechildren_url + children.join(), response => handle_show_more_comments(JSON.parse(response)));
}
if(children.length > 0) {
comment_ids.add(...children);
}
}
// Normal comment
else {
const data = comment.data;
if(data.replies) {
data.replies.data.children.forEach(child => extract_id_from_comment(child));
}
delete data.replies;
comment_lookup.set(data.id, data);
comment_ids.add(data.id);
}
}
function handle_show_more_comments(comments) {
comments.jquery[14][3][0].forEach(comment => {
if(comment.kind == "more") {
let children = comment.data.children;
if(children.length < comment.data.count) {
ajax_calls_left++;
get(morechildren_url + children.join(), response => handle_show_more_comments(JSON.parse(response)));
}
comment_ids.add(...children);
} else {
comment_ids.add(comment.data.id);
comment_lookup.set(comment.data.id, comment.data);
}
});
ajax_calls_left--;
if(ajax_calls_left == 0) {
get_all_comment_ids();
}
}
function get_all_comment_ids() {
const ids_diff = new Set([...all_ids].filter(x => !comment_ids.has(x)));
console.log(all_ids);
console.log(comment_ids);
console.log(ids_diff);
if(ids_diff.size > 144) {
alert("very many removal, aborting");
return;
}
get(removed_comments_url + [...ids_diff].join(), response => create_comments(JSON.parse(response).data));
}
function create_comments(comments) {
create_comment_info(comments.length);
comments.forEach(comment => {
comment["removed"] = true;
comments_to_generate.push(comment);
comments_to_generate_ids.add(comment.id);
comment_lookup.set(comment.id, comment);
});
create_parent_comments();
}
function create_parent_comments() {
let done = true;
let parent_id;
let comment;
for(let i = comments_to_generate.length - 1; i >= 0; i--) {
comment = comments_to_generate[i];
parent_id = comment_lookup.get(comment.id).parent_id.split("_")[1];
// Done with this comment
if(parent_id == thread_id || comments_to_generate_ids.has(parent_id)) {}
// parent comment exists in lookup but hasnt been added to the queue yet
else if(comment_lookup.has(parent_id)) {
console.log(i, "finding parent in lookup");
comments_to_generate.push(comment_lookup.get(parent_id));
comments_to_generate_ids.add(parent_id);
done = false;
}
// parent comment doesn't exists
else {
get(single_comment_url + parent_id, response => {
let new_comment = JSON.parse(response).data.children[0].data;
comments_to_generate.push(new_comment);
comments_to_generate_ids.add(new_comment.id);
create_parent_comments();
console.log(parent_id, " created via /api/info ???");
});
done = false;
console.log(i, " doesn't exist");
}
}
if(!done) {
create_parent_comments();
} else {
generate_comments();
}
}
function generate_comments() {
const comment_section = document.createElement("div");
comment_section.id = thread_id;
main_div.insertBefore(comment_section, loading_comments);
comments_to_generate.sort(function(a, b) {
if(a.score == b.score) {
return 0;
}
return a.score > b.score ? 1 : -1;
});
const generated_comment_ids = new Set([thread_id]);
let parent_id;
let comment;
while(comments_to_generate.length > 0) {
for(let i = comments_to_generate.length -1; i >= 0; i--) {
comment = comments_to_generate[i];
parent_id = comment.parent_id.split("_")[1];
if(generated_comment_ids.has(parent_id)) {
document.getElementById(parent_id).appendChild(create_comment(comment_lookup.get(comment.id)));
generated_comment_ids.add(comment.id);
comments_to_generate.splice(i, 1);
}
}
}
}
function create_comment(comment) {
const comment_div = document.createElement("div");
//comment_div.className = "comment " + (comment.hasOwnProperty("removed") ? "comment-removed" : );
if(comment.hasOwnProperty("removed")) {
comment_div.className = "comment comment-removed";
} else {
comment_div.className = "comment comment-" + (comment.depth % 2 == 0 ? "even" : "odd");
}
comment_div.id = comment.id;
const comment_html = `
<div class="comment-head">
<a href="javascript:void(0)" class="user-link">[]</a>
<a href="https://www.reddit.com/user/${comment.author}" class="user-link comment-author">${comment.author}</a>
<span class="comment-score">${comment.score} point${(comment.score == 1) ? '': 's'}</span>
<span class="comment-time">${pretty_date(comment.created_utc) }</span>
</div>
<div class="comment-body">${markdown.render(comment.body)}</div>
<div class="comment-links">
<a href="https://todo.com">permalink</a>
</div>
`;
comment_div.innerHTML = comment_html;
return comment_div;
}
function create_comment_info(removed_comments) {
const comment_info = document.createElement("div");
comment_info.innerHTML = `
<div id="comment-info">
removed comments: ${removed_comments}/${total_comments} (${ (100 * removed_comments / total_comments).toFixed(1)}%)
</div>
<div id="comment-sort">sorted by: top</div>
`;
main_div.insertBefore(comment_info, loading_comments);
}
// ---------------- Other less interesting functions ------------------------
function get(url, callback) {
const xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
callback(JSON.parse(this.responseText));
} else if (this.readyState == 4) {
alert(this.status + " error: " + this.responseText);
// Error handle
}
}
xhttp.open("GET", url, true);
xhttp.setRequestHeader("Authorization", "bearer " + token);
xhttp.send();
}
function get_multiple(urls, callback, all_completed_callback) {
let num_calls_left = urls.length;
urls.forEach(url => {
get(url, function(data){
callback(data);
num_calls_left--;
if(num_calls_left == 0) {
all_completed_callback();
}
});
});
}
// UTC -> "Reddit time format"
function pretty_date(created_utc) {
const current_utc = Math.floor((new Date()).getTime() / 1000);
const second_diff = current_utc - created_utc;
const day_diff = Math.floor(second_diff / 86400);
if(day_diff < 0)
return '';
if(day_diff == 0) {
if(second_diff < 10)
return "just now";
if(second_diff < 60)
return second_diff + " seconds ago";
if(second_diff < 120)
return "a minute ago";
if(second_diff < 3600)
return Math.floor(second_diff / 60) + " minutes ago";
if(second_diff < 7200)
return "an hour ago";
if(second_diff < 86400)
return Math.floor(second_diff / 3600) + " hours ago";
}
if(day_diff == 1)
return "Yesterday";
if(day_diff < 7)
return day_diff + " days ago";
if(day_diff < 31)
return Math.floor(day_diff / 7) + " weeks ago";
if(day_diff < 365)
return Math.floor(day_diff / 30) + " months ago";
return Math.floor(day_diff / 365) + " years ago";
}
function pretty_score(score) {
if(score >= 10000) {
return (score / 1000).toFixed(1) + "k";
} else {
return score;
}
}