From d5833347623e0e7f64b4669be420d48ec043e02c Mon Sep 17 00:00:00 2001 From: sam Date: Mon, 28 Jul 2025 17:51:59 +0700 Subject: [PATCH 1/7] also mark note as approved if the author is the community creator --- src/components/groups/PostList.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/components/groups/PostList.tsx b/src/components/groups/PostList.tsx index 5a68d8d7..78c1dafe 100644 --- a/src/components/groups/PostList.tsx +++ b/src/components/groups/PostList.tsx @@ -343,10 +343,11 @@ export function PostList({ communityId, showOnlyApproved = true, pendingOnly = f } // For legacy kind 11 posts, they are always considered top-level - // Auto-approve for approved members and moderators + // Auto-approve for approved members, moderators, and the community owner const isApprovedMember = approvedMembers.includes(post.pubkey); const isModerator = moderators.includes(post.pubkey); - if (isApprovedMember || isModerator) { + const isOwner = communityEvent && post.pubkey === communityEvent.pubkey; + if (isApprovedMember || isModerator || isOwner) { return { ...post, approval: { @@ -396,10 +397,11 @@ export function PostList({ communityId, showOnlyApproved = true, pendingOnly = f return existingApproval; } - // Auto-approve for approved members and moderators - const isApprovedMember = approvedMembers.includes(post.pubkey); - const isModerator = moderators.includes(post.pubkey); - if (isApprovedMember || isModerator) { + // Auto-approve for approved members, moderators, and the community owner + const isApprovedMember = approvedMembers.includes(post.pubkey); + const isModerator = moderators.includes(post.pubkey); + const isOwner = communityEvent && post.pubkey === communityEvent.pubkey; + if (isApprovedMember || isModerator || isOwner) { return { ...post, approval: { From 95a0e04dcdbcfed53ad589d4a7330a39e1fa2324 Mon Sep 17 00:00:00 2001 From: sam Date: Mon, 28 Jul 2025 17:57:22 +0700 Subject: [PATCH 2/7] refactor code a little --- src/components/groups/PostList.tsx | 34 +++++++++++++++--------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/components/groups/PostList.tsx b/src/components/groups/PostList.tsx index 78c1dafe..4a37224d 100644 --- a/src/components/groups/PostList.tsx +++ b/src/components/groups/PostList.tsx @@ -347,19 +347,19 @@ export function PostList({ communityId, showOnlyApproved = true, pendingOnly = f const isApprovedMember = approvedMembers.includes(post.pubkey); const isModerator = moderators.includes(post.pubkey); const isOwner = communityEvent && post.pubkey === communityEvent.pubkey; - if (isApprovedMember || isModerator || isOwner) { - return { - ...post, - approval: { + const isApproved = isApprovedMember || isModerator || isOwner + + return { + ...post, + ...(isApproved ? { approval: { id: `auto-approved-${post.id}`, pubkey: post.pubkey, created_at: post.created_at, autoApproved: true, kind: post.kind } - }; - } - return post; + } : {}) + }; }).filter(Boolean); // Count approved and pending posts @@ -398,22 +398,22 @@ export function PostList({ communityId, showOnlyApproved = true, pendingOnly = f } // Auto-approve for approved members, moderators, and the community owner - const isApprovedMember = approvedMembers.includes(post.pubkey); - const isModerator = moderators.includes(post.pubkey); - const isOwner = communityEvent && post.pubkey === communityEvent.pubkey; - if (isApprovedMember || isModerator || isOwner) { - return { - ...post, - approval: { + const isApprovedMember = approvedMembers.includes(post.pubkey); + const isModerator = moderators.includes(post.pubkey); + const isOwner = communityEvent && post.pubkey === communityEvent.pubkey; + const isApproved = isApprovedMember || isModerator || isOwner + + return { + ...post, + ...(isApproved ? { approval: { id: `auto-approved-${post.id}`, pubkey: post.pubkey, created_at: post.created_at, autoApproved: true, kind: post.kind } - }; - } - return post; + } : {}) + }; }); // Filter pinned posts based on approval status From 48abbcf15b46ec6d747189410d6754d7c158af99 Mon Sep 17 00:00:00 2001 From: sam Date: Mon, 28 Jul 2025 18:35:15 +0700 Subject: [PATCH 3/7] determine approval prop in one place only --- src/components/groups/PostList.tsx | 106 ++++++++++++----------------- 1 file changed, 43 insertions(+), 63 deletions(-) diff --git a/src/components/groups/PostList.tsx b/src/components/groups/PostList.tsx index 4a37224d..4891522d 100644 --- a/src/components/groups/PostList.tsx +++ b/src/components/groups/PostList.tsx @@ -342,24 +342,7 @@ export function PostList({ communityId, showOnlyApproved = true, pendingOnly = f if (isNestedReply) return post; } - // For legacy kind 11 posts, they are always considered top-level - // Auto-approve for approved members, moderators, and the community owner - const isApprovedMember = approvedMembers.includes(post.pubkey); - const isModerator = moderators.includes(post.pubkey); - const isOwner = communityEvent && post.pubkey === communityEvent.pubkey; - const isApproved = isApprovedMember || isModerator || isOwner - - return { - ...post, - ...(isApproved ? { approval: { - id: `auto-approved-${post.id}`, - pubkey: post.pubkey, - created_at: post.created_at, - autoApproved: true, - kind: post.kind - } - } : {}) - }; + return post; }).filter(Boolean); // Count approved and pending posts @@ -384,63 +367,60 @@ export function PostList({ communityId, showOnlyApproved = true, pendingOnly = f // Memoize the sorted posts to avoid unnecessary re-renders const sortedPosts = useMemo(() => { - // Process pinned posts through the same approval logic const pinnedPostsProcessed = (pinnedPosts || []) .filter(post => !removedPostIds.includes(post.id) && !bannedUsers.includes(post.pubkey) ) - .map(post => { - // Check if this pinned post is already in the approved posts - const existingApproval = (approvedPosts || []).find(ap => ap.id === post.id); - if (existingApproval) { - return existingApproval; - } - - // Auto-approve for approved members, moderators, and the community owner - const isApprovedMember = approvedMembers.includes(post.pubkey); - const isModerator = moderators.includes(post.pubkey); - const isOwner = communityEvent && post.pubkey === communityEvent.pubkey; - const isApproved = isApprovedMember || isModerator || isOwner - - return { - ...post, - ...(isApproved ? { approval: { - id: `auto-approved-${post.id}`, - pubkey: post.pubkey, - created_at: post.created_at, - autoApproved: true, - kind: post.kind - } - } : {}) - }; - }); + // Combine all posts and apply approval logic once + const allPosts = [ + ...filteredPosts, + ...pinnedPostsProcessed + ]; + + // Apply approval logic to all posts + const postsWithApproval = allPosts.map(post => { + if (!post) return post; + + // If post already has approval info, return it as is + if ('approval' in post) return post; + + // Auto-approve for approved members, moderators, and the community owner + const isApprovedMember = approvedMembers.includes(post.pubkey); + const isModerator = moderators.includes(post.pubkey); + const isOwner = communityEvent && post.pubkey === communityEvent.pubkey; + const isApproved = isApprovedMember || isModerator || isOwner; + + return { + ...post, + ...(isApproved ? { approval: { + id: `auto-approved-${post.id}`, + pubkey: post.pubkey, + created_at: post.created_at, + autoApproved: true, + kind: post.kind + }} : {}) + }; + }); - // Filter pinned posts based on approval status - let filteredPinnedPosts = pinnedPostsProcessed; + // Filter posts based on approval status + let filteredPostsWithApproval = postsWithApproval; if (showOnlyApproved) { - filteredPinnedPosts = pinnedPostsProcessed.filter(post => 'approval' in post); + filteredPostsWithApproval = postsWithApproval.filter(post => 'approval' in post); } else if (pendingOnly) { - filteredPinnedPosts = pinnedPostsProcessed.filter(post => !('approval' in post)); + filteredPostsWithApproval = postsWithApproval.filter(post => { + // If it has an approval property, it's either manually approved or auto-approved + if ('approval' in post) { + return false; + } + return true; + }); } - // Separate regular posts (excluding pinned ones) - const regularPosts = filteredPosts.filter(post => - post && !pinnedPostIds.includes(post.id) - ); - - // Sort regular posts by creation time - const sortedRegularPosts = regularPosts.sort((a, b) => - (b?.created_at || 0) - (a?.created_at || 0) - ); - - // Sort pinned posts by creation time (most recent pins first) - const sortedPinnedPosts = filteredPinnedPosts.sort((a, b) => + // Sort all posts by creation time (pinned posts will naturally be at the top due to their IDs) + return filteredPostsWithApproval.sort((a, b) => (b?.created_at || 0) - (a?.created_at || 0) ); - - // Combine pinned posts first, then regular posts - return [...sortedPinnedPosts, ...sortedRegularPosts]; }, [ pinnedPosts, removedPostIds, From df09811312b6ae2d468e7db32aa2f5f8541e0a7b Mon Sep 17 00:00:00 2001 From: sam Date: Mon, 28 Jul 2025 18:37:42 +0700 Subject: [PATCH 4/7] since we already kept in / failed fast falsies, filter only for truthies --- src/components/groups/PostList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/groups/PostList.tsx b/src/components/groups/PostList.tsx index 4891522d..f07beb6c 100644 --- a/src/components/groups/PostList.tsx +++ b/src/components/groups/PostList.tsx @@ -401,7 +401,7 @@ export function PostList({ communityId, showOnlyApproved = true, pendingOnly = f kind: post.kind }} : {}) }; - }); + }).filter(Boolean); // Filter posts based on approval status let filteredPostsWithApproval = postsWithApproval; From 0bfc5fe3225ae3cb9211dfe457e3ac1a701c0be6 Mon Sep 17 00:00:00 2001 From: sam Date: Mon, 28 Jul 2025 18:48:07 +0700 Subject: [PATCH 5/7] iife filteredPosts to be more immutable, purer --- src/components/groups/PostList.tsx | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/components/groups/PostList.tsx b/src/components/groups/PostList.tsx index f07beb6c..cf51bb26 100644 --- a/src/components/groups/PostList.tsx +++ b/src/components/groups/PostList.tsx @@ -404,18 +404,20 @@ export function PostList({ communityId, showOnlyApproved = true, pendingOnly = f }).filter(Boolean); // Filter posts based on approval status - let filteredPostsWithApproval = postsWithApproval; - if (showOnlyApproved) { - filteredPostsWithApproval = postsWithApproval.filter(post => 'approval' in post); - } else if (pendingOnly) { - filteredPostsWithApproval = postsWithApproval.filter(post => { - // If it has an approval property, it's either manually approved or auto-approved - if ('approval' in post) { - return false; - } - return true; - }); - } + const filteredPostsWithApproval = (() => { + if (showOnlyApproved) { + return postsWithApproval.filter(post => 'approval' in post); + } else if (pendingOnly) { + return postsWithApproval.filter(post => { + // If it has an approval property, it's either manually approved or auto-approved + if ('approval' in post) { + return false; + } + return true; + }); + } + return postsWithApproval; + })(); // Sort all posts by creation time (pinned posts will naturally be at the top due to their IDs) return filteredPostsWithApproval.sort((a, b) => From 4ae03b15af0572fc4891165c81b3ec6219cb2e9e Mon Sep 17 00:00:00 2001 From: sam Date: Mon, 28 Jul 2025 18:51:14 +0700 Subject: [PATCH 6/7] streamline with bool chain casting --- src/components/groups/PostList.tsx | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/components/groups/PostList.tsx b/src/components/groups/PostList.tsx index cf51bb26..c2b16f6d 100644 --- a/src/components/groups/PostList.tsx +++ b/src/components/groups/PostList.tsx @@ -383,7 +383,7 @@ export function PostList({ communityId, showOnlyApproved = true, pendingOnly = f if (!post) return post; // If post already has approval info, return it as is - if ('approval' in post) return post; + if (!!post?.approval) return post; // Auto-approve for approved members, moderators, and the community owner const isApprovedMember = approvedMembers.includes(post.pubkey); @@ -406,15 +406,9 @@ export function PostList({ communityId, showOnlyApproved = true, pendingOnly = f // Filter posts based on approval status const filteredPostsWithApproval = (() => { if (showOnlyApproved) { - return postsWithApproval.filter(post => 'approval' in post); + return postsWithApproval.filter(post => !!post?.approval); } else if (pendingOnly) { - return postsWithApproval.filter(post => { - // If it has an approval property, it's either manually approved or auto-approved - if ('approval' in post) { - return false; - } - return true; - }); + return postsWithApproval.filter(post => !post?.approval); } return postsWithApproval; })(); From 5a6749a5c00561df04b42dfef46c832a865ca2ec Mon Sep 17 00:00:00 2001 From: sam Date: Tue, 29 Jul 2025 09:08:33 +0700 Subject: [PATCH 7/7] remove obsolete comment --- src/components/groups/PostList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/groups/PostList.tsx b/src/components/groups/PostList.tsx index c2b16f6d..5f260298 100644 --- a/src/components/groups/PostList.tsx +++ b/src/components/groups/PostList.tsx @@ -413,7 +413,7 @@ export function PostList({ communityId, showOnlyApproved = true, pendingOnly = f return postsWithApproval; })(); - // Sort all posts by creation time (pinned posts will naturally be at the top due to their IDs) + // Sort all posts by creation time return filteredPostsWithApproval.sort((a, b) => (b?.created_at || 0) - (a?.created_at || 0) );