diff --git a/Tusker/Screens/Timeline/TimelineViewController.swift b/Tusker/Screens/Timeline/TimelineViewController.swift index 22d0fef4..acabb7ac 100644 --- a/Tusker/Screens/Timeline/TimelineViewController.swift +++ b/Tusker/Screens/Timeline/TimelineViewController.swift @@ -25,6 +25,8 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro private var contentOffsetObservation: NSKeyValueObservation? private var activityToRestore: NSUserActivity? + // the last time this VC disappeared or the scene was backgrounded while it was active, used to decide if we want to check for present when reappearing + private var disappearedAt: Date? init(for timeline: Timeline, mastodonController: MastodonController!) { self.timeline = timeline @@ -115,6 +117,7 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro } NotificationCenter.default.addObserver(self, selector: #selector(sceneWillEnterForeground), name: UIScene.willEnterForegroundNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(sceneDidEnterBackground), name: UIScene.didEnterBackgroundNotification, object: nil) } // separate method because InstanceTimelineViewController needs to be able to customize it @@ -199,6 +202,8 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro await controller.loadInitial() } } + } else { + checkPresentIfEnoughTimeElapsed() } } @@ -215,6 +220,12 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro } } + override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + + disappearedAt = Date() + } + func stateRestorationActivity() -> NSUserActivity? { guard isViewLoaded else { return nil @@ -376,9 +387,16 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro view.window?.windowScene == scene else { return } - Task { - await checkPresent(jumpImmediately: false) + checkPresentIfEnoughTimeElapsed() + } + + @objc private func sceneDidEnterBackground(_ notification: Foundation.Notification) { + guard let scene = notification.object as? UIScene, + // view.window is nil when the VC is not on screen + view.window?.windowScene == scene else { + return } + disappearedAt = Date() } @objc func refresh() { @@ -406,6 +424,17 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro } } + private func checkPresentIfEnoughTimeElapsed() { + guard let disappearedAt, + -disappearedAt.timeIntervalSinceNow > 60 * 60 /* 1 hour */ else { + return + } + self.disappearedAt = nil + Task { + await checkPresent(jumpImmediately: false) + } + } + func checkPresent(jumpImmediately: Bool) async { if case .idle = controller.state, let presentItems = try? await loadInitial(),