@ -30,15 +30,19 @@
{
{
useCache: true,
useCache: true,
cacheResults: true,
cacheResults: true,
onUpdate: (updatedEvents) => {
onUpdate: async (updatedEvents) => {
// Update threads when fresh data arrives from relays
// Update threads when fresh data arrives from relays
threads = sortThreads(updatedEvents);
threads = await sortThreads(updatedEvents);
}
}
}
}
);
);
// Set initial cached data immediately
// Set initial cached data immediately
threads = sortThreads(events);
if (sortBy === 'newest') {
threads = sortThreadsSync(events);
} else {
threads = await sortThreads(events);
}
} catch (error) {
} catch (error) {
console.error('Error loading threads:', error);
console.error('Error loading threads:', error);
threads = []; // Set empty array on error to prevent undefined issues
threads = []; // Set empty array on error to prevent undefined issues
@ -47,16 +51,53 @@
}
}
}
}
function sortThreads(events: NostrEvent[]): NostrEvent[] {
function sortThreadsSync(events: NostrEvent[]): NostrEvent[] {
// Synchronous version for 'newest' sorting
return [...events].sort((a, b) => b.created_at - a.created_at);
}
async function sortThreads(events: NostrEvent[]): Promise< NostrEvent [] > {
switch (sortBy) {
switch (sortBy) {
case 'newest':
case 'newest':
return [...events].sort((a, b) => b.created_at - a.created_at);
return sortThreadsSync(events );
case 'active':
case 'active':
// Placeholder - would need to count comments
// Sort by most recent comment activity
return [...events].sort((a, b) => b.created_at - a.created_at);
const activeSorted = await Promise.all(
events.map(async (event) => {
const config = nostrClient.getConfig();
const comments = await nostrClient.fetchEvents(
[{ kinds : [ 1111 ], '#E' : [ event . id ], '#K' : [ '11' ], limit : 1 } ],
[...config.defaultRelays],
{ useCache : true }
);
const lastCommentTime = comments.length > 0
? comments.sort((a, b) => b.created_at - a.created_at)[0].created_at
: event.created_at;
return { event , lastActivity : lastCommentTime } ;
})
);
return activeSorted
.sort((a, b) => b.lastActivity - a.lastActivity)
.map(({ event } ) => event);
case 'upvoted':
case 'upvoted':
// Placeholder - would need to count reactions
// Sort by upvote count
return [...events].sort((a, b) => b.created_at - a.created_at);
const upvotedSorted = await Promise.all(
events.map(async (event) => {
const config = nostrClient.getConfig();
const reactions = await nostrClient.fetchEvents(
[{ kinds : [ 7 ], '#e' : [ event . id ] } ],
[...config.defaultRelays],
{ useCache : true }
);
const upvoteCount = reactions.filter(
(r) => r.content.trim() === '+' || r.content.trim() === '⬆️ ' || r.content.trim() === '↑'
).length;
return { event , upvotes : upvoteCount } ;
})
);
return upvotedSorted
.sort((a, b) => b.upvotes - a.upvotes)
.map(({ event } ) => event);
default:
default:
return events;
return events;
}
}
@ -156,7 +197,7 @@
/>
/>
Show older threads
Show older threads
< / label >
< / label >
< select bind:value = { sortBy } onchange= {() => ( threads = sortThreads ( threads )) } class = "border border-fog-border dark:border-fog-dark-border bg-fog-post dark:bg-fog-dark-post text-fog-text dark:text-fog-dark-text px-2 py-1 rounded" >
< select bind:value = { sortBy } onchange= { async () => { threads = await sortThreads ( threads ); } } class = "border border-fog-border dark:border-fog-dark-border bg-fog-post dark:bg-fog-dark-post text-fog-text dark:text-fog-dark-text px-2 py-1 rounded" >
< option value = "newest" > Newest< / option >
< option value = "newest" > Newest< / option >
< option value = "active" > Most Active< / option >
< option value = "active" > Most Active< / option >
< option value = "upvoted" > Most Upvoted< / option >
< option value = "upvoted" > Most Upvoted< / option >