Merge pull request #2236 from rizwankce/account-details-settings

Add settings account details view and implementations
This commit is contained in:
Maurice Parker
2020-07-09 09:27:37 -05:00
committed by GitHub
6 changed files with 208 additions and 8 deletions

View File

@@ -0,0 +1,55 @@
//
// SettingsDetailAccountModel.swift
// Multiplatform iOS
//
// Created by Rizwan on 08/07/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import SwiftUI
import Account
import RSCore
class SettingsDetailAccountModel: ObservableObject {
let account: Account
@Published var name: String {
didSet {
account.name = name.isEmpty ? nil : name
}
}
@Published var isActive: Bool {
didSet {
account.isActive = isActive
}
}
init(_ account: Account) {
self.account = account
self.name = account.name ?? ""
self.isActive = account.isActive
}
var defaultName: String {
account.defaultName
}
var nameForDisplay: String {
account.nameForDisplay
}
var accountImage: RSImage {
AppAssets.image(for: account.type)!
}
var isCredentialsAvailable: Bool {
return account.type != .onMyMac
}
var isDeletable: Bool {
return AccountManager.shared.defaultAccount != account
}
func delete() {
AccountManager.shared.deleteAccount(account)
}
}

View File

@@ -0,0 +1,94 @@
//
// SettingsDetailAccountView.swift
// Multiplatform iOS
//
// Created by Rizwan on 08/07/20.
// Copyright © 2020 Ranchero Software. All rights reserved.
//
import SwiftUI
import Combine
import Account
import RSWeb
import RSCore
struct SettingsDetailAccountView: View {
@Environment(\.presentationMode) var presentationMode
@ObservedObject var settingsModel: SettingsDetailAccountModel
@State private var isFeedbinCredentialsPresented = false
@State private var isDeleteAlertPresented = false
init(_ account: Account) {
settingsModel = SettingsDetailAccountModel.init(account)
}
var body: some View {
List {
Section(header:AccountHeaderImageView(image: settingsModel.accountImage)) {
HStack {
TextField(settingsModel.defaultName, text: $settingsModel.name)
}
Toggle(isOn: $settingsModel.isActive) {
Text("Active")
}
}
if settingsModel.isCredentialsAvailable {
Section {
HStack {
Spacer()
Button(action: {
self.isFeedbinCredentialsPresented.toggle()
}) {
Text("Credentials")
}
Spacer()
}
}
.sheet(isPresented: $isFeedbinCredentialsPresented) {
self.settingsFeedbinAccountView
}
}
if settingsModel.isDeletable {
Section {
HStack {
Spacer()
Button(action: {
self.isDeleteAlertPresented.toggle()
}) {
Text("Delete Account").foregroundColor(.red)
}
Spacer()
}
.alert(isPresented: $isDeleteAlertPresented) {
Alert(
title: Text("Are you sure you want to delete \"\(settingsModel.nameForDisplay)\"?"),
primaryButton: Alert.Button.default(
Text("Delete"),
action: {
self.settingsModel.delete()
self.dismiss()
}),
secondaryButton: Alert.Button.cancel()
)
}
}
}
}
.listStyle(InsetGroupedListStyle())
.navigationBarTitle(Text(verbatim: settingsModel.nameForDisplay), displayMode: .inline)
}
var settingsFeedbinAccountView: SettingsFeedbinAccountView {
return SettingsFeedbinAccountView(account: settingsModel.account)
}
func dismiss() {
presentationMode.wrappedValue.dismiss()
}
}
struct SettingsDetailAccountView_Previews: PreviewProvider {
static var previews: some View {
return SettingsDetailAccountView(AccountManager.shared.defaultAccount)
}
}

View File

@@ -14,7 +14,16 @@ import Secrets
struct SettingsFeedbinAccountView: View {
@Environment(\.presentationMode) var presentationMode
@StateObject var settingsModel = SettingsFeedbinAccountModel()
@ObservedObject var settingsModel: SettingsFeedbinAccountModel
init(account: Account? = nil) {
if let account = account {
self.settingsModel = SettingsFeedbinAccountModel(account: account)
}
else {
self.settingsModel = SettingsFeedbinAccountModel()
}
}
var body: some View {
NavigationView {

View File

@@ -7,6 +7,7 @@
//
import Foundation
import Account
class SettingsModel: ObservableObject {
@@ -36,6 +37,23 @@ class SettingsModel: ObservableObject {
}
@Published var presentSheet: Bool = false
var accounts: [Account] {
get {
AccountManager.shared.sortedAccounts
}
set {
}
}
// MARK: Init
init() {
NotificationCenter.default.addObserver(self, selector: #selector(displayNameDidChange), name: .DisplayNameDidChange, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(userDidAddAccount), name: .UserDidAddAccount, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(userDidDeleteAccount), name: .UserDidDeleteAccount, object: nil)
}
var selectedWebsite: HelpSites = .none {
didSet {
if selectedWebsite == .none {
@@ -45,5 +63,22 @@ class SettingsModel: ObservableObject {
}
}
}
func refreshAccounts() {
objectWillChange.self.send()
}
// MARK:- Notifications
@objc func displayNameDidChange() {
refreshAccounts()
}
@objc func userDidAddAccount() {
refreshAccounts()
}
@objc func userDidDeleteAccount() {
refreshAccounts()
}
}

View File

@@ -12,7 +12,6 @@ import UniformTypeIdentifiers
struct SettingsView: View {
let sortedAccounts = AccountManager.shared.sortedAccounts
@Environment(\.presentationMode) var presentationMode
@Environment(\.exportFiles) var exportAction
@Environment(\.importFiles) var importAction
@@ -59,11 +58,11 @@ struct SettingsView: View {
var accounts: some View {
Section(header: Text("Accounts"), content: {
ForEach(0..<sortedAccounts.count, content: { i in
ForEach(0..<viewModel.accounts.count, id: \.hashValue , content: { i in
NavigationLink(
destination: EmptyView(),
destination: SettingsDetailAccountView(viewModel.accounts[i]),
label: {
Text(sortedAccounts[i].nameForDisplay)
Text(viewModel.accounts[i].nameForDisplay)
})
})
NavigationLink(
@@ -103,7 +102,7 @@ struct SettingsView: View {
}
private func importActionSheet() -> ActionSheet {
var buttons = sortedAccounts.map { (account) -> ActionSheet.Button in
var buttons = viewModel.accounts.map { (account) -> ActionSheet.Button in
ActionSheet.Button.default(Text(account.nameForDisplay)) {
importOPML(account: account)
}
@@ -116,7 +115,7 @@ struct SettingsView: View {
}
private func exportActionSheet() -> ActionSheet {
var buttons = sortedAccounts.map { (account) -> ActionSheet.Button in
var buttons = viewModel.accounts.map { (account) -> ActionSheet.Button in
ActionSheet.Button.default(Text(account.nameForDisplay)) {
exportOPML(account: account)
}