Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ android {
applicationId = "dev.typetype.android"
minSdk = 23
targetSdk = 37
versionCode = 10805
versionName = "1.8.0-beta.5"
versionCode = 10806
versionName = "1.8.0-beta.6"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
resValue("string", "app_name", "TypeType")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package dev.typetype.android.feature.player.components

import androidx.activity.ComponentActivity
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.ui.Modifier
import androidx.compose.ui.test.junit4.v2.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.compose.ui.unit.dp
import androidx.test.ext.junit.runners.AndroidJUnit4
import dev.typetype.android.domain.comments.Comment
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class CommentBodyTest {
@get:Rule
val composeRule = createAndroidComposeRule<ComponentActivity>()

@Test
fun longCommentCollapsesAndExpandsWithReadMore() {
val suffix = " more comment detail".repeat(60)
val comment = Comment(
id = "comment",
text = "Long comment starts here$suffix",
authorName = "Reporter",
authorAvatarUrl = "",
likeCount = 2,
textualLikeCount = "2",
publishedTime = "1 day ago",
isHeartedByUploader = false,
isPinned = false,
uploaderVerified = false,
replyCount = 0,
)

composeRule.setContent {
CommentBody(
comment = comment,
avatarSize = 36.dp,
onUrlClick = {},
onTimestampClick = {},
modifier = Modifier.fillMaxWidth().padding(16.dp),
)
}

composeRule.onNodeWithText("Read more").assertExists().performClick()
composeRule.onNodeWithText("Long comment starts here$suffix").assertExists()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
Expand All @@ -20,6 +21,10 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
Expand All @@ -43,9 +48,10 @@ internal fun CommentBody(
avatarSize: Dp,
onUrlClick: (String) -> Unit,
onTimestampClick: (Long) -> Unit,
modifier: Modifier = Modifier,
) {
val serverBaseUrl = LocalServerBaseUrl.current
Row(modifier = Modifier.fillMaxWidth()) {
Row(modifier = modifier.fillMaxWidth()) {
AsyncImage(
model = buildImageUrl(serverBaseUrl, comment.authorAvatarUrl),
contentDescription = null,
Expand Down Expand Up @@ -82,10 +88,8 @@ internal fun CommentBody(
)
}
Spacer(Modifier.height(4.dp))
LinkedText(
text = comment.text,
style = MaterialTheme.typography.bodyMedium.copy(color = MaterialTheme.colorScheme.onSurface),
linkColor = MaterialTheme.colorScheme.primary,
ExpandableCommentText(
comment = comment,
onUrlClick = onUrlClick,
onTimestampClick = onTimestampClick,
)
Expand Down Expand Up @@ -115,6 +119,38 @@ internal fun CommentBody(
}
}

@Composable
private fun ExpandableCommentText(
comment: Comment,
onUrlClick: (String) -> Unit,
onTimestampClick: (Long) -> Unit,
) {
var expanded by remember(comment.text) { mutableStateOf(false) }
val needsTruncation = comment.text.length > COMMENT_COLLAPSE_CHARACTER_LIMIT ||
comment.text.count { it == '\n' } >= COMMENT_COLLAPSE_LINE_LIMIT

Column {
LinkedText(
text = comment.text,
style = MaterialTheme.typography.bodyMedium.copy(color = MaterialTheme.colorScheme.onSurface),
linkColor = MaterialTheme.colorScheme.primary,
onUrlClick = onUrlClick,
onTimestampClick = onTimestampClick,
maxLines = if (expanded) Int.MAX_VALUE else COMMENT_COLLAPSE_LINE_LIMIT,
overflow = if (expanded) TextOverflow.Clip else TextOverflow.Ellipsis,
)
if (needsTruncation && !expanded) {
TextButton(
onClick = { expanded = true },
contentPadding = PaddingValues(horizontal = 4.dp),
modifier = Modifier.padding(top = 2.dp),
) {
Text(stringResource(R.string.comments_read_more))
}
}
}
}

@Composable
internal fun FooterState(items: LazyPagingItems<Comment>) {
val state = items.loadState
Expand Down Expand Up @@ -156,3 +192,6 @@ private fun CommentSkeletons(count: Int) {
}
}
}

private const val COMMENT_COLLAPSE_CHARACTER_LIMIT = 320
private const val COMMENT_COLLAPSE_LINE_LIMIT = 6
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import androidx.compose.ui.text.TextLinkStyles
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.text.withLink
import java.net.URI
import java.net.URLDecoder
Expand Down Expand Up @@ -97,6 +98,8 @@ internal fun LinkedText(
onUrlClick: (String) -> Unit,
modifier: Modifier = Modifier,
onTimestampClick: (Long) -> Unit = {},
maxLines: Int = Int.MAX_VALUE,
overflow: TextOverflow = TextOverflow.Clip,
) {
val latestOnUrlClick = rememberUpdatedState(onUrlClick)
val latestOnTimestampClick = rememberUpdatedState(onTimestampClick)
Expand Down Expand Up @@ -141,5 +144,11 @@ internal fun LinkedText(
}
append(text.substring(cursor))
}
Text(text = annotated, style = style, modifier = modifier)
Text(
text = annotated,
style = style,
modifier = modifier,
maxLines = maxLines,
overflow = overflow,
)
}
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@
<string name="accounts_forget_failed">Couldn\'t forget account</string>
<string name="comments_title">Comments</string>
<string name="comments_empty">No comments</string>
<string name="comments_read_more">Read more</string>
<string name="comments_like_count">Likes: %1$s</string>
<string name="comments_replies_failed">Couldn\'t load replies</string>
<string name="comments_load_failed">Couldn\'t load comments</string>
Expand Down