forked from shadowfacts/Tusker
Clean up account switching code
This commit is contained in:
parent
863867c522
commit
c45dd99088
|
@ -21,6 +21,7 @@ class LocalData: ObservableObject {
|
|||
if ProcessInfo.processInfo.environment.keys.contains("UI_TESTING_LOGIN") {
|
||||
accounts = [
|
||||
UserAccountInfo(
|
||||
id: UUID().uuidString,
|
||||
instanceURL: URL(string: "http://localhost:8080")!,
|
||||
clientID: "client_id",
|
||||
clientSecret: "client_secret",
|
||||
|
@ -38,15 +39,16 @@ class LocalData: ObservableObject {
|
|||
get {
|
||||
if let array = defaults.array(forKey: accountsKey) as? [[String: String]] {
|
||||
return array.compactMap { (info) in
|
||||
guard let instanceURL = info["instanceURL"],
|
||||
guard let id = info["id"],
|
||||
let instanceURL = info["instanceURL"],
|
||||
let url = URL(string: instanceURL),
|
||||
let id = info["clientID"],
|
||||
let clientId = info["clientID"],
|
||||
let secret = info["clientSecret"],
|
||||
let username = info["username"],
|
||||
let accessToken = info["accessToken"] else {
|
||||
return nil
|
||||
}
|
||||
return UserAccountInfo(instanceURL: url, clientID: id, clientSecret: secret, username: username, accessToken: accessToken)
|
||||
return UserAccountInfo(id: id, instanceURL: url, clientID: clientId, clientSecret: secret, username: username, accessToken: accessToken)
|
||||
}
|
||||
} else {
|
||||
return []
|
||||
|
@ -56,6 +58,7 @@ class LocalData: ObservableObject {
|
|||
objectWillChange.send()
|
||||
let array = newValue.map { (info) in
|
||||
return [
|
||||
"id": info.id,
|
||||
"instanceURL": info.instanceURL.absoluteString,
|
||||
"clientID": info.clientID,
|
||||
"clientSecret": info.clientSecret,
|
||||
|
@ -68,7 +71,7 @@ class LocalData: ObservableObject {
|
|||
}
|
||||
|
||||
private let mostRecentAccountKey = "mostRecentAccount"
|
||||
var mostRecentAccount: String? {
|
||||
private var mostRecentAccount: String? {
|
||||
get {
|
||||
return defaults.string(forKey: mostRecentAccountKey)
|
||||
}
|
||||
|
@ -82,41 +85,60 @@ class LocalData: ObservableObject {
|
|||
return !accounts.isEmpty
|
||||
}
|
||||
|
||||
func addAccount(instanceURL url: URL, clientID id: String, clientSecret secret: String, username: String, accessToken: String) -> UserAccountInfo {
|
||||
func addAccount(instanceURL url: URL, clientID: String, clientSecret secret: String, username: String, accessToken: String) -> UserAccountInfo {
|
||||
var accounts = self.accounts
|
||||
if let index = accounts.firstIndex(where: { $0.instanceURL == url && $0.username == username }) {
|
||||
accounts.remove(at: index)
|
||||
}
|
||||
let info = UserAccountInfo(instanceURL: url, clientID: id, clientSecret: secret, username: username, accessToken: accessToken)
|
||||
let id = UUID().uuidString
|
||||
let info = UserAccountInfo(id: id, instanceURL: url, clientID: clientID, clientSecret: secret, username: username, accessToken: accessToken)
|
||||
accounts.append(info)
|
||||
self.accounts = accounts
|
||||
return info
|
||||
}
|
||||
|
||||
func removeAccount(_ info: UserAccountInfo) {
|
||||
|
||||
accounts.removeAll(where: { $0.id == info.id })
|
||||
}
|
||||
|
||||
func getMostRecentAccount() -> UserAccountInfo? {
|
||||
if let accessToken = mostRecentAccount {
|
||||
return accounts.first { $0.accessToken == accessToken }
|
||||
guard onboardingComplete else { return nil }
|
||||
let mostRecent: UserAccountInfo?
|
||||
if let id = mostRecentAccount {
|
||||
mostRecent = accounts.first { $0.id == id }
|
||||
} else {
|
||||
return nil
|
||||
mostRecent = nil
|
||||
}
|
||||
return mostRecent ?? accounts.first!
|
||||
}
|
||||
|
||||
func setMostRecentAccount(_ account: UserAccountInfo?) {
|
||||
mostRecentAccount = account?.id
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension LocalData {
|
||||
struct UserAccountInfo: Equatable, Hashable {
|
||||
let id: String
|
||||
let instanceURL: URL
|
||||
let clientID: String
|
||||
let clientSecret: String
|
||||
let username: String
|
||||
let accessToken: String
|
||||
|
||||
func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(id)
|
||||
}
|
||||
|
||||
static func ==(lhs: UserAccountInfo, rhs: UserAccountInfo) -> Bool {
|
||||
return lhs.id == rhs.id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Notification.Name {
|
||||
static let userLoggedOut = Notification.Name("userLoggedOut")
|
||||
static let userLoggedOut = Notification.Name("Tusker.userLoggedOut")
|
||||
static let addAccount = Notification.Name("Tusker.addAccount")
|
||||
static let activateAccount = Notification.Name("Tusker.activateAccount")
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||
|
||||
window!.makeKeyAndVisible()
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(onUserLoggedOut), name: .userLoggedOut, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(themePrefChanged), name: .themePreferenceChanged, object: nil)
|
||||
themePrefChanged()
|
||||
|
||||
|
@ -110,11 +109,20 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||
}
|
||||
|
||||
func activateAccount(_ account: LocalData.UserAccountInfo) {
|
||||
LocalData.shared.mostRecentAccount = account.accessToken
|
||||
LocalData.shared.setMostRecentAccount(account)
|
||||
window!.windowScene!.session.mastodonController = MastodonController.getForAccount(account)
|
||||
showAppUI()
|
||||
}
|
||||
|
||||
func logoutCurrent() {
|
||||
LocalData.shared.removeAccount(LocalData.shared.getMostRecentAccount()!)
|
||||
if LocalData.shared.onboardingComplete {
|
||||
activateAccount(LocalData.shared.accounts.first!)
|
||||
} else {
|
||||
showOnboardingUI()
|
||||
}
|
||||
}
|
||||
|
||||
func showAppUI() {
|
||||
let mastodonController = window!.windowScene!.session.mastodonController!
|
||||
mastodonController.getOwnAccount()
|
||||
|
@ -130,10 +138,6 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||
window!.rootViewController = onboarding
|
||||
}
|
||||
|
||||
@objc func onUserLoggedOut() {
|
||||
showOnboardingUI()
|
||||
}
|
||||
|
||||
@objc func themePrefChanged() {
|
||||
window?.overrideUserInterfaceStyle = Preferences.shared.theme
|
||||
}
|
||||
|
|
|
@ -69,9 +69,9 @@ extension OnboardingViewController: InstanceSelectorTableViewControllerDelegate
|
|||
|
||||
mastodonController.authorize(authorizationCode: authCode) { (accessToken) in
|
||||
mastodonController.getOwnAccount { (account) in
|
||||
DispatchQueue.main.async {
|
||||
let accountInfo = LocalData.shared.addAccount(instanceURL: instanceURL, clientID: clientID, clientSecret: clientSecret, username: account.username, accessToken: accessToken)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.onboardingDelegate?.didFinishOnboarding(account: accountInfo)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ class PreferencesNavigationController: UINavigationController {
|
|||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(showAddAccount), name: .addAccount, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(activateAccount(_:)), name: .activateAccount, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(userLoggedOut), name: .userLoggedOut, object: nil)
|
||||
}
|
||||
|
||||
override func viewWillDisappear(_ animated: Bool) {
|
||||
|
@ -48,26 +49,35 @@ class PreferencesNavigationController: UINavigationController {
|
|||
}
|
||||
|
||||
@objc func cancelAddAccount() {
|
||||
dismiss(animated: true)
|
||||
dismiss(animated: true) // dismisses instance selector
|
||||
}
|
||||
|
||||
@objc func activateAccount(_ notification: Notification) {
|
||||
let account = notification.userInfo!["account"] as! LocalData.UserAccountInfo
|
||||
let sceneDelegate = self.view.window!.windowScene!.delegate as! SceneDelegate
|
||||
dismiss(animated: true) {
|
||||
dismiss(animated: true) { // dismiss preferences
|
||||
sceneDelegate.activateAccount(account)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@objc func userLoggedOut() {
|
||||
let sceneDelegate = self.view.window!.windowScene!.delegate as! SceneDelegate
|
||||
dismiss(animated: true) { // dismiss preferences
|
||||
sceneDelegate.logoutCurrent()
|
||||
}
|
||||
}
|
||||
|
||||
extension Notification.Name {
|
||||
static let addAccount = Notification.Name("Tusker.addAccount")
|
||||
static let activateAccount = Notification.Name("Tusker.activateAccount")
|
||||
}
|
||||
|
||||
extension PreferencesNavigationController: OnboardingViewControllerDelegate {
|
||||
func didFinishOnboarding(account: LocalData.UserAccountInfo) {
|
||||
LocalData.shared.mostRecentAccount = account.accessToken
|
||||
DispatchQueue.main.async {
|
||||
let sceneDelegate = self.view.window!.windowScene!.delegate as! SceneDelegate
|
||||
self.dismiss(animated: true) { // dismiss instance selector
|
||||
self.dismiss(animated: true) { // dismiss preferences
|
||||
sceneDelegate.activateAccount(account)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ struct PreferencesView: View {
|
|||
Text(account.username)
|
||||
.foregroundColor(.primary)
|
||||
Spacer()
|
||||
if account.accessToken == self.localData.mostRecentAccount {
|
||||
if account == self.localData.getMostRecentAccount() {
|
||||
Image(systemName: "checkmark")
|
||||
.renderingMode(.template)
|
||||
.foregroundColor(.secondary)
|
||||
|
@ -37,7 +37,7 @@ struct PreferencesView: View {
|
|||
}) {
|
||||
Text("Add Account...")
|
||||
}
|
||||
if localData.mostRecentAccount != nil {
|
||||
if localData.getMostRecentAccount() != nil {
|
||||
Button(action: {
|
||||
self.showingLogoutConfirmation = true
|
||||
}) {
|
||||
|
@ -73,8 +73,6 @@ struct PreferencesView: View {
|
|||
}
|
||||
|
||||
func logoutPressed() {
|
||||
// LocalData.shared.removeAccount(currentAccount)
|
||||
localData.removeAccount(localData.getMostRecentAccount()!)
|
||||
NotificationCenter.default.post(name: .userLoggedOut, object: nil)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue