From db140385638eca1e07ea78441d866d5c0b8ab9a6 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Wed, 14 Feb 2024 13:29:08 -0500 Subject: [PATCH 1/5] Adding additional vote display modes - Also removing redundant score counts from comment and post footers. - Context: #1372 --- .../main/java/com/jerboa/datatypes/Others.kt | 9 ++ app/src/main/java/com/jerboa/feat/Voting.kt | 36 ++++- .../java/com/jerboa/model/SiteViewModel.kt | 31 +++- .../ui/components/comment/CommentNode.kt | 33 +++-- .../ui/components/comment/CommentNodes.kt | 11 +- .../comment/mentionnode/CommentMentionNode.kt | 29 ++-- .../components/comment/reply/CommentReply.kt | 43 +++--- .../comment/reply/CommentReplyActivity.kt | 8 +- .../comment/replynode/CommentReplyNode.kt | 29 ++-- .../jerboa/ui/components/common/AppBars.kt | 13 +- .../jerboa/ui/components/common/TimeAgo.kt | 133 ++++++++++++++++-- .../ui/components/common/VoteHelpers.kt | 13 -- .../components/community/CommunityActivity.kt | 2 +- .../jerboa/ui/components/home/HomeActivity.kt | 2 +- .../ui/components/inbox/InboxActivity.kt | 4 +- .../person/PersonProfileActivity.kt | 9 +- .../jerboa/ui/components/post/PostActivity.kt | 4 +- .../jerboa/ui/components/post/PostListing.kt | 74 +++++----- .../jerboa/ui/components/post/PostListings.kt | 7 +- 19 files changed, 334 insertions(+), 156 deletions(-) diff --git a/app/src/main/java/com/jerboa/datatypes/Others.kt b/app/src/main/java/com/jerboa/datatypes/Others.kt index 4b13f5d00..78643630e 100644 --- a/app/src/main/java/com/jerboa/datatypes/Others.kt +++ b/app/src/main/java/com/jerboa/datatypes/Others.kt @@ -180,3 +180,12 @@ data class PostFeatureData( val type: PostFeatureType, val featured: Boolean, ) + +// TODO this should be got rid of after https://github.com/LemmyNet/lemmy/issues/4449 +enum class VoteDisplayMode { + Full, + ScoreAndUpvotePercentage, + UpvotePercentage, + Score, + HideAll, +} diff --git a/app/src/main/java/com/jerboa/feat/Voting.kt b/app/src/main/java/com/jerboa/feat/Voting.kt index 86cc2af6b..12ebc2176 100644 --- a/app/src/main/java/com/jerboa/feat/Voting.kt +++ b/app/src/main/java/com/jerboa/feat/Voting.kt @@ -1,5 +1,7 @@ package com.jerboa.feat +import com.jerboa.datatypes.VoteDisplayMode + enum class VoteType(val value: Int) { Upvote(1), Downvote(-1), @@ -19,7 +21,8 @@ data class InstantScores( val newVote = newVote(this.myVote, voteAction) // get original (up/down)votes, add (up/down)vote if (up/down)voted val upvotes = this.upvotes - (if (this.myVote == 1) 1 else 0) + (if (newVote == 1) 1 else 0) - val downvotes = this.downvotes - (if (this.myVote == -1) 1 else 0) + (if (newVote == -1) 1 else 0) + val downvotes = + this.downvotes - (if (this.myVote == -1) 1 else 0) + (if (newVote == -1) 1 else 0) return InstantScores( myVote = newVote, @@ -28,6 +31,15 @@ data class InstantScores( score = upvotes - downvotes, ) } + + fun scoreOrPctStr(voteDisplayMode: VoteDisplayMode): String? { + return scoreOrPctStr( + score = score, + upvotes = upvotes, + downvotes = downvotes, + voteDisplayMode = voteDisplayMode, + ) + } } // Set myVote to given action unless it was already set to that action, in which case we reset to 0 @@ -35,3 +47,25 @@ fun newVote( oldVote: Int, voteAction: VoteType, ): Int = if (voteAction.value == oldVote) 0 else voteAction.value + +fun upvotePercentStr( + upvotes: Long, + downvotes: Long, +): String { + val pct = (upvotes / (upvotes + downvotes)) * 100F + val formatted = "%.0f".format(pct) + return "$formatted%" +} + +private fun scoreOrPctStr( + score: Long, + upvotes: Long, + downvotes: Long, + voteDisplayMode: VoteDisplayMode, +): String? { + return when (voteDisplayMode) { + VoteDisplayMode.UpvotePercentage -> upvotePercentStr(upvotes, downvotes) + VoteDisplayMode.HideAll -> null + else -> score.toString() + } +} diff --git a/app/src/main/java/com/jerboa/model/SiteViewModel.kt b/app/src/main/java/com/jerboa/model/SiteViewModel.kt index 57184e75c..4f5767806 100644 --- a/app/src/main/java/com/jerboa/model/SiteViewModel.kt +++ b/app/src/main/java/com/jerboa/model/SiteViewModel.kt @@ -15,6 +15,7 @@ import com.jerboa.api.API import com.jerboa.api.ApiState import com.jerboa.api.DEFAULT_INSTANCE import com.jerboa.api.toApiState +import com.jerboa.datatypes.VoteDisplayMode import com.jerboa.db.entity.AnonAccount import com.jerboa.db.entity.isAnon import com.jerboa.db.repository.AccountRepository @@ -35,7 +36,9 @@ class SiteViewModel(private val accountRepository: AccountRepository) : ViewMode var siteRes: ApiState by mutableStateOf(ApiState.Empty) private var unreadCountRes: ApiState by mutableStateOf(ApiState.Empty) - private var unreadAppCountRes: ApiState by mutableStateOf(ApiState.Empty) + private var unreadAppCountRes: ApiState by mutableStateOf( + ApiState.Empty, + ) val unreadCount by derivedStateOf { getUnreadCountTotal() } val unreadAppCount by derivedStateOf { getUnreadAppCountTotal() } @@ -120,7 +123,8 @@ class SiteViewModel(private val accountRepository: AccountRepository) : ViewMode viewModelScope.launch { viewModelScope.launch { unreadAppCountRes = ApiState.Loading - unreadAppCountRes = API.getInstance().getUnreadRegistrationApplicationCount().toApiState() + unreadAppCountRes = + API.getInstance().getUnreadRegistrationApplicationCount().toApiState() } } } @@ -169,7 +173,10 @@ class SiteViewModel(private val accountRepository: AccountRepository) : ViewMode fun showAvatar(): Boolean { return when (val res = siteRes) { - is ApiState.Success -> res.data.my_user?.local_user_view?.local_user?.show_avatars ?: true + is ApiState.Success -> + res.data.my_user?.local_user_view?.local_user?.show_avatars + ?: true + else -> true } } @@ -181,10 +188,22 @@ class SiteViewModel(private val accountRepository: AccountRepository) : ViewMode } } - fun showScores(): Boolean { + // TODO this should probably be persisted rather than waited for + // For the current default, just use FullScores + fun voteDisplayMode(): VoteDisplayMode { + val defaultMode = VoteDisplayMode.Full return when (val res = siteRes) { - is ApiState.Success -> res.data.my_user?.local_user_view?.local_user?.show_scores ?: true - else -> true + is ApiState.Success -> + res.data.my_user?.let { mui -> + if (mui.local_user_view.local_user.show_scores) { + defaultMode + } else { + VoteDisplayMode.HideAll + } + } ?: run { + defaultMode + } + else -> defaultMode } } diff --git a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt index ea7bf8113..9783022bb 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt @@ -51,6 +51,7 @@ import com.jerboa.border import com.jerboa.buildCommentsTree import com.jerboa.calculateCommentOffset import com.jerboa.datatypes.BanFromCommunityData +import com.jerboa.datatypes.VoteDisplayMode import com.jerboa.datatypes.getContent import com.jerboa.datatypes.sampleCommentView import com.jerboa.datatypes.sampleCommunity @@ -99,17 +100,22 @@ fun CommentNodeHeader( commentView: CommentView, onPersonClick: (personId: PersonId) -> Unit, score: Long, + upvotes: Long, + downvotes: Long, myVote: Int, collapsedCommentsCount: Long, isExpanded: Boolean, onClick: () -> Unit, onLongClick: () -> Unit, showAvatar: Boolean, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, ) { CommentOrPostNodeHeader( creator = commentView.creator, score = score, + upvotes = upvotes, + downvotes = downvotes, + voteDisplayMode = voteDisplayMode, myVote = myVote, published = commentView.comment.published, updated = commentView.comment.updated, @@ -122,7 +128,6 @@ fun CommentNodeHeader( onClick = onClick, onLongCLick = onLongClick, showAvatar = showAvatar, - showScores = showScores, isModerator = commentView.creator_is_moderator, isAdmin = commentView.creator_is_admin, ) @@ -134,6 +139,9 @@ fun CommentNodeHeaderPreview() { CommentNodeHeader( commentView = sampleCommentView, score = 23, + upvotes = 21, + downvotes = 2, + voteDisplayMode = VoteDisplayMode.Full, myVote = 26, onPersonClick = {}, onClick = {}, @@ -141,7 +149,6 @@ fun CommentNodeHeaderPreview() { collapsedCommentsCount = 5, isExpanded = false, showAvatar = true, - showScores = true, ) } @@ -220,7 +227,7 @@ fun LazyListScope.commentNodeItem( enableDownVotes: Boolean, showAvatar: Boolean, blurNSFW: BlurNSFW, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, swipeToActionPreset: SwipeToActionPreset, ) { val commentView = node.commentView @@ -333,6 +340,9 @@ fun LazyListScope.commentNodeItem( onPersonClick = onPersonClick, score = instantScores.score, myVote = instantScores.myVote, + upvotes = instantScores.upvotes, + downvotes = instantScores.downvotes, + voteDisplayMode = voteDisplayMode, onClick = { onHeaderClick(commentView) }, @@ -342,7 +352,6 @@ fun LazyListScope.commentNodeItem( collapsedCommentsCount = commentView.counts.child_count, isExpanded = isExpanded(commentId), showAvatar = showAvatar, - showScores = showScores, ) AnimatedVisibility( visible = isExpanded(commentId) || showCollapsedCommentContent, @@ -408,7 +417,6 @@ fun LazyListScope.commentNodeItem( }, account = account, enableDownVotes = enableDownVotes, - showScores = showScores, viewSource = viewSource, ) } @@ -482,7 +490,7 @@ fun LazyListScope.commentNodeItem( enableDownVotes = enableDownVotes, showAvatar = showAvatar, blurNSFW = blurNSFW, - showScores = showScores, + voteDisplayMode = voteDisplayMode, admins = admins, moderators = moderators, swipeToActionPreset = swipeToActionPreset, @@ -528,7 +536,7 @@ fun LazyListScope.missingCommentNodeItem( enableDownVotes: Boolean, showAvatar: Boolean, blurNSFW: BlurNSFW, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, swipeToActionPreset: SwipeToActionPreset, ) { val commentId = node.missingCommentView.commentId @@ -634,7 +642,7 @@ fun LazyListScope.missingCommentNodeItem( enableDownVotes = enableDownVotes, showAvatar = showAvatar, blurNSFW = blurNSFW, - showScores = showScores, + voteDisplayMode = voteDisplayMode, swipeToActionPreset = swipeToActionPreset, ) } @@ -760,7 +768,6 @@ fun CommentFooterLine( onClick: () -> Unit, onLongClick: () -> Unit, account: Account, - showScores: Boolean, viewSource: Boolean, ) { var showMoreOptions by remember { mutableStateOf(false) } @@ -832,18 +839,14 @@ fun CommentFooterLine( ) { VoteGeneric( myVote = instantScores.myVote, - votes = instantScores.upvotes, type = VoteType.Upvote, onVoteClick = onUpvoteClick, - showNumber = (instantScores.downvotes != 0L) && showScores, account = account, ) if (enableDownVotes) { VoteGeneric( myVote = instantScores.myVote, - votes = instantScores.downvotes, type = VoteType.Downvote, - showNumber = showScores, onVoteClick = onDownvoteClick, account = account, ) @@ -937,7 +940,7 @@ fun CommentNodesPreview() { showAvatar = true, blurNSFW = BlurNSFW.NSFW, account = AnonAccount, - showScores = true, + voteDisplayMode = VoteDisplayMode.Full, swipeToActionPreset = SwipeToActionPreset.DEFAULT, ) } diff --git a/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt b/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt index 747970e43..ed8f09257 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/CommentNodes.kt @@ -12,6 +12,7 @@ import com.jerboa.CommentNode import com.jerboa.CommentNodeData import com.jerboa.MissingCommentNode import com.jerboa.datatypes.BanFromCommunityData +import com.jerboa.datatypes.VoteDisplayMode import com.jerboa.db.entity.Account import com.jerboa.feat.BlurNSFW import com.jerboa.feat.SwipeToActionPreset @@ -65,7 +66,7 @@ fun CommentNodes( enableDownVotes: Boolean, showAvatar: Boolean, blurNSFW: BlurNSFW, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, swipeToActionPreset: SwipeToActionPreset, ) { LazyColumn(state = listState) { @@ -108,7 +109,7 @@ fun CommentNodes( enableDownVotes = enableDownVotes, showAvatar = showAvatar, blurNSFW = blurNSFW, - showScores = showScores, + voteDisplayMode = voteDisplayMode, swipeToActionPreset = swipeToActionPreset, ) item { @@ -156,7 +157,7 @@ fun LazyListScope.commentNodeItems( enableDownVotes: Boolean, showAvatar: Boolean, blurNSFW: BlurNSFW, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, swipeToActionPreset: SwipeToActionPreset, ) { nodes.forEach { node -> @@ -201,7 +202,7 @@ fun LazyListScope.commentNodeItems( enableDownVotes = enableDownVotes, showAvatar = showAvatar, blurNSFW = blurNSFW, - showScores = showScores, + voteDisplayMode = voteDisplayMode, swipeToActionPreset = swipeToActionPreset, ) @@ -245,7 +246,7 @@ fun LazyListScope.commentNodeItems( enableDownVotes = enableDownVotes, showAvatar = showAvatar, blurNSFW = blurNSFW, - showScores = showScores, + voteDisplayMode = voteDisplayMode, swipeToActionPreset = swipeToActionPreset, ) } diff --git a/app/src/main/java/com/jerboa/ui/components/comment/mentionnode/CommentMentionNode.kt b/app/src/main/java/com/jerboa/ui/components/comment/mentionnode/CommentMentionNode.kt index 254986c04..98595c49c 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/mentionnode/CommentMentionNode.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/mentionnode/CommentMentionNode.kt @@ -27,6 +27,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import com.jerboa.R +import com.jerboa.datatypes.VoteDisplayMode import com.jerboa.datatypes.samplePersonMentionView import com.jerboa.db.entity.Account import com.jerboa.feat.BlurNSFW @@ -54,16 +55,21 @@ fun CommentMentionNodeHeader( personMentionView: PersonMentionView, onPersonClick: (personId: PersonId) -> Unit, score: Long, + upvotes: Long, + downvotes: Long, myVote: Int, onClick: () -> Unit, onLongClick: () -> Unit, showAvatar: Boolean, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, ) { CommentOrPostNodeHeader( creator = personMentionView.creator, score = score, myVote = myVote, + upvotes = upvotes, + downvotes = downvotes, + voteDisplayMode = voteDisplayMode, published = personMentionView.comment.published, updated = personMentionView.comment.updated, deleted = personMentionView.comment.deleted, @@ -75,7 +81,6 @@ fun CommentMentionNodeHeader( onClick = onClick, onLongCLick = onLongClick, showAvatar = showAvatar, - showScores = showScores, ) } @@ -86,11 +91,13 @@ fun CommentMentionNodeHeaderPreview() { personMentionView = samplePersonMentionView, score = 23, myVote = 26, + upvotes = 21, + downvotes = 2, + voteDisplayMode = VoteDisplayMode.Full, onPersonClick = {}, onClick = {}, onLongClick = {}, showAvatar = true, - showScores = true, ) } @@ -111,11 +118,8 @@ fun CommentMentionNodeFooterLine( onLinkClick: (personMentionView: PersonMentionView) -> Unit, onBlockCreatorClick: (creator: Person) -> Unit, myVote: Int, - upvotes: Long, - downvotes: Long, account: Account, enableDownvotes: Boolean, - showScores: Boolean, viewSource: Boolean, ) { var showMoreOptions by remember { mutableStateOf(false) } @@ -158,18 +162,14 @@ fun CommentMentionNodeFooterLine( ) { VoteGeneric( myVote = myVote, - votes = upvotes, type = VoteType.Upvote, onVoteClick = onUpvoteClick, - showNumber = (downvotes != 0L) && showScores, account = account, ) if (enableDownvotes) { VoteGeneric( myVote = myVote, - votes = downvotes, type = VoteType.Downvote, - showNumber = showScores, onVoteClick = onDownvoteClick, account = account, ) @@ -265,7 +265,7 @@ fun CommentMentionNode( showAvatar: Boolean, blurNSFW: BlurNSFW, enableDownvotes: Boolean, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, ) { // These are necessary for instant comment voting val score = personMentionView.counts.score @@ -294,6 +294,9 @@ fun CommentMentionNode( onPersonClick = onPersonClick, score = score, myVote = myVote, + upvotes = upvotes, + downvotes = downvotes, + voteDisplayMode = voteDisplayMode, onClick = { isExpanded = !isExpanded }, @@ -301,7 +304,6 @@ fun CommentMentionNode( isActionBarExpanded = !isActionBarExpanded }, showAvatar = showAvatar, - showScores = showScores, ) AnimatedVisibility( visible = isExpanded, @@ -345,11 +347,8 @@ fun CommentMentionNode( onLinkClick = onLinkClick, onBlockCreatorClick = onBlockCreatorClick, myVote = myVote, - upvotes = upvotes, - downvotes = downvotes, account = account, enableDownvotes = enableDownvotes, - showScores = showScores, viewSource = viewSource, ) } diff --git a/app/src/main/java/com/jerboa/ui/components/comment/reply/CommentReply.kt b/app/src/main/java/com/jerboa/ui/components/comment/reply/CommentReply.kt index d94736850..0b5565007 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/reply/CommentReply.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/reply/CommentReply.kt @@ -15,6 +15,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.tooling.preview.Preview import com.jerboa.R +import com.jerboa.datatypes.VoteDisplayMode import com.jerboa.datatypes.getContent import com.jerboa.datatypes.sampleCommentView import com.jerboa.db.entity.Account @@ -36,20 +37,22 @@ fun RepliedComment( commentView: CommentView, onPersonClick: (personId: PersonId) -> Unit, showAvatar: Boolean, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, ) { Column(modifier = Modifier.padding(MEDIUM_PADDING)) { CommentNodeHeader( commentView = commentView, onPersonClick = onPersonClick, score = commentView.counts.score, + upvotes = commentView.counts.upvotes, + downvotes = commentView.counts.downvotes, myVote = commentView.my_vote, collapsedCommentsCount = 0, isExpanded = true, onClick = {}, onLongClick = {}, showAvatar = showAvatar, - showScores = showScores, + voteDisplayMode = voteDisplayMode, ) SelectionContainer { Text(text = commentView.comment.getContent()) @@ -62,18 +65,20 @@ fun RepliedCommentReply( commentReplyView: CommentReplyView, onPersonClick: (personId: PersonId) -> Unit, showAvatar: Boolean, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, ) { Column(modifier = Modifier.padding(MEDIUM_PADDING)) { CommentReplyNodeHeader( commentReplyView = commentReplyView, onPersonClick = onPersonClick, score = commentReplyView.counts.score, + upvotes = commentReplyView.counts.upvotes, + downvotes = commentReplyView.counts.downvotes, myVote = commentReplyView.my_vote, onClick = {}, onLongClick = {}, showAvatar = showAvatar, - showScores = showScores, + voteDisplayMode = voteDisplayMode, ) SelectionContainer { Text(text = commentReplyView.comment.getContent()) @@ -86,18 +91,20 @@ fun RepliedMentionReply( personMentionView: PersonMentionView, onPersonClick: (personId: PersonId) -> Unit, showAvatar: Boolean, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, ) { Column(modifier = Modifier.padding(MEDIUM_PADDING)) { CommentMentionNodeHeader( personMentionView = personMentionView, onPersonClick = onPersonClick, score = personMentionView.counts.score, + upvotes = personMentionView.counts.upvotes, + downvotes = personMentionView.counts.downvotes, myVote = personMentionView.my_vote, onClick = {}, onLongClick = {}, showAvatar = showAvatar, - showScores = showScores, + voteDisplayMode = voteDisplayMode, ) SelectionContainer { Text(text = personMentionView.comment.getContent()) @@ -112,7 +119,7 @@ fun RepliedCommentPreview() { commentView = sampleCommentView, onPersonClick = {}, showAvatar = true, - showScores = true, + VoteDisplayMode.Full, ) } @@ -121,16 +128,18 @@ fun RepliedPost( postView: PostView, onPersonClick: (personId: PersonId) -> Unit, showAvatar: Boolean, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, ) { Column(modifier = Modifier.padding(MEDIUM_PADDING)) { PostNodeHeader( postView = postView, myVote = postView.my_vote, score = postView.counts.score, + upvotes = postView.counts.upvotes, + downvotes = postView.counts.downvotes, onPersonClick = onPersonClick, showAvatar = showAvatar, - showScores = showScores, + voteDisplayMode = voteDisplayMode, ) val text = postView.post.body ?: run { postView.post.name } SelectionContainer { @@ -148,7 +157,7 @@ fun CommentReply( account: Account, modifier: Modifier = Modifier, showAvatar: Boolean, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, ) { val scrollState = rememberScrollState() @@ -159,7 +168,7 @@ fun CommentReply( commentView = commentView, onPersonClick = onPersonClick, showAvatar = showAvatar, - showScores = showScores, + voteDisplayMode = voteDisplayMode, ) HorizontalDivider(modifier = Modifier.padding(vertical = LARGE_PADDING)) MarkdownTextField( @@ -180,7 +189,7 @@ fun CommentReplyReply( account: Account, modifier: Modifier = Modifier, showAvatar: Boolean, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, ) { val scrollState = rememberScrollState() @@ -191,7 +200,7 @@ fun CommentReplyReply( commentReplyView = commentReplyView, onPersonClick = onPersonClick, showAvatar = showAvatar, - showScores = showScores, + voteDisplayMode = voteDisplayMode, ) HorizontalDivider(modifier = Modifier.padding(vertical = LARGE_PADDING)) MarkdownTextField( @@ -212,7 +221,7 @@ fun MentionReply( account: Account, modifier: Modifier = Modifier, showAvatar: Boolean, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, ) { val scrollState = rememberScrollState() @@ -223,7 +232,7 @@ fun MentionReply( personMentionView = personMentionView, onPersonClick = onPersonClick, showAvatar = showAvatar, - showScores = showScores, + voteDisplayMode = voteDisplayMode, ) HorizontalDivider(modifier = Modifier.padding(vertical = LARGE_PADDING)) MarkdownTextField( @@ -244,7 +253,7 @@ fun PostReply( account: Account, modifier: Modifier = Modifier, showAvatar: Boolean, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, ) { val scrollState = rememberScrollState() @@ -255,7 +264,7 @@ fun PostReply( postView = postView, onPersonClick = onPersonClick, showAvatar = showAvatar, - showScores = showScores, + voteDisplayMode = voteDisplayMode, ) HorizontalDivider(modifier = Modifier.padding(vertical = LARGE_PADDING)) MarkdownTextField( diff --git a/app/src/main/java/com/jerboa/ui/components/comment/reply/CommentReplyActivity.kt b/app/src/main/java/com/jerboa/ui/components/comment/reply/CommentReplyActivity.kt index a84993f02..a7a9c09e5 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/reply/CommentReplyActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/reply/CommentReplyActivity.kt @@ -103,7 +103,7 @@ fun CommentReplyActivity( .padding(padding) .imePadding(), showAvatar = siteViewModel.showAvatar(), - showScores = siteViewModel.showScores(), + voteDisplayMode = siteViewModel.voteDisplayMode(), ) is ReplyItem.PostItem -> @@ -114,7 +114,7 @@ fun CommentReplyActivity( onReplyChange = { reply = it }, onPersonClick = appState::toProfile, showAvatar = siteViewModel.showAvatar(), - showScores = siteViewModel.showScores(), + voteDisplayMode = siteViewModel.voteDisplayMode(), modifier = Modifier .padding(padding) @@ -133,7 +133,7 @@ fun CommentReplyActivity( .padding(padding) .imePadding(), showAvatar = siteViewModel.showAvatar(), - showScores = siteViewModel.showScores(), + voteDisplayMode = siteViewModel.voteDisplayMode(), ) is ReplyItem.MentionReplyItem -> @@ -148,7 +148,7 @@ fun CommentReplyActivity( .padding(padding) .imePadding(), showAvatar = siteViewModel.showAvatar(), - showScores = siteViewModel.showScores(), + voteDisplayMode = siteViewModel.voteDisplayMode(), ) } } diff --git a/app/src/main/java/com/jerboa/ui/components/comment/replynode/CommentReplyNode.kt b/app/src/main/java/com/jerboa/ui/components/comment/replynode/CommentReplyNode.kt index 88136544c..fe7ad7abe 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/replynode/CommentReplyNode.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/replynode/CommentReplyNode.kt @@ -27,6 +27,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import com.jerboa.R +import com.jerboa.datatypes.VoteDisplayMode import com.jerboa.datatypes.sampleCommentReplyView import com.jerboa.db.entity.Account import com.jerboa.feat.BlurNSFW @@ -51,15 +52,19 @@ fun CommentReplyNodeHeader( commentReplyView: CommentReplyView, onPersonClick: (personId: PersonId) -> Unit, score: Long, + upvotes: Long, + downvotes: Long, myVote: Int, onClick: () -> Unit, onLongClick: () -> Unit, showAvatar: Boolean, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, ) { CommentOrPostNodeHeader( creator = commentReplyView.creator, score = score, + upvotes = upvotes, + downvotes = downvotes, myVote = myVote, published = commentReplyView.comment.published, updated = commentReplyView.comment.updated, @@ -72,7 +77,7 @@ fun CommentReplyNodeHeader( onClick = onClick, onLongCLick = onLongClick, showAvatar = showAvatar, - showScores = showScores, + voteDisplayMode = voteDisplayMode, ) } @@ -83,11 +88,13 @@ fun CommentReplyNodeHeaderPreview() { commentReplyView = sampleCommentReplyView, score = 23, myVote = 26, + upvotes = 21, + downvotes = 2, + voteDisplayMode = VoteDisplayMode.Full, onPersonClick = {}, onClick = {}, onLongClick = {}, showAvatar = true, - showScores = true, ) } @@ -105,11 +112,8 @@ fun CommentReplyNodeInboxFooterLine( onCommentLinkClick: (commentReplyView: CommentReplyView) -> Unit, onBlockCreatorClick: (creator: Person) -> Unit, myVote: Int, - upvotes: Long, - downvotes: Long, account: Account, enableDownvotes: Boolean, - showScores: Boolean, viewSource: Boolean, ) { var showMoreOptions by remember { mutableStateOf(false) } @@ -140,18 +144,14 @@ fun CommentReplyNodeInboxFooterLine( ) { VoteGeneric( myVote = myVote, - votes = upvotes, type = VoteType.Upvote, onVoteClick = onUpvoteClick, - showNumber = (downvotes != 0L) && showScores, account = account, ) if (enableDownvotes) { VoteGeneric( myVote = myVote, - votes = downvotes, type = VoteType.Downvote, - showNumber = showScores, onVoteClick = onDownvoteClick, account = account, ) @@ -245,7 +245,7 @@ fun CommentReplyNodeInbox( showAvatar: Boolean, blurNSFW: BlurNSFW, enableDownvotes: Boolean, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, ) { // These are necessary for instant comment voting val score = commentReplyView.counts.score @@ -273,6 +273,8 @@ fun CommentReplyNodeInbox( commentReplyView = commentReplyView, onPersonClick = onPersonClick, score = score, + upvotes = upvotes, + downvotes = downvotes, myVote = myVote, onClick = { isExpanded = !isExpanded @@ -281,7 +283,7 @@ fun CommentReplyNodeInbox( isActionBarExpanded = !isActionBarExpanded }, showAvatar = showAvatar, - showScores = showScores, + voteDisplayMode = voteDisplayMode, ) AnimatedVisibility( visible = isExpanded, @@ -322,11 +324,8 @@ fun CommentReplyNodeInbox( onCommentLinkClick = onCommentLinkClick, onBlockCreatorClick = onBlockCreatorClick, myVote = myVote, - upvotes = upvotes, - downvotes = downvotes, account = account, enableDownvotes = enableDownvotes, - showScores = showScores, viewSource = viewSource, ) } diff --git a/app/src/main/java/com/jerboa/ui/components/common/AppBars.kt b/app/src/main/java/com/jerboa/ui/components/common/AppBars.kt index 864c0181c..d452f01f4 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/AppBars.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/AppBars.kt @@ -48,6 +48,7 @@ import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.TextUnitType import androidx.compose.ui.unit.dp import com.jerboa.R +import com.jerboa.datatypes.VoteDisplayMode import com.jerboa.datatypes.samplePerson import com.jerboa.datatypes.samplePost import com.jerboa.db.entity.Account @@ -234,6 +235,8 @@ fun CommentNavigationBottomAppBar( fun CommentOrPostNodeHeader( creator: Person, score: Long, + upvotes: Long, + downvotes: Long, myVote: Int, published: String, updated: String?, @@ -248,7 +251,7 @@ fun CommentOrPostNodeHeader( isExpanded: Boolean = true, collapsedCommentsCount: Long = 0, showAvatar: Boolean, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, ) { FlowRow( horizontalArrangement = Arrangement.SpaceBetween, @@ -293,12 +296,14 @@ fun CommentOrPostNodeHeader( } ScoreAndTime( score = score, + upvotes = upvotes, + downvotes = downvotes, myVote = myVote, published = published, updated = updated, isExpanded = isExpanded, collapsedCommentsCount = collapsedCommentsCount, - showScores = showScores, + voteDisplayMode = voteDisplayMode, ) } } @@ -309,6 +314,8 @@ fun CommentOrPostNodeHeaderPreview() { CommentOrPostNodeHeader( creator = samplePerson, score = 23, + upvotes = 21, + downvotes = 2, myVote = 1, published = samplePost.published, updated = samplePost.updated, @@ -321,7 +328,7 @@ fun CommentOrPostNodeHeaderPreview() { onClick = {}, onLongCLick = {}, showAvatar = true, - showScores = true, + voteDisplayMode = VoteDisplayMode.Full, ) } diff --git a/app/src/main/java/com/jerboa/ui/components/common/TimeAgo.kt b/app/src/main/java/com/jerboa/ui/components/common/TimeAgo.kt index 50fa3add0..92dbf3748 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/TimeAgo.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/TimeAgo.kt @@ -24,8 +24,10 @@ import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.jerboa.R +import com.jerboa.datatypes.VoteDisplayMode import com.jerboa.datatypes.samplePerson import com.jerboa.datatypes.samplePost +import com.jerboa.feat.upvotePercentStr import com.jerboa.formatDuration import com.jerboa.ui.theme.SMALL_PADDING import com.jerboa.ui.theme.muted @@ -57,13 +59,13 @@ fun TimeAgo( Text( text = afterPreceding, color = MaterialTheme.colorScheme.onBackground.muted, - style = MaterialTheme.typography.bodyMedium, + style = MaterialTheme.typography.labelMedium, ) updated?.also { DotSpacer( padding = SMALL_PADDING, - style = MaterialTheme.typography.bodyMedium, + style = MaterialTheme.typography.labelMedium, ) val updatedPretty = dateStringToPretty(it, longTimeFormat) @@ -72,7 +74,7 @@ fun TimeAgo( } else { Text( text = "($updatedPretty)", - style = MaterialTheme.typography.bodyMedium, + style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.onBackground.muted, fontStyle = FontStyle.Italic, ) @@ -116,13 +118,15 @@ fun TimeAgoPreview() { @Composable fun ScoreAndTime( score: Long, + upvotes: Long, + downvotes: Long, myVote: Int, published: String, updated: String?, isExpanded: Boolean = true, collapsedCommentsCount: Long = 0, isNsfw: Boolean = false, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, ) { Row( horizontalArrangement = Arrangement.spacedBy(SMALL_PADDING), @@ -131,27 +135,126 @@ fun ScoreAndTime( NsfwBadge(isNsfw) CollapsedIndicator(visible = !isExpanded, descendants = collapsedCommentsCount) Spacer(modifier = Modifier.padding(end = SMALL_PADDING)) - if (showScores) { - Text( - text = score.toString(), - color = scoreColor(myVote = myVote), - fontSize = MaterialTheme.typography.bodyMedium.fontSize.times(1.3), - ) + val upvotePct = upvotePercentStr( + upvotes = upvotes, + downvotes = downvotes, + ) + when (voteDisplayMode) { + VoteDisplayMode.Full -> { + LargeVoteIndicator(data = score.toString(), myVote = myVote) + DotSpacer(style = MaterialTheme.typography.labelMedium) + SmallVoteIndicator(data = "-$downvotes".toString()) + DotSpacer(style = MaterialTheme.typography.labelMedium) + } + VoteDisplayMode.ScoreAndUpvotePercentage -> { + LargeVoteIndicator(data = score.toString(), myVote = myVote) + DotSpacer(style = MaterialTheme.typography.labelMedium) + SmallVoteIndicator(data = upvotePct) + DotSpacer(style = MaterialTheme.typography.labelMedium) + } + VoteDisplayMode.UpvotePercentage -> { + LargeVoteIndicator(data = upvotePct, myVote = myVote) + DotSpacer(style = MaterialTheme.typography.labelMedium) + } + VoteDisplayMode.Score -> { + LargeVoteIndicator(data = score.toString(), myVote = myVote) + DotSpacer(style = MaterialTheme.typography.labelMedium) + } + VoteDisplayMode.HideAll -> {} } - DotSpacer(style = MaterialTheme.typography.bodyMedium) TimeAgo(published = published, updated = updated) } } +@Composable +private fun LargeVoteIndicator( + data: String, + myVote: Int, +) { + Text( + text = data, + color = scoreColor(myVote = myVote), + style = MaterialTheme.typography.labelMedium, + fontSize = MaterialTheme.typography.labelMedium.fontSize.times(1.3), + ) +} + +@Composable +private fun SmallVoteIndicator(data: String) { + Text( + text = data, + color = MaterialTheme.colorScheme.onBackground.muted, + style = MaterialTheme.typography.labelSmall, + ) +} + +@Preview +@Composable +fun ScoreFullAndTimePreview() { + ScoreAndTime( + score = 25, + myVote = -1, + upvotes = 10, + downvotes = 15, + published = samplePost.published, + updated = samplePost.updated, + voteDisplayMode = VoteDisplayMode.Full, + ) +} + +@Preview +@Composable +fun ScoreAndUpvotePctAndTimePreview() { + ScoreAndTime( + score = 25, + myVote = -1, + upvotes = 10, + downvotes = 15, + published = samplePost.published, + updated = samplePost.updated, + voteDisplayMode = VoteDisplayMode.ScoreAndUpvotePercentage, + ) +} + +@Preview +@Composable +fun UpvotePctAndTimePreview() { + ScoreAndTime( + score = 25, + myVote = -1, + upvotes = 10, + downvotes = 15, + published = samplePost.published, + updated = samplePost.updated, + voteDisplayMode = VoteDisplayMode.UpvotePercentage, + ) +} + @Preview @Composable fun ScoreAndTimePreview() { ScoreAndTime( - score = 23, + score = 25, + myVote = -1, + upvotes = 10, + downvotes = 15, + published = samplePost.published, + updated = samplePost.updated, + voteDisplayMode = VoteDisplayMode.Score, + ) +} + +@Preview +@Composable +fun HideAllAndTimePreview() { + ScoreAndTime( + score = 25, myVote = -1, + upvotes = 10, + downvotes = 15, published = samplePost.published, updated = samplePost.updated, - showScores = true, + voteDisplayMode = VoteDisplayMode.HideAll, ) } @@ -175,7 +278,7 @@ fun CollapsedIndicator( ) { Text( text = "+$descendants", - style = MaterialTheme.typography.bodyMedium, + style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.onSecondary, ) } @@ -206,7 +309,7 @@ fun NsfwBadge(visible: Boolean) { ) { Text( text = "NSFW", - style = MaterialTheme.typography.bodyMedium, + style = MaterialTheme.typography.labelMedium, color = MaterialTheme.colorScheme.onSecondary, ) } diff --git a/app/src/main/java/com/jerboa/ui/components/common/VoteHelpers.kt b/app/src/main/java/com/jerboa/ui/components/common/VoteHelpers.kt index e17933919..a09142a38 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/VoteHelpers.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/VoteHelpers.kt @@ -14,10 +14,8 @@ import com.jerboa.ui.theme.muted @Composable fun VoteGeneric( myVote: Int, - votes: Long, type: VoteType, onVoteClick: () -> Unit, - showNumber: Boolean = true, account: Account, ) { val iconAndColor = @@ -26,16 +24,6 @@ fun VoteGeneric( else -> downvoteIconAndColor(myVote = myVote) } - val votesStr = - if (showNumber) { - if (type == VoteType.Downvote && votes == 0L) { - null - } else { - votes.toString() - } - } else { - null - } val contentDescription: String = if (type == VoteType.Upvote) { if (myVote == 1) { @@ -55,7 +43,6 @@ fun VoteGeneric( contentColor = iconAndColor.second, icon = iconAndColor.first, contentDescription = contentDescription, - text = votesStr, account = account, ) } diff --git a/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt b/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt index 7798467e9..8534290ee 100644 --- a/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/community/CommunityActivity.kt @@ -426,7 +426,7 @@ fun CommunityActivity( } }, showIfRead = true, - showScores = siteViewModel.showScores(), + voteDisplayMode = siteViewModel.voteDisplayMode(), postActionBarMode = postActionBarMode, showPostAppendRetry = communityViewModel.postsRes is ApiState.AppendingFailure, swipeToActionPreset = swipeToActionPreset, diff --git a/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt b/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt index 8a8f03675..3d526836d 100644 --- a/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/home/HomeActivity.kt @@ -426,7 +426,7 @@ fun MainPostListingsContent( } }, showIfRead = true, - showScores = siteViewModel.showScores(), + voteDisplayMode = siteViewModel.voteDisplayMode(), postActionBarMode = postActionBarMode, showPostAppendRetry = homeViewModel.postsRes is ApiState.AppendingFailure, swipeToActionPreset = swipeToActionPreset, diff --git a/app/src/main/java/com/jerboa/ui/components/inbox/InboxActivity.kt b/app/src/main/java/com/jerboa/ui/components/inbox/InboxActivity.kt index c40605435..b9e7cc04b 100644 --- a/app/src/main/java/com/jerboa/ui/components/inbox/InboxActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/inbox/InboxActivity.kt @@ -432,7 +432,7 @@ fun InboxTabs( showAvatar = siteViewModel.showAvatar(), blurNSFW = blurNSFW, enableDownvotes = siteViewModel.enableDownvotes(), - showScores = siteViewModel.showScores(), + voteDisplayMode = siteViewModel.voteDisplayMode(), ) } } @@ -646,7 +646,7 @@ fun InboxTabs( account = account, showAvatar = siteViewModel.showAvatar(), blurNSFW = blurNSFW, - showScores = siteViewModel.showScores(), + voteDisplayMode = siteViewModel.voteDisplayMode(), enableDownvotes = siteViewModel.enableDownvotes(), ) } diff --git a/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt b/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt index 1e4132e8f..984e33649 100644 --- a/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/person/PersonProfileActivity.kt @@ -47,6 +47,7 @@ import com.jerboa.R import com.jerboa.api.ApiState import com.jerboa.commentsToFlatNodes import com.jerboa.datatypes.BanFromCommunityData +import com.jerboa.datatypes.VoteDisplayMode import com.jerboa.datatypes.getDisplayName import com.jerboa.datatypes.getLocalizedStringForUserTab import com.jerboa.db.entity.Account @@ -273,7 +274,7 @@ fun PersonProfileActivity( showPostLinkPreviews = showPostLinkPreviews, markAsReadOnScroll = markAsReadOnScroll, snackbarHostState = snackbarHostState, - showScores = siteViewModel.showScores(), + voteDisplayMode = siteViewModel.voteDisplayMode(), postActionBarMode = postActionBarMode, swipeToActionPreset = swipeToActionPreset, ) @@ -309,7 +310,7 @@ fun UserTabs( showPostLinkPreviews: Boolean, markAsReadOnScroll: Boolean, snackbarHostState: SnackbarHostState, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, postActionBarMode: PostActionBarMode, swipeToActionPreset: SwipeToActionPreset, ) { @@ -627,7 +628,7 @@ fun UserTabs( } }, showIfRead = false, - showScores = showScores, + voteDisplayMode = voteDisplayMode, postActionBarMode = postActionBarMode, showPostAppendRetry = personProfileViewModel.personDetailsRes is ApiState.AppendingFailure, swipeToActionPreset = swipeToActionPreset, @@ -851,7 +852,7 @@ fun UserTabs( enableDownVotes = enableDownVotes, showAvatar = showAvatar, blurNSFW = blurNSFW, - showScores = showScores, + voteDisplayMode = voteDisplayMode, swipeToActionPreset = swipeToActionPreset, ) } diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt b/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt index b614cb2eb..7c94e5f4c 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostActivity.kt @@ -476,7 +476,7 @@ fun PostActivity( appState = appState, showPostLinkPreview = showPostLinkPreview, showIfRead = false, - showScores = siteViewModel.showScores(), + voteDisplayMode = siteViewModel.voteDisplayMode(), postActionBarMode = postActionBarMode, swipeToActionPreset = swipeToActionPreset, ) @@ -708,7 +708,7 @@ fun PostActivity( ) }, blurNSFW = blurNSFW, - showScores = siteViewModel.showScores(), + voteDisplayMode = siteViewModel.voteDisplayMode(), swipeToActionPreset = swipeToActionPreset, ) item { diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt b/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt index 9f22d1d7a..2ad04f5eb 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt @@ -62,6 +62,7 @@ import com.jerboa.PostViewMode import com.jerboa.R import com.jerboa.datatypes.BanFromCommunityData import com.jerboa.datatypes.PostFeatureData +import com.jerboa.datatypes.VoteDisplayMode import com.jerboa.datatypes.sampleImagePostView import com.jerboa.datatypes.sampleLinkNoThumbnailPostView import com.jerboa.datatypes.sampleLinkPostView @@ -130,6 +131,8 @@ fun PostHeaderLine( postView: PostView, myVote: Int, score: Long, + upvotes: Long, + downvotes: Long, onCommunityClick: (community: Community) -> Unit, onPersonClick: (personId: PersonId) -> Unit, modifier: Modifier = Modifier, @@ -137,7 +140,7 @@ fun PostHeaderLine( showAvatar: Boolean, fullBody: Boolean, blurNSFW: BlurNSFW, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, ) { val community = postView.community Column(modifier = modifier) { @@ -232,10 +235,12 @@ fun PostHeaderLine( ScoreAndTime( score = score, myVote = myVote, + upvotes = upvotes, + downvotes = downvotes, published = postView.post.published, updated = postView.post.updated, isNsfw = nsfwCheck(postView), - showScores = showScores, + voteDisplayMode = voteDisplayMode, ) } } @@ -249,12 +254,14 @@ fun PostHeaderLinePreview() { postView = postView, myVote = 0, score = 10, + upvotes = 9, + downvotes = 1, onCommunityClick = {}, onPersonClick = {}, showAvatar = true, blurNSFW = BlurNSFW.NSFW, - showScores = true, fullBody = true, + voteDisplayMode = VoteDisplayMode.Full, ) } @@ -263,14 +270,18 @@ fun PostNodeHeader( postView: PostView, myVote: Int, score: Long, + upvotes: Long, + downvotes: Long, onPersonClick: (personId: PersonId) -> Unit, showAvatar: Boolean, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, ) { CommentOrPostNodeHeader( creator = postView.creator, myVote = myVote, score = score, + upvotes = upvotes, + downvotes = downvotes, published = postView.post.published, updated = postView.post.updated, deleted = postView.post.deleted, @@ -280,7 +291,7 @@ fun PostNodeHeader( onClick = {}, onLongCLick = {}, showAvatar = showAvatar, - showScores = showScores, + voteDisplayMode = voteDisplayMode, isModerator = postView.creator_is_moderator, isAdmin = postView.creator_is_admin, ) @@ -576,7 +587,6 @@ fun PostFooterLine( account: Account, enableDownVotes: Boolean, viewSource: Boolean, - showScores: Boolean, postActionBarMode: PostActionBarMode, fromPostActivity: Boolean, scope: CoroutineScope, @@ -662,17 +672,13 @@ fun PostFooterLine( VoteGeneric( myVote = instantScores.myVote, - votes = instantScores.upvotes, type = VoteType.Upvote, - showNumber = (instantScores.downvotes != 0L) && showScores, onVoteClick = onUpvoteClick, account = account, ) if (enableDownVotes) { VoteGeneric( myVote = instantScores.myVote, - votes = instantScores.downvotes, - showNumber = showScores, type = VoteType.Downvote, onVoteClick = onDownvoteClick, account = account, @@ -835,7 +841,6 @@ fun PostFooterLinePreview() { account = AnonAccount, enableDownVotes = true, viewSource = false, - showScores = true, postActionBarMode = PostActionBarMode.Long, fromPostActivity = true, scope = rememberCoroutineScope(), @@ -877,7 +882,7 @@ fun PreviewPostListingCard() { appState = rememberJerboaAppState(), showPostLinkPreview = true, showIfRead = true, - showScores = true, + voteDisplayMode = VoteDisplayMode.Full, postActionBarMode = PostActionBarMode.Long, swipeToActionPreset = SwipeToActionPreset.DEFAULT, ) @@ -918,7 +923,7 @@ fun PreviewLinkPostListing() { appState = rememberJerboaAppState(), showPostLinkPreview = true, showIfRead = true, - showScores = true, + voteDisplayMode = VoteDisplayMode.Full, postActionBarMode = PostActionBarMode.Long, swipeToActionPreset = SwipeToActionPreset.DEFAULT, ) @@ -959,7 +964,7 @@ fun PreviewImagePostListingCard() { appState = rememberJerboaAppState(), showPostLinkPreview = true, showIfRead = true, - showScores = true, + voteDisplayMode = VoteDisplayMode.Full, postActionBarMode = PostActionBarMode.Long, swipeToActionPreset = SwipeToActionPreset.DEFAULT, ) @@ -1000,7 +1005,7 @@ fun PreviewImagePostListingSmallCard() { appState = rememberJerboaAppState(), showPostLinkPreview = true, showIfRead = true, - showScores = true, + voteDisplayMode = VoteDisplayMode.Full, postActionBarMode = PostActionBarMode.Long, swipeToActionPreset = SwipeToActionPreset.DEFAULT, ) @@ -1041,7 +1046,7 @@ fun PreviewLinkNoThumbnailPostListing() { appState = rememberJerboaAppState(), showPostLinkPreview = true, showIfRead = true, - showScores = true, + voteDisplayMode = VoteDisplayMode.Full, postActionBarMode = PostActionBarMode.Long, swipeToActionPreset = SwipeToActionPreset.DEFAULT, ) @@ -1083,7 +1088,7 @@ fun PostListing( appState: JerboaAppState, showPostLinkPreview: Boolean, showIfRead: Boolean, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, postActionBarMode: PostActionBarMode, swipeToActionPreset: SwipeToActionPreset, ) { @@ -1186,7 +1191,7 @@ fun PostListing( showPostLinkPreview = showPostLinkPreview, appState = appState, showIfRead = showIfRead, - showScores = showScores, + voteDisplayMode = voteDisplayMode, postActionBarMode = postActionBarMode, ) @@ -1234,7 +1239,7 @@ fun PostListing( blurNSFW = blurNSFW, showPostLinkPreview = showPostLinkPreview, appState = appState, - showScores = showScores, + voteDisplayMode = voteDisplayMode, postActionBarMode = postActionBarMode, ) @@ -1260,7 +1265,7 @@ fun PostListing( appState = appState, showIfRead = showIfRead, enableDownVotes = enableDownVotes, - showScores = showScores, + voteDisplayMode = voteDisplayMode, ) } } @@ -1287,7 +1292,7 @@ fun PostVotingTile( onDownvoteClick: () -> Unit, account: Account, enableDownVotes: Boolean, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, ) { Column( horizontalAlignment = Alignment.CenterHorizontally, @@ -1299,17 +1304,19 @@ fun PostVotingTile( ) { VoteGeneric( myVote = instantScores.myVote, - votes = instantScores.upvotes, type = VoteType.Upvote, - showNumber = false, onVoteClick = onUpvoteClick, account = account, ) + + val scoreOrPctStr = instantScores.scoreOrPctStr(voteDisplayMode) + Text( - text = instantScores.score.toString(), + text = scoreOrPctStr ?: "", style = MaterialTheme.typography.bodyMedium, color = scoreColor(myVote = instantScores.myVote), - modifier = Modifier.alpha(if (showScores) 1f else 0f), + // Hide the vote number if its + modifier = Modifier.alpha(if (scoreOrPctStr != null) 1f else 0f), ) if (enableDownVotes) { @@ -1321,9 +1328,7 @@ fun PostVotingTile( ) VoteGeneric( myVote = instantScores.myVote, - votes = instantScores.downvotes, type = VoteType.Downvote, - showNumber = false, onVoteClick = onDownvoteClick, account = account, ) @@ -1348,7 +1353,7 @@ fun PostListingList( appState: JerboaAppState, showIfRead: Boolean, enableDownVotes: Boolean, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, ) { Column( modifier = @@ -1373,7 +1378,7 @@ fun PostListingList( onDownvoteClick = onDownvoteClick, account = account, enableDownVotes = enableDownVotes, - showScores = showScores, + voteDisplayMode = voteDisplayMode, ) } Column( @@ -1576,7 +1581,7 @@ fun PostListingListPreview() { appState = rememberJerboaAppState(), showIfRead = true, enableDownVotes = false, - showScores = true, + voteDisplayMode = VoteDisplayMode.Full, ) } @@ -1605,7 +1610,7 @@ fun PostListingListWithThumbPreview() { appState = rememberJerboaAppState(), showIfRead = true, enableDownVotes = false, - showScores = true, + voteDisplayMode = VoteDisplayMode.Full, ) } @@ -1646,7 +1651,7 @@ fun PostListingCard( showPostLinkPreview: Boolean, appState: JerboaAppState, showIfRead: Boolean = false, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, postActionBarMode: PostActionBarMode, ) { Column( @@ -1664,13 +1669,15 @@ fun PostListingCard( postView = postView, myVote = instantScores.myVote, score = instantScores.score, + upvotes = instantScores.upvotes, + downvotes = instantScores.downvotes, onCommunityClick = onCommunityClick, onPersonClick = onPersonClick, showCommunityName = showCommunityName, modifier = Modifier.padding(horizontal = MEDIUM_PADDING), showAvatar = showAvatar, blurNSFW = blurNSFW, - showScores = showScores, + voteDisplayMode = voteDisplayMode, fullBody = fullBody, ) @@ -1717,7 +1724,6 @@ fun PostListingCard( account = account, enableDownVotes = enableDownVotes, viewSource = viewSource, - showScores = showScores, postActionBarMode = postActionBarMode, fromPostActivity = fullBody, scope = appState.coroutineScope, diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt b/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt index ba712545f..6241e33b4 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostListings.kt @@ -22,6 +22,7 @@ import com.jerboa.JerboaAppState import com.jerboa.PostViewMode import com.jerboa.datatypes.BanFromCommunityData import com.jerboa.datatypes.PostFeatureData +import com.jerboa.datatypes.VoteDisplayMode import com.jerboa.datatypes.sampleLinkPostView import com.jerboa.datatypes.samplePostView import com.jerboa.db.entity.Account @@ -81,7 +82,7 @@ fun PostListings( markAsReadOnScroll: Boolean, onMarkAsRead: (postView: PostView) -> Unit, showIfRead: Boolean, - showScores: Boolean, + voteDisplayMode: VoteDisplayMode, postActionBarMode: PostActionBarMode, showPostAppendRetry: Boolean, swipeToActionPreset: SwipeToActionPreset, @@ -136,7 +137,7 @@ fun PostListings( appState = appState, showPostLinkPreview = showPostLinkPreviews, showIfRead = showIfRead, - showScores = showScores, + voteDisplayMode = voteDisplayMode, postActionBarMode = postActionBarMode, swipeToActionPreset = swipeToActionPreset, ).let { @@ -212,7 +213,7 @@ fun PreviewPostListings() { markAsReadOnScroll = false, onMarkAsRead = {}, showIfRead = true, - showScores = true, + voteDisplayMode = VoteDisplayMode.Full, postActionBarMode = PostActionBarMode.Long, showPostAppendRetry = false, swipeToActionPreset = SwipeToActionPreset.DEFAULT, From b3b9e9a256adc2dbebc95b2b779054cfa11a50fa Mon Sep 17 00:00:00 2001 From: Dessalines Date: Wed, 14 Feb 2024 18:03:31 -0500 Subject: [PATCH 2/5] Adding a threshold. --- app/src/main/java/com/jerboa/Constants.kt | 5 +++++ app/src/main/java/com/jerboa/feat/Voting.kt | 13 ++++++----- .../jerboa/ui/components/common/TimeAgo.kt | 22 ++++++++++++------- 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/jerboa/Constants.kt b/app/src/main/java/com/jerboa/Constants.kt index 27ead9b5e..54876d9c8 100644 --- a/app/src/main/java/com/jerboa/Constants.kt +++ b/app/src/main/java/com/jerboa/Constants.kt @@ -4,3 +4,8 @@ const val DEBOUNCE_DELAY = 1000L const val MAX_POST_TITLE_LENGTH = 200 const val DEFAULT_FONT_SIZE = 16 const val INSTANCE_FONT_SIZE = 9 + +/** + * Hides the downvote or percentage, if below this threshold + */ +const val SHOW_UPVOTE_PCT_THRESHOLD = .9F diff --git a/app/src/main/java/com/jerboa/feat/Voting.kt b/app/src/main/java/com/jerboa/feat/Voting.kt index 12ebc2176..d634e39ff 100644 --- a/app/src/main/java/com/jerboa/feat/Voting.kt +++ b/app/src/main/java/com/jerboa/feat/Voting.kt @@ -48,12 +48,15 @@ fun newVote( voteAction: VoteType, ): Int = if (voteAction.value == oldVote) 0 else voteAction.value -fun upvotePercentStr( +fun upvotePercent( upvotes: Long, downvotes: Long, -): String { - val pct = (upvotes / (upvotes + downvotes)) * 100F - val formatted = "%.0f".format(pct) +): Float { + return (upvotes.toFloat() / (upvotes + downvotes)) +} + +fun formatPercent(pct: Float): String { + val formatted = "%.0f".format(pct * 100F) return "$formatted%" } @@ -64,7 +67,7 @@ private fun scoreOrPctStr( voteDisplayMode: VoteDisplayMode, ): String? { return when (voteDisplayMode) { - VoteDisplayMode.UpvotePercentage -> upvotePercentStr(upvotes, downvotes) + VoteDisplayMode.UpvotePercentage -> formatPercent(upvotePercent(upvotes, downvotes)) VoteDisplayMode.HideAll -> null else -> score.toString() } diff --git a/app/src/main/java/com/jerboa/ui/components/common/TimeAgo.kt b/app/src/main/java/com/jerboa/ui/components/common/TimeAgo.kt index 92dbf3748..4ec8094a2 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/TimeAgo.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/TimeAgo.kt @@ -24,10 +24,12 @@ import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.jerboa.R +import com.jerboa.SHOW_UPVOTE_PCT_THRESHOLD import com.jerboa.datatypes.VoteDisplayMode import com.jerboa.datatypes.samplePerson import com.jerboa.datatypes.samplePost -import com.jerboa.feat.upvotePercentStr +import com.jerboa.feat.formatPercent +import com.jerboa.feat.upvotePercent import com.jerboa.formatDuration import com.jerboa.ui.theme.SMALL_PADDING import com.jerboa.ui.theme.muted @@ -135,7 +137,7 @@ fun ScoreAndTime( NsfwBadge(isNsfw) CollapsedIndicator(visible = !isExpanded, descendants = collapsedCommentsCount) Spacer(modifier = Modifier.padding(end = SMALL_PADDING)) - val upvotePct = upvotePercentStr( + val upvotePct = upvotePercent( upvotes = upvotes, downvotes = downvotes, ) @@ -143,17 +145,21 @@ fun ScoreAndTime( VoteDisplayMode.Full -> { LargeVoteIndicator(data = score.toString(), myVote = myVote) DotSpacer(style = MaterialTheme.typography.labelMedium) - SmallVoteIndicator(data = "-$downvotes".toString()) - DotSpacer(style = MaterialTheme.typography.labelMedium) + if (upvotePct < SHOW_UPVOTE_PCT_THRESHOLD) { + SmallVoteIndicator(data = "$downvotes↓") + DotSpacer(style = MaterialTheme.typography.labelMedium) + } } VoteDisplayMode.ScoreAndUpvotePercentage -> { LargeVoteIndicator(data = score.toString(), myVote = myVote) DotSpacer(style = MaterialTheme.typography.labelMedium) - SmallVoteIndicator(data = upvotePct) - DotSpacer(style = MaterialTheme.typography.labelMedium) + if (upvotePct < SHOW_UPVOTE_PCT_THRESHOLD) { + SmallVoteIndicator(data = formatPercent(upvotePct)) + DotSpacer(style = MaterialTheme.typography.labelMedium) + } } VoteDisplayMode.UpvotePercentage -> { - LargeVoteIndicator(data = upvotePct, myVote = myVote) + LargeVoteIndicator(data = formatPercent(upvotePct), myVote = myVote) DotSpacer(style = MaterialTheme.typography.labelMedium) } VoteDisplayMode.Score -> { @@ -184,7 +190,7 @@ private fun SmallVoteIndicator(data: String) { Text( text = data, color = MaterialTheme.colorScheme.onBackground.muted, - style = MaterialTheme.typography.labelSmall, + style = MaterialTheme.typography.labelMedium, ) } From 2fceefbdea8db17e9e7a841d55e9b76fe36a156b Mon Sep 17 00:00:00 2001 From: Dessalines Date: Wed, 14 Feb 2024 18:15:11 -0500 Subject: [PATCH 3/5] Using label for comment count. --- app/src/main/java/com/jerboa/ui/components/common/AppBars.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/jerboa/ui/components/common/AppBars.kt b/app/src/main/java/com/jerboa/ui/components/common/AppBars.kt index 0bd1828fa..f3c4e0aa1 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/AppBars.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/AppBars.kt @@ -438,7 +438,7 @@ fun ActionBarButtonAndBadge( Text( text = text, color = contentColor, - style = MaterialTheme.typography.bodyMedium, + style = MaterialTheme.typography.labelMedium, ) } iconBadgeCount?.also { @@ -446,7 +446,7 @@ fun ActionBarButtonAndBadge( TextBadge( containerColor = MaterialTheme.colorScheme.tertiaryContainer, text = iconBadgeCount, - textStyle = MaterialTheme.typography.bodySmall.copy(fontStyle = FontStyle.Italic), + textStyle = MaterialTheme.typography.labelSmall.copy(fontStyle = FontStyle.Italic), textColor = contentColor, verticalTextPadding = 2f, horizontalTextPadding = 4f, From 0d690c35694449074656f97b8a7579773ece2ac9 Mon Sep 17 00:00:00 2001 From: Dessalines Date: Wed, 21 Feb 2024 09:59:14 -0500 Subject: [PATCH 4/5] Refactor to pass in instantscores. --- app/src/main/java/com/jerboa/Constants.kt | 2 +- app/src/main/java/com/jerboa/feat/Voting.kt | 3 +- .../ui/components/comment/CommentNode.kt | 25 +++---- .../comment/mentionnode/CommentMentionNode.kt | 47 +++++++------ .../components/comment/reply/CommentReply.kt | 41 ++++++----- .../comment/replynode/CommentReplyNode.kt | 48 +++++++------ .../jerboa/ui/components/common/AppBars.kt | 23 +++--- .../jerboa/ui/components/common/TimeAgo.kt | 70 +++++++++++-------- .../jerboa/ui/components/post/PostListing.kt | 35 +++------- .../components/reports/CommentReportItem.kt | 11 +-- .../ui/components/reports/PostReportItem.kt | 11 +-- 11 files changed, 163 insertions(+), 153 deletions(-) diff --git a/app/src/main/java/com/jerboa/Constants.kt b/app/src/main/java/com/jerboa/Constants.kt index 26b311e50..99e52efb2 100644 --- a/app/src/main/java/com/jerboa/Constants.kt +++ b/app/src/main/java/com/jerboa/Constants.kt @@ -6,5 +6,5 @@ const val MAX_POST_TITLE_LENGTH = 200 /** * Hides the downvote or percentage, if below this threshold */ -const val SHOW_UPVOTE_PCT_THRESHOLD = .9F +const val SHOW_UPVOTE_PCT_THRESHOLD = 0.9F const val VIEW_VOTES_LIMIT = 40L diff --git a/app/src/main/java/com/jerboa/feat/Voting.kt b/app/src/main/java/com/jerboa/feat/Voting.kt index d634e39ff..bff78ee92 100644 --- a/app/src/main/java/com/jerboa/feat/Voting.kt +++ b/app/src/main/java/com/jerboa/feat/Voting.kt @@ -56,8 +56,7 @@ fun upvotePercent( } fun formatPercent(pct: Float): String { - val formatted = "%.0f".format(pct * 100F) - return "$formatted%" + return "%.0f".format(pct * 100F) + "%" } private fun scoreOrPctStr( diff --git a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt index 5509c5e31..c4b670ae1 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/CommentNode.kt @@ -99,10 +99,7 @@ import it.vercruysse.lemmyapi.v0x19.datatypes.PostId fun CommentNodeHeader( commentView: CommentView, onPersonClick: (personId: PersonId) -> Unit, - score: Long, - upvotes: Long, - downvotes: Long, - myVote: Int, + instantScores: InstantScores, collapsedCommentsCount: Long, isExpanded: Boolean, onClick: () -> Unit, @@ -112,11 +109,8 @@ fun CommentNodeHeader( ) { CommentOrPostNodeHeader( creator = commentView.creator, - score = score, - upvotes = upvotes, - downvotes = downvotes, + instantScores = instantScores, voteDisplayMode = voteDisplayMode, - myVote = myVote, published = commentView.comment.published, updated = commentView.comment.updated, deleted = commentView.comment.deleted, @@ -137,11 +131,13 @@ fun CommentNodeHeader( fun CommentNodeHeaderPreview() { CommentNodeHeader( commentView = sampleCommentView, - score = 23, - upvotes = 21, - downvotes = 2, + instantScores = InstantScores( + score = 23, + upvotes = 21, + downvotes = 2, + myVote = 26, + ), voteDisplayMode = VoteDisplayMode.Full, - myVote = 26, onPersonClick = {}, onClick = {}, onLongClick = {}, @@ -338,10 +334,7 @@ fun LazyListScope.commentNodeItem( CommentNodeHeader( commentView = commentView, onPersonClick = onPersonClick, - score = instantScores.score, - myVote = instantScores.myVote, - upvotes = instantScores.upvotes, - downvotes = instantScores.downvotes, + instantScores = instantScores, voteDisplayMode = voteDisplayMode, onClick = { onHeaderClick(commentView) diff --git a/app/src/main/java/com/jerboa/ui/components/comment/mentionnode/CommentMentionNode.kt b/app/src/main/java/com/jerboa/ui/components/comment/mentionnode/CommentMentionNode.kt index 2a9267638..e7364c299 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/mentionnode/CommentMentionNode.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/mentionnode/CommentMentionNode.kt @@ -31,6 +31,7 @@ import com.jerboa.datatypes.VoteDisplayMode import com.jerboa.datatypes.samplePersonMentionView import com.jerboa.db.entity.Account import com.jerboa.feat.BlurNSFW +import com.jerboa.feat.InstantScores import com.jerboa.feat.VoteType import com.jerboa.feat.canMod import com.jerboa.ui.components.comment.CommentBody @@ -54,10 +55,7 @@ import it.vercruysse.lemmyapi.v0x19.datatypes.PostId fun CommentMentionNodeHeader( personMentionView: PersonMentionView, onPersonClick: (personId: PersonId) -> Unit, - score: Long, - upvotes: Long, - downvotes: Long, - myVote: Int, + instantScores: InstantScores, onClick: () -> Unit, onLongClick: () -> Unit, showAvatar: Boolean, @@ -65,10 +63,7 @@ fun CommentMentionNodeHeader( ) { CommentOrPostNodeHeader( creator = personMentionView.creator, - score = score, - myVote = myVote, - upvotes = upvotes, - downvotes = downvotes, + instantScores = instantScores, voteDisplayMode = voteDisplayMode, published = personMentionView.comment.published, updated = personMentionView.comment.updated, @@ -88,10 +83,12 @@ fun CommentMentionNodeHeader( fun CommentMentionNodeHeaderPreview() { CommentMentionNodeHeader( personMentionView = samplePersonMentionView, - score = 23, - myVote = 26, - upvotes = 21, - downvotes = 2, + instantScores = InstantScores( + score = 23, + myVote = 26, + upvotes = 21, + downvotes = 2, + ), voteDisplayMode = VoteDisplayMode.Full, onPersonClick = {}, onClick = {}, @@ -267,10 +264,17 @@ fun CommentMentionNode( voteDisplayMode: VoteDisplayMode, ) { // These are necessary for instant comment voting - val score = personMentionView.counts.score - val myVote = personMentionView.my_vote - val upvotes = personMentionView.counts.upvotes - val downvotes = personMentionView.counts.downvotes + var instantScores by + remember { + mutableStateOf( + InstantScores( + score = personMentionView.counts.score, + myVote = personMentionView.my_vote, + upvotes = personMentionView.counts.upvotes, + downvotes = personMentionView.counts.downvotes, + ), + ) + } var viewSource by remember { mutableStateOf(false) } var isExpanded by remember { mutableStateOf(true) } @@ -291,10 +295,7 @@ fun CommentMentionNode( CommentMentionNodeHeader( personMentionView = personMentionView, onPersonClick = onPersonClick, - score = score, - myVote = myVote, - upvotes = upvotes, - downvotes = downvotes, + instantScores = instantScores, voteDisplayMode = voteDisplayMode, onClick = { isExpanded = !isExpanded @@ -329,9 +330,13 @@ fun CommentMentionNode( admins = admins, moderators = moderators, onUpvoteClick = { + instantScores = + instantScores.update(VoteType.Upvote) onUpvoteClick(personMentionView) }, onDownvoteClick = { + instantScores = + instantScores.update(VoteType.Downvote) onDownvoteClick(personMentionView) }, onPersonClick = onPersonClick, @@ -345,10 +350,10 @@ fun CommentMentionNode( onRemoveClick = onRemoveClick, onLinkClick = onLinkClick, onBlockCreatorClick = onBlockCreatorClick, - myVote = myVote, account = account, enableDownvotes = enableDownvotes, viewSource = viewSource, + myVote = instantScores.myVote, ) } } diff --git a/app/src/main/java/com/jerboa/ui/components/comment/reply/CommentReply.kt b/app/src/main/java/com/jerboa/ui/components/comment/reply/CommentReply.kt index 0b5565007..b2ebaced6 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/reply/CommentReply.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/reply/CommentReply.kt @@ -19,6 +19,7 @@ import com.jerboa.datatypes.VoteDisplayMode import com.jerboa.datatypes.getContent import com.jerboa.datatypes.sampleCommentView import com.jerboa.db.entity.Account +import com.jerboa.feat.InstantScores import com.jerboa.ui.components.comment.CommentNodeHeader import com.jerboa.ui.components.comment.mentionnode.CommentMentionNodeHeader import com.jerboa.ui.components.comment.replynode.CommentReplyNodeHeader @@ -43,10 +44,12 @@ fun RepliedComment( CommentNodeHeader( commentView = commentView, onPersonClick = onPersonClick, - score = commentView.counts.score, - upvotes = commentView.counts.upvotes, - downvotes = commentView.counts.downvotes, - myVote = commentView.my_vote, + instantScores = InstantScores( + score = commentView.counts.score, + upvotes = commentView.counts.upvotes, + downvotes = commentView.counts.downvotes, + myVote = commentView.my_vote, + ), collapsedCommentsCount = 0, isExpanded = true, onClick = {}, @@ -71,10 +74,12 @@ fun RepliedCommentReply( CommentReplyNodeHeader( commentReplyView = commentReplyView, onPersonClick = onPersonClick, - score = commentReplyView.counts.score, - upvotes = commentReplyView.counts.upvotes, - downvotes = commentReplyView.counts.downvotes, - myVote = commentReplyView.my_vote, + instantScores = InstantScores( + score = commentReplyView.counts.score, + upvotes = commentReplyView.counts.upvotes, + downvotes = commentReplyView.counts.downvotes, + myVote = commentReplyView.my_vote, + ), onClick = {}, onLongClick = {}, showAvatar = showAvatar, @@ -97,10 +102,12 @@ fun RepliedMentionReply( CommentMentionNodeHeader( personMentionView = personMentionView, onPersonClick = onPersonClick, - score = personMentionView.counts.score, - upvotes = personMentionView.counts.upvotes, - downvotes = personMentionView.counts.downvotes, - myVote = personMentionView.my_vote, + instantScores = InstantScores( + score = personMentionView.counts.score, + upvotes = personMentionView.counts.upvotes, + downvotes = personMentionView.counts.downvotes, + myVote = personMentionView.my_vote, + ), onClick = {}, onLongClick = {}, showAvatar = showAvatar, @@ -133,10 +140,12 @@ fun RepliedPost( Column(modifier = Modifier.padding(MEDIUM_PADDING)) { PostNodeHeader( postView = postView, - myVote = postView.my_vote, - score = postView.counts.score, - upvotes = postView.counts.upvotes, - downvotes = postView.counts.downvotes, + instantScores = InstantScores( + myVote = postView.my_vote, + score = postView.counts.score, + upvotes = postView.counts.upvotes, + downvotes = postView.counts.downvotes, + ), onPersonClick = onPersonClick, showAvatar = showAvatar, voteDisplayMode = voteDisplayMode, diff --git a/app/src/main/java/com/jerboa/ui/components/comment/replynode/CommentReplyNode.kt b/app/src/main/java/com/jerboa/ui/components/comment/replynode/CommentReplyNode.kt index 390df6bc9..1cc6404e1 100644 --- a/app/src/main/java/com/jerboa/ui/components/comment/replynode/CommentReplyNode.kt +++ b/app/src/main/java/com/jerboa/ui/components/comment/replynode/CommentReplyNode.kt @@ -31,6 +31,7 @@ import com.jerboa.datatypes.VoteDisplayMode import com.jerboa.datatypes.sampleCommentReplyView import com.jerboa.db.entity.Account import com.jerboa.feat.BlurNSFW +import com.jerboa.feat.InstantScores import com.jerboa.feat.VoteType import com.jerboa.ui.components.comment.CommentBody import com.jerboa.ui.components.comment.PostAndCommunityContextHeader @@ -51,10 +52,7 @@ import it.vercruysse.lemmyapi.v0x19.datatypes.PostId fun CommentReplyNodeHeader( commentReplyView: CommentReplyView, onPersonClick: (personId: PersonId) -> Unit, - score: Long, - upvotes: Long, - downvotes: Long, - myVote: Int, + instantScores: InstantScores, onClick: () -> Unit, onLongClick: () -> Unit, showAvatar: Boolean, @@ -62,10 +60,7 @@ fun CommentReplyNodeHeader( ) { CommentOrPostNodeHeader( creator = commentReplyView.creator, - score = score, - upvotes = upvotes, - downvotes = downvotes, - myVote = myVote, + instantScores = instantScores, published = commentReplyView.comment.published, updated = commentReplyView.comment.updated, deleted = commentReplyView.comment.deleted, @@ -85,10 +80,12 @@ fun CommentReplyNodeHeader( fun CommentReplyNodeHeaderPreview() { CommentReplyNodeHeader( commentReplyView = sampleCommentReplyView, - score = 23, - myVote = 26, - upvotes = 21, - downvotes = 2, + instantScores = InstantScores( + score = 23, + myVote = 26, + upvotes = 21, + downvotes = 2, + ), voteDisplayMode = VoteDisplayMode.Full, onPersonClick = {}, onClick = {}, @@ -247,10 +244,18 @@ fun CommentReplyNodeInbox( voteDisplayMode: VoteDisplayMode, ) { // These are necessary for instant comment voting - val score = commentReplyView.counts.score - val myVote = commentReplyView.my_vote - val upvotes = commentReplyView.counts.upvotes - val downvotes = commentReplyView.counts.downvotes + // This stores vote data + var instantScores by + remember { + mutableStateOf( + InstantScores( + score = commentReplyView.counts.score, + myVote = commentReplyView.my_vote, + upvotes = commentReplyView.counts.upvotes, + downvotes = commentReplyView.counts.downvotes, + ), + ) + } var viewSource by remember { mutableStateOf(false) } var isExpanded by remember { mutableStateOf(true) } @@ -271,10 +276,7 @@ fun CommentReplyNodeInbox( CommentReplyNodeHeader( commentReplyView = commentReplyView, onPersonClick = onPersonClick, - score = score, - upvotes = upvotes, - downvotes = downvotes, - myVote = myVote, + instantScores = instantScores, onClick = { isExpanded = !isExpanded }, @@ -307,9 +309,13 @@ fun CommentReplyNodeInbox( CommentReplyNodeInboxFooterLine( commentReplyView = commentReplyView, onUpvoteClick = { + instantScores = + instantScores.update(VoteType.Upvote) onUpvoteClick(commentReplyView) }, onDownvoteClick = { + instantScores = + instantScores.update(VoteType.Downvote) onDownvoteClick(commentReplyView) }, onPersonClick = onPersonClick, @@ -322,7 +328,7 @@ fun CommentReplyNodeInbox( onReportClick = onReportClick, onCommentLinkClick = onCommentLinkClick, onBlockCreatorClick = onBlockCreatorClick, - myVote = myVote, + myVote = instantScores.myVote, account = account, enableDownvotes = enableDownvotes, viewSource = viewSource, diff --git a/app/src/main/java/com/jerboa/ui/components/common/AppBars.kt b/app/src/main/java/com/jerboa/ui/components/common/AppBars.kt index 91b8d1521..85152f221 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/AppBars.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/AppBars.kt @@ -53,6 +53,7 @@ import com.jerboa.datatypes.samplePerson import com.jerboa.datatypes.samplePost import com.jerboa.db.entity.Account import com.jerboa.db.entity.AnonAccount +import com.jerboa.feat.InstantScores import com.jerboa.feat.isReadyAndIfNotShowSimplifiedInfoToast import com.jerboa.scrollToNextParentComment import com.jerboa.scrollToPreviousParentComment @@ -64,7 +65,7 @@ import it.vercruysse.lemmyapi.v0x19.datatypes.Person import it.vercruysse.lemmyapi.v0x19.datatypes.PersonId import kotlinx.coroutines.CoroutineScope -@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun SimpleTopAppBar( text: String, @@ -242,10 +243,7 @@ fun CommentNavigationBottomAppBar( @Composable fun CommentOrPostNodeHeader( creator: Person, - score: Long, - upvotes: Long, - downvotes: Long, - myVote: Int, + instantScores: InstantScores, published: String, updated: String?, deleted: Boolean, @@ -301,10 +299,7 @@ fun CommentOrPostNodeHeader( ) } ScoreAndTime( - score = score, - upvotes = upvotes, - downvotes = downvotes, - myVote = myVote, + instantScores = instantScores, published = published, updated = updated, isExpanded = isExpanded, @@ -319,10 +314,12 @@ fun CommentOrPostNodeHeader( fun CommentOrPostNodeHeaderPreview() { CommentOrPostNodeHeader( creator = samplePerson, - score = 23, - upvotes = 21, - downvotes = 2, - myVote = 1, + instantScores = InstantScores( + score = 23, + upvotes = 21, + downvotes = 2, + myVote = 1, + ), published = samplePost.published, updated = samplePost.updated, deleted = false, diff --git a/app/src/main/java/com/jerboa/ui/components/common/TimeAgo.kt b/app/src/main/java/com/jerboa/ui/components/common/TimeAgo.kt index ba07bfca4..df9f89e86 100644 --- a/app/src/main/java/com/jerboa/ui/components/common/TimeAgo.kt +++ b/app/src/main/java/com/jerboa/ui/components/common/TimeAgo.kt @@ -29,6 +29,7 @@ import com.jerboa.SHOW_UPVOTE_PCT_THRESHOLD import com.jerboa.datatypes.VoteDisplayMode import com.jerboa.datatypes.samplePerson import com.jerboa.datatypes.samplePost +import com.jerboa.feat.InstantScores import com.jerboa.feat.formatPercent import com.jerboa.feat.upvotePercent import com.jerboa.formatDuration @@ -121,10 +122,7 @@ fun TimeAgoPreview() { @Composable fun ScoreAndTime( - score: Long, - upvotes: Long, - downvotes: Long, - myVote: Int, + instantScores: InstantScores, published: String, updated: String?, isExpanded: Boolean = true, @@ -140,20 +138,20 @@ fun ScoreAndTime( CollapsedIndicator(visible = !isExpanded, descendants = collapsedCommentsCount) Spacer(modifier = Modifier.padding(end = SMALL_PADDING)) val upvotePct = upvotePercent( - upvotes = upvotes, - downvotes = downvotes, + upvotes = instantScores.upvotes, + downvotes = instantScores.downvotes, ) when (voteDisplayMode) { VoteDisplayMode.Full -> { - LargeVoteIndicator(data = score.toString(), myVote = myVote) + LargeVoteIndicator(data = instantScores.score.toString(), myVote = instantScores.myVote) DotSpacer(style = MaterialTheme.typography.labelMedium) if (upvotePct < SHOW_UPVOTE_PCT_THRESHOLD) { - SmallVoteIndicator(data = "$downvotes↓") + SmallVoteIndicator(data = "${instantScores.downvotes}↓") DotSpacer(style = MaterialTheme.typography.labelMedium) } } VoteDisplayMode.ScoreAndUpvotePercentage -> { - LargeVoteIndicator(data = score.toString(), myVote = myVote) + LargeVoteIndicator(data = instantScores.score.toString(), myVote = instantScores.myVote) DotSpacer(style = MaterialTheme.typography.labelMedium) if (upvotePct < SHOW_UPVOTE_PCT_THRESHOLD) { SmallVoteIndicator(data = formatPercent(upvotePct)) @@ -161,11 +159,11 @@ fun ScoreAndTime( } } VoteDisplayMode.UpvotePercentage -> { - LargeVoteIndicator(data = formatPercent(upvotePct), myVote = myVote) + LargeVoteIndicator(data = formatPercent(upvotePct), myVote = instantScores.myVote) DotSpacer(style = MaterialTheme.typography.labelMedium) } VoteDisplayMode.Score -> { - LargeVoteIndicator(data = score.toString(), myVote = myVote) + LargeVoteIndicator(data = instantScores.score.toString(), myVote = instantScores.myVote) DotSpacer(style = MaterialTheme.typography.labelMedium) } VoteDisplayMode.HideAll -> {} @@ -200,10 +198,12 @@ private fun SmallVoteIndicator(data: String) { @Composable fun ScoreFullAndTimePreview() { ScoreAndTime( - score = 25, - myVote = -1, - upvotes = 10, - downvotes = 15, + instantScores = InstantScores( + score = 25, + myVote = -1, + upvotes = 10, + downvotes = 15, + ), published = samplePost.published, updated = samplePost.updated, voteDisplayMode = VoteDisplayMode.Full, @@ -214,10 +214,12 @@ fun ScoreFullAndTimePreview() { @Composable fun ScoreAndUpvotePctAndTimePreview() { ScoreAndTime( - score = 25, - myVote = -1, - upvotes = 10, - downvotes = 15, + instantScores = InstantScores( + score = 25, + myVote = -1, + upvotes = 10, + downvotes = 15, + ), published = samplePost.published, updated = samplePost.updated, voteDisplayMode = VoteDisplayMode.ScoreAndUpvotePercentage, @@ -228,10 +230,12 @@ fun ScoreAndUpvotePctAndTimePreview() { @Composable fun UpvotePctAndTimePreview() { ScoreAndTime( - score = 25, - myVote = -1, - upvotes = 10, - downvotes = 15, + instantScores = InstantScores( + score = 25, + myVote = -1, + upvotes = 10, + downvotes = 15, + ), published = samplePost.published, updated = samplePost.updated, voteDisplayMode = VoteDisplayMode.UpvotePercentage, @@ -242,10 +246,12 @@ fun UpvotePctAndTimePreview() { @Composable fun ScoreAndTimePreview() { ScoreAndTime( - score = 25, - myVote = -1, - upvotes = 10, - downvotes = 15, + instantScores = InstantScores( + score = 25, + myVote = -1, + upvotes = 10, + downvotes = 15, + ), published = samplePost.published, updated = samplePost.updated, voteDisplayMode = VoteDisplayMode.Score, @@ -256,10 +262,12 @@ fun ScoreAndTimePreview() { @Composable fun HideAllAndTimePreview() { ScoreAndTime( - score = 25, - myVote = -1, - upvotes = 10, - downvotes = 15, + instantScores = InstantScores( + score = 25, + myVote = -1, + upvotes = 10, + downvotes = 15, + ), published = samplePost.published, updated = samplePost.updated, voteDisplayMode = VoteDisplayMode.HideAll, diff --git a/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt b/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt index 2aa6faea2..1c2406467 100644 --- a/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt +++ b/app/src/main/java/com/jerboa/ui/components/post/PostListing.kt @@ -129,10 +129,7 @@ import kotlinx.coroutines.CoroutineScope @Composable fun PostHeaderLine( postView: PostView, - myVote: Int, - score: Long, - upvotes: Long, - downvotes: Long, + instantScores: InstantScores, onCommunityClick: (community: Community) -> Unit, onPersonClick: (personId: PersonId) -> Unit, modifier: Modifier = Modifier, @@ -231,10 +228,7 @@ fun PostHeaderLine( } } ScoreAndTime( - score = score, - myVote = myVote, - upvotes = upvotes, - downvotes = downvotes, + instantScores = instantScores, published = postView.post.published, updated = postView.post.updated, isNsfw = nsfwCheck(postView), @@ -250,10 +244,12 @@ fun PostHeaderLinePreview() { val postView = sampleLinkPostView PostHeaderLine( postView = postView, - myVote = 0, - score = 10, - upvotes = 9, - downvotes = 1, + instantScores = InstantScores( + myVote = 0, + score = 10, + upvotes = 9, + downvotes = 1, + ), onCommunityClick = {}, onPersonClick = {}, showAvatar = true, @@ -266,20 +262,14 @@ fun PostHeaderLinePreview() { @Composable fun PostNodeHeader( postView: PostView, - myVote: Int, - score: Long, - upvotes: Long, - downvotes: Long, + instantScores: InstantScores, onPersonClick: (personId: PersonId) -> Unit, showAvatar: Boolean, voteDisplayMode: VoteDisplayMode, ) { CommentOrPostNodeHeader( creator = postView.creator, - myVote = myVote, - score = score, - upvotes = upvotes, - downvotes = downvotes, + instantScores = instantScores, published = postView.post.published, updated = postView.post.updated, deleted = postView.post.deleted, @@ -1662,10 +1652,7 @@ fun PostListingCard( // Header PostHeaderLine( postView = postView, - myVote = instantScores.myVote, - score = instantScores.score, - upvotes = instantScores.upvotes, - downvotes = instantScores.downvotes, + instantScores = instantScores, onCommunityClick = onCommunityClick, onPersonClick = onPersonClick, showCommunityName = showCommunityName, diff --git a/app/src/main/java/com/jerboa/ui/components/reports/CommentReportItem.kt b/app/src/main/java/com/jerboa/ui/components/reports/CommentReportItem.kt index fb29dae67..4409a4c1f 100644 --- a/app/src/main/java/com/jerboa/ui/components/reports/CommentReportItem.kt +++ b/app/src/main/java/com/jerboa/ui/components/reports/CommentReportItem.kt @@ -9,6 +9,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import com.jerboa.datatypes.VoteDisplayMode import com.jerboa.datatypes.sampleCommentReportView +import com.jerboa.feat.InstantScores import com.jerboa.ui.components.comment.CommentBody import com.jerboa.ui.components.comment.CommentNodeHeader import com.jerboa.ui.theme.MEDIUM_PADDING @@ -62,10 +63,12 @@ fun CommentReportItem( // Don't use the full CommentNode, as you don't need any of the actions there CommentNodeHeader( commentView = commentView, - myVote = commentView.my_vote, - score = commentView.counts.score, - upvotes = commentView.counts.upvotes, - downvotes = commentView.counts.downvotes, + instantScores = InstantScores( + myVote = commentView.my_vote, + score = commentView.counts.score, + upvotes = commentView.counts.upvotes, + downvotes = commentView.counts.downvotes, + ), onPersonClick = onPersonClick, showAvatar = showAvatar, voteDisplayMode = voteDisplayMode, diff --git a/app/src/main/java/com/jerboa/ui/components/reports/PostReportItem.kt b/app/src/main/java/com/jerboa/ui/components/reports/PostReportItem.kt index 0a11ccbf3..4a432e39b 100644 --- a/app/src/main/java/com/jerboa/ui/components/reports/PostReportItem.kt +++ b/app/src/main/java/com/jerboa/ui/components/reports/PostReportItem.kt @@ -15,6 +15,7 @@ import com.jerboa.datatypes.samplePostReportView import com.jerboa.db.entity.Account import com.jerboa.db.entity.AnonAccount import com.jerboa.feat.BlurNSFW +import com.jerboa.feat.InstantScores import com.jerboa.rememberJerboaAppState import com.jerboa.ui.components.post.PostBody import com.jerboa.ui.components.post.PostHeaderLine @@ -83,10 +84,12 @@ fun PostReportItem( ) { PostHeaderLine( postView = postView, - myVote = postView.my_vote, - score = postView.counts.score, - upvotes = postView.counts.upvotes, - downvotes = postView.counts.downvotes, + instantScores = InstantScores( + myVote = postView.my_vote, + score = postView.counts.score, + upvotes = postView.counts.upvotes, + downvotes = postView.counts.downvotes, + ), onCommunityClick = onCommunityClick, onPersonClick = onPersonClick, showCommunityName = true, From e39a35542e21a4339f184916af99757ad2c1898e Mon Sep 17 00:00:00 2001 From: Dessalines Date: Wed, 21 Feb 2024 11:22:49 -0500 Subject: [PATCH 5/5] Fixing format percent. --- app/src/main/java/com/jerboa/feat/Voting.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/jerboa/feat/Voting.kt b/app/src/main/java/com/jerboa/feat/Voting.kt index bff78ee92..ee653cd30 100644 --- a/app/src/main/java/com/jerboa/feat/Voting.kt +++ b/app/src/main/java/com/jerboa/feat/Voting.kt @@ -56,7 +56,7 @@ fun upvotePercent( } fun formatPercent(pct: Float): String { - return "%.0f".format(pct * 100F) + "%" + return "%.0f%%".format(pct * 100F) } private fun scoreOrPctStr(