···
font-family: 'JetBrains Mono', monospace;
···
-
text-overflow: ellipsis;
···
color: var(--accent-color);
-
text-overflow: ellipsis;
color: var(--text-muted);
···
transition: all 0.3s ease;
-
.feed-item.content-open {
border-left-color: var(--accent-color);
background-color: rgba(77, 250, 123, 0.03);
···
-
.feed-item-external-links {
-
border-top: 1px dashed var(--border-color);
-
background-color: rgba(77, 250, 123, 0.02);
···
item.addEventListener('mouseenter', () => {
// Close all sections in previously hovered item
if (currentHoveredItem && currentHoveredItem !== item) {
-
// Don't close manually opened content (with the button)
-
if (!currentHoveredItem.classList.contains('content-open')) {
-
const prevContent = currentHoveredItem.querySelector('.feed-item-content');
-
prevContent.style.display = 'none';
-
const prevButton = currentHoveredItem.querySelector('.read-more-btn');
-
prevButton.textContent = '📄';
-
prevButton.title = 'Show content';
-
// Don't close manually opened external links
-
if (!currentHoveredItem.classList.contains('links-open')) {
-
const prevLinks = currentHoveredItem.querySelector('.feed-item-external-links');
-
prevLinks.style.display = 'none';
-
const prevButton = currentHoveredItem.querySelector('.external-links-toggle');
-
prevButton.textContent = '🌐';
-
prevButton.title = 'Show external links';
-
// Don't close manually opened references
-
if (!currentHoveredItem.classList.contains('refs-to-open')) {
-
const prevRefsTo = currentHoveredItem.querySelector('.references-to');
-
prevRefsTo.style.display = 'none';
-
const prevButton = currentHoveredItem.querySelector('.references-to-toggle');
-
prevButton.textContent = '➡️';
-
prevButton.title = 'Show references to other posts';
-
if (!currentHoveredItem.classList.contains('refs-by-open')) {
-
const prevRefsBy = currentHoveredItem.querySelector('.references-by');
-
prevRefsBy.style.display = 'none';
-
const prevButton = currentHoveredItem.querySelector('.references-by-toggle');
-
prevButton.textContent = '⬅️';
-
prevButton.title = 'Show posts referencing this one';
// Set this as current hovered item
currentHoveredItem = item;
-
// Show content on hover (unless manually closed)
-
const content = item.querySelector('.feed-item-content');
-
content.style.display = 'block';
-
const button = item.querySelector('.read-more-btn');
-
button.textContent = '📕';
-
button.title = 'Hide content';
-
// Show external links if available
-
const externalLinks = item.querySelector('.feed-item-external-links');
-
externalLinks.style.display = 'flex';
-
const externalButton = item.querySelector('.external-links-toggle');
-
externalButton.textContent = '🌐';
-
externalButton.title = 'Hide external links';
···
-
// Function to get first line of text
-
function getFirstLine(html) {
// Create a temporary div to parse HTML
const tempDiv = document.createElement('div');
tempDiv.innerHTML = html;
-
// Extract text content
const text = tempDiv.textContent || '';
-
// Get first line (up to first period or newline, whichever comes first)
-
const firstPeriod = text.indexOf('.');
-
const firstNewline = text.indexOf('\n');
-
if (firstPeriod !== -1 && firstNewline !== -1) {
-
endIndex = Math.min(firstPeriod, firstNewline);
-
} else if (firstPeriod !== -1) {
-
endIndex = firstPeriod;
-
} else if (firstNewline !== -1) {
-
endIndex = firstNewline;
-
// If no period or newline, take first 80 chars
-
endIndex = Math.min(text.length, 80);
-
return text.substring(0, endIndex + 1).trim();
-
// Function to toggle content visibility
-
function toggleContent(articleId) {
-
const article = document.getElementById(articleId);
-
const content = article.querySelector('.feed-item-content');
-
const button = article.querySelector('.read-more-btn');
-
if (content.style.display === 'block') {
-
content.style.display = 'none';
-
button.textContent = '📄';
-
button.title = 'Show content';
-
// Remove forced hover state
-
article.classList.remove('content-open');
-
content.style.display = 'block';
-
button.textContent = '📕';
-
button.title = 'Hide content';
-
// Add forced hover state
-
article.classList.add('content-open');
-
// Function to toggle external links visibility
-
function toggleExternalLinks(articleId) {
-
const article = document.getElementById(articleId);
-
const linksContainer = article.querySelector('.feed-item-external-links');
-
const button = article.querySelector('.external-links-toggle');
-
if (!linksContainer || !button) {
-
console.error(`External links container or button for ${articleId} not found`);
-
if (linksContainer.style.display === 'flex') {
-
linksContainer.style.display = 'none';
-
button.textContent = '🌐';
-
button.title = 'Show external links';
-
article.classList.remove('links-open');
-
linksContainer.style.display = 'flex';
-
button.textContent = '🌐';
-
button.title = 'Hide external links';
-
article.classList.add('links-open');
-
// Function to toggle references visibility
-
function toggleReferences(articleId, type) {
-
const article = document.getElementById(articleId);
-
const referencesContainer = article.querySelector(`.references-${type}`);
-
const button = article.querySelector(`.references-${type}-toggle`);
-
if (!referencesContainer || !button) {
-
console.error(`References container or button for ${articleId} not found`);
-
if (referencesContainer.style.display === 'block') {
-
referencesContainer.style.display = 'none';
-
button.textContent = type === 'to' ? '➡️' : '⬅️';
-
button.title = type === 'to' ? 'Show references to other posts' : 'Show posts referencing this one';
-
article.classList.remove(`refs-${type}-open`);
-
referencesContainer.style.display = 'block';
-
button.textContent = type === 'to' ? '➡️' : '⬅️';
-
button.title = type === 'to' ? 'Hide references to other posts' : 'Hide posts referencing this one';
-
article.classList.add(`refs-${type}-open`);
// Fetch the Atom feed and threads data in parallel
···
-
// Get the first line for preview
const firstLine = getFirstLine(contentHtml);
···
···
<article id="${entry.articleId}" class="feed-item" ${dateAttr}>
<div class="feed-item-row">
<div class="feed-item-date">${formatDate(entry.published)}</div>
<div class="feed-item-author">${entry.author}</div>
-
<div class="feed-item-title"><a href="${entry.link}" target="_blank">${entry.title}</a></div>
-
<div class="feed-item-preview">${entry.firstLine}</div>
-
<div class="feed-item-actions">
-
<button class="read-more-btn" onclick="toggleContent('${entry.articleId}')" title="Show/hide content">📄</button>
-
<a href="${entry.link}" target="_blank" class="external-link" title="Open original post">🔗</a>
-
${entry.externalLinks && entry.externalLinks.length > 0 ?
-
`<button class="external-links-toggle" onclick="toggleExternalLinks('${entry.articleId}')" title="Show/hide external links">🌐</button>` : ''}
-
${entry.referencesTo && entry.referencesTo.length > 0 ?
-
`<button class="references-to-toggle references-toggle" onclick="toggleReferences('${entry.articleId}', 'to')" title="Show/hide references to other posts">➡️</button>` : ''}
-
${entry.referencedBy && entry.referencedBy.length > 0 ?
-
`<button class="references-by-toggle references-toggle" onclick="toggleReferences('${entry.articleId}', 'by')" title="Show/hide posts referencing this one">⬅️</button>` : ''}
-
<div class="feed-item-content">${entry.contentHtml}</div>
-
${entry.externalLinks && entry.externalLinks.length > 0 ? `
-
<div class="feed-item-external-links">
-
<span class="external-links-label">External links:</span>
-
${entry.externalLinks.map(link => `<a href="${link.url}" target="_blank" class="external-link-item" title="${link.url}">${new URL(link.url).hostname}</a>`).join(', ')}
-
${entry.referencesTo && entry.referencesTo.length > 0 ? `
-
<div class="references-container references-to" style="display: none;">
-
<div class="reference-header">References to other posts:</div>
-
${entry.referencesTo.map(ref => `
-
<div class="reference-item">
-
<span class="reference-indicator">→</span>
-
<a href="${ref.link}" target="_blank" class="reference-link">${ref.title}</a>
-
<span class="reference-author"> by ${ref.author}</span>
-
${entry.referencedBy && entry.referencedBy.length > 0 ? `
-
<div class="references-container references-by" style="display: none;">
-
<div class="reference-header">Posts referencing this one:</div>
-
${entry.referencedBy.map(ref => `
-
<div class="reference-item">
-
<span class="reference-indicator">←</span>
-
<a href="${ref.link}" target="_blank" class="reference-link">${ref.title}</a>
-
<span class="reference-author"> by ${ref.author}</span>
···
sourceCountElement.textContent = sources.size;
-
// Add the toggle functions to the global scope
-
window.toggleContent = toggleContent;
-
window.toggleExternalLinks = toggleExternalLinks;
-
window.toggleReferences = toggleReferences;
// Build timeline sidebar
const timelineSidebar = document.getElementById('timeline-sidebar');