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}
+
-
+
-
- {#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);
+}