From 4dca231a0613007dcd4ce6c55e130f7f561fac39 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sun, 1 Jan 2023 12:25:44 -0500 Subject: [PATCH] Add loading animation while syncing timeline position --- .../Timeline/TimelineViewController.swift | 38 ++++++++++++------- .../TimelinesPageViewController.swift | 4 +- Tusker/Views/Toast/ToastView.swift | 3 ++ 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/Tusker/Screens/Timeline/TimelineViewController.swift b/Tusker/Screens/Timeline/TimelineViewController.swift index adc71df8..48160fd4 100644 --- a/Tusker/Screens/Timeline/TimelineViewController.swift +++ b/Tusker/Screens/Timeline/TimelineViewController.swift @@ -213,12 +213,10 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro clearSelectionOnAppear(animated: animated) if case .notLoadedInitial = controller.state { - if restoreState() { - Task { + Task { + if await restoreState() { await checkPresent(jumpImmediately: false) - } - } else { - Task { + } else { await controller.loadInitial() } } @@ -329,18 +327,16 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro return activity } - func restoreState() -> Bool { + func restoreState() async -> Bool { guard persistsState, Preferences.shared.timelineStateRestoration, let position = mastodonController.persistentContainer.getTimelinePosition(timeline: timeline) else { return false } loadViewIfNeeded() - Task { - await controller.restoreInitial { - await loadStatusesToRestore(position: position) - applyItemsToRestore(position: position) - } + await controller.restoreInitial { + await loadStatusesToRestore(position: position) + applyItemsToRestore(position: position) } return true } @@ -492,15 +488,29 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro return false } if !alwaysPrompt { - _ = self.restoreState() + Task { + _ = await restoreState() + } } else { var config = ToastConfiguration(title: "Sync Position") config.edge = .top config.dismissAutomaticallyAfter = 5 config.systemImageName = "arrow.triangle.2.circlepath" config.action = { [unowned self] toast in - toast.dismissToast(animated: true) - _ = self.restoreState() + toast.isUserInteractionEnabled = false + UIView.animateKeyframes(withDuration: 1, delay: 0, options: .repeat) { + UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.5) { + toast.imageView!.transform = CGAffineTransform(rotationAngle: 0.5 * .pi) + } + UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5) { + // the translation is because the symbol isn't perfectly centered + toast.imageView!.transform = CGAffineTransform(translationX: -0.5, y: 0).rotated(by: .pi) + } + } + Task { + _ = await self.restoreState() + toast.dismissToast(animated: true) + } } showToast(configuration: config, animated: true) UIAccessibility.post(notification: .announcement, argument: "Synced Position Updated") diff --git a/Tusker/Screens/Timeline/TimelinesPageViewController.swift b/Tusker/Screens/Timeline/TimelinesPageViewController.swift index eacb7f7b..831efab6 100644 --- a/Tusker/Screens/Timeline/TimelinesPageViewController.swift +++ b/Tusker/Screens/Timeline/TimelinesPageViewController.swift @@ -59,7 +59,9 @@ class TimelinesPageViewController: SegmentedPageViewController