mirror of
https://github.com/metabolist/metatext.git
synced 2024-12-22 05:26:30 +00:00
Conversation unread state
This commit is contained in:
parent
63f9b59135
commit
6294b1c52f
6 changed files with 60 additions and 0 deletions
|
@ -107,6 +107,7 @@
|
|||
"compose.visibility-button.accessibility-label-%@" = "Privacy: %@";
|
||||
"compose-button.accessibility-label.post" = "Compose Post";
|
||||
"compose-button.accessibility-label.toot" = "Compose Toot";
|
||||
"conversation.unread" = "Unread";
|
||||
"emoji.custom" = "Custom";
|
||||
"emoji.default-skin-tone" = "Default skin tone";
|
||||
"emoji.default-skin-tone-button.accessibility-label" = "Select default skin tone";
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright © 2020 Metabolist. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import HTTP
|
||||
import Mastodon
|
||||
|
||||
public enum ConversationEndpoint {
|
||||
case read(id: Conversation.Id)
|
||||
}
|
||||
|
||||
extension ConversationEndpoint: Endpoint {
|
||||
public typealias ResultType = Conversation
|
||||
|
||||
public var context: [String] {
|
||||
defaultContext + ["conversations"]
|
||||
}
|
||||
|
||||
public var pathComponentsInContext: [String] {
|
||||
switch self {
|
||||
case let .read(id):
|
||||
return [id, "read"]
|
||||
}
|
||||
}
|
||||
|
||||
public var method: HTTPMethod {
|
||||
switch self {
|
||||
case .read:
|
||||
return .post
|
||||
}
|
||||
}
|
||||
}
|
|
@ -26,6 +26,14 @@ public struct ConversationsService {
|
|||
}
|
||||
}
|
||||
|
||||
public extension ConversationsService {
|
||||
func markConversationAsRead(id: Conversation.Id) -> AnyPublisher<Never, Error> {
|
||||
mastodonAPIClient.request(ConversationEndpoint.read(id: id))
|
||||
.flatMap { contentDatabase.insert(conversations: [$0]) }
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
}
|
||||
|
||||
extension ConversationsService: CollectionService {
|
||||
public func request(maxId: String?, minId: String?, search: Search?) -> AnyPublisher<Never, Error> {
|
||||
mastodonAPIClient.pagedRequest(ConversationsEndpoint.conversations, maxId: maxId, minId: minId)
|
||||
|
|
|
@ -149,6 +149,10 @@ extension CollectionItemsViewModel: CollectionViewModel {
|
|||
case let .conversation(conversation):
|
||||
guard let status = conversation.lastStatus else { break }
|
||||
|
||||
(collectionService as? ConversationsService)?.markConversationAsRead(id: conversation.id)
|
||||
.sink { _ in } receiveValue: { _ in }
|
||||
.store(in: &cancellables)
|
||||
|
||||
send(event: .navigation(.collection(collectionService
|
||||
.navigationService
|
||||
.contextService(id: status.displayStatus.id))))
|
||||
|
|
|
@ -33,3 +33,7 @@ public final class ConversationViewModel: ObservableObject {
|
|||
self.identityContext = identityContext
|
||||
}
|
||||
}
|
||||
|
||||
public extension ConversationViewModel {
|
||||
var isUnread: Bool { conversationService.conversation.unread }
|
||||
}
|
||||
|
|
|
@ -7,6 +7,9 @@ import ViewModels
|
|||
final class ConversationView: UIView {
|
||||
let avatarsView = ConversationAvatarsView()
|
||||
let displayNamesLabel = UILabel()
|
||||
let unreadIndicator = UIImageView(image: UIImage(
|
||||
systemName: "circlebadge.fill",
|
||||
withConfiguration: UIImage.SymbolConfiguration(scale: .small)))
|
||||
let timeLabel = UILabel()
|
||||
let statusBodyView = StatusBodyView()
|
||||
|
||||
|
@ -78,6 +81,7 @@ private extension ConversationView {
|
|||
namesTimeStackView.spacing = .compactSpacing
|
||||
namesTimeStackView.alignment = .top
|
||||
namesTimeStackView.addArrangedSubview(displayNamesLabel)
|
||||
namesTimeStackView.addArrangedSubview(unreadIndicator)
|
||||
namesTimeStackView.addArrangedSubview(timeLabel)
|
||||
|
||||
mainStackView.axis = .vertical
|
||||
|
@ -90,6 +94,9 @@ private extension ConversationView {
|
|||
displayNamesLabel.adjustsFontForContentSizeCategory = true
|
||||
displayNamesLabel.numberOfLines = 0
|
||||
|
||||
unreadIndicator.contentMode = .scaleAspectFit
|
||||
unreadIndicator.setContentHuggingPriority(.required, for: .horizontal)
|
||||
|
||||
timeLabel.font = .preferredFont(forTextStyle: .subheadline)
|
||||
timeLabel.adjustsFontForContentSizeCategory = true
|
||||
timeLabel.textColor = .secondaryLabel
|
||||
|
@ -126,6 +133,7 @@ private extension ConversationView {
|
|||
view: displayNamesLabel)
|
||||
mutableDisplayNames.resizeAttachments(toLineHeight: displayNamesLabel.font.lineHeight)
|
||||
|
||||
unreadIndicator.isHidden = !viewModel.isUnread
|
||||
displayNamesLabel.attributedText = mutableDisplayNames
|
||||
timeLabel.text = viewModel.statusViewModel?.time
|
||||
timeLabel.accessibilityLabel = viewModel.statusViewModel?.accessibilityTime
|
||||
|
@ -134,6 +142,10 @@ private extension ConversationView {
|
|||
|
||||
let accessibilityAttributedLabel = NSMutableAttributedString(attributedString: mutableDisplayNames)
|
||||
|
||||
if viewModel.isUnread {
|
||||
accessibilityAttributedLabel.appendWithSeparator(NSLocalizedString("conversation.unread", comment: ""))
|
||||
}
|
||||
|
||||
if let statusBodyAccessibilityAttributedLabel = statusBodyView.accessibilityAttributedLabel {
|
||||
accessibilityAttributedLabel.appendWithSeparator(statusBodyAccessibilityAttributedLabel)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue