Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ struct ArchivedPaymentHistoryItem: PaymentsHistoryItem {
return archivedPayment.statusDescription(isOutgoing: isOutgoing)
}

func statusDescriptionForAccessibility(isLongForm: Bool) -> String? {
return statusDescription(isLongForm: isLongForm)
}

/// Read status is only tracked on TSPaymentModels, so there's not really anything to do here.
func markAsRead(tx: SignalServiceKit.DBWriteTransaction) { }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public protocol PaymentsHistoryItem {

func statusDescription(isLongForm: Bool) -> String?

func statusDescriptionForAccessibility(isLongForm: Bool) -> String?

func markAsRead(tx: DBWriteTransaction)

func reload(tx: DBReadTransaction) -> Self?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ class PaymentsDetailViewController: OWSTableViewController2, DatabaseChangeDeleg
comment: "Label for the transaction status in the payment details view in the app settings.",
),
bottomText: statusMessage,
bottomAccessibilityText: paymentItem.statusDescriptionForAccessibility(isLongForm: true),
useFailedColor: paymentItem.isFailed,
))
}
Expand Down Expand Up @@ -374,6 +375,7 @@ class PaymentsDetailViewController: OWSTableViewController2, DatabaseChangeDeleg
private func buildStatusItem(
topText: String,
bottomText: String,
bottomAccessibilityText: String? = nil,
useFailedColor: Bool = false,
) -> OWSTableItem {
OWSTableItem(
Expand All @@ -387,6 +389,7 @@ class PaymentsDetailViewController: OWSTableViewController2, DatabaseChangeDeleg

let bottomLabel = UILabel()
bottomLabel.text = bottomText
bottomLabel.accessibilityLabel = bottomAccessibilityText
bottomLabel.textColor = .Signal.secondaryLabel
bottomLabel.font = UIFont.dynamicTypeFootnoteClamped
bottomLabel.numberOfLines = 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,8 @@ class PaymentsSettingsViewController: OWSTableViewController2, PaymentsHistoryDa
)

if let balanceConversionText = Self.buildBalanceConversionText(paymentBalance: paymentBalance) {
conversionLabel.text = balanceConversionText
conversionLabel.text = balanceConversionText.display
conversionLabel.accessibilityLabel = balanceConversionText.accessibility
} else {
conversionStack.alpha = 0
}
Expand Down Expand Up @@ -598,7 +599,7 @@ class PaymentsSettingsViewController: OWSTableViewController2, PaymentsHistoryDa
return button
}

private static func buildBalanceConversionText(paymentBalance: PaymentBalance) -> String? {
private static func buildBalanceConversionText(paymentBalance: PaymentBalance) -> (display: String, accessibility: String)? {
let localCurrencyCode = SSKEnvironment.shared.paymentsCurrenciesRef.currentCurrencyCode
guard let currencyConversionInfo = SSKEnvironment.shared.paymentsCurrenciesRef.conversionInfo(forCurrencyCode: localCurrencyCode) else {
return nil
Expand All @@ -619,11 +620,14 @@ class PaymentsSettingsViewController: OWSTableViewController2, PaymentsHistoryDa
//
// It is sufficient to format as a time, currency conversions go stale in less than a day.
let conversionFreshnessString = DateUtil.formatDateAsTime(currencyConversionInfo.conversionDate)
let conversionFreshnessAccessibilityString = DateUtil.formatDateAsTimeForAccessibility(currencyConversionInfo.conversionDate)
let formatString = OWSLocalizedString(
"SETTINGS_PAYMENTS_BALANCE_CONVERSION_FORMAT",
comment: "Format string for the 'local balance converted into local currency' indicator. Embeds: {{ %1$@ the local balance in the local currency, %2$@ the local currency code, %3$@ the date the currency conversion rate was obtained. }}..",
)
return String.nonPluralLocalizedStringWithFormat(formatString, fiatAmountString, localCurrencyCode, conversionFreshnessString)
let display = String.nonPluralLocalizedStringWithFormat(formatString, fiatAmountString, localCurrencyCode, conversionFreshnessString)
let accessibility = String.nonPluralLocalizedStringWithFormat(formatString, fiatAmountString, localCurrencyCode, conversionFreshnessAccessibilityString)
return (display: display, accessibility: accessibility)
}

private func configureHistorySection(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,15 @@ extension TSPaymentModel {
return result
}

func statusDescriptionForAccessibility(isLongForm: Bool) -> String {
var result = statusDescription(isLongForm: isLongForm)
// Replace the appended date with the accessibility-friendly version.
result = String(result.dropLast(Self.formatDate(sortDate, isLongForm: isLongForm).count + 1))
result.append(" ")
result.append(Self.formatDateForAccessibility(sortDate, isLongForm: isLongForm))
return result
}

static func formatDate(_ date: Date, isLongForm: Bool) -> String {
if isLongForm {
return statusDateTimeLongFormatter.string(from: date)
Expand All @@ -365,6 +374,17 @@ extension TSPaymentModel {
}
}

static func formatDateForAccessibility(_ date: Date, isLongForm: Bool) -> String {
if isLongForm {
// Replace only the time portion with the spoken form; keep the date portion visual.
let datePart = DateFormatter.localizedString(from: date, dateStyle: .medium, timeStyle: .none)
let timePart = DateUtil.formatDateAsTimeForAccessibility(date)
return "\(datePart) \(timePart)"
} else {
return statusDateShortFormatter.string(from: date)
}
}

private static func description(
forFailure failure: TSPaymentFailure,
isIncoming: Bool,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ public struct PaymentsHistoryModelItem: PaymentsHistoryItem {
paymentModel.statusDescription(isLongForm: isLongForm)
}

public func statusDescriptionForAccessibility(isLongForm: Bool) -> String? {
paymentModel.statusDescriptionForAccessibility(isLongForm: isLongForm)
}

public func markAsRead(tx: DBWriteTransaction) {
PaymentUtils.markPaymentAsRead(paymentModel, transaction: tx)
}
Expand Down
16 changes: 16 additions & 0 deletions SignalServiceKit/Util/DateUtil.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ public class DateUtil {
return formatter
}()

private static let accessibilityTimeFormatter: DateComponentsFormatter = {
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .spellOut
formatter.allowedUnits = [.hour, .minute]
return formatter
}()

public static let weekdayFormatter: DateFormatter = {
let formatter = DateFormatter()
formatter.setLocalizedDateFormatFromTemplate("EEEE")
Expand Down Expand Up @@ -170,6 +177,11 @@ public class DateUtil {
return timeFormatter.string(from: date)
}

public static func formatDateAsTimeForAccessibility(_ date: Date) -> String {
let components = Calendar.current.dateComponents([.hour, .minute], from: date)
return accessibilityTimeFormatter.string(from: components) ?? timeFormatter.string(from: date)
}

// MARK: Formatting for UI

// We might receive a message "from the future" due to a bug or
Expand Down Expand Up @@ -206,6 +218,10 @@ public class DateUtil {
let format = shouldUseLongFormat ? longFormat : shortFormat
return String.localizedStringWithFormat(format, minutesDiff)
} else {
if shouldUseLongFormat {
let components = Calendar.current.dateComponents([.hour, .minute], from: date)
return accessibilityTimeFormatter.string(from: components) ?? timeFormatter.string(from: date)
}
return timeFormatter.string(from: date)
}
}
Expand Down