Files
GitHawk/Classes/Systems/RootNavigationManager.swift
Ivan Smetanin f619a256bc Changing accounts resets to main tab fix (#2114)
* Fix issue changing accounts resets to main tab

* Pull request review code fix
2018-08-13 21:53:45 -04:00

170 lines
5.7 KiB
Swift

//
// RootNavigationManager.swift
// Freetime
//
// Created by Ryan Nystrom on 5/17/17.
// Copyright © 2017 Ryan Nystrom. All rights reserved.
//
import UIKit
import GitHubAPI
import GitHubSession
final class RootNavigationManager: GitHubSessionListener {
private let sessionManager: GitHubSessionManager
private let splitDelegate = SplitViewControllerDelegate()
private let tabDelegate = TabBarControllerDelegate()
// weak refs to avoid cycles
weak private var rootViewController: UISplitViewController?
// keep alive between switching accounts
private var settingsRootViewController: UIViewController?
private var lastClient: GithubClient?
init(
sessionManager: GitHubSessionManager,
rootViewController: UISplitViewController
) {
self.sessionManager = sessionManager
self.rootViewController = rootViewController
rootViewController.delegate = splitDelegate
rootViewController.preferredDisplayMode = .allVisible
sessionManager.addListener(listener: self)
self.tabBarController?.tabBar.tintColor = Styles.Colors.Blue.medium.color
self.tabBarController?.tabBar.unselectedItemTintColor = Styles.Colors.Gray.light.color
self.tabBarController?.delegate = self.tabDelegate
}
// MARK: Public API
public func showLogin(animated: Bool = false) {
guard let root = rootViewController else { return }
let login = newLoginViewController()
login.modalPresentationStyle = .formSheet
let block: () -> Void = { root.present(login, animated: animated) }
if let presented = root.presentedViewController {
presented.dismiss(animated: animated, completion: block)
} else {
block()
}
self.tabBarController?.selectedIndex = 0
}
public func resetRootViewController(userSession: GitHubUserSession?) {
guard let userSession = userSession else { return }
let client = newGithubClient(userSession: userSession)
lastClient = client
fetchUsernameForMigrationIfNecessary(client: client, userSession: userSession, sessionManager: sessionManager)
// rebuild the settings VC if it doesn't exist
settingsRootViewController = settingsRootViewController ?? newSettingsRootViewController(
sessionManager: sessionManager,
client: client,
rootNavigationManager: self
)
tabBarController?.viewControllers = [
newNotificationsRootViewController(client: client),
newSearchRootViewController(client: client),
newBookmarksRootViewController(client: client),
settingsRootViewController ?? UIViewController() // simply satisfying compiler
]
}
public func pushLoginViewController(nav: UINavigationController) {
let login = newLoginViewController()
nav.pushViewController(login, animated: trueUnlessReduceMotionEnabled)
}
@discardableResult
public func selectViewController(atIndex index: Int) -> UIViewController? {
tabBarController?.selectedIndex = index
return tabBarController?.selectedViewController
}
@discardableResult
public func selectViewController(atTab tab: TabBarController.Tab) -> UIViewController? {
tabBarController?.showTab(tab)
return tabBarController?.selectedViewController
}
// MARK: GitHubSessionListener
func didFocus(manager: GitHubSessionManager, userSession: GitHubUserSession, dismiss: Bool) {
resetRootViewController(userSession: userSession)
if dismiss {
rootViewController?.presentedViewController?.dismiss(animated: trueUnlessReduceMotionEnabled)
}
}
func didLogout(manager: GitHubSessionManager) {
settingsRootViewController = nil
for vc in tabBarController?.viewControllers ?? [] {
if let nav = vc as? UINavigationController {
nav.viewControllers = [SplitPlaceholderViewController()]
}
}
detailNavigationController?.viewControllers = [SplitPlaceholderViewController()]
showLogin(animated: trueUnlessReduceMotionEnabled)
}
func didReceiveRedirect(manager: GitHubSessionManager, code: String) {}
// MARK: Private API
private func fetchUsernameForMigrationIfNecessary(
client: GithubClient,
userSession: GitHubUserSession,
sessionManager: GitHubSessionManager
) {
// only required when there is no username
guard userSession.username == nil else { return }
client.client.send(V3VerifyPersonalAccessTokenRequest(token: userSession.token)) { result in
switch result {
case .success(let user):
userSession.username = user.data.login
// user session ref is same session that manager should be using
// update w/ mutated session
sessionManager.save()
case .failure: break
}
}
}
private var detailNavigationController: UINavigationController? {
return rootViewController?.viewControllers.last as? UINavigationController
}
private var tabBarController: TabBarController? {
return rootViewController?.viewControllers.first as? TabBarController
}
private func newLoginViewController() -> UIViewController {
let controller = UIStoryboard(
name: "OauthLogin",
bundle: Bundle(for: AppDelegate.self))
.instantiateInitialViewController() as! LoginSplashViewController
controller.config(
client: newGithubClient().client,
sessionManager: sessionManager
)
return controller
}
}