Implement limited replies feature in NostrFeed component
- Introduced a mechanism to track posts that should display limited replies (only the first 2) instead of collapsing them entirely, enhancing user interaction with threaded discussions. - Updated the ThreadedPost component to support toggling between limited and full replies, improving visibility and engagement with nested replies. - Enhanced the FeedService to ensure proper filtering and handling of feed types, contributing to a more organized and user-friendly experience within the NostrFeed module.
This commit is contained in:
parent
872954d5ce
commit
f0a6b2bd1d
4 changed files with 85 additions and 40 deletions
|
|
@ -14,19 +14,22 @@ interface Props {
|
|||
depth?: number
|
||||
parentCollapsed?: boolean
|
||||
collapsedPosts?: Set<string>
|
||||
limitedReplyPosts?: Set<string>
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'reply-to-note', note: { id: string; content: string; pubkey: string }): void
|
||||
(e: 'toggle-like', note: FeedPost): void
|
||||
(e: 'toggle-collapse', postId: string): void
|
||||
(e: 'toggle-limited', postId: string): void
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
adminPubkeys: () => [],
|
||||
depth: 0,
|
||||
parentCollapsed: false,
|
||||
collapsedPosts: () => new Set<string>()
|
||||
collapsedPosts: () => new Set<string>(),
|
||||
limitedReplyPosts: () => new Set<string>()
|
||||
})
|
||||
|
||||
const emit = defineEmits<Emits>()
|
||||
|
|
@ -34,8 +37,11 @@ const emit = defineEmits<Emits>()
|
|||
// Check if this post is collapsed based on centralized state
|
||||
const isCollapsed = computed(() => props.collapsedPosts?.has(props.post.id) || false)
|
||||
|
||||
// Check if this post has limited replies showing (only first 2)
|
||||
const hasLimitedReplies = computed(() => props.limitedReplyPosts?.has(props.post.id) || false)
|
||||
|
||||
// Check if this post should be visible (not hidden by parent collapse)
|
||||
const isVisible = computed(() => !props.parentCollapsed)
|
||||
const isVisible = computed(() => !props.parentCollapsed && !isCollapsed.value)
|
||||
|
||||
// Check if this is an admin post
|
||||
const isAdminPost = computed(() => props.adminPubkeys.includes(props.post.pubkey))
|
||||
|
|
@ -188,16 +194,13 @@ function getRideshareType(post: FeedPost): string {
|
|||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Post Content (hidden when collapsed if has replies) -->
|
||||
<div
|
||||
v-if="!isCollapsed || !hasReplies"
|
||||
class="text-sm leading-relaxed whitespace-pre-wrap"
|
||||
>
|
||||
<!-- Post Content (always visible for non-collapsed posts) -->
|
||||
<div class="text-sm leading-relaxed whitespace-pre-wrap">
|
||||
{{ post.content }}
|
||||
</div>
|
||||
|
||||
<!-- Post Actions (hidden when collapsed) -->
|
||||
<div v-if="!isCollapsed" class="mt-2">
|
||||
<!-- Post Actions (always visible) -->
|
||||
<div class="mt-2">
|
||||
<div class="flex items-center gap-1">
|
||||
<!-- Reply Button -->
|
||||
<Button
|
||||
|
|
@ -240,25 +243,27 @@ function getRideshareType(post: FeedPost): string {
|
|||
|
||||
<!-- Render replies recursively -->
|
||||
<div v-if="hasReplies">
|
||||
<!-- Show first 2 replies when collapsed, or all when expanded -->
|
||||
<!-- Show first 2 replies when limited, or all when not limited -->
|
||||
<ThreadedPost
|
||||
v-for="reply in isCollapsed ? post.replies?.slice(0, 2) : post.replies"
|
||||
v-for="reply in hasLimitedReplies ? post.replies?.slice(0, 2) : post.replies"
|
||||
:key="reply.id"
|
||||
:post="reply"
|
||||
:admin-pubkeys="adminPubkeys"
|
||||
:get-display-name="getDisplayName"
|
||||
:get-event-reactions="getEventReactions"
|
||||
:depth="depth + 1"
|
||||
:parent-collapsed="isCollapsed"
|
||||
:parent-collapsed="false"
|
||||
:collapsed-posts="collapsedPosts"
|
||||
:limited-reply-posts="limitedReplyPosts"
|
||||
@reply-to-note="$emit('reply-to-note', $event)"
|
||||
@toggle-like="$emit('toggle-like', $event)"
|
||||
@toggle-collapse="$emit('toggle-collapse', $event)"
|
||||
@toggle-limited="$emit('toggle-limited', $event)"
|
||||
/>
|
||||
|
||||
<!-- Show "Load more replies" button when collapsed and there are more than 2 replies -->
|
||||
<!-- Show "Load more replies" button when limited and there are more than 2 replies -->
|
||||
<div
|
||||
v-if="isCollapsed && (post.replies?.length || 0) > 2"
|
||||
v-if="hasLimitedReplies && (post.replies?.length || 0) > 2"
|
||||
class="mt-2"
|
||||
:style="{ marginLeft: `${(depth + 1) * 6}px` }"
|
||||
>
|
||||
|
|
@ -266,7 +271,7 @@ function getRideshareType(post: FeedPost): string {
|
|||
variant="ghost"
|
||||
size="sm"
|
||||
class="h-6 px-2 text-xs text-muted-foreground hover:text-foreground hover:bg-accent/50"
|
||||
@click="toggleCollapse"
|
||||
@click="() => emit('toggle-limited', post.id)"
|
||||
>
|
||||
Show {{ (post.replies?.length || 0) - 2 }} more {{ (post.replies?.length || 0) - 2 === 1 ? 'reply' : 'replies' }}
|
||||
</Button>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue