diff --git a/iOS/Account/Views/FeedbinAddAccountView.swift b/iOS/Account/Views/FeedbinAddAccountView.swift index e6fa61f40..678ab8c27 100644 --- a/iOS/Account/Views/FeedbinAddAccountView.swift +++ b/iOS/Account/Views/FeedbinAddAccountView.swift @@ -101,7 +101,7 @@ struct FeedbinAddAccountView: View { } var feedbinAccountExplainer: some View { - Text("FEEDBIN_FOOTER_EXPLAINER", tableName: "Account").multilineTextAlignment(.center) + Text(account == nil ? "FEEDBIN_FOOTER_EXPLAINER" : "", tableName: "Account").multilineTextAlignment(.center) } private func retrieveCredentials() { diff --git a/iOS/Account/Views/NewsBlurAddAccountView.swift b/iOS/Account/Views/NewsBlurAddAccountView.swift index b1a208125..1f30dda17 100644 --- a/iOS/Account/Views/NewsBlurAddAccountView.swift +++ b/iOS/Account/Views/NewsBlurAddAccountView.swift @@ -118,7 +118,7 @@ struct NewsBlurAddAccountView: View, Logging { } var newsBlurAccountExplainer: some View { - Text("NEWSBLUR_FOOTER_EXPLAINER", tableName: "Account").multilineTextAlignment(.center) + Text(account == nil ? "NEWSBLUR_FOOTER_EXPLAINER" : "", tableName: "Account").multilineTextAlignment(.center) } private func executeAccountCredentials() async throws { diff --git a/iOS/Inspector/Views/WebFeedInspectorView.swift b/iOS/Inspector/Views/WebFeedInspectorView.swift index c35888b80..568729e2a 100644 --- a/iOS/Inspector/Views/WebFeedInspectorView.swift +++ b/iOS/Inspector/Views/WebFeedInspectorView.swift @@ -63,6 +63,7 @@ struct WebFeedInspectorView: View { .sheet(isPresented: $showHomePage, onDismiss: nil) { SafariView(url: URL(string: webFeed.homePageURL!)!) } + .tint(Color(uiColor: AppAssets.primaryAccentColor)) .dismissOnExternalContextLaunch() } @@ -73,6 +74,7 @@ struct WebFeedInspectorView: View { .resizable() .aspectRatio(contentMode: .fit) .frame(width: 48, height: 48) + .clipShape(RoundedRectangle(cornerRadius: 4)) Spacer() } } diff --git a/iOS/Settings/Views/Account and Extensions/Accounts/AccountsManagementView.swift b/iOS/Settings/Views/Account and Extensions/Accounts/AccountsManagementView.swift index b63c8e1db..020cd53d6 100644 --- a/iOS/Settings/Views/Account and Extensions/Accounts/AccountsManagementView.swift +++ b/iOS/Settings/Views/Account and Extensions/Accounts/AccountsManagementView.swift @@ -10,76 +10,92 @@ import SwiftUI import Account import Combine +public final class AccountManagementViewModel: ObservableObject { + + @Published var sortedActiveAccounts = [Account]() + @Published var sortedInactiveAccounts = [Account]() + @Published var showAccountDeletionAlert: Bool = false + @Published var showAddAccountSheet: Bool = false + public var accountToDelete: Account? = nil + + init() { + refreshAccounts() + + NotificationCenter.default.addObserver(forName: .AccountStateDidChange, object: nil, queue: .main) { [weak self] _ in + self?.refreshAccounts() + } + + NotificationCenter.default.addObserver(forName: .UserDidAddAccount, object: nil, queue: .main) { [weak self] _ in + self?.refreshAccounts() + } + + NotificationCenter.default.addObserver(forName: .UserDidDeleteAccount, object: nil, queue: .main) { [weak self] _ in + self?.refreshAccounts() + } + + NotificationCenter.default.addObserver(forName: .DisplayNameDidChange, object: nil, queue: .main) { [weak self] _ in + self?.refreshAccounts() + } + } + + private func refreshAccounts() { + sortedActiveAccounts = AccountManager.shared.sortedActiveAccounts + sortedInactiveAccounts = AccountManager.shared.sortedAccounts.filter({ $0.isActive == false }) + } + +} + + struct AccountsManagementView: View { - @State private var showAddAccountSheet: Bool = false - @State private var sortedActiveAccounts = [Account]() - @State private var sortedInactiveAccounts = [Account]() - @State private var accountToRemove: Account? - @State private var showRemoveAccountAlert: Bool = false + @StateObject private var viewModel = AccountManagementViewModel() var body: some View { List { Section(header: Text("ACTIVE_ACCOUNTS_HEADER", tableName: "Settings")) { - ForEach(sortedActiveAccounts, id: \.self) { account in - accountRow(account, showRemoveAccountAlert: $showRemoveAccountAlert, accountToRemove: $accountToRemove) + ForEach(viewModel.sortedActiveAccounts, id: \.self) { account in + accountRow(account) } } Section(header: Text("INACTIVE_ACCOUNTS_HEADER", tableName: "Settings")) { - ForEach(sortedInactiveAccounts, id: \.self) { account in - accountRow(account, showRemoveAccountAlert: $showRemoveAccountAlert, accountToRemove: $accountToRemove) + ForEach(viewModel.sortedInactiveAccounts, id: \.self) { account in + accountRow(account) } } } .navigationTitle(Text("MANAGE_ACCOUNTS", tableName: "Settings")) - .tint(Color(uiColor: AppAssets.primaryAccentColor)) .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button { - showAddAccountSheet = true + viewModel.showAddAccountSheet = true } label: { Image(systemName: "plus") } } } - .onReceive(NotificationCenter.default.publisher(for: .AccountStateDidChange)) { _ in - refreshAccounts() - } - .onReceive(NotificationCenter.default.publisher(for: .UserDidAddAccount)) { _ in - refreshAccounts() - } - .onReceive(NotificationCenter.default.publisher(for: .UserDidDeleteAccount)) { _ in - refreshAccounts() - } - .onReceive(NotificationCenter.default.publisher(for: .DisplayNameDidChange)) { _ in - refreshAccounts() - } - .task(priority: .userInitiated) { - refreshAccounts() - } - .sheet(isPresented: $showAddAccountSheet) { + .sheet(isPresented: $viewModel.showAddAccountSheet) { AddAccountListView() } - .alert(Text("ACCOUNT_REMOVE \(accountToRemove?.nameForDisplay ?? "")", tableName: "Settings"), - isPresented: $showRemoveAccountAlert) { + .alert(Text("ACCOUNT_REMOVE \(viewModel.accountToDelete?.nameForDisplay ?? "")", tableName: "Settings"), + isPresented: $viewModel.showAccountDeletionAlert) { Button(role: .destructive) { - AccountManager.shared.deleteAccount(accountToRemove!) + AccountManager.shared.deleteAccount(viewModel.accountToDelete!) } label: { Text("REMOVE_ACCOUNT_BUTTON_TITLE", tableName: "Buttons") } Button(role: .cancel) { - accountToRemove = nil + // } label: { Text("CANCEL_BUTTON_TITLE", tableName: "Buttons") } } message: { - switch accountToRemove { + switch viewModel.accountToDelete { case .none: Text("") - case .some(let wrapped): - switch wrapped.type { + case .some(let account): + switch account.type { case .feedly: Text("REMOVE_FEEDLY_CONFIRMATION", tableName: "Settings") default: @@ -89,14 +105,7 @@ struct AccountsManagementView: View { } } - func refreshAccounts() { - sortedActiveAccounts = [] - sortedInactiveAccounts = [] - sortedActiveAccounts = AccountManager.shared.sortedActiveAccounts - sortedInactiveAccounts = AccountManager.shared.sortedAccounts.filter({ $0.isActive == false }) - } - - func accountRow(_ account: Account, showRemoveAccountAlert: Binding, accountToRemove: Binding) -> some View { + func accountRow(_ account: Account) -> some View { NavigationLink { AccountInspectorView(account: account) } label: { @@ -109,15 +118,15 @@ struct AccountsManagementView: View { .swipeActions(edge: .trailing, allowsFullSwipe: false) { if account != AccountManager.shared.defaultAccount { Button(role: .destructive) { - accountToRemove.wrappedValue = account - showRemoveAccountAlert.wrappedValue = true + viewModel.accountToDelete = account + viewModel.showAccountDeletionAlert = true } label: { Label { Text("REMOVE_ACCOUNT_BUTTON_TITLE", tableName: "Buttons") } icon: { Image(systemName: "trash") } - }.tint(.red) + } } Button { withAnimation {