Skip to content

Commit

Permalink
fix: Cache profiles (#1531)
Browse files Browse the repository at this point in the history
  • Loading branch information
PhilippeWeidmann authored Sep 27, 2024
2 parents 4550dc9 + 624214b commit a346792
Show file tree
Hide file tree
Showing 27 changed files with 158 additions and 178 deletions.
11 changes: 6 additions & 5 deletions Mail/Proxy/Implementation/CacheManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,23 @@ import Contacts
import Foundation
import InfomaniakCore
import InfomaniakDI
import InfomaniakLogin
import MailCore

@available(iOSApplicationExtension, unavailable)
public final class CacheManager: CacheManageable {
@LazyInjectService private var accountManager: AccountManager

public func refreshCacheData(account: Account?) {
public func refreshCacheData(account: ApiToken?) {
guard let account else { return }

// Try to enable at least once before attempting fetching new user
accountManager.enableBugTrackerIfAvailable()

Task {
// Try to enable at least once before attempting fetching new user
await accountManager.enableBugTrackerIfAvailable()

do {
try await accountManager.updateUser(for: account)
accountManager.enableBugTrackerIfAvailable()
await accountManager.enableBugTrackerIfAvailable()

guard CNContactStore.authorizationStatus(for: .contacts) != .notDetermined else {
return
Expand Down
2 changes: 1 addition & 1 deletion Mail/Proxy/Implementation/MessageActionHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public struct MessageActionHandler: MessageActionHandlable {
private func switchAccountIfNeeded(mailbox: Mailbox, mailboxManager: MailboxManager) {
if accountManager.currentMailboxManager?.mailbox != mailboxManager.mailbox {
if accountManager.getCurrentAccount()?.userId != mailboxManager.mailbox.userId {
if let switchedAccount = accountManager.accounts.values
if let switchedAccount = accountManager.accounts
.first(where: { $0.userId == mailboxManager.mailbox.userId }) {
accountManager.switchAccount(newUserId: switchedAccount.userId)
accountManager.switchMailbox(newMailbox: mailbox)
Expand Down
3 changes: 2 additions & 1 deletion Mail/Proxy/Protocols/CacheManageable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@

import Foundation
import InfomaniakCore
import InfomaniakLogin

/// Something that can manipulate cached data
public protocol CacheManageable {
func refreshCacheData(account: Account?)
func refreshCacheData(account: ApiToken?)
}
10 changes: 6 additions & 4 deletions Mail/UserAccountScene.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ struct UserAccountScene: Scene {
.standardWindow()
.environmentObject(rootViewState)
.sceneLifecycle(willEnterForeground: willEnterForeground, didEnterBackground: didEnterBackground)
.task(id: rootViewState.account) {
.task(id: rootViewState.account?.userId) {
cacheManager.refreshCacheData(account: rootViewState.account)
}
}
Expand Down Expand Up @@ -76,8 +76,10 @@ struct UserAccountScene: Scene {
}

private func willEnterForeground() {
appLaunchCounter.increase()
reviewManager.decreaseOpeningUntilReview()
if rootViewState.state != .onboarding && rootViewState.state != .preloading {
appLaunchCounter.increase()
reviewManager.decreaseOpeningUntilReview()
}
cacheManager.refreshCacheData(account: rootViewState.account)
rootViewState.transitionToLockViewIfNeeded()
checkAppVersion()
Expand All @@ -104,7 +106,7 @@ struct UserAccountScene: Scene {
}
case .isUpToDate:
if rootViewState.state == .updateRequired {
rootViewState.transitionToMainViewIfPossible(targetAccount: nil, targetMailbox: nil)
await rootViewState.transitionToMainViewIfPossible(targetAccount: nil, targetMailbox: nil)
}
}
} catch {
Expand Down
2 changes: 1 addition & 1 deletion Mail/Views/Alerts/DetachMailboxConfirmationView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ struct DetachMailboxConfirmationView: View {
matomo.track(eventWithCategory: .invalidPasswordMailbox, name: "detachMailboxConfirm")
await tryOrDisplayError {
try await accountManager.detachMailbox(mailbox: mailbox)
navigationState.transitionToMainViewIfPossible(targetAccount: nil, targetMailbox: nil)
await navigationState.transitionToMainViewIfPossible(targetAccount: nil, targetMailbox: nil)
}
}
}
Expand Down
1 change: 0 additions & 1 deletion Mail/Views/Alerts/LogoutConfirmationView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ struct LogoutConfirmationView: View {
if let nextAccount = accountManager.accounts.first {
accountManager.switchAccount(newUserId: nextAccount.userId)
}
accountManager.saveAccounts()

async let _ = NotificationsHelper.updateUnreadCountBadge()
}
Expand Down
4 changes: 1 addition & 3 deletions Mail/Views/LockedAppView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,7 @@ struct LockedAppView: View {
isEvaluatingPolicy = true
if await (try? appLockHelper.evaluatePolicy(reason: MailResourcesStrings.Localizable.lockAppTitle)) == true {
appLockHelper.setTime()
Task {
navigationState.transitionToMainViewIfPossible(targetAccount: nil, targetMailbox: nil)
}
await navigationState.transitionToMainViewIfPossible(targetAccount: nil, targetMailbox: nil)
} else {
isEvaluatingPolicy = false
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import NavigationBackport
import SwiftUI

struct CurrentComposeMailboxView: View {
@LazyInjectService private var accountManager: AccountManager
@LazyInjectService private var platformDetector: PlatformDetectable

@AppStorage(UserDefaults.shared.key(.accentColor)) private var accentColor = DefaultPreferences.accentColor
Expand Down Expand Up @@ -85,7 +84,9 @@ struct CurrentComposeMailboxView: View {
}
.padding(.horizontal, value: .medium)
.mailboxCellStyle(.account)
.onAppear(perform: viewModel.initDefaultAccountAndMailbox)
.task {
await viewModel.initProfilesSelectDefaultAccountAndMailbox()
}
.backButtonDisplayMode(.minimal)
.navigationBarTitleDisplayMode(.inline)
.toolbar {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ import NavigationBackport
import SwiftUI

struct SelectComposeMailboxView: View {
@LazyInjectService private var accountManager: AccountManager

@AppStorage(UserDefaults.shared.key(.accentColor)) private var accentColor = DefaultPreferences.accentColor

@Binding var composeMessageIntent: ComposeMessageIntent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,31 @@ final class SelectComposeMailboxViewModel: ObservableObject {

init(composeMessageIntent: Binding<ComposeMessageIntent>) {
self.composeMessageIntent = composeMessageIntent
}

listProfiles()
@MainActor
func initProfilesSelectDefaultAccountAndMailbox() async {
await listProfiles()
initDefaultAccountAndMailbox()
}

func listProfiles() {
userProfiles = accountManager.accounts.compactMap { $0.user }.sorted { lhs, rhs in
if (lhs.id == accountManager.currentUserId) != (rhs.id == accountManager.currentUserId) {
return lhs.id == accountManager.currentUserId
} else {
return lhs.displayName < rhs.displayName
@MainActor
private func listProfiles() async {
let fetchedUserProfiles = await accountManager.accounts
.asyncMap { await self.accountManager.userProfileStore.getUserProfile(id: $0.userId) }
.compactMap { $0 }
.sorted { lhs, rhs in
if (lhs.id == accountManager.currentUserId) != (rhs.id == accountManager.currentUserId) {
return lhs.id == accountManager.currentUserId
} else {
return lhs.displayName < rhs.displayName
}
}
}

userProfiles = fetchedUserProfiles
}

func initDefaultAccountAndMailbox() {
private func initDefaultAccountAndMailbox() {
guard let defaultMailbox = accountManager.currentMailboxManager?.mailbox,
let mailboxManager = accountManager.getMailboxManager(for: defaultMailbox),
let user = userProfiles.first(where: { $0.id == defaultMailbox.userId }) else {
Expand Down
2 changes: 1 addition & 1 deletion Mail/Views/Onboarding/AuthorizationView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ struct AuthorizationView: View {
func requestNotificationsAuthorization() {
Task {
await NotificationsHelper.askForPermissions()
navigationState.transitionToMainViewIfPossible(targetAccount: nil, targetMailbox: nil)
await navigationState.transitionToMainViewIfPossible(targetAccount: nil, targetMailbox: nil)
}
}
}
Expand Down
12 changes: 10 additions & 2 deletions Mail/Views/PreloadingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ extension VerticalAlignment {
}

struct PreloadingView: View {
@LazyInjectService private var tokenStore: TokenStore
@LazyInjectService private var appLaunchCounter: AppLaunchCounter
@LazyInjectService private var accountManager: AccountManager

@EnvironmentObject private var rootViewState: RootViewState
Expand All @@ -60,6 +62,12 @@ struct PreloadingView: View {
.padding(.bottom, value: .medium)
}
.task {
guard !appLaunchCounter.isFirstLaunch else {
tokenStore.removeAllTokens()
rootViewState.transitionToRootViewState(.onboarding)
return
}

guard let currentAccount = accountManager.getCurrentAccount() else {
rootViewState.transitionToRootViewState(.onboarding)
return
Expand All @@ -70,7 +78,7 @@ struct PreloadingView: View {
if targetMailboxManager.getFolder(with: .inbox) == nil {
try await targetMailboxManager.refreshAllFolders()
}
rootViewState.transitionToMainViewIfPossible(
await rootViewState.transitionToMainViewIfPossible(
targetAccount: currentAccount,
targetMailbox: targetMailboxManager.mailbox
)
Expand All @@ -83,7 +91,7 @@ struct PreloadingView: View {
try await currentMailboxManager.refreshAllFolders()
}

rootViewState.transitionToMainViewIfPossible(targetAccount: currentAccount, targetMailbox: nil)
await rootViewState.transitionToMainViewIfPossible(targetAccount: currentAccount, targetMailbox: nil)
} catch let error as MailError where error == MailError.noMailbox {
rootViewState.transitionToRootViewState(.noMailboxes)
} catch {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ final class SettingsAccountManagementViewDelegate: DeleteAccountDelegate {
accountManager.switchAccount(newUserId: nextAccount.userId)
}
snackbarPresenter.show(message: MailResourcesStrings.Localizable.snackBarAccountDeleted)
accountManager.saveAccounts()
}
}

Expand All @@ -57,7 +56,7 @@ struct SettingsAccountManagementView: View {
@ModalState(wrappedValue: nil, context: ContextKeys.account) private var presentedAccountDeletionToken: ApiToken?
@State private var delegate = SettingsAccountManagementViewDelegate()

let account: Account
let user: UserProfile

var body: some View {
ScrollView {
Expand All @@ -66,15 +65,15 @@ struct SettingsAccountManagementView: View {
VStack(alignment: .leading, spacing: IKPadding.extraSmall) {
Text(MailResourcesStrings.Localizable.usernameTitle)
.textStyle(.header2)
Text(account.user.displayName)
Text(user.displayName)
.textStyle(.bodySecondary)
}
.lineLimit(1)

VStack(alignment: .leading, spacing: IKPadding.extraSmall) {
Text(MailResourcesStrings.Localizable.attachMailboxInputHint)
.textStyle(.header2)
Text(account.user.email)
Text(user.email)
.textStyle(.bodySecondary)
}
.lineLimit(1)
Expand All @@ -85,7 +84,7 @@ struct SettingsAccountManagementView: View {

Button {
matomo.track(eventWithCategory: .account, name: Action.deleteAccount.matomoName)
presentedAccountDeletionToken = tokenStore.tokenFor(userId: account.userId)
presentedAccountDeletionToken = tokenStore.tokenFor(userId: user.id)
} label: {
ActionButtonLabel(action: Action.deleteAccount)
}
Expand Down Expand Up @@ -113,5 +112,5 @@ extension ApiToken: @retroactive Identifiable {
}

#Preview {
SettingsAccountManagementView(account: PreviewHelper.sampleAccount)
SettingsAccountManagementView(user: PreviewHelper.sampleUser)
}
10 changes: 4 additions & 6 deletions Mail/Views/Settings/SettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -213,12 +213,10 @@ struct SettingsView: View {
SettingsDataManagementView()
}

if let account = accountManager.getCurrentAccount() {
SettingsSubMenuCell(
title: MailResourcesStrings.Localizable.settingsAccountManagementTitle
) {
SettingsAccountManagementView(account: account)
}
SettingsSubMenuCell(
title: MailResourcesStrings.Localizable.settingsAccountManagementTitle
) {
SettingsAccountManagementView(user: currentUser.value)
}
}
}
Expand Down
21 changes: 21 additions & 0 deletions Mail/Views/Switch User/AccountCellView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,27 @@ import MailResources
import RealmSwift
import SwiftUI

struct AccountCellPlaceholderView: View {
var body: some View {
HStack {
Circle()
.fill(MailResourcesAsset.grayActionColor.swiftUIColor)
.frame(width: 40, height: 40)
VStack(alignment: .leading, spacing: 0) {
Text("user.displayName")
.redacted(reason: .placeholder)
.textStyle(.bodyMedium)
Text("user.email")
.redacted(reason: .placeholder)
.textStyle(.bodySecondary)
}
.lineLimit(1)
.frame(maxWidth: .infinity, alignment: .leading)
}
.padding(.vertical, value: .small)
}
}

struct AccountCellView: View {
@LazyInjectService private var matomo: MatomoUtils
@LazyInjectService private var accountManager: AccountManager
Expand Down
33 changes: 24 additions & 9 deletions Mail/Views/Switch User/AccountListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,32 @@ import MailResources
import SwiftUI

struct AccountListView: View {
@State private var isShowingNewAccountView = false

@LazyInjectService private var orientationManager: OrientationManageable
@LazyInjectService private var accountManager: AccountManager

@State private var isShowingNewAccountView = false
@State private var users: [UserProfile]?

/// Optional as this view can be displayed from a context without a mailboxManager available
let mailboxManager: MailboxManager?

var body: some View {
VStack(spacing: 0) {
VStack(spacing: IKPadding.extraSmall) {
ForEach(accountManager.accounts.values) { account in
AccountCellView(
selectedUserId: .constant(accountManager.currentUserId),
mailboxManager: mailboxManager,
user: account.user
)
.padding(.horizontal, value: .medium)
if let users {
ForEach(users) { user in
AccountCellView(
selectedUserId: .constant(accountManager.currentUserId),
mailboxManager: mailboxManager,
user: user
)
.padding(.horizontal, value: .medium)
}
} else {
ForEach(accountManager.accounts) { _ in
AccountCellPlaceholderView()
.padding(.horizontal, value: .medium)
}
}
}

Expand All @@ -67,11 +75,18 @@ struct AccountListView: View {

private func updateUsers() async throws {
await withThrowingTaskGroup(of: Void.self) { group in
var storedUsers = [UserProfile]()
for account in accountManager.accounts {
if let user = await accountManager.userProfileStore.getUserProfile(id: account.userId) {
storedUsers.append(user)
}

group.addTask {
_ = try await accountManager.updateUser(for: account)
}
}

users = storedUsers
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion Mail/Views/Thread/OpenThreadIntentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ struct OpenThreadIntentView: View, IntentViewable {
}

func initFromIntent() async {
guard let user = accountManager.account(for: openThreadIntent.userId)?.user,
guard let user = await accountManager.userProfileStore.getUserProfile(id: openThreadIntent.userId),
let mailboxManager = accountManager.getMailboxManager(
for: openThreadIntent.mailboxId,
userId: openThreadIntent.userId
Expand Down
Loading

0 comments on commit a346792

Please sign in to comment.