fix: mobile tags pills show all active tags regardless of item count

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Yusuf Suleman
2026-04-01 22:42:56 -05:00
parent 9f51f3bcd3
commit 2ab27d048a
2 changed files with 49 additions and 18 deletions

View File

@@ -452,10 +452,9 @@
</button>
{/each}
<span class="pill-separator"></span>
{#each sidebarTags.filter(t => t.is_active && t.item_count > 0) as tag}
{#each sidebarTags.filter(t => t.is_active) as tag}
<button class="pill pill-tag" class:active={activeTag === tag.name} onclick={() => { activeTag = tag.name; activeTagId = tag.id; activeFolder = null; activeFolderId = null; loadItems(); }}>
#{tag.name}
<span class="pill-count">{tag.item_count}</span>
</button>
{/each}
</div>

View File

@@ -27,6 +27,7 @@
let autoScrollSpeed = $state(1.5);
let articleListEl: HTMLDivElement;
let scrollRAF: number | null = null;
let lastScrollTs = 0;
let loading = $state(true);
let loadingMore = $state(false);
let hasMore = $state(true);
@@ -315,22 +316,31 @@
if (scrollRAF) cancelAnimationFrame(scrollRAF);
if (!usesPageScroll() && !articleListEl) return;
autoScrollActive = true;
function step() {
lastScrollTs = 0;
function step(timestamp: number) {
if (!autoScrollActive) return;
const dt = lastScrollTs ? Math.min(34, timestamp - lastScrollTs) : 16;
lastScrollTs = timestamp;
const pxPerSecond = 28 * autoScrollSpeed;
const delta = pxPerSecond * (dt / 1000);
if (usesPageScroll()) {
const nextY = window.scrollY + autoScrollSpeed;
const maxY = Math.max(0, document.documentElement.scrollHeight - window.innerHeight);
window.scrollTo({ top: Math.min(nextY, maxY), behavior: 'auto' });
if (nextY >= maxY) {
const scroller = document.scrollingElement;
if (!scroller) return;
const nextY = scroller.scrollTop + delta;
const maxY = Math.max(0, scroller.scrollHeight - window.innerHeight);
scroller.scrollTop = Math.min(nextY, maxY);
checkScrolledCards();
if (nextY >= maxY - 1) {
stopAutoScroll();
return;
}
} else {
if (!articleListEl) return;
articleListEl.scrollTop += autoScrollSpeed;
articleListEl.scrollTop += delta;
const maxScroll = articleListEl.scrollHeight - articleListEl.clientHeight;
if (articleListEl.scrollTop >= maxScroll) {
checkScrolledCards();
if (articleListEl.scrollTop >= maxScroll - 1) {
stopAutoScroll();
return;
}
@@ -342,6 +352,7 @@
}
function stopAutoScroll() {
autoScrollActive = false;
lastScrollTs = 0;
if (scrollRAF) { cancelAnimationFrame(scrollRAF); scrollRAF = null; }
}
function toggleAutoScroll() {
@@ -366,6 +377,7 @@
let scrollCheckTimer: ReturnType<typeof setTimeout> | null = null;
function handleListScroll() {
if (usesPageScroll()) return;
// Throttle: only check every 400ms
if (scrollCheckTimer) return;
scrollCheckTimer = setTimeout(() => {
@@ -374,21 +386,40 @@
}, 400);
}
function handleViewportScroll() {
if (!usesPageScroll()) return;
if (scrollCheckTimer) return;
scrollCheckTimer = setTimeout(() => {
scrollCheckTimer = null;
checkScrolledCards();
}, 240);
}
function checkScrolledCards() {
if (!articleListEl) return;
// Infinite scroll — load more when near bottom
const cards = articleListEl.querySelectorAll('[data-entry-id]');
if (usesPageScroll()) {
const pageBottom = window.scrollY + window.innerHeight;
const loadThreshold = document.documentElement.scrollHeight - 500;
if (hasMore && !loadingMore && pageBottom >= loadThreshold) {
loadEntries(true);
}
} else {
const { scrollTop, scrollHeight, clientHeight } = articleListEl;
if (hasMore && !loadingMore && scrollHeight - scrollTop - clientHeight < 300) {
loadEntries(true);
}
}
const listTop = articleListEl.getBoundingClientRect().top;
const cards = articleListEl.querySelectorAll('[data-entry-id]');
let newlyRead = 0;
cards.forEach(card => {
if (card.getBoundingClientRect().bottom < listTop + 20) {
const rect = card.getBoundingClientRect();
const passedThreshold = usesPageScroll()
? rect.bottom < 84
: rect.bottom < articleListEl.getBoundingClientRect().top + 20;
if (passedThreshold) {
const id = Number(card.getAttribute('data-entry-id'));
if (!id) return;
const article = articles.find(a => a.id === id);
@@ -422,16 +453,17 @@
}
// ── Init ──
onMount(() => {
onMount(() => {
loadSidebar();
loadEntries();
return () => {
if (flushTimer) clearTimeout(flushTimer);
if (scrollCheckTimer) clearTimeout(scrollCheckTimer);
};
});
</script>
<svelte:window onkeydown={handleKeydown} />
<svelte:window onkeydown={handleKeydown} onscroll={handleViewportScroll} />
<div class="reader-layout">