IceCubesApp/Packages/StatusKit/Sources/StatusKit/Row/Subviews/StatusRowDetailView.swift

115 lines
3.5 KiB
Swift
Raw Normal View History

import DesignSystem
2023-02-12 15:29:41 +00:00
import Env
import Models
2023-02-12 15:29:41 +00:00
import SwiftUI
@MainActor
struct StatusRowDetailView: View {
@Environment(\.openURL) private var openURL
2023-03-13 12:38:28 +00:00
@Environment(StatusDataController.self) private var statusDataController
2023-02-12 15:29:41 +00:00
var viewModel: StatusRowViewModel
2023-02-12 15:29:41 +00:00
var body: some View {
2023-12-27 15:48:50 +00:00
VStack(alignment: .leading, spacing: 12) {
Divider()
HStack {
Timeline & Timeline detail accessibility uplift (#1323) * Improve accessibility of StatusPollView Previously, this view did not provide the proper context to indicate that it represented a poll. Now, we’ve added - A container that will stay “Active poll” or “Poll results” when the cursor first hits one of the options; - A prefix to say “Option X of Y” before each option; - A Selected trait on the selected option(s), if present - Consolidating and adding an `.updatesFrequently` trait to the footer view with the countdown. * Add poll description in StatusRowView combinedAccessibilityLabel This largely duplicates the logic in `StatusPollView`. * Improve accessibility of media attachments Previously, the media attachments without alt text would not show up in the consolidated `StatusRowView`, nor would they be meaningfully explained on the status detail screen. Now, they are presented with their attachment type. * Change accessibilityRepresentation of AppAcountsSelectorView * Change Notifications tab title view accessibility representation to Menu Previously it would present as a button * Hide layout `Rectangle`s from accessibility * Consolidate `StatusRowDetailView` accessibility representation * Improve readability of Poll accessibility label * Ensure poll options don’t present as interactive when the poll is finished * Improve accessibility of StatusRowCardView Previously, it would present as four separate elements, including an image without a description, all interactive, none with an interactive trait. Now, it presents as a single element with the `.link` trait * Improve accessibility of StatusRowHeaderView Previously, it had no traits and no actions except inherited ones. Now it presents as a button, triggering its primary action. It also has custom actions corresponding to its context menu * Avoid applying the StatusRowView custom actions to every view when contained * Provide context for the application name * Add pauses to StatusRowView combinedAccessibilityLabel * Hide `TimelineView.scrollToTopView` from accessibility * Set appropriate font style on Notification header After the change the Text needed a `.headline` style to match the prior appearance. * Fix bug in accessibilityRepresentation of TimelineView nav bar title Previously, it would not display the proper label for .remoteLocal filter options. * Ensure that pop-up button nav bar titles are interactive * Ensure TextView responds to Environment.sizeCategory This resolves #1309 * Fix button --------- Co-authored-by: Thomas Ricouard <ricouard77@gmail.com>
2023-03-28 16:48:58 +00:00
Group {
Text(viewModel.status.createdAt.asDate, style: .date) +
Text("status.summary.at-time") +
Text(viewModel.status.createdAt.asDate, style: .time) +
Text(" ·")
Image(systemName: viewModel.status.visibility.iconName)
.accessibilityHidden(true)
}.accessibilityElement(children: .combine)
Spacer()
Timeline & Timeline detail accessibility uplift (#1323) * Improve accessibility of StatusPollView Previously, this view did not provide the proper context to indicate that it represented a poll. Now, we’ve added - A container that will stay “Active poll” or “Poll results” when the cursor first hits one of the options; - A prefix to say “Option X of Y” before each option; - A Selected trait on the selected option(s), if present - Consolidating and adding an `.updatesFrequently` trait to the footer view with the countdown. * Add poll description in StatusRowView combinedAccessibilityLabel This largely duplicates the logic in `StatusPollView`. * Improve accessibility of media attachments Previously, the media attachments without alt text would not show up in the consolidated `StatusRowView`, nor would they be meaningfully explained on the status detail screen. Now, they are presented with their attachment type. * Change accessibilityRepresentation of AppAcountsSelectorView * Change Notifications tab title view accessibility representation to Menu Previously it would present as a button * Hide layout `Rectangle`s from accessibility * Consolidate `StatusRowDetailView` accessibility representation * Improve readability of Poll accessibility label * Ensure poll options don’t present as interactive when the poll is finished * Improve accessibility of StatusRowCardView Previously, it would present as four separate elements, including an image without a description, all interactive, none with an interactive trait. Now, it presents as a single element with the `.link` trait * Improve accessibility of StatusRowHeaderView Previously, it had no traits and no actions except inherited ones. Now it presents as a button, triggering its primary action. It also has custom actions corresponding to its context menu * Avoid applying the StatusRowView custom actions to every view when contained * Provide context for the application name * Add pauses to StatusRowView combinedAccessibilityLabel * Hide `TimelineView.scrollToTopView` from accessibility * Set appropriate font style on Notification header After the change the Text needed a `.headline` style to match the prior appearance. * Fix bug in accessibilityRepresentation of TimelineView nav bar title Previously, it would not display the proper label for .remoteLocal filter options. * Ensure that pop-up button nav bar titles are interactive * Ensure TextView responds to Environment.sizeCategory This resolves #1309 * Fix button --------- Co-authored-by: Thomas Ricouard <ricouard77@gmail.com>
2023-03-28 16:48:58 +00:00
if let name = viewModel.status.application?.name, let url = viewModel.status.application?.website {
Button {
openURL(url)
} label: {
Text(name)
.underline()
}
Timeline & Timeline detail accessibility uplift (#1323) * Improve accessibility of StatusPollView Previously, this view did not provide the proper context to indicate that it represented a poll. Now, we’ve added - A container that will stay “Active poll” or “Poll results” when the cursor first hits one of the options; - A prefix to say “Option X of Y” before each option; - A Selected trait on the selected option(s), if present - Consolidating and adding an `.updatesFrequently` trait to the footer view with the countdown. * Add poll description in StatusRowView combinedAccessibilityLabel This largely duplicates the logic in `StatusPollView`. * Improve accessibility of media attachments Previously, the media attachments without alt text would not show up in the consolidated `StatusRowView`, nor would they be meaningfully explained on the status detail screen. Now, they are presented with their attachment type. * Change accessibilityRepresentation of AppAcountsSelectorView * Change Notifications tab title view accessibility representation to Menu Previously it would present as a button * Hide layout `Rectangle`s from accessibility * Consolidate `StatusRowDetailView` accessibility representation * Improve readability of Poll accessibility label * Ensure poll options don’t present as interactive when the poll is finished * Improve accessibility of StatusRowCardView Previously, it would present as four separate elements, including an image without a description, all interactive, none with an interactive trait. Now, it presents as a single element with the `.link` trait * Improve accessibility of StatusRowHeaderView Previously, it had no traits and no actions except inherited ones. Now it presents as a button, triggering its primary action. It also has custom actions corresponding to its context menu * Avoid applying the StatusRowView custom actions to every view when contained * Provide context for the application name * Add pauses to StatusRowView combinedAccessibilityLabel * Hide `TimelineView.scrollToTopView` from accessibility * Set appropriate font style on Notification header After the change the Text needed a `.headline` style to match the prior appearance. * Fix bug in accessibilityRepresentation of TimelineView nav bar title Previously, it would not display the proper label for .remoteLocal filter options. * Ensure that pop-up button nav bar titles are interactive * Ensure TextView responds to Environment.sizeCategory This resolves #1309 * Fix button --------- Co-authored-by: Thomas Ricouard <ricouard77@gmail.com>
2023-03-28 16:48:58 +00:00
.buttonStyle(.plain)
.accessibilityLabel("accessibility.status.application.label")
.accessibilityValue(name)
.accessibilityAddTraits(.isLink)
.accessibilityRemoveTraits(.isButton)
}
}
.font(.scaledCaption)
2023-12-04 14:49:44 +00:00
.foregroundStyle(.secondary)
if let editedAt = viewModel.status.editedAt {
Divider()
HStack {
Text("status.summary.edited-time") +
Text(editedAt.asDate, style: .date) +
Text("status.summary.at-time") +
Text(editedAt.asDate, style: .time)
Spacer()
}
.onTapGesture {
viewModel.routerPath.presentedSheet = .statusEditHistory(status: viewModel.status.id)
}
.underline()
.font(.scaledCaption)
2023-12-04 14:49:44 +00:00
.foregroundStyle(.secondary)
}
if viewModel.actionsAccountsFetched, statusDataController.favoritesCount > 0 {
Divider()
Button {
viewModel.routerPath.navigate(to: .favoritedBy(id: viewModel.status.id))
} label: {
HStack {
Text("status.summary.n-favorites \(statusDataController.favoritesCount)")
.font(.scaledCallout)
Spacer()
makeAccountsScrollView(accounts: viewModel.favoriters)
Image(systemName: "chevron.right")
}
.frame(height: 20)
}
.buttonStyle(.borderless)
.transition(.move(edge: .leading))
}
2023-09-18 19:03:52 +00:00
if viewModel.actionsAccountsFetched, statusDataController.reblogsCount > 0 {
Divider()
Button {
viewModel.routerPath.navigate(to: .rebloggedBy(id: viewModel.status.id))
} label: {
HStack {
Text("status.summary.n-boosts \(statusDataController.reblogsCount)")
.font(.scaledCallout)
Spacer()
makeAccountsScrollView(accounts: viewModel.rebloggers)
Image(systemName: "chevron.right")
}
.frame(height: 20)
}
.buttonStyle(.borderless)
.transition(.move(edge: .leading))
}
}
.task {
await viewModel.fetchActionsAccounts()
}
}
2023-02-12 15:29:41 +00:00
private func makeAccountsScrollView(accounts: [Account]) -> some View {
ScrollView(.horizontal, showsIndicators: false) {
LazyHStack(spacing: 0) {
ForEach(accounts) { account in
AvatarView(account.avatar, config: .list)
.padding(.leading, -4)
}
.transition(.opacity)
}
.padding(.leading, .layoutPadding)
}
}
}