diff --git a/packages/mobile/src/components/comments/CommentDrawer.tsx b/packages/mobile/src/components/comments/CommentDrawer.tsx
index 9d80fa6a1bd..833be4c8cbe 100644
--- a/packages/mobile/src/components/comments/CommentDrawer.tsx
+++ b/packages/mobile/src/components/comments/CommentDrawer.tsx
@@ -14,6 +14,7 @@ import {
import { useSafeAreaInsets } from 'react-native-safe-area-context'
import { Box, Divider, Flex, useTheme } from '@audius/harmony-native'
+import { LoadingSpinner } from 'app/harmony-native/components/LoadingSpinner/LoadingSpinner'
import { useDrawer } from 'app/hooks/useDrawer'
import { CommentDrawerForm } from './CommentDrawerForm'
@@ -25,8 +26,12 @@ import { useGestureEventsHandlers } from './useGestureEventHandlers'
import { useScrollEventsHandlers } from './useScrollEventHandlers'
const CommentDrawerContent = () => {
- const { comments, commentSectionLoading: isLoading } =
- useCurrentCommentSection()
+ const {
+ comments,
+ commentSectionLoading: isLoading,
+ loadMorePages,
+ isLoadingMorePages
+ } = useCurrentCommentSection()
// Loading state
if (isLoading) {
@@ -53,10 +58,22 @@ const CommentDrawerContent = () => {
data={comments}
keyExtractor={({ id }) => id}
ListHeaderComponent={}
- ListFooterComponent={}
+ ListFooterComponent={
+ <>
+ {isLoadingMorePages ? (
+
+
+
+ ) : null}
+
+
+ >
+ }
enableFooterMarginAdjustment
scrollEventsHandlersHook={useScrollEventsHandlers}
keyboardShouldPersistTaps='handled'
+ onEndReached={loadMorePages}
+ onEndReachedThreshold={0.3}
renderItem={({ item }) => (
diff --git a/packages/mobile/src/components/comments/CommentThread.tsx b/packages/mobile/src/components/comments/CommentThread.tsx
index c5c4914d618..8f5330ccacb 100644
--- a/packages/mobile/src/components/comments/CommentThread.tsx
+++ b/packages/mobile/src/components/comments/CommentThread.tsx
@@ -1,7 +1,6 @@
import { useState } from 'react'
-import { useGetCommentById } from '@audius/common/api'
-import { useCurrentCommentSection } from '@audius/common/context'
+import { useGetCommentById, useGetCommentRepliesById } from '@audius/common/api'
import { commentsMessages as messages } from '@audius/common/messages'
import type { ReplyComment } from '@audius/sdk'
@@ -25,8 +24,6 @@ export const CommentThread = (props: CommentThreadProps) => {
id: commentId
})
- const { handleLoadMoreReplies } = useCurrentCommentSection()
-
const [hiddenReplies, setHiddenReplies] = useState<{
[parentCommentId: number]: boolean
}>({})
@@ -36,6 +33,36 @@ export const CommentThread = (props: CommentThreadProps) => {
newHiddenReplies[commentId] = !newHiddenReplies[commentId]
setHiddenReplies(newHiddenReplies)
}
+ const [hasLoadedMore, setHasLoadedMore] = useState(false)
+ const {
+ data: moreReplies,
+ loadMore,
+ hasMore
+ } = useGetCommentRepliesById(
+ { id: commentId },
+ {
+ // Root comments already have the first 3 replies so we only need to load more when the user requests them
+ disabled: (rootComment?.replies?.length ?? 0) < 3 || !hasLoadedMore,
+ pageSize: 3,
+ // Start at the 4th reply
+ startOffset: 3
+ }
+ )
+
+ const hasMoreReplies = hasMore && (rootComment?.replies?.length ?? 0) >= 3
+
+ const handleLoadMoreReplies = () => {
+ if (hasLoadedMore) {
+ loadMore()
+ } else {
+ // If hasLoadedMore is false, this is the first time the user is requesting more replies
+ // In this case audius-query will automatically fetch the first page of replies, no need to trigger via loadMore()
+ setHasLoadedMore(true)
+ }
+ }
+
+ // Combine the replies from the root comment and the additional loaded replies
+ const allReplies = [...(rootComment?.replies ?? []), ...(moreReplies ?? [])]
if (!rootComment) return null
@@ -43,7 +70,7 @@ export const CommentThread = (props: CommentThreadProps) => {
<>
- {(rootComment?.replies?.length ?? 0) > 0 ? (
+ {(allReplies.length ?? 0) > 0 ? (
toggleReplies(rootComment.id)}
@@ -59,7 +86,7 @@ export const CommentThread = (props: CommentThreadProps) => {
{hiddenReplies[rootComment.id] ? null : (
<>
- {rootComment?.replies?.map((reply: ReplyComment) => (
+ {allReplies?.map((reply: ReplyComment) => (
{
))}
- {(rootComment?.replies?.length ?? 0) > 0 ? (
-
- handleLoadMoreReplies(rootComment.id)}
- >
- {messages.showMoreReplies}
-
-
+ {hasMoreReplies ? (
+
+ {messages.showMoreReplies}
+
) : null}
>
)}
diff --git a/packages/web/src/components/comments/CommentSectionDesktop.tsx b/packages/web/src/components/comments/CommentSectionDesktop.tsx
index 4e98319b844..55c6cd5178e 100644
--- a/packages/web/src/components/comments/CommentSectionDesktop.tsx
+++ b/packages/web/src/components/comments/CommentSectionDesktop.tsx
@@ -1,4 +1,4 @@
-import { useEffect, useRef } from 'react'
+import { useRef } from 'react'
import { useCurrentCommentSection } from '@audius/common/context'
import { Button, Divider, Flex, LoadingSpinner, Paper } from '@audius/harmony'
@@ -34,15 +34,6 @@ export const CommentSectionDesktop = () => {
const commentPostAllowed = currentUserId !== null
const commentSectionRef = useRef(null)
- // Need refs for these values because the scroll handler will not be able to access state changes
- const isLoadingMorePagesRef = useRef(isLoadingMorePages)
- const hasMorePagesRef = useRef(hasMorePages)
- useEffect(() => {
- // Keep the ref values up to date
- isLoadingMorePagesRef.current = isLoadingMorePages
- hasMorePagesRef.current = hasMorePages
- }, [isLoadingMorePages, hasMorePages])
-
if (commentSectionLoading) {
return
}
diff --git a/packages/web/src/components/comments/CommentThread.tsx b/packages/web/src/components/comments/CommentThread.tsx
index 013d6b9cfe3..e8fe7335947 100644
--- a/packages/web/src/components/comments/CommentThread.tsx
+++ b/packages/web/src/components/comments/CommentThread.tsx
@@ -96,7 +96,7 @@ export const CommentThread = ({ commentId }: { commentId: string }) => {
))}
)}
- {/* TODO: need a way to hide this when no more to load */}
+
{hasMoreReplies ? (