diff --git a/frontend/app.js b/frontend/app.js index 59d5272..a8f1193 100644 --- a/frontend/app.js +++ b/frontend/app.js @@ -631,7 +631,7 @@ async function loadStats() { async function loadFeed(force) { try { const allPosts = await invoke('get_feed'); - const posts = allPosts.filter(p => p.intentKind !== 'direct'); + const posts = allPosts.filter(p => p.intentKind !== 'direct' && !(p.intentKind === 'unknown' && (p.visibility === 'encrypted-for-me' || (p.isMe && p.recipients && p.recipients.length > 0)))); // Fingerprint: post IDs + reaction counts + comment counts const fp = posts.map(p => `${p.id}:${(p.reactionCounts||[]).map(r=>r.emoji+r.count).join(',')}:${p.commentCount||0}`).join('|'); if (!force && fp === _feedFingerprint) return; @@ -687,20 +687,12 @@ async function loadFeed(force) { } catch (e) { feedList.innerHTML = `

Error: ${e}

`; } - // Update feed badge if not currently viewing feed - if (currentTab !== 'feed' && _lastFeedViewMs > 0) { - try { - const allPosts = await invoke('get_feed'); - const newCount = allPosts.filter(p => p.intentKind !== 'direct' && !p.isMe && p.timestampMs > _lastFeedViewMs).length; - updateTabBadge('feed', newCount); - } catch (_) {} - } } async function loadMyPosts(force) { try { const posts = await invoke('get_all_posts'); - const mine = posts.filter(p => p.isMe && p.intentKind !== 'direct'); + const mine = posts.filter(p => p.isMe && p.intentKind !== 'direct' && !(p.intentKind === 'unknown' && p.recipients && p.recipients.length > 0)); const fp = mine.map(p => `${p.id}:${(p.reactionCounts||[]).map(r=>r.emoji+r.count).join(',')}:${p.commentCount||0}`).join('|'); if (!force && fp === _myPostsFingerprint) return; _myPostsFingerprint = fp; @@ -725,24 +717,6 @@ async function loadMyPosts(force) { } } } - // Count posts with new engagement (before marking as seen) - if (currentTab !== 'myposts') { - let newEngagement = 0; - for (const p of mine) { - const totalReacts = (p.reactionCounts || []).reduce((sum, r) => sum + r.count, 0); - const totalComments = p.commentCount || 0; - if (totalReacts > 0 || totalComments > 0) { - try { - const seen = await invoke('get_seen_engagement', { postId: p.id }); - if (totalReacts > (seen.seenReactCount || 0) || totalComments > (seen.seenCommentCount || 0)) { - newEngagement++; - } - } catch (_) { newEngagement++; } - } - } - updateTabBadge('myposts', newEngagement); - } - // Mark all visible own posts' engagement as seen (DB-backed) when viewing tab if (currentTab === 'myposts') { for (const p of mine) { @@ -2994,17 +2968,44 @@ async function init() { // Initial network indicator updateNetworkIndicator(); - // Auto-refresh every 10 seconds + // Auto-refresh every 10 seconds — only the active tab setInterval(() => { if (currentTab === 'feed') loadFeed(); if (currentTab === 'myposts') loadMyPosts(); if (currentTab === 'people') { loadFollows(); loadPeers(); loadAudience(); } updateNetworkIndicator(); - // Update badges for non-active tabs - if (currentTab !== 'feed') loadFeed(); - if (currentTab !== 'myposts') loadMyPosts(); }, 10000); + // Badge updates for non-active tabs — every 30 seconds (lightweight) + setInterval(async () => { + try { + // Feed badge + if (currentTab !== 'feed' && _lastFeedViewMs > 0) { + const allPosts = await invoke('get_feed'); + const isDM = p => p.intentKind === 'direct' || (p.intentKind === 'unknown' && (p.visibility === 'encrypted-for-me' || (p.isMe && p.recipients && p.recipients.length > 0))); + const newCount = allPosts.filter(p => !isDM(p) && !p.isMe && p.timestampMs > _lastFeedViewMs).length; + updateTabBadge('feed', newCount); + } + // My Posts badge (new engagement) + if (currentTab !== 'myposts') { + const posts = await invoke('get_all_posts'); + const mine = posts.filter(p => p.isMe && p.intentKind !== 'direct' && !(p.intentKind === 'unknown' && p.recipients && p.recipients.length > 0)); + let newEngagement = 0; + for (const p of mine) { + const totalReacts = (p.reactionCounts || []).reduce((sum, r) => sum + r.count, 0); + const totalComments = p.commentCount || 0; + if (totalReacts > 0 || totalComments > 0) { + try { + const seen = await invoke('get_seen_engagement', { postId: p.id }); + if (totalReacts > (seen.seenReactCount || 0) || totalComments > (seen.seenCommentCount || 0)) newEngagement++; + } catch (_) { newEngagement++; } + } + } + updateTabBadge('myposts', newEngagement); + } + } catch (_) {} + }, 30000); + // Tiered DM polling: frequency based on recency of last message let _lastMsgPollMs = 0; setInterval(() => {