replies timeline only, appview-less bluesky client

fix each error by not using array as each key but just index in RichText

ptr.pet 6bc6e038 d47ce48d

verified
-1
src/components/BskyPost.svelte
··· 10 10 import { 11 11 parseCanonicalResourceUri, 12 12 type ActorIdentifier, 13 - type CanonicalResourceUri, 14 13 type Did, 15 14 type RecordKey, 16 15 type ResourceUri
+5 -4
src/components/FollowingView.svelte
··· 28 28 let isLongCalculation = $state(false); 29 29 let calculationTimer: ReturnType<typeof setTimeout> | undefined; 30 30 31 - // Optimization: Use a static timestamp for calculation to avoid re-sorting every second. 32 - // Only update this when the sort mode changes. 31 + // we could update the "now" every second but its pretty unnecessary 32 + // so we only do it when we receive new data or sort mode changes 33 33 let staticNow = $state(Date.now()); 34 34 35 35 const updateList = async () => { ··· 59 59 ) 60 60 : null; 61 61 62 - const userStatsList = Array.from(followsMap.values()).map((f) => ({ 62 + const userStatsList = followsMap.values().map((f) => ({ 63 63 did: f.subject, 64 64 data: calculateFollowedUserStats( 65 65 followingSort, ··· 80 80 isLongCalculation = false; 81 81 }; 82 82 83 + // todo: there is a bug where 83 84 $effect(() => { 84 85 // Dependencies that trigger a re-sort 85 86 // eslint-disable-next-line @typescript-eslint/no-unused-vars 86 87 const _s = followingSort; 87 88 // eslint-disable-next-line @typescript-eslint/no-unused-vars 88 - const _f = followsMap; 89 + const _f = followsMap?.size; 89 90 // Update time when sort changes 90 91 staticNow = Date.now(); 91 92
+2 -2
src/components/ProfileView.svelte
··· 71 71 </script> 72 72 73 73 <div class="flex min-h-dvh flex-col"> 74 - <!-- Header --> 74 + <!-- header --> 75 75 <div 76 76 class="sticky top-0 z-20 flex items-center gap-4 border-b-2 bg-(--nucleus-bg)/80 p-4 backdrop-blur-md" 77 77 style="border-color: {color}40;" ··· 96 96 <p>failed to load profile: {error}</p> 97 97 </div> 98 98 {:else} 99 - <!-- Banner --> 99 + <!-- banner --> 100 100 <div class="relative h-32 w-full overflow-hidden bg-(--nucleus-fg)/5 md:h-48"> 101 101 {#if bannerUrl} 102 102 <img src={bannerUrl} alt="banner" class="h-full w-full object-cover" />
+2 -2
src/components/RichText.svelte
··· 33 33 {/snippet} 34 34 35 35 {#snippet segments(segments: RichtextSegment[])} 36 - {#each segments as segment, idx ([segment, idx])} 36 + {#each segments as segment, idx (idx)} 37 37 {@const { text, features: _features } = segment} 38 38 {@const features = _features ?? []} 39 39 {#if features.length > 0} 40 - {#each features as feature, idx ([feature, idx])} 40 + {#each features as feature, idx (idx)} 41 41 {#if feature.$type === 'app.bsky.richtext.facet#mention'} 42 42 <a 43 43 class="text-(--nucleus-accent2) hover:cursor-pointer hover:underline"