Finally, I am using this for now:
cscript type="text/discourse-plugin" version="0.11.3"
api.onPageChange(() => {
if (window.location.pathname === "/") {
const container = document.querySelector(".latest-topic-list");
if (!container) return;
// Prevent multiple initializations
if (window.latestRepliesInitialized) return;
window.latestRepliesInitialized = true;
// Settings
const POLLING_INTERVAL = 2000; // 2 seconds
const COMMENTS_TO_SHOW = 15;
const CACHE_DURATION = 30 * 60 * 1000; // 30 minutes
// Cache keys
const CACHE_KEY = "discourse_latest_replies_data";
const CACHE_TIMESTAMP_KEY = "discourse_latest_replies_timestamp";
const CACHE_LAST_ID_KEY = "discourse_latest_replies_last_id";
// Store the last seen post ID for comparison
let lastSeenPostId = parseInt(localStorage.getItem(CACHE_LAST_ID_KEY) || "0");
let pollingIntervalId = null;
console.log(`Initializing latest comments plugin (last ID in cache: ${lastSeenPostId})`);
// Function to load the latest replies
function loadLatestReplies(silent = false, forceRefresh = false) {
// Check cache first, if not a forced update
if (!forceRefresh) {
const cachedData = localStorage.getItem(CACHE_KEY);
const cacheTimestamp = localStorage.getItem(CACHE_TIMESTAMP_KEY);
const now = Date.now();
// If we have valid cache data
if (cachedData && cacheTimestamp && now - parseInt(cacheTimestamp) < CACHE_DURATION) {
try {
const results = JSON.parse(cachedData);
console.log(`Using cached data (${results.length} comments, cache from ${Math.round((now - parseInt(cacheTimestamp)) / 1000 / 60)} minutes ago)`);
renderLatestReplies(results, false);
// If not silent, no need to do more
if (!silent) {
return;
}
// If silent, continue to check for updates
} catch (e) {
console.error("Error processing cache:", e);
// If cache error, continue to fetch fresh data
}
} else if (cachedData) {
console.log("Cache expired, fetching fresh data");
} else {
console.log("No cache found, fetching fresh data");
}
} else {
console.log("Forcing update, ignoring cache");
}
// If it is not silent, show the loading indicator
if (!silent) {
// If a comments container already exists, do not show the indicator
const existingContainer = document.querySelector(".latest-replies-container");
if (!existingContainer) {
let loadingIndicator = document.getElementById("latest-replies-loading");
if (!loadingIndicator) {
loadingIndicator = document.createElement("div");
loadingIndicator.id = "latest-replies-loading";
loadingIndicator.innerHTML = `
<div style="text-align: center; padding: 20px;">
<span class="spinner small"></span>
<span style="margin-left: 10px;">Loading recent comments...</span>
</div>
`;
container.parentNode.insertBefore(loadingIndicator, container.nextSibling);
}
}
}
// Fetch the latest data
fetch("/posts.json?order=created")
.then(res => res.json())
.then(data => {
// Diagnostic log
if (!silent) {
console.log("Data received from API:", data.latest_posts.length);
}
const replies = data.latest_posts
.filter(p => p.post_number > 1 && !p.topic_slug.includes("private-message"))
.slice(0, COMMENTS_TO_SHOW);
// Check for new posts
const maxId = replies.length > 0 ? Math.max(...replies.map(post => post.id)) : 0;
const hasNewPosts = maxId > lastSeenPostId;
// Diagnostic log
if (hasNewPosts && !silent) {
console.log(`New posts detected. Last ID: ${lastSeenPostId}, New max ID: ${maxId}`);
}
// Update the last seen ID
if (maxId > lastSeenPostId) {
lastSeenPostId = maxId;
localStorage.setItem(CACHE_LAST_ID_KEY, lastSeenPostId.toString());
}
// If there are no new posts and the check is silent, do nothing
if (!hasNewPosts && silent && !forceRefresh) {
return;
...