diff --git a/Tusker/Screens/Timeline/TimelineGapCollectionViewCell.swift b/Tusker/Screens/Timeline/TimelineGapCollectionViewCell.swift index 49113843..304a6ff9 100644 --- a/Tusker/Screens/Timeline/TimelineGapCollectionViewCell.swift +++ b/Tusker/Screens/Timeline/TimelineGapCollectionViewCell.swift @@ -15,6 +15,8 @@ class TimelineGapCollectionViewCell: UICollectionViewCell { private let indicator = UIActivityIndicatorView(style: .medium) private let chevronView = AnimatingChevronView() + var fillGap: ((TimelineGapDirection) async -> Void)? + override var isHighlighted: Bool { didSet { backgroundColor = isHighlighted ? .systemFill : .systemGroupedBackground @@ -100,6 +102,36 @@ class TimelineGapCollectionViewCell: UICollectionViewCell { } } + // MARK: Accessibility + + override var isAccessibilityElement: Bool { + get { true } + set {} + } + + override var accessibilityLabel: String? { + get { + "Load \(direction.accessibilityLabel)" + } + set {} + } + + override var accessibilityCustomActions: [UIAccessibilityCustomAction]? { + get { + [TimelineGapDirection.below, .above].map { dir in + UIAccessibilityCustomAction(name: "Load \(dir.accessibilityLabel)") { [unowned self] _ in + Task { + showsIndicator = true + await fillGap?(dir) + showsIndicator = false + } + return true + } + } + } + set {} + } + } private class AnimatingChevronView: UIView { diff --git a/Tusker/Screens/Timeline/TimelineViewController.swift b/Tusker/Screens/Timeline/TimelineViewController.swift index acabb7ac..030baf35 100644 --- a/Tusker/Screens/Timeline/TimelineViewController.swift +++ b/Tusker/Screens/Timeline/TimelineViewController.swift @@ -137,8 +137,11 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro } let zeroHeightCell = UICollectionView.CellRegistration { _, _, _ in } - let gapCell = UICollectionView.CellRegistration { cell, indexPath, _ in + let gapCell = UICollectionView.CellRegistration { [unowned self] cell, indexPath, _ in cell.showsIndicator = false + cell.fillGap = { [unowned self] direction in + await self.controller.fillGap(in: direction) + } } let timelineDescriptionCell = UICollectionView.CellRegistration { [unowned self] cell, indexPath, item in guard case .public(let local) = timeline else { diff --git a/Tusker/TimelineLikeController.swift b/Tusker/TimelineLikeController.swift index a2996201..e8016d9c 100644 --- a/Tusker/TimelineLikeController.swift +++ b/Tusker/TimelineLikeController.swift @@ -379,4 +379,13 @@ enum TimelineGapDirection { case below /// Fill in above the gap. I.e., statuses that are immediately older than the status above the gap. case above + + var accessibilityLabel: String { + switch self { + case .below: + return "Newer" + case .above: + return "Older" + } + } }