Enhance FeedService with reaction handling and post sorting

- Introduced a ReactionService to manage like counts for posts, improving engagement metrics.
- Implemented sorting logic for posts based on likes and timestamps, enhancing the visibility of popular content.
- Added recursive sorting for replies to maintain order within threads, ensuring a coherent display of discussions.

These changes contribute to a more dynamic and user-friendly experience within the NostrFeed module.
This commit is contained in:
padreug 2025-09-20 12:20:26 +02:00
parent 19ab660ed3
commit 1e1cd69aaf

View file

@ -46,6 +46,7 @@ export class FeedService extends BaseService {
protected relayHub: any = null
protected visibilityService: any = null
protected reactionService: any = null
// Event ID tracking for deduplication
private seenEventIds = new Set<string>()
@ -70,9 +71,11 @@ export class FeedService extends BaseService {
this.relayHub = injectService(SERVICE_TOKENS.RELAY_HUB)
this.visibilityService = injectService(SERVICE_TOKENS.VISIBILITY_SERVICE)
this.reactionService = injectService(SERVICE_TOKENS.REACTION_SERVICE)
console.log('FeedService: RelayHub injected:', !!this.relayHub)
console.log('FeedService: VisibilityService injected:', !!this.visibilityService)
console.log('FeedService: ReactionService injected:', !!this.reactionService)
if (!this.relayHub) {
throw new Error('RelayHub service not available')
@ -437,8 +440,6 @@ export class FeedService extends BaseService {
currentPost.depth = (parentPost.depth || 0) + 1
parentPost.replies = parentPost.replies || []
parentPost.replies.push(currentPost)
// Sort replies by timestamp (oldest first for better reading flow)
parentPost.replies.sort((a, b) => a.created_at - b.created_at)
} else {
// Parent not found, treat as root post
rootPosts.push(currentPost)
@ -449,12 +450,63 @@ export class FeedService extends BaseService {
}
})
// Sort root posts by newest first
rootPosts.sort((a, b) => b.created_at - a.created_at)
// Sort posts using like count and timestamp
this.sortPostsByLikesAndTime(rootPosts)
// Sort all reply threads recursively
rootPosts.forEach(post => this.sortRepliesRecursively(post))
return rootPosts
}
/**
* Sort posts by likes first, then by time (newest first)
*/
private sortPostsByLikesAndTime(posts: FeedPost[]): void {
posts.sort((a, b) => {
// Get like counts from reaction service if available
const aLikes = this.getLikeCount(a.id)
const bLikes = this.getLikeCount(b.id)
// Sort by likes first (descending)
if (aLikes !== bLikes) {
return bLikes - aLikes
}
// If likes are equal, sort by time (newest first)
return b.created_at - a.created_at
})
}
/**
* Recursively sort replies within each thread
*/
private sortRepliesRecursively(post: FeedPost): void {
if (post.replies && post.replies.length > 0) {
// Sort replies by likes first, then time
this.sortPostsByLikesAndTime(post.replies)
// Recursively sort nested replies
post.replies.forEach(reply => this.sortRepliesRecursively(reply))
}
}
/**
* Get like count for a post from ReactionService
*/
private getLikeCount(postId: string): number {
try {
if (this.reactionService && typeof this.reactionService.getEventReactions === 'function') {
const reactions = this.reactionService.getEventReactions(postId)
return reactions?.likes || 0
}
} catch (error) {
// Silently fail if reaction service is not available
console.debug('FeedService: Could not get like count for post', postId, error)
}
return 0
}
/**
* Get filtered posts for specific feed type
*/