11package project.pipepipe.app.ui.screens.videodetail
22
33import androidx.activity.compose.BackHandler
4- import androidx.compose.foundation.ExperimentalFoundationApi
4+ import androidx.compose.foundation.layout.Box
55import androidx.compose.foundation.layout.fillMaxSize
6- import androidx.compose.foundation.lazy.LazyColumn
76import androidx.compose.foundation.lazy.LazyListState
8- import androidx.compose.runtime.*
7+ import androidx.compose.runtime.Composable
8+ import androidx.compose.runtime.DisposableEffect
9+ import androidx.compose.runtime.collectAsState
10+ import androidx.compose.runtime.getValue
11+ import androidx.compose.runtime.remember
12+ import androidx.compose.runtime.rememberCoroutineScope
913import androidx.compose.ui.Modifier
1014import androidx.navigation.NavHostController
11- import kotlinx.coroutines.flow.distinctUntilChanged
1215import kotlinx.coroutines.launch
1316import project.pipepipe.app.SharedContext
1417import project.pipepipe.app.ui.component.ErrorComponent
15- import project.pipepipe.app.ui.list.commentListContent
16- import project.pipepipe.shared.infoitem.StreamInfo
18+ import project.pipepipe.app.ui.list.CommentList
1719
18- @OptIn(ExperimentalFoundationApi ::class )
1920@Composable
2021fun CommentSection (
21- streamInfo : StreamInfo ,
22- navController : NavHostController ,
23- onPlayAudioClick : () -> Unit ,
24- onAddToPlaylistClick : () -> Unit ,
22+ modifier : Modifier = Modifier ,
2523 onTimestampClick : (Long ) -> Unit ,
26- modifier : Modifier = Modifier
24+ navController : NavHostController ,
2725) {
2826 val viewModel = SharedContext .sharedVideoDetailViewModel
2927 val uiState by viewModel.uiState.collectAsState()
@@ -60,56 +58,24 @@ fun CommentSection(
6058
6159 val serviceId = uiState.currentStreamInfo?.serviceId
6260
63- if (commentsState.common.error != null ) {
64- ErrorComponent (
65- error = commentsState.common.error!! ,
66- onRetry = {
67- uiState.currentStreamInfo?.let { streamInfo ->
68- coroutineScope.launch {
69- viewModel.loadComments(streamInfo)
70- }
71- }
72- },
73- modifier = modifier.fillMaxSize(),
74- shouldStartFromTop = true
75- )
76- } else {
77- when {
78- commentsState.parentComment != null -> {
79- // Replies view with common header
80- LaunchedEffect (repliesListState, commentsState.replies.nextPageUrl, commentsState.common.isLoading) {
81- snapshotFlow {
82- val layoutInfo = repliesListState.layoutInfo
83- val lastVisibleIndex = layoutInfo.visibleItemsInfo.lastOrNull()?.index ? : - 1
84- val totalItemsCount = layoutInfo.totalItemsCount
85- lastVisibleIndex to totalItemsCount
86- }
87- .distinctUntilChanged()
88- .collect { (lastVisibleIndex, totalItemsCount) ->
89- val isAtBottom = totalItemsCount > 0 && lastVisibleIndex == totalItemsCount - 1
90- val hasMoreReplies = commentsState.replies.nextPageUrl != null
91- if (isAtBottom && hasMoreReplies && ! commentsState.common.isLoading) {
92- serviceId?.let {
93- viewModel.loadMoreReplies(it)
94- }
95- }
61+ Box (modifier = modifier.fillMaxSize()) {
62+ if (commentsState.common.error != null ) {
63+ ErrorComponent (
64+ error = commentsState.common.error!! ,
65+ onRetry = {
66+ uiState.currentStreamInfo?.let { streamInfo ->
67+ coroutineScope.launch {
68+ viewModel.loadComments(streamInfo)
9669 }
97- }
98-
99- LazyColumn (
100- modifier = modifier.fillMaxSize(),
101- state = repliesListState
102- ) {
103- // Common header
104- videoDetailCommonHeader(
105- streamInfo = streamInfo,
106- navController = navController,
107- onPlayAudioClick = onPlayAudioClick,
108- onAddToPlaylistClick = onAddToPlaylistClick
109- )
110-
111- // Replies content (inline from CommentList)
112- commentListContent(
70+ }
71+ },
72+ modifier = Modifier .fillMaxSize(),
73+ shouldStartFromTop = true
74+ )
75+ } else {
76+ when {
77+ commentsState.parentComment != null -> {
78+ CommentList (
11379 comments = commentsState.replies.itemList,
11480 isLoading = commentsState.common.isLoading,
11581 hasMoreComments = commentsState.replies.nextPageUrl != null ,
@@ -123,49 +89,16 @@ fun CommentSection(
12389 },
12490 showStickyHeader = true ,
12591 onBackClick = { viewModel.backToCommentList() },
92+ listState = repliesListState,
12693 navController = navController,
12794 onTimestampClick = onTimestampClick
12895 )
129- }
130- BackHandler {
131- viewModel.backToCommentList()
132- }
133- }
134- else -> {
135- // Comments list with common header
136- LaunchedEffect (commentsListState, commentsState.comments.nextPageUrl, commentsState.common.isLoading) {
137- snapshotFlow {
138- val layoutInfo = commentsListState.layoutInfo
139- val lastVisibleIndex = layoutInfo.visibleItemsInfo.lastOrNull()?.index ? : - 1
140- val totalItemsCount = layoutInfo.totalItemsCount
141- lastVisibleIndex to totalItemsCount
96+ BackHandler () {
97+ viewModel.backToCommentList()
14298 }
143- .distinctUntilChanged()
144- .collect { (lastVisibleIndex, totalItemsCount) ->
145- val isAtBottom = totalItemsCount > 0 && lastVisibleIndex == totalItemsCount - 1
146- val hasMoreComments = commentsState.comments.nextPageUrl != null
147- if (isAtBottom && hasMoreComments && ! commentsState.common.isLoading) {
148- serviceId?.let {
149- viewModel.loadMoreComments(it)
150- }
151- }
152- }
15399 }
154-
155- LazyColumn (
156- modifier = modifier.fillMaxSize(),
157- state = commentsListState
158- ) {
159- // Common header
160- videoDetailCommonHeader(
161- streamInfo = streamInfo,
162- navController = navController,
163- onPlayAudioClick = onPlayAudioClick,
164- onAddToPlaylistClick = onAddToPlaylistClick
165- )
166-
167- // Comments content (inline from CommentList)
168- commentListContent(
100+ else -> {
101+ CommentList (
169102 comments = commentsState.comments.itemList,
170103 isLoading = commentsState.common.isLoading,
171104 hasMoreComments = commentsState.comments.nextPageUrl != null ,
@@ -183,8 +116,8 @@ fun CommentSection(
183116 }
184117 }
185118 },
186- showStickyHeader = false ,
187119 onBackClick = { },
120+ listState = commentsListState,
188121 navController = navController,
189122 onTimestampClick = onTimestampClick
190123 )
0 commit comments