dont show threads on following timeline if the root thread is not user we follow
10 unmodified lines111213141515161718192024 unmodified lines454647484849495051525354555657585960616257636465666768140 unmodified linesExpand all10 unmodified lines fetchFollowingTimeline, allPosts, followingFeed, accountPreferences, fetchInteractionsToFollowingTimelineEnd fetchInteractionsToFollowingTimelineEnd, follows } from '$lib/state.svelte'; import Icon from '@iconify/svelte'; import { buildThreads, filterThreads, type ThreadPost } from '$lib/thread'; import type { Did } from '@atcute/lexicons/syntax';24 unmodified lines
const currentPrefs = $derived(userDid ? accountPreferences.get(userDid) : null); const mutes = $derived(currentPrefs?.mutes ?? []);
// We use userDid as the 'root' for buildThreads merely to provide a context, // but we are passing `followingFeed.get(userDid)` (merged set) as the source. const followedDids = $derived.by(() => { if (!userDid) return new Set<Did>(); const map = follows.get(userDid); if (!map) return new Set<Did>(); return new Set(Array.from(map.values()).map((f) => f.subject)); });
const threads = $derived( filterThreads( userDid ? buildThreads(userDid, followingFeed.get(userDid) ?? new SvelteSet(), allPosts, mutes) : [], $accounts, { viewOwnPosts viewOwnPosts, filterRootsToDids: followedDids } ) );
140 unmodified linesExpand all456 unmodified linesExpand all45745845946046146246146246346446546846646747046846947047153 unmodified lines525526527528532533534529530531532533574 unmodified linesExpand all456 unmodified linesExpand all userFeed.add(uri); buffer.delete(uri); }
// If we had enough in buffer, return. If we exhausted buffer but needed more? // For simplicity, just return. The UI will call loadMore again if needed/short. return; }
const followsMap = follows.get(userDid); const subjects = new Set<Did>(); if (followsMap) { if (followsMap) for (const follow of followsMap.values()) subjects.add(follow.subject); } subjects.add(userDid);
// 2. Find the "newest" cursor(s) let maxCursor: string | undefined = undefined;53 unmodified lines // update cursor if (res.cursor) userCursors!.set(did, res.cursor); else userCursors!.set(did, null); // null = exhausted
for (const record of res.records) { newPosts.push(record.uri); } for (const record of res.records) newPosts.push(record.uri); }
if (newPosts.length === 0) return;
574 unmodified linesExpand all165 unmodified linesExpand all166167168169170170171172173174175176177178178179180181182183184185186187188189190191192193194195196197198165 unmodified linesExpand all accounts.some((account) => account.did === post.did);export const hasNonOwnPost = (posts: ThreadPost[], accounts: Account[]) => posts.some((post) => !isOwnPost(post, accounts));
// todo: add more filtering optionsexport type FilterOptions = { viewOwnPosts: boolean; filterRootsToDids?: Set<Did>;};
export const filterThreads = (threads: Thread[], accounts: Account[], opts: FilterOptions) => threads.filter((thread) => { if (thread.posts.length === 0) return false; if (!opts.viewOwnPosts) return hasNonOwnPost(thread.posts, accounts); if (!opts.viewOwnPosts) if (hasNonOwnPost(thread.posts, accounts)) return false;
if (opts.filterRootsToDids) { const rootDid = extractDidFromUri(thread.rootUri); if ( rootDid && !opts.filterRootsToDids.has(rootDid) && !accounts.some((a) => a.did === rootDid) ) { return false; } }
return true; });
// Helper to extract DID from URI if not already imported from elsewhereconst extractDidFromUri = (uri: ResourceUri): Did | null => { const match = uri.match(/^at:\/\/(did:plc:[a-z0-9]+)/); return match ? (match[1] as Did) : null;};