diff --git a/src/components/BskyPost.svelte b/src/components/BskyPost.svelte index 4b62a13..f559ef4 100644 --- a/src/components/BskyPost.svelte +++ b/src/components/BskyPost.svelte @@ -24,7 +24,14 @@ import BskyPost from './BskyPost.svelte'; import Icon from '@iconify/svelte'; import { type Backlink, type BacklinksSource } from '$lib/at/constellation'; - import { clients, postActions, posts, pulsingPostId, type PostActions } from '$lib/state.svelte'; + import { + clients, + postActions, + posts, + pulsingPostId, + type PostActions, + currentTime + } from '$lib/state.svelte'; import * as TID from '@atcute/tid'; import type { PostWithUri } from '$lib/at/fetch'; import { onMount } from 'svelte'; @@ -405,7 +412,7 @@ title={new Date(record.createdAt).toLocaleString()} class="pl-0.5 text-nowrap text-(--nucleus-fg)/67" > - {getRelativeTime(new Date(record.createdAt))} + {getRelativeTime(new Date(record.createdAt), currentTime)}

diff --git a/src/components/FollowingView.svelte b/src/components/FollowingView.svelte index e78ba0d..b5876ea 100644 --- a/src/components/FollowingView.svelte +++ b/src/components/FollowingView.svelte @@ -1,11 +1,13 @@ +{#snippet followingItems()} + {#each sortedFollowing as user (user.did)} + {@const stats = user.data!} + {@const lastPostAt = stats.lastPostAt} + {@const relTime = getRelativeTime(lastPostAt, currentTime)} + {@const color = generateColorForDid(user.did)} +

+
+ +
+
+ {#await Promise.all([user.profile, user.handle]) then [displayName, handle]} + {displayName || handle} + @{handle} + {/await} +
+
+ + posted {relTime} + {relTime !== 'now' ? 'ago' : ''} + + {#if stats.recentPostCount > 0} + + {stats.recentPostCount} posts / 6h + + {/if} + {#if followingSort === 'conversational' && stats.conversationalScore > 0} + + ★ {stats.conversationalScore.toFixed(1)} + + {/if} +
+
+
+
+ {/each} +{/snippet} +
-
+

following

@@ -92,13 +251,13 @@
-
- {#each ['recent', 'active'] as Sort[] as type (type)} +
+ {#each ['recent', 'active', 'conversational'] as type (type)} @@ -115,57 +274,7 @@ >
{:else} - {#each sortedFollowing as user (user.did)} - {@const lastPostAt = user.lastPostAt} - {@const relTime = getRelativeTime(lastPostAt)} - {@const color = generateColorForDid(user.did)} - {@const isHighlighted = highlightedDid === user.did} - {@const displayName = getClient(user.did as AtprotoDid) - .then((client) => client.getProfile()) - .then((profile) => { - if (profile.ok) return profile.value.displayName; - return null; - })} - {@const handle = resolveDidDoc(user.did).then((doc) => { - if (doc.ok) return doc.value.handle; - return 'handle.invalid'; - })} - -
(highlightedDid = user.did)} - onmouseleave={() => (highlightedDid = undefined)} - > - -
-
- {#await Promise.all([displayName, handle]) then [displayName, handle]} - {displayName || handle} - @{handle} - {/await} -
-
- - posted {relTime} - {relTime !== 'now' ? 'ago' : ''} - - {#if user.postsInBurst > 0} - - {user.postsInBurst} posts / 1h - - {/if} -
-
-
- {/each} + {@render followingItems()} {/if}
diff --git a/src/lib/date.ts b/src/lib/date.ts index 1ab98ac..50e42a8 100644 --- a/src/lib/date.ts +++ b/src/lib/date.ts @@ -1,5 +1,4 @@ -export const getRelativeTime = (date: Date) => { - const now = new Date(); +export const getRelativeTime = (date: Date, now: Date = new Date()) => { const diff = now.getTime() - date.getTime(); const seconds = Math.floor(diff / 1000); const minutes = Math.floor(seconds / 60); @@ -9,7 +8,7 @@ export const getRelativeTime = (date: Date) => { const years = Math.floor(months / 12); if (years > 0) return `${years}y`; - if (months > 0) return `${months}m`; + if (months > 0) return `${months}mo`; if (days > 0) return `${days}d`; if (hours > 0) return `${hours}h`; if (minutes > 0) return `${minutes}m`; diff --git a/src/lib/state.svelte.ts b/src/lib/state.svelte.ts index 2bd874d..5ea1382 100644 --- a/src/lib/state.svelte.ts +++ b/src/lib/state.svelte.ts @@ -1,6 +1,6 @@ import { writable } from 'svelte/store'; import { AtpClient, newPublicClient, type NotificationsStream } from './at/client'; -import { SvelteMap } from 'svelte/reactivity'; +import { SvelteMap, SvelteDate } from 'svelte/reactivity'; import type { Did, InferOutput, ResourceUri } from '@atcute/lexicons'; import type { Backlink } from './at/constellation'; import { fetchPostsWithBacklinks, hydratePosts, type PostWithUri } from './at/fetch'; @@ -133,3 +133,11 @@ export const handleJetstreamEvent = (event: JetstreamEvent) => { } } }; + +export const currentTime = new SvelteDate(); + +if (typeof window !== 'undefined') { + setInterval(() => { + currentTime.setTime(Date.now()); + }, 1000); +}