Use Fragment.content extension, improve comment composables

This commit is contained in:
Isira Seneviratne 2024-08-26 19:23:50 +05:30
parent 3641698379
commit d3a6991fd4
4 changed files with 56 additions and 76 deletions

View File

@ -216,7 +216,7 @@ dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.documentfile:documentfile:1.0.1'
implementation 'androidx.fragment:fragment-ktx:1.6.2'
implementation 'androidx.fragment:fragment-compose:1.8.2'
implementation "androidx.lifecycle:lifecycle-livedata-ktx:${androidxLifecycleVersion}"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:${androidxLifecycleVersion}"
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.1.0'

View File

@ -3,28 +3,25 @@ package org.schabi.newpipe.fragments.list.comments
import android.os.Bundle
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.fragment.compose.content
import org.schabi.newpipe.ui.components.comment.CommentSection
import org.schabi.newpipe.ui.theme.AppTheme
import org.schabi.newpipe.util.KEY_SERVICE_ID
import org.schabi.newpipe.util.KEY_URL
import org.schabi.newpipe.viewmodels.CommentsViewModel
class CommentsFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
) = ComposeView(requireContext()).apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
val viewModel = viewModel<CommentsViewModel>()
AppTheme {
CommentSection(commentsFlow = viewModel.comments)
) = content {
AppTheme {
Surface(color = MaterialTheme.colorScheme.background) {
CommentSection()
}
}
}

View File

@ -2,14 +2,12 @@ package org.schabi.newpipe.fragments.list.videos
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.fragment.compose.content
import org.schabi.newpipe.extractor.stream.StreamInfo
import org.schabi.newpipe.ktx.serializable
import org.schabi.newpipe.ui.components.video.RelatedItems
@ -21,15 +19,10 @@ class RelatedItemsFragment : Fragment() {
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return ComposeView(requireContext()).apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
AppTheme {
Surface(color = MaterialTheme.colorScheme.background) {
RelatedItems(requireArguments().serializable<StreamInfo>(KEY_INFO)!!)
}
}
) = content {
AppTheme {
Surface(color = MaterialTheme.colorScheme.background) {
RelatedItems(requireArguments().serializable<StreamInfo>(KEY_INFO)!!)
}
}
}

View File

@ -1,30 +1,24 @@
package org.schabi.newpipe.ui.components.comment
import android.content.res.Configuration
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.rememberNestedScrollInteropConnection
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.paging.LoadState
import androidx.paging.LoadStates
import androidx.paging.PagingData
@ -37,66 +31,58 @@ import org.schabi.newpipe.extractor.comments.CommentsInfoItem
import org.schabi.newpipe.extractor.stream.Description
import org.schabi.newpipe.paging.CommentsDisabledException
import org.schabi.newpipe.ui.components.common.LoadingIndicator
import org.schabi.newpipe.ui.components.common.NoItemsMessage
import org.schabi.newpipe.ui.theme.AppTheme
import org.schabi.newpipe.viewmodels.CommentsViewModel
@Composable
fun CommentSection(commentsViewModel: CommentsViewModel = viewModel()) {
CommentSection(commentsFlow = commentsViewModel.comments)
}
@Composable
fun CommentSection(
parentComment: CommentsInfoItem? = null,
commentsFlow: Flow<PagingData<CommentsInfoItem>>
) {
Surface(color = MaterialTheme.colorScheme.background) {
val comments = commentsFlow.collectAsLazyPagingItems()
val itemCount by remember { derivedStateOf { comments.itemCount } }
val nestedScrollInterop = rememberNestedScrollInteropConnection()
val state = rememberLazyListState()
val comments = commentsFlow.collectAsLazyPagingItems()
val itemCount by remember { derivedStateOf { comments.itemCount } }
val nestedScrollInterop = rememberNestedScrollInteropConnection()
val state = rememberLazyListState()
LazyColumnScrollbar(state = state) {
LazyColumn(modifier = Modifier.nestedScroll(nestedScrollInterop), state = state) {
if (parentComment != null) {
item {
CommentRepliesHeader(comment = parentComment)
HorizontalDivider(thickness = 1.dp)
LazyColumnScrollbar(state = state) {
LazyColumn(modifier = Modifier.nestedScroll(nestedScrollInterop), state = state) {
if (parentComment != null) {
item {
CommentRepliesHeader(comment = parentComment)
HorizontalDivider(thickness = 1.dp)
}
}
if (itemCount == 0) {
item {
val refresh = comments.loadState.refresh
if (refresh is LoadState.Loading) {
LoadingIndicator(modifier = Modifier.padding(top = 8.dp))
} else {
val error = (refresh as? LoadState.Error)?.error
val message = if (error is CommentsDisabledException) {
R.string.comments_are_disabled
} else {
R.string.no_comments
}
NoItemsMessage(message)
}
}
if (itemCount == 0) {
item {
val refresh = comments.loadState.refresh
if (refresh is LoadState.Loading) {
LoadingIndicator(modifier = Modifier.padding(top = 8.dp))
} else {
NoCommentsMessage((refresh as? LoadState.Error)?.error)
}
}
} else {
items(itemCount) {
Comment(comment = comments[it]!!)
}
} else {
items(itemCount) {
Comment(comment = comments[it]!!)
}
}
}
}
}
@Composable
private fun NoCommentsMessage(error: Throwable?) {
val message = if (error is CommentsDisabledException) {
R.string.comments_are_disabled
} else {
R.string.no_comments
}
Column(
modifier = Modifier
.fillMaxWidth()
.wrapContentSize(Alignment.Center),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(text = "(╯°-°)╯", fontSize = 35.sp)
Text(text = stringResource(id = message), fontSize = 24.sp)
}
}
private class CommentDataProvider : PreviewParameterProvider<PagingData<CommentsInfoItem>> {
private val notLoading = LoadState.NotLoading(true)
@ -130,7 +116,9 @@ private fun CommentSectionPreview(
@PreviewParameter(CommentDataProvider::class) pagingData: PagingData<CommentsInfoItem>
) {
AppTheme {
CommentSection(commentsFlow = flowOf(pagingData))
Surface(color = MaterialTheme.colorScheme.background) {
CommentSection(commentsFlow = flowOf(pagingData))
}
}
}
@ -154,6 +142,8 @@ private fun CommentRepliesPreview() {
val flow = flowOf(PagingData.from(replies))
AppTheme {
CommentSection(parentComment = comment, commentsFlow = flow)
Surface(color = MaterialTheme.colorScheme.background) {
CommentSection(parentComment = comment, commentsFlow = flow)
}
}
}