Skip to content

Instantly share code, notes, and snippets.

@xpl
Last active December 25, 2025 23:54
Show Gist options
  • Select an option

  • Save xpl/23adcc1f1ab80f4b3e32df86a682d0f3 to your computer and use it in GitHub Desktop.

Select an option

Save xpl/23adcc1f1ab80f4b3e32df86a682d0f3 to your computer and use it in GitHub Desktop.
HackerNews Chat Mode (Live Comments Updater)
// ==UserScript==
// @name HN Chat Mode
// @namespace https://news.ycombinator.com/
// @version 2024-09-18
// @description live comments updater
// @author You
// @match https://news.ycombinator.com/item*
// @icon https://www.google.com/s2/favicons?sz=64&domain=news.ycombinator.com
// @grant none
// ==/UserScript==
(function() {
// Function to get the item ID from the URL
function getItemIDFromURL() {
let urlParams = new URLSearchParams(window.location.search);
return urlParams.get('id');
}
// Function to update comments
function updateComments() {
console.log('Starting updateComments at', new Date().toLocaleTimeString());
let itemID = getItemIDFromURL();
console.log('Fetching the page:', location.href);
fetch(location.href)
.then(response => response.text())
.then(responseText => {
console.log('Page fetched successfully.');
let parser = new DOMParser();
let doc = parser.parseFromString(responseText, "text/html");
console.log('HTML parsed.');
// Get new and existing comment elements
let newCommentElems = Array.from(doc.querySelectorAll("tr.athing.comtr"));
let existingCommentElems = Array.from(document.querySelectorAll("tr.athing.comtr"));
console.log(`Found ${newCommentElems.length} comments on fetched page.`);
console.log(`Found ${existingCommentElems.length} comments on current page.`);
let existingCommentIDs = new Set(existingCommentElems.map(c => c.id));
let commentTree = document.querySelector("table.comment-tree");
let newCommentsFound = false;
for (let i = 0; i < newCommentElems.length; i++) {
let newCommentElem = newCommentElems[i];
let commentID = newCommentElem.id;
if (!existingCommentIDs.has(commentID)) {
newCommentsFound = true;
console.log(`New comment detected with ID: ${commentID}`);
// Find the previous comment in the new list that exists in the current DOM
let inserted = false;
for (let j = i - 1; j >= 0; j--) {
let prevCommentID = newCommentElems[j].id;
let prevCommentElem = document.getElementById(prevCommentID);
if (prevCommentElem) {
// Insert after the previous comment
let clonedCommentElem = newCommentElem.cloneNode(true);
// Apply highlight effect
clonedCommentElem.style.backgroundColor = "#fff8dc"; // Cornsilk color
prevCommentElem.parentNode.insertBefore(clonedCommentElem, prevCommentElem.nextSibling);
console.log(`Inserted new comment after comment ID: ${prevCommentID}`);
inserted = true;
break;
}
}
if (!inserted) {
// Insert at the beginning if no previous comment exists
let clonedCommentElem = newCommentElem.cloneNode(true);
clonedCommentElem.style.backgroundColor = "#fff8dc";
commentTree.insertBefore(clonedCommentElem, commentTree.firstChild);
console.log('Inserted new comment at the beginning of the comment tree.');
}
}
}
if (!newCommentsFound) {
console.log('No new comments found.');
} else {
console.log('Update complete. New comments have been inserted.');
}
})
.catch(error => {
console.error('Error fetching comments:', error);
});
}
// Run updateComments every 10 seconds
console.log('Starting comment updater. It will run every 10 seconds.');
setInterval(updateComments, 10000);
})();
@bdmorin

bdmorin commented Sep 19, 2024

Copy link
Copy Markdown

What an awesome idea

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