{/* Topic header */}
@@ -150,11 +188,10 @@ export default function TopicFeed({ slug }: TopicFeedProps) {
onClick={toggleFollow}
disabled={followLoading}
aria-label={topic.isFollowing ? `Unfollow #${topic.name}` : `Follow #${topic.name}`}
- className={`shrink-0 px-4 py-1.5 rounded-full text-sm font-semibold transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 disabled:opacity-60 ${
- topic.isFollowing
+ className={`shrink-0 px-4 py-1.5 rounded-full text-sm font-semibold transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 disabled:opacity-60 ${topic.isFollowing
? 'bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 hover:bg-red-50 hover:text-red-600 dark:hover:bg-red-900/30 dark:hover:text-red-400'
: 'bg-blue-600 text-white hover:bg-blue-700'
- }`}
+ }`}
>
{followLoading ? '…' : topic.isFollowing ? 'Following' : 'Follow'}
@@ -181,8 +218,11 @@ export default function TopicFeed({ slug }: TopicFeedProps) {
{/* Sort bar */}
- {/* Posts list */}
-
+ {/* Posts list container with virtualization */}
+
{/* Initial loading skeletons */}
{loading &&
posts.length === 0 &&
@@ -226,8 +266,11 @@ export default function TopicFeed({ slug }: TopicFeedProps) {
)}
- {/* Post items */}
- {posts.map((post) => (
+ {/* Virtualized Top Spacer */}
+ {topSpacerHeight > 0 &&
}
+
+ {/* Virtualized Post items */}
+ {virtualPosts.map((post) => (
))}
+ {/* Virtualized Bottom Spacer */}
+ {bottomSpacerHeight > 0 && }
+
{/* Infinite scroll sentinel */}
{hasMore && }
@@ -331,4 +377,4 @@ export default function TopicFeed({ slug }: TopicFeedProps) {
);
-}
+}
\ No newline at end of file