diff --git a/Mlem/Icons.swift b/Mlem/Icons.swift index 7459b350d..180cf36c3 100644 --- a/Mlem/Icons.swift +++ b/Mlem/Icons.swift @@ -46,7 +46,8 @@ struct Icons { // misc post static let posts: String = "doc.plaintext" - static let replies: String = "bubble.right" + static let replies: String = "bubble" + static let unreadReplies: String = "text.bubble" static let textPost: String = "text.book.closed" static let titleOnlyPost: String = "character.bubble" static let pinned: String = "pin.fill" diff --git a/Mlem/Models/Content/Post Model.swift b/Mlem/Models/Content/Post Model.swift index b5767a3b6..49081467b 100644 --- a/Mlem/Models/Content/Post Model.swift +++ b/Mlem/Models/Content/Post Model.swift @@ -15,7 +15,8 @@ struct PostModel { let creator: UserModel let community: CommunityModel var votes: VotesModel - let numReplies: Int + let commentCount: Int + let unreadCommentCount: Int let saved: Bool let read: Bool let published: Date @@ -32,7 +33,8 @@ struct PostModel { self.creator = UserModel(from: apiPostView.creator) self.community = CommunityModel(from: apiPostView.community, subscribed: apiPostView.subscribed.isSubscribed) self.votes = VotesModel(from: apiPostView.counts, myVote: apiPostView.myVote) - self.numReplies = apiPostView.counts.comments + self.commentCount = apiPostView.counts.comments + self.unreadCommentCount = apiPostView.unreadComments self.saved = apiPostView.saved self.read = apiPostView.read self.published = apiPostView.post.published @@ -60,7 +62,8 @@ struct PostModel { creator: UserModel? = nil, community: CommunityModel? = nil, votes: VotesModel? = nil, - numReplies: Int? = nil, + commentCount: Int? = nil, + unreadCommentCount: Int? = nil, saved: Bool? = nil, read: Bool? = nil, published: Date? = nil, @@ -71,7 +74,8 @@ struct PostModel { self.creator = creator ?? other.creator self.community = community ?? other.community self.votes = votes ?? other.votes - self.numReplies = numReplies ?? other.numReplies + self.commentCount = commentCount ?? other.commentCount + self.unreadCommentCount = unreadCommentCount ?? other.unreadCommentCount self.saved = saved ?? other.saved self.read = read ?? other.read self.published = published ?? other.published diff --git a/Mlem/Views/Shared/Comments/Comment Item.swift b/Mlem/Views/Shared/Comments/Comment Item.swift index 883a5cbbc..9f2d43cf8 100644 --- a/Mlem/Views/Shared/Comments/Comment Item.swift +++ b/Mlem/Views/Shared/Comments/Comment Item.swift @@ -165,7 +165,7 @@ struct CommentItem: View { votes: VotesModel(from: hierarchicalComment.commentView.counts, myVote: hierarchicalComment.commentView.myVote), published: hierarchicalComment.commentView.comment.published, updated: hierarchicalComment.commentView.comment.updated, - numReplies: hierarchicalComment.commentView.counts.childCount, + commentCount: hierarchicalComment.commentView.counts.childCount, saved: hierarchicalComment.commentView.saved, accessibilityContext: "comment", widgets: layoutWidgetTracker.groups.comment, diff --git a/Mlem/Views/Shared/Components/Components/InfoStackView.swift b/Mlem/Views/Shared/Components/Components/InfoStackView.swift index b7dbb0b39..c4f9306a4 100644 --- a/Mlem/Views/Shared/Components/Components/InfoStackView.swift +++ b/Mlem/Views/Shared/Components/Components/InfoStackView.swift @@ -22,6 +22,8 @@ struct InfoStackView: View { let published: Date? let updated: Date? let commentCount: Int? + let unreadCommentCount: Int? + let saved: Bool? let alignment: HorizontalAlignment let colorizeVotes: Bool @@ -52,7 +54,11 @@ struct InfoStackView: View { } if let commentCount { - repliesView(numReplies: commentCount) + if let unreadCommentCount, unreadCommentCount > 0, unreadCommentCount != commentCount { + unreadRepliesView(commentCount: commentCount, unreadCommentCount: unreadCommentCount) + } else { + repliesView(commentCount: commentCount) + } } } .fixedSize() @@ -112,13 +118,25 @@ struct InfoStackView: View { } @ViewBuilder - func repliesView(numReplies: Int) -> some View { + func repliesView(commentCount: Int) -> some View { HStack(spacing: AppConstants.iconToTextSpacing) { Image(systemName: Icons.replies) - Text(numReplies.description) + Text(String(describing: commentCount)) + } + .accessibilityAddTraits(.isStaticText) + .accessibilityElement(children: .ignore) + .accessibilityLabel("\(commentCount) comments") + } + + @ViewBuilder + func unreadRepliesView(commentCount: Int, unreadCommentCount: Int) -> some View { + HStack(spacing: AppConstants.iconToTextSpacing) { + Image(systemName: Icons.unreadReplies) + Text("\(commentCount)") + + Text(" +\(unreadCommentCount)").foregroundColor(.green) } .accessibilityAddTraits(.isStaticText) .accessibilityElement(children: .ignore) - .accessibilityLabel("\(numReplies) comments") + .accessibilityLabel("\(commentCount) comments, \(unreadCommentCount) new") } } diff --git a/Mlem/Views/Shared/Components/InteractionBarView.swift b/Mlem/Views/Shared/Components/InteractionBarView.swift index 5cb53f737..e498de61a 100644 --- a/Mlem/Views/Shared/Components/InteractionBarView.swift +++ b/Mlem/Views/Shared/Components/InteractionBarView.swift @@ -20,7 +20,8 @@ struct InteractionBarView: View { let votes: VotesModel let published: Date let updated: Date? - let numReplies: Int + let commentCount: Int + var unreadCommentCount: Int = 0 let saved: Bool let accessibilityContext: String @@ -111,7 +112,8 @@ struct InteractionBarView: View { : nil, published: shouldShowTime ? published : nil, updated: shouldShowTime ? updated : nil, - commentCount: shouldShowReplies ? numReplies : nil, + commentCount: shouldShowReplies ? commentCount : nil, + unreadCommentCount: unreadCommentCount, saved: shouldShowSaved ? saved : nil, alignment: infoStackAlignment(offset), colorizeVotes: false diff --git a/Mlem/Views/Shared/Posts/Expanded Post.swift b/Mlem/Views/Shared/Posts/Expanded Post.swift index 2fe647777..a69d752aa 100644 --- a/Mlem/Views/Shared/Posts/Expanded Post.swift +++ b/Mlem/Views/Shared/Posts/Expanded Post.swift @@ -249,7 +249,8 @@ struct ExpandedPost: View { votes: post.votes, published: post.published, updated: post.updated, - numReplies: post.numReplies, + commentCount: post.commentCount, + unreadCommentCount: post.unreadCommentCount, saved: post.saved, accessibilityContext: "post", widgets: layoutWidgetTracker.groups.post, diff --git a/Mlem/Views/Shared/Posts/ExpandedPostLogic.swift b/Mlem/Views/Shared/Posts/ExpandedPostLogic.swift index 32e5b59f3..986882b33 100644 --- a/Mlem/Views/Shared/Posts/ExpandedPostLogic.swift +++ b/Mlem/Views/Shared/Posts/ExpandedPostLogic.swift @@ -215,6 +215,10 @@ extension ExpandedPost { isLoading = true do { + // Making this request marks unread comments as read. + post = PostModel(from: try await postRepository.loadPost(postId: post.postId)) + postTracker.update(with: post) + let comments = try await commentRepository.comments(for: post.post.id) let sorted = sortComments(comments, by: commentSortingType) commentTracker.comments = sorted diff --git a/Mlem/Views/Shared/Posts/Feed Post.swift b/Mlem/Views/Shared/Posts/Feed Post.swift index 3920122bb..1de13e721 100644 --- a/Mlem/Views/Shared/Posts/Feed Post.swift +++ b/Mlem/Views/Shared/Posts/Feed Post.swift @@ -198,7 +198,8 @@ struct FeedPost: View { votes: post.votes, published: post.published, updated: post.updated, - numReplies: post.numReplies, + commentCount: post.commentCount, + unreadCommentCount: post.unreadCommentCount, saved: post.saved, accessibilityContext: "post", widgets: layoutWidgetTracker.groups.post, diff --git a/Mlem/Views/Shared/Posts/Post Sizes/Compact Post.swift b/Mlem/Views/Shared/Posts/Post Sizes/Compact Post.swift index 424688f2e..0f6f8e3ed 100644 --- a/Mlem/Views/Shared/Posts/Post Sizes/Compact Post.swift +++ b/Mlem/Views/Shared/Posts/Post Sizes/Compact Post.swift @@ -116,7 +116,8 @@ struct CompactPost: View { ), published: post.published, updated: post.updated, - commentCount: post.numReplies, + commentCount: post.commentCount, + unreadCommentCount: post.unreadCommentCount, saved: post.saved, alignment: .center, colorizeVotes: true