From 56c80ce6dd554eab6899a05066c8274b34e6f8d2 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Fri, 17 May 2024 10:17:09 +0530 Subject: [PATCH] Added missing comment features, fixed theming --- .../java/org/schabi/newpipe/MainActivity.java | 2 +- .../fragments/list/comments/Comment.kt | 123 +++++++++---- .../list/comments/CommentRepliesFragment.kt | 5 +- .../list/comments/CommentRepliesHeader.kt | 165 ++++++++++-------- 4 files changed, 181 insertions(+), 114 deletions(-) diff --git a/app/src/main/java/org/schabi/newpipe/MainActivity.java b/app/src/main/java/org/schabi/newpipe/MainActivity.java index 43b01c70d..175694125 100644 --- a/app/src/main/java/org/schabi/newpipe/MainActivity.java +++ b/app/src/main/java/org/schabi/newpipe/MainActivity.java @@ -871,7 +871,7 @@ public class MainActivity extends AppCompatActivity { @Nullable final CommentRepliesFragment repliesFragment = (CommentRepliesFragment) fm.findFragmentByTag(CommentRepliesFragment.TAG); @Nullable final CommentsInfoItem rootComment = - repliesFragment == null ? null : repliesFragment.commentsInfoItem; + repliesFragment == null ? null : repliesFragment.getCommentsInfoItem(); // sometimes this function pops the backstack, other times it's handled by the system if (popBackStack) { diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/Comment.kt b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/Comment.kt index c622aa18d..b293adedc 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/Comment.kt +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/Comment.kt @@ -1,16 +1,19 @@ package org.schabi.newpipe.fragments.list.comments +import android.content.res.Configuration +import androidx.compose.foundation.Image import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -20,6 +23,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.fragment.app.FragmentActivity @@ -27,6 +31,7 @@ import coil.compose.AsyncImage import org.schabi.newpipe.R import org.schabi.newpipe.extractor.comments.CommentsInfoItem import org.schabi.newpipe.extractor.stream.Description +import org.schabi.newpipe.ui.theme.AppTheme import org.schabi.newpipe.util.NavigationHelper import org.schabi.newpipe.util.image.ImageStrategy @@ -34,51 +39,93 @@ import org.schabi.newpipe.util.image.ImageStrategy fun Comment(comment: CommentsInfoItem) { val context = LocalContext.current - Row(modifier = Modifier.padding(all = 8.dp)) { - if (ImageStrategy.shouldLoadImages()) { - AsyncImage( - model = ImageStrategy.choosePreferredImage(comment.uploaderAvatars), - contentDescription = null, - placeholder = painterResource(R.drawable.placeholder_person), - error = painterResource(R.drawable.placeholder_person), - modifier = Modifier - .size(42.dp) - .clip(CircleShape) - .clickable { - NavigationHelper.openCommentAuthorIfPresent(context as FragmentActivity, comment) + Surface(color = MaterialTheme.colorScheme.background) { + Row(modifier = Modifier.padding(all = 8.dp)) { + if (ImageStrategy.shouldLoadImages()) { + AsyncImage( + model = ImageStrategy.choosePreferredImage(comment.uploaderAvatars), + contentDescription = null, + placeholder = painterResource(R.drawable.placeholder_person), + error = painterResource(R.drawable.placeholder_person), + modifier = Modifier + .size(42.dp) + .clip(CircleShape) + .clickable { + NavigationHelper.openCommentAuthorIfPresent( + context as FragmentActivity, + comment + ) + } + ) + } + + Spacer(modifier = Modifier.width(8.dp)) + + var isExpanded by rememberSaveable { mutableStateOf(false) } + + Column( + modifier = Modifier.clickable { isExpanded = !isExpanded }, + verticalArrangement = Arrangement.spacedBy(4.dp) + ) { + Text( + text = comment.uploaderName, + color = MaterialTheme.colorScheme.secondary + ) + + Text( + text = comment.commentText.content, + // If the comment is expanded, we display all its content + // otherwise we only display the first two lines + maxLines = if (isExpanded) Int.MAX_VALUE else 2, + style = MaterialTheme.typography.bodyMedium + ) + + Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { + Image( + painter = painterResource(R.drawable.ic_thumb_up), + contentDescription = stringResource(R.string.detail_likes_img_view_description) + ) + Text(text = comment.likeCount.toString()) + + if (comment.isHeartedByUploader) { + Image( + painter = painterResource(R.drawable.ic_heart), + contentDescription = stringResource(R.string.detail_heart_img_view_description) + ) } - ) + + if (comment.isPinned) { + Image( + painter = painterResource(R.drawable.ic_pin), + contentDescription = stringResource(R.string.detail_pinned_comment_view_description) + ) + } + } + } } - Spacer(modifier = Modifier.width(8.dp)) - - var isExpanded by rememberSaveable { mutableStateOf(false) } - - Column(modifier = Modifier.clickable { isExpanded = !isExpanded }) { - Text( - text = comment.uploaderName, - color = MaterialTheme.colors.secondary - ) - - Spacer(modifier = Modifier.height(4.dp)) - - Text( - text = comment.commentText.content, - // If the comment is expanded, we display all its content - // otherwise we only display the first line - maxLines = if (isExpanded) Int.MAX_VALUE else 1, - style = MaterialTheme.typography.body2 - ) - } + // TODO: Add support for comment replies } } -@Preview +@Preview( + name = "Light mode", + uiMode = Configuration.UI_MODE_NIGHT_NO +) +@Preview( + name = "Dark mode", + uiMode = Configuration.UI_MODE_NIGHT_YES +) @Composable fun CommentPreview() { val comment = CommentsInfoItem(1, "", "") comment.commentText = Description("Hello world!", Description.PLAIN_TEXT) comment.uploaderName = "Test" + comment.likeCount = 100 + comment.isHeartedByUploader = true + comment.isPinned = true - Comment(comment) + AppTheme { + Comment(comment) + } } diff --git a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.kt b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.kt index 4bfb04d6e..1847d7d31 100644 --- a/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.kt +++ b/app/src/main/java/org/schabi/newpipe/fragments/list/comments/CommentRepliesFragment.kt @@ -14,6 +14,7 @@ import org.schabi.newpipe.extractor.ListExtractor.InfoItemsPage import org.schabi.newpipe.extractor.comments.CommentsInfoItem import org.schabi.newpipe.fragments.list.BaseListInfoFragment import org.schabi.newpipe.info_list.ItemViewMode +import org.schabi.newpipe.ui.theme.AppTheme import org.schabi.newpipe.util.ExtractorHelper import org.schabi.newpipe.util.Localization import java.util.Queue @@ -50,7 +51,9 @@ class CommentRepliesFragment() : BaseListInfoFragment + TextView(context).apply { + movementMethod = LinkMovementMethodCompat.getInstance() + } + }, + update = { view -> + // setup comment content + TextLinkifier.fromDescription( + view, comment.commentText, HtmlCompat.FROM_HTML_MODE_LEGACY, + ServiceHelper.getServiceById(comment.serviceId), comment.url, disposables, + null ) } - - if (comment.isPinned) { - Image( - painter = painterResource(R.drawable.ic_pin), - contentDescription = stringResource(R.string.detail_pinned_comment_view_description) - ) - } - } + ) } - - AndroidView( - factory = { context -> - TextView(context).apply { - movementMethod = LinkMovementMethodCompat.getInstance() - } - }, - update = { view -> - // setup comment content - TextLinkifier.fromDescription( - view, comment.commentText, HtmlCompat.FROM_HTML_MODE_LEGACY, - ServiceHelper.getServiceById(comment.serviceId), comment.url, disposables, - null - ) - } - ) } } -@Preview +@Preview( + name = "Light mode", + uiMode = Configuration.UI_MODE_NIGHT_NO +) +@Preview( + name = "Dark mode", + uiMode = Configuration.UI_MODE_NIGHT_YES +) @Composable fun CommentRepliesHeaderPreview() { val disposables = CompositeDisposable() @@ -140,5 +155,7 @@ fun CommentRepliesHeaderPreview() { comment.isPinned = true comment.isHeartedByUploader = true - CommentRepliesHeader(comment, disposables) + AppTheme { + CommentRepliesHeader(comment, disposables) + } }