Add logging in to additional accounts and switching accounts via Preferences
See #16
This commit is contained in:
parent
08c84688cf
commit
863867c522
|
@ -7,8 +7,9 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import Combine
|
||||||
|
|
||||||
class LocalData {
|
class LocalData: ObservableObject {
|
||||||
|
|
||||||
static let shared = LocalData()
|
static let shared = LocalData()
|
||||||
|
|
||||||
|
@ -52,6 +53,7 @@ class LocalData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
|
objectWillChange.send()
|
||||||
let array = newValue.map { (info) in
|
let array = newValue.map { (info) in
|
||||||
return [
|
return [
|
||||||
"instanceURL": info.instanceURL.absoluteString,
|
"instanceURL": info.instanceURL.absoluteString,
|
||||||
|
@ -71,6 +73,7 @@ class LocalData {
|
||||||
return defaults.string(forKey: mostRecentAccountKey)
|
return defaults.string(forKey: mostRecentAccountKey)
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
|
objectWillChange.send()
|
||||||
defaults.set(newValue, forKey: mostRecentAccountKey)
|
defaults.set(newValue, forKey: mostRecentAccountKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,6 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||||
|
|
||||||
var window: UIWindow?
|
var window: UIWindow?
|
||||||
|
|
||||||
// let mastodonController = MastodonController.shared
|
|
||||||
|
|
||||||
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
||||||
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
|
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
|
||||||
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
|
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
|
||||||
|
@ -111,6 +109,12 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||||
DraftsManager.save()
|
DraftsManager.save()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func activateAccount(_ account: LocalData.UserAccountInfo) {
|
||||||
|
LocalData.shared.mostRecentAccount = account.accessToken
|
||||||
|
window!.windowScene!.session.mastodonController = MastodonController.getForAccount(account)
|
||||||
|
showAppUI()
|
||||||
|
}
|
||||||
|
|
||||||
func showAppUI() {
|
func showAppUI() {
|
||||||
let mastodonController = window!.windowScene!.session.mastodonController!
|
let mastodonController = window!.windowScene!.session.mastodonController!
|
||||||
mastodonController.getOwnAccount()
|
mastodonController.getOwnAccount()
|
||||||
|
@ -138,8 +142,6 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||||
|
|
||||||
extension SceneDelegate: OnboardingViewControllerDelegate {
|
extension SceneDelegate: OnboardingViewControllerDelegate {
|
||||||
func didFinishOnboarding(account: LocalData.UserAccountInfo) {
|
func didFinishOnboarding(account: LocalData.UserAccountInfo) {
|
||||||
LocalData.shared.mostRecentAccount = account.accessToken
|
activateAccount(account)
|
||||||
window!.windowScene!.session.mastodonController = MastodonController.getForAccount(account)
|
|
||||||
showAppUI()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import SwiftUI
|
||||||
class PreferencesNavigationController: UINavigationController {
|
class PreferencesNavigationController: UINavigationController {
|
||||||
|
|
||||||
init(mastodonController: MastodonController) {
|
init(mastodonController: MastodonController) {
|
||||||
let view = PreferencesView(currentAccount: mastodonController.accountInfo!)
|
let view = PreferencesView()
|
||||||
let hostingController = UIHostingController(rootView: view)
|
let hostingController = UIHostingController(rootView: view)
|
||||||
super.init(rootViewController: hostingController)
|
super.init(rootViewController: hostingController)
|
||||||
hostingController.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(donePressed))
|
hostingController.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(donePressed))
|
||||||
|
@ -21,6 +21,13 @@ class PreferencesNavigationController: UINavigationController {
|
||||||
required init?(coder aDecoder: NSCoder) {
|
required init?(coder aDecoder: NSCoder) {
|
||||||
fatalError("init(coder:) has not been implemented")
|
fatalError("init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
|
super.viewWillAppear(animated)
|
||||||
|
|
||||||
|
NotificationCenter.default.addObserver(self, selector: #selector(showAddAccount), name: .addAccount, object: nil)
|
||||||
|
NotificationCenter.default.addObserver(self, selector: #selector(activateAccount(_:)), name: .activateAccount, object: nil)
|
||||||
|
}
|
||||||
|
|
||||||
override func viewWillDisappear(_ animated: Bool) {
|
override func viewWillDisappear(_ animated: Bool) {
|
||||||
super.viewWillDisappear(animated)
|
super.viewWillDisappear(animated)
|
||||||
|
@ -32,5 +39,35 @@ class PreferencesNavigationController: UINavigationController {
|
||||||
@objc func donePressed() {
|
@objc func donePressed() {
|
||||||
dismiss(animated: true)
|
dismiss(animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc func showAddAccount() {
|
||||||
|
let onboardingController = OnboardingViewController()
|
||||||
|
onboardingController.onboardingDelegate = self
|
||||||
|
onboardingController.instanceSelector.navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelAddAccount))
|
||||||
|
show(onboardingController, sender: self)
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func cancelAddAccount() {
|
||||||
|
dismiss(animated: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
@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) {
|
||||||
|
sceneDelegate.activateAccount(account)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct PreferencesView : View {
|
struct PreferencesView: View {
|
||||||
var currentAccount: LocalData.UserAccountInfo
|
@ObservedObject var localData = LocalData.shared
|
||||||
@State private var showingLogoutConfirmation = false
|
@State private var showingLogoutConfirmation = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
@ -16,12 +16,35 @@ struct PreferencesView : View {
|
||||||
// NavigationView {
|
// NavigationView {
|
||||||
List {
|
List {
|
||||||
Section {
|
Section {
|
||||||
|
ForEach(localData.accounts, id: \.accessToken) { (account) in
|
||||||
|
Button(action: {
|
||||||
|
NotificationCenter.default.post(name: .activateAccount, object: nil, userInfo: ["account": account])
|
||||||
|
}) {
|
||||||
|
HStack {
|
||||||
|
Text(account.username)
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
Spacer()
|
||||||
|
if account.accessToken == self.localData.mostRecentAccount {
|
||||||
|
Image(systemName: "checkmark")
|
||||||
|
.renderingMode(.template)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Button(action: {
|
Button(action: {
|
||||||
self.showingLogoutConfirmation = true
|
NotificationCenter.default.post(name: .addAccount, object: nil)
|
||||||
}) {
|
}) {
|
||||||
Text("Logout")
|
Text("Add Account...")
|
||||||
}.alert(isPresented: $showingLogoutConfirmation) {
|
}
|
||||||
Alert(title: Text("Are you sure you want to logout?"), message: nil, primaryButton: .destructive(Text("Logout"), action: self.logoutPressed), secondaryButton: .cancel())
|
if localData.mostRecentAccount != nil {
|
||||||
|
Button(action: {
|
||||||
|
self.showingLogoutConfirmation = true
|
||||||
|
}) {
|
||||||
|
Text("Logout from current")
|
||||||
|
}.alert(isPresented: $showingLogoutConfirmation) {
|
||||||
|
Alert(title: Text("Are you sure you want to logout?"), message: nil, primaryButton: .destructive(Text("Logout"), action: self.logoutPressed), secondaryButton: .cancel())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +73,8 @@ struct PreferencesView : View {
|
||||||
}
|
}
|
||||||
|
|
||||||
func logoutPressed() {
|
func logoutPressed() {
|
||||||
LocalData.shared.removeAccount(currentAccount)
|
// LocalData.shared.removeAccount(currentAccount)
|
||||||
|
localData.removeAccount(localData.getMostRecentAccount()!)
|
||||||
NotificationCenter.default.post(name: .userLoggedOut, object: nil)
|
NotificationCenter.default.post(name: .userLoggedOut, object: nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,8 +82,7 @@ struct PreferencesView : View {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
struct PreferencesView_Previews : PreviewProvider {
|
struct PreferencesView_Previews : PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
let account = LocalData.UserAccountInfo(instanceURL: URL(string: "https://mastodon.social")!, clientID: "clientID", clientSecret: "clientSecret", username: "example", accessToken: "accessToken")
|
return PreferencesView()
|
||||||
return PreferencesView(currentAccount: account)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -128,7 +128,7 @@ class ProfileTableViewController: EnhancedTableViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func updateUIForPreferences() {
|
@objc func updateUIForPreferences() {
|
||||||
guard let account = mastodonController.cache.account(for: accountID) else { fatalError("Missing cached account \(accountID!)") }
|
guard let accountID = accountID, let account = mastodonController.cache.account(for: accountID) else { return }
|
||||||
navigationItem.title = account.realDisplayName
|
navigationItem.title = account.realDisplayName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue