From b64c748b73ac7f1997beeacf12d98c60574042ed Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sun, 4 Dec 2022 22:06:04 -0500 Subject: [PATCH] Add Jump to Present VoiceOver action Closes #288 --- .../Timeline/TimelineViewController.swift | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/Tusker/Screens/Timeline/TimelineViewController.swift b/Tusker/Screens/Timeline/TimelineViewController.swift index 65285c78..d3aac693 100644 --- a/Tusker/Screens/Timeline/TimelineViewController.swift +++ b/Tusker/Screens/Timeline/TimelineViewController.swift @@ -114,6 +114,19 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro self.reapplyFilters(actionsChanged: actionsChanged) } + let jumpToPresentName = NSMutableAttributedString("Jump to Present") + // otherwise it pronounces it as 'pɹizˈənt' + // its IPA is also bad, this should be an alveolar approximant not a trill + jumpToPresentName.addAttribute(.accessibilitySpeechIPANotation, value: "ˈprɛ.zənt", range: NSRange(location: "Jump to ".count, length: "Present".count)) + accessibilityCustomActions = [ + UIAccessibilityCustomAction(attributedName: jumpToPresentName, actionHandler: { [unowned self] _ in + Task { + await self.checkPresent(jumpImmediately: true) + } + return true + }) + ] + NotificationCenter.default.addObserver(self, selector: #selector(sceneWillEnterForeground), name: UIScene.willEnterForegroundNotification, object: nil) } @@ -192,7 +205,7 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro if case .notLoadedInitial = controller.state { if doRestore() { Task { - await checkPresent() + await checkPresent(jumpImmediately: false) } } else { Task { @@ -376,7 +389,7 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro return } Task { - await checkPresent() + await checkPresent(jumpImmediately: false) } } @@ -405,10 +418,20 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro } } - private func checkPresent() async { + private func checkPresent(jumpImmediately: Bool) async { if case .idle = controller.state, - let presentItems = try? await loadInitial() { - insertPresentItemsIfNecessary(presentItems) + let presentItems = try? await loadInitial(), + !presentItems.isEmpty { + if jumpImmediately { + var snapshot = NSDiffableDataSourceSnapshot() + snapshot.appendSections([.statuses]) + snapshot.appendItems(presentItems.map { .status(id: $0, collapseState: .unknown, filterState: .unknown) }, toSection: .statuses) + dataSource.apply(snapshot, animatingDifferences: true) { + UIAccessibility.post(notification: .screenChanged, argument: self.collectionView.cellForItem(at: IndexPath(row: 0, section: 0))) + } + } else { + insertPresentItemsIfNecessary(presentItems) + } } }