grain.social is a photo sharing platform built on atproto. grain.social
atproto photography appview
47
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: show unpinned feed tab on current page and remove duplicate feeds list

- FeedTabs appends current page's feed as a tab even when not pinned
- Remove redundant "Pinned" section from My Feeds that duplicated custom feeds

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

+12 -21
+12 -3
app/lib/components/molecules/FeedTabs.svelte
··· 1 1 <script lang="ts"> 2 2 import { page } from '$app/state' 3 - import { pinnedFeeds } from '$lib/preferences' 3 + import { pinnedFeeds, DEFAULT_PINNED } from '$lib/preferences' 4 4 import { isAuthenticated } from '$lib/stores' 5 5 6 6 const authOnlyFeeds = new Set(['following', 'foryou']) 7 - const tabFeeds = $derived( 8 - $isAuthenticated ? $pinnedFeeds : $pinnedFeeds.filter((f) => !authOnlyFeeds.has(f.id)) 7 + const pinnedIds = $derived(new Set($pinnedFeeds.map((f) => f.id))) 8 + 9 + // Include unpinned default feed if user is currently viewing it 10 + const currentUnpinned = $derived( 11 + DEFAULT_PINNED.find((f) => !pinnedIds.has(f.id) && page.url.pathname === f.path) 9 12 ) 13 + 14 + const tabFeeds = $derived.by(() => { 15 + const pinned = $isAuthenticated ? $pinnedFeeds : $pinnedFeeds.filter((f) => !authOnlyFeeds.has(f.id)) 16 + if (currentUnpinned && $isAuthenticated) return [...pinned, currentUnpinned] 17 + return pinned 18 + }) 10 19 </script> 11 20 12 21 <div class="center-header">
-18
app/routes/feeds/+page.svelte
··· 6 6 import { isAuthenticated } from '$lib/stores' 7 7 import OGMeta from '$lib/components/atoms/OGMeta.svelte' 8 8 9 - const coreIds = new Set(DEFAULT_PINNED.map((f) => f.id)) 10 - const customFeeds = $derived($pinnedFeeds.filter((f) => !coreIds.has(f.id))) 11 9 const pinnedIds = $derived(new Set($pinnedFeeds.map((f) => f.id))) 12 10 const unpinnedDefaults = $derived(DEFAULT_PINNED.filter((f) => !pinnedIds.has(f.id))) 13 11 ··· 125 123 {/if} 126 124 </a> 127 125 {/each} 128 - 129 - {#if customFeeds.length > 0} 130 - <div class="section-label">Pinned</div> 131 - {#each customFeeds as feed (feed.id)} 132 - {@const Icon = feedIcon(feed)} 133 - <a href={feed.path} class="feed-row"> 134 - <span class="feed-icon"> 135 - <Icon size={18} /> 136 - </span> 137 - <span class="feed-label">{feed.label}</span> 138 - {#if $isAuthenticated} 139 - <PinButton {feed} stopPropagation /> 140 - {/if} 141 - </a> 142 - {/each} 143 - {/if} 144 126 145 127 {#if unpinnedDefaults.length > 0 && $isAuthenticated} 146 128 <div class="section-label">Feeds</div>