From 8d08911bd3ae81478b1c6fdf689965e9b13ac6fd Mon Sep 17 00:00:00 2001 From: Gigi Date: Mon, 20 Oct 2025 13:00:34 +0200 Subject: [PATCH] feat(reads): separate archive vs reading-progress filters; archive shows emoji-only, progress filters ignore emoji --- src/components/Me.tsx | 82 +++++++++++++++++++++++++------ src/utils/readingProgressUtils.ts | 12 ++--- 2 files changed, 74 insertions(+), 20 deletions(-) diff --git a/src/components/Me.tsx b/src/components/Me.tsx index 05cd68f0..03b76599 100644 --- a/src/components/Me.tsx +++ b/src/components/Me.tsx @@ -626,6 +626,39 @@ const Me: React.FC = ({ highlights ) + // Archive-only list: independent of reading progress + const archiveOnlyReads: ReadItem[] = (() => { + if (readingProgressFilter !== 'archive') return [] + const markedIds = new Set([ + ...archiveController.getMarkedIds(), + // We intentionally ignore readingProgress marks here per requirement + ]) + const items: ReadItem[] = [] + // Add items from existing reads/links that are marked + for (const item of [...readsWithProgress, ...linksWithProgress]) { + const id = item.type === 'article' ? item.id : (item.url || item.id) + if (id && markedIds.has(id)) { + items.push({ ...item, markedAsRead: true }) + } + } + // Add any marked IDs not present in reads/links yet + for (const id of markedIds) { + const exists = items.find(i => (i.type === 'article' ? i.id : (i.url || i.id)) === id) + if (!exists) { + const isArticle = id.startsWith('naddr1') + items.push({ + id, + source: 'marked-as-read', + type: isArticle ? 'article' : 'external', + url: isArticle ? undefined : id, + markedAsRead: true, + readingTimestamp: Math.floor(Date.now() / 1000) + }) + } + } + return items + })() + // Debug logs for archive filter issues if (readingProgressFilter === 'archive') { const ids = Array.from(new Set([ @@ -785,21 +818,42 @@ const Me: React.FC = ({ selectedFilter={readingProgressFilter} onFilterChange={handleReadingProgressFilterChange} /> - {filteredReads.length === 0 ? ( -
- No articles match this filter. -
+ {readingProgressFilter === 'archive' ? ( + archiveOnlyReads.length === 0 ? ( +
+ No articles in archive. +
+ ) : ( +
+ {archiveOnlyReads + .filter(item => item.type === 'article') + .map((item) => ( + + ))} +
+ ) ) : ( -
- {filteredReads.map((item) => ( - - ))} -
+ filteredReads.length === 0 ? ( +
+ No articles match this filter. +
+ ) : ( +
+ {filteredReads.map((item) => ( + + ))} +
+ ) )} ) diff --git a/src/utils/readingProgressUtils.ts b/src/utils/readingProgressUtils.ts index 933da157..d919cddb 100644 --- a/src/utils/readingProgressUtils.ts +++ b/src/utils/readingProgressUtils.ts @@ -50,23 +50,23 @@ export function filterByReadingProgress( return items.filter((item) => { const progress = item.readingProgress || 0 - const isMarked = item.markedAsRead || false + // Reading progress filters MUST ignore emoji/archive reactions const hasHighlights = (articleHighlightCount.get(item.id) || 0) > 0 || (item.url && (articleHighlightCount.get(item.url) || 0) > 0) switch (filter) { case 'unopened': - return progress === 0 && !isMarked + return progress === 0 case 'started': - return progress > 0 && progress <= 0.10 && !isMarked + return progress > 0 && progress <= 0.10 case 'reading': - return progress > 0.10 && progress <= 0.94 && !isMarked + return progress > 0.10 && progress <= 0.94 case 'completed': // Completed is 95%+ progress only (no emoji fallback) return progress >= 0.95 case 'archive': - // Archive-marked items (previously emoji-marked) regardless of progress - return isMarked + // Archive filter handled upstream; keep fallback as false to avoid mixing + return false case 'highlighted': return hasHighlights case 'all':