mirror of
https://github.com/Dimillian/IceCubesApp.git
synced 2024-06-01 07:08:17 +00:00
123 lines
4.2 KiB
Swift
123 lines
4.2 KiB
Swift
import SwiftUI
|
|
import Models
|
|
|
|
/// A utility that creates a suitable combined accessibility label for a `StatusRowView` that is not focused.
|
|
@MainActor
|
|
struct StatusRowAccessibilityLabel {
|
|
let viewModel: StatusRowViewModel
|
|
|
|
var hasSpoiler: Bool {
|
|
viewModel.displaySpoiler && viewModel.finalStatus.spoilerText.asRawText.isEmpty == false
|
|
}
|
|
|
|
var isReply: Bool {
|
|
if let accountId = viewModel.status.inReplyToAccountId, viewModel.status.mentions.contains(where: { $0.id == accountId }) {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
var isBoost: Bool {
|
|
viewModel.status.reblog != nil
|
|
}
|
|
|
|
var filter: Filter? {
|
|
guard viewModel.isFiltered else {
|
|
return nil
|
|
}
|
|
return viewModel.filter?.filter
|
|
}
|
|
|
|
func finalLabel() -> Text {
|
|
if let filter {
|
|
switch filter.filterAction {
|
|
case .warn:
|
|
Text("status.filter.filtered-by-\(filter.title)")
|
|
case .hide:
|
|
Text("")
|
|
}
|
|
} else {
|
|
userNamePreamble() +
|
|
Text(hasSpoiler
|
|
? viewModel.finalStatus.spoilerText.asRawText
|
|
: viewModel.finalStatus.content.asRawText
|
|
) +
|
|
Text(hasSpoiler
|
|
? "status.editor.spoiler"
|
|
: ""
|
|
) + Text(", ") +
|
|
pollText() +
|
|
imageAltText() +
|
|
Text(viewModel.finalStatus.createdAt.relativeFormatted) + Text(", ") +
|
|
Text("status.summary.n-replies \(viewModel.finalStatus.repliesCount)") + Text(", ") +
|
|
Text("status.summary.n-boosts \(viewModel.finalStatus.reblogsCount)") + Text(", ") +
|
|
Text("status.summary.n-favorites \(viewModel.finalStatus.favouritesCount)")
|
|
}
|
|
}
|
|
|
|
func userNamePreamble() -> Text {
|
|
switch (isReply, isBoost) {
|
|
case (true, false):
|
|
Text("accessibility.status.a-replied-to-\(finalUserDisplayName())") + Text(" ")
|
|
case (_, true):
|
|
Text("accessibility.status.a-boosted-b-\(userDisplayName())-\(finalUserDisplayName())") + Text(", ")
|
|
default:
|
|
Text(userDisplayName()) + Text(", ")
|
|
}
|
|
}
|
|
|
|
func userDisplayName() -> String {
|
|
viewModel.status.account.displayNameWithoutEmojis.count < 4
|
|
? viewModel.status.account.safeDisplayName
|
|
: viewModel.status.account.displayNameWithoutEmojis
|
|
}
|
|
|
|
func finalUserDisplayName() -> String {
|
|
viewModel.finalStatus.account.displayNameWithoutEmojis.count < 4
|
|
? viewModel.finalStatus.account.safeDisplayName
|
|
: viewModel.finalStatus.account.displayNameWithoutEmojis
|
|
}
|
|
|
|
func imageAltText() -> Text {
|
|
let descriptions = viewModel.finalStatus.mediaAttachments
|
|
.compactMap(\.description)
|
|
|
|
if descriptions.count == 1 {
|
|
return Text("accessibility.image.alt-text-\(descriptions[0])") + Text(", ")
|
|
} else if descriptions.count > 1 {
|
|
return Text("accessibility.image.alt-text-\(descriptions[0])") + Text(", ") + Text("accessibility.image.alt-text-more.label") + Text(", ")
|
|
} else if viewModel.finalStatus.mediaAttachments.isEmpty == false {
|
|
let differentTypes = Set(viewModel.finalStatus.mediaAttachments.compactMap(\.localizedTypeDescription)).sorted()
|
|
return Text("accessibility.status.contains-media.label-\(ListFormatter.localizedString(byJoining: differentTypes))") + Text(", ")
|
|
} else {
|
|
return Text("")
|
|
}
|
|
}
|
|
|
|
func pollText() -> Text {
|
|
if let poll = viewModel.finalStatus.poll {
|
|
let showPercentage = poll.expired || poll.voted ?? false
|
|
let title: LocalizedStringKey = poll.expired
|
|
? "accessibility.status.poll.finished.label"
|
|
: "accessibility.status.poll.active.label"
|
|
|
|
return poll.options.enumerated().reduce(into: Text(title)) { text, pair in
|
|
let (index, option) = pair
|
|
let selected = poll.ownVotes?.contains(index) ?? false
|
|
let percentage = poll.safeVotersCount > 0 && option.votesCount != nil
|
|
? Int(round(Double(option.votesCount!) / Double(poll.safeVotersCount) * 100))
|
|
: 0
|
|
|
|
text = text +
|
|
Text(selected ? "accessibility.status.poll.selected.label" : "") +
|
|
Text(", ") +
|
|
Text("accessibility.status.poll.option-prefix-\(index + 1)-of-\(poll.options.count)") +
|
|
Text(", ") +
|
|
Text(option.title) +
|
|
Text(showPercentage ? ", \(percentage)%. " : ". ")
|
|
}
|
|
}
|
|
return Text("")
|
|
}
|
|
}
|