// A handy bookmarklet to display comments from the top-rated Hacker News thread related to the current page // Written with the help of GPT-4 javascript:(function() { const createCommentElement = (comment, depth) => { const commentWrapper = document.createElement(‘div’); commentWrapper.style.paddingLeft = (depth * 20) + ‘px’; commentWrapper.style.marginBottom = ’10px’; commentWrapper.style.marginLeft = ’10px’; commentWrapper.style.color = ‘#333’; commentWrapper.style.background = ‘#f6f6ef’; const toggleButton = document.createElement(‘button’); toggleButton.textContent = ‘[-]’; toggleButton.style.marginRight = ’10px’; toggleButton.style.background = ‘none’; toggleButton.style.border = ‘none’; toggleButton.style.color = ‘#888’; toggleButton.style.cursor = ‘pointer’; commentWrapper.appendChild(toggleButton); const commentText = document.createElement(‘span’); const decoded = new DOMParser().parseFromString(comment.text, ‘text/html’).body.textContent || ; const author = comment.author || ‘Anonymous’; const formattedDate = new Date(comment.created_at).toLocaleString(); commentText.innerHTML = `${author} ${formattedDate}
${makeUrlsClickable(decoded)}`
; commentWrapper.appendChild(commentText); const childrenWrapper = document.createElement(‘div’); childrenWrapper.style.marginLeft = ’20px’; childrenWrapper.style.marginTop = ’10px’; commentWrapper.appendChild(childrenWrapper); let isCollapsed = false; toggleButton.addEventListener(‘click’, () => { if(isCollapsed) { commentText.style.display = ; childrenWrapper.style.display = ; toggleButton.textContent = ‘[-]’; isCollapsed = false; } else { commentText.style.display = ‘none’; childrenWrapper.style.display = ‘none’; toggleButton.textContent = ‘[+]’; isCollapsed = true; } }); return { commentWrapper, childrenWrapper }; }; const addCommentsToSidebar = (comments, depth, sidebarContent) => { for(let c of comments) { if(c.text){ const { commentWrapper, childrenWrapper } = createCommentElement(c, depth); sidebarContent.appendChild(commentWrapper); if (c.children) { addCommentsToSidebar(c.children, depth + 1, childrenWrapper); } } } }; const makeUrlsClickable = (text) => { const urlRegex = /(https?://[^s]+)/g; return text.replace(urlRegex, $&); }; const url = `https://hn.algolia.com/api/v1/search?query=${encodeURIComponent(document.location.href)}&tags=story`; fetch(url) .then((response) => response.json()) .then((data) => { if(data.hits.length === 0){ alert(‘This page has not been posted on Hacker News.’); return; } const highestScoringStory = data.hits.reduce((prev, cur) => (prev.points > cur.points) ? prev : cur); const storyId = highestScoringStory.objectID; const commentsUrl = `https://hn.algolia.com/api/v1/items/${storyId}`; fetch(commentsUrl) .then((response) => response.json()) .then((data) => { const sidebar = document.createElement(‘div’); sidebar.style.cssText = ‘position:fixed;right:0;top:0;width:600px;height:100%;background-color:#f6f6ef;overflow-y:auto;padding:1em;z-index:999999;font-family:Verdana,Geneva,sans-serif;font-size:14px;color:#333;’; document.body.appendChild(sidebar); const sidebarContent = document.createElement(‘div’); sidebarContent.style.cssText = ‘overflow-y:scroll;height:100%;background-color:#f6f6ef;’; sidebar.appendChild(sidebarContent); addCommentsToSidebar(data.children, 0, sidebarContent); const dragHandle = document.createElement(‘div’); dragHandle.style.cssText = ‘position:absolute;top:0;left:0;bottom:0;width:10px;background:rgba(0,0,0,0.1);cursor:ew-resize;’; sidebar.appendChild(dragHandle); let isDragging = false; let initialX = 0; let initialWidth = 0; dragHandle.addEventListener(‘mousedown’, (e) => { isDragging = true; initialX = e.clientX; initialWidth = sidebar.offsetWidth; }); window.addEventListener(‘mousemove’, (e) => { if(isDragging) { const offsetX = e.clientX initialX; const newWidth = Math.max(400, initialWidth offsetX); sidebar.style.width = newWidth + ‘px’; } }); window.addEventListener(‘mouseup’, () => { isDragging = false; }); sidebar.addEventListener(‘scroll’, (e) => { dragHandle.style.top = sidebar.scrollTop + ‘px’; }); }) .catch((error) => console.error(‘Error:’, error)); }) .catch((error) => console.error(‘Error:’, error)); })();

Read More