Skip to content

Instantly share code, notes, and snippets.

@q00u
Last active February 11, 2022 19:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save q00u/b543f2be143368f4b6da519285c1bfda to your computer and use it in GitHub Desktop.
Save q00u/b543f2be143368f4b6da519285c1bfda to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name Restore Imgur Comment Sidebar
// @namespace https://gist.github.com/q00u
// @version 0.4
// @description Copy the top comments from the leaderboard page to the imgur (old non-beta) homepage
// @author Phoenix G
// @run-at document-idle
// @match https://imgur.com/
// @match https://imgur.com/new/time
// @match https://imgur.com/new/rising
// @match https://imgur.com/new/viral
// @match https://imgur.com/hot/time
// @match https://imgur.com/hot/rising
// @match https://imgur.com/hot/viral
// @match https://imgur.com/top
// @match https://imgur.com/top/viral
// @match https://imgur.com/top/viral/week
// @match https://imgur.com/top/viral/month
// @match https://imgur.com/top/viral/year
// @match https://imgur.com/top/viral/all
// @icon https://www.google.com/s2/favicons?domain=imgur.com
// @grant GM_xmlhttpRequest
// ==/UserScript==
(function () {
'use strict';
const controller = new AbortController();
function listenForSidebar() {
controller.abort() // We don't need this listener anymore
console.log('Trying to restore comment sidebar...');
const currentList = document.getElementById('tags-current-list');
if (currentList.innerText === '') { // Big IF, is this sidebar even empty to begin with?
const panel = document.createElement('div');
panel.className = 'panel';
currentList.appendChild(panel);
const textbox = document.createElement('div');
textbox.className = 'textbox';
panel.appendChild(textbox);
const title = document.createElement('h2');
title.innerText = 'Today\'s Best Comments';
textbox.appendChild(title);
const bestcaptions = document.createElement('div');
bestcaptions.className = 'captions best-captions';
panel.appendChild(bestcaptions);
const loading = document.createElement('img');
loading.src = 'https://i.imgur.com/pKopwXp.gif';
loading.style.width = '123px';
loading.style.height = '123px';
loading.style.margin = 'auto';
loading.style.display = 'block';
loading.style.padding = '20px';
bestcaptions.appendChild(loading);
function getCommentsFromPage(respObject) {
if (respObject.status === 429 || respObject.status === 403) {
console.log('Imgur is over capacity');
reportOverloaded_Error(respObject);
return;
}
if (respObject.status != 200 && respObject.status != 304) {
console.log('Status not 200 nor 304:', respObject.status);
reportAJAX_Error(respObject);
return;
}
const data = respObject.response.data;
if (data) {
bestcaptions.removeChild(loading);
//console.log('getCommentsFromPage', data, data.length);
for (let i = 0; i < data.length; i++) {
const captionContainer = document.createElement('div');
let containerClass = 'caption-container';
if (i < 3) containerClass += ' rank-' + i;
if (i === data.length - 1) containerClass += ' last-child';
captionContainer.className = containerClass;
const clickability = document.createElement('p');
clickability.className = 'clickability';
captionContainer.appendChild(clickability);
const anchor = document.createElement('a');
anchor.href = '/gallery/' + data[i].post.id + '/comment/' + data[i].id;
clickability.appendChild(anchor);
const caption = document.createElement('div');
caption.className = 'caption';
captionContainer.appendChild(caption);
const p = document.createElement('p');
caption.appendChild(p);
const img = document.createElement('img');
let imageUrl = data[i].post.cover.url;
imageUrl = imageUrl.split('.');
imageUrl.pop();
// img.src = data[i].post.cover.url;
//img.src = imageUrl.join('.') + '_d.jpg?maxwidth=180&shape=thumb&fidelity=high'; // Low-res thumbnail
img.src = imageUrl.join('.') + 's.jpg'; // small square thumbnail
//img.src = imageUrl.join('.') + '.jpg'; // full-size image
// img.setAttribute('original-title', ''); NO LONGER INCLUDED IN JSON
p.appendChild(img);
const author = document.createElement('div');
author.className = 'author';
caption.appendChild(author);
const authorLink = document.createElement('a');
const authorName = data[i].account.username;
const authorNameText = document.createTextNode(authorName);
authorLink.href = '/user/' + authorName;
authorLink.appendChild(authorNameText);
author.appendChild(authorLink);
const authorText = document.createTextNode(` ${(data[i].upvote_count - data[i].downvote_count).toLocaleString()} points `);
author.appendChild(authorText);
let commentText = data[i].comment;
// Replace any imgur image links with working links and tooltips
const imgurPattern = /\b(https?):\/\/(?:i\.)?(?:imgur.com\/)([\w\d]*)\.([\w\d]*)/gmi
const imgurMatches = [...commentText.matchAll(imgurPattern)];
imgurMatches.forEach((match) => {
const full = match[0];
let modFull = full;
const prot = match[1];
const code = match[2];
const ext = match[3];
if (prot === 'http') {
modFull = modFull.replace('http', 'https'); // only https gets served in the tipsy
}
if (ext === 'gifv') {
modFull = modFull.replace('gifv', 'gif'); // .gifv is broken on show-tipsy
}
const newLink = `<a class="imgur-image show-tipsy" data-hash="${code}" href="${modFull}">${full}</a>`;
commentText = commentText.replace(full, newLink);
});
caption.insertAdjacentHTML('beforeend', commentText);
const clear = document.createElement('div');
clear.className = 'clear hr';
if (i === data.length - 1) clear.classname = 'clear';
bestcaptions.appendChild(captionContainer);
bestcaptions.appendChild(clear);
}
}
}
function reportOverloaded_Error(respObject) {
console.log('reportOverloaded_Error', respObject);
const overloadedIcon = document.createElement('img');
overloadedIcon.src = 'https://i.imgur.com/C8PyKTM.jpg';
overloadedIcon.style.width = '359px';
overloadedIcon.style.margin = 'auto';
overloadedIcon.style.display = 'block';
bestcaptions.removeChild(loading);
bestcaptions.appendChild(overloadedIcon);
}
function reportAJAX_Error(respObject) {
// Handle error here
console.log('reportAJAX_Error', respObject);
const failIcon = document.createElement('img');
failIcon.src = 'https://i.imgur.com/YUNl30i.png';
failIcon.style.width = '123px';
failIcon.style.height = '123px';
failIcon.style.margin = 'auto';
failIcon.style.display = 'block';
failIcon.style.padding = '20px';
bestcaptions.removeChild(loading);
bestcaptions.appendChild(failIcon);
}
GM_xmlhttpRequest({
method: 'GET',
url: 'https://api.imgur.com/comment/v1/comments/top',
responseType: 'json',
onload: getCommentsFromPage,
onabort: reportAJAX_Error,
onerror: reportAJAX_Error,
ontimeout: reportAJAX_Error
});
} // End Big IF
}
document.getElementById('outside-tagging-showhide') // Only run if someone is LOOKING for sidebar content
.addEventListener('click', listenForSidebar, { signal: controller.signal });
})();
@q00u
Copy link
Author

q00u commented Dec 21, 2021

Still needs testing for when comment includes imgur image link.

@q00u
Copy link
Author

q00u commented Dec 21, 2021

Updated to only run when sidebar is actively shown, and to replace imgur links in comments with working links and tooltips

@q00u
Copy link
Author

q00u commented Dec 22, 2021

0.3: Tool-tip images are only served from https, so make sure that's what we're requesting

@q00u
Copy link
Author

q00u commented Dec 25, 2021

0.4: Add an 'Overloaded' image to the sidebar for days when the Top Comments API isn't responding (like, Christmas)

@q00u
Copy link
Author

q00u commented Feb 11, 2022

I guess it's not coming back? Their own leaderboard page https://imgur.com/leaderboard (linked from their header on their homepage) is likewise blank. The api access point for this is just gone. Alas.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment