Skip to content

Commit

Permalink
Merge pull request #849 from Infomaniak/mailbox-locked
Browse files Browse the repository at this point in the history
feat: Mailbox locked
  • Loading branch information
PhilippeWeidmann committed Jul 4, 2023
2 parents 7246db5 + 956efd0 commit df514b8
Show file tree
Hide file tree
Showing 25 changed files with 604 additions and 99 deletions.
17 changes: 0 additions & 17 deletions Mail/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,23 +96,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
return AppDelegate.orientationLock
}

func refreshCacheData() {
guard let currentAccount = AccountManager.instance.currentAccount else {
return
}

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

try await accountManager.currentContactManager?.fetchContactsAndAddressBooks()
} catch {
DDLogError("Error while updating user account: \(error)")
}
}
}

func setupDI() {
let networkLoginService = Factory(type: InfomaniakNetworkLoginable.self) { _, _ in
InfomaniakNetworkLogin(clientId: MailApiFetcher.clientId)
Expand Down
79 changes: 79 additions & 0 deletions Mail/Components/MailboxListView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
Infomaniak Mail - iOS App
Copyright (C) 2022 Infomaniak Network SA
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import MailCore
import MailResources
import RealmSwift
import SwiftUI

struct MailboxListView: View {
@Environment(\.window) private var window

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

@ObservedResults(
Mailbox.self,
configuration: MailboxInfosManager.instance.realmConfiguration,
where: { $0.userId == AccountManager.instance.currentUserId },
sortDescriptor: SortDescriptor(keyPath: \Mailbox.mailboxId)
) private var mailboxes

private var otherMailboxes: [Mailbox] {
return mailboxes.filter { $0.mailboxId != currentMailbox?.mailboxId }
}

let currentMailbox: Mailbox?

var body: some View {
VStack(alignment: .leading, spacing: 12) {
HStack(alignment: .center) {
Text(MailResourcesStrings.Localizable.buttonAccountAssociatedEmailAddresses)
.textStyle(.bodySmallSecondary)

Spacer()

NavigationLink {
AddMailboxView { mailbox in
DispatchQueue.main.async {
guard let mailbox = mailbox else { return }
(window?.windowScene?.delegate as? SceneDelegate)?.switchMailbox(mailbox)
}
}
} label: {
MailResourcesAsset.addCircle.swiftUIImage
.resizable()
.foregroundColor(accentColor.primary)
.frame(width: 16, height: 16)
}
}
.padding(.bottom, 16)

if let currentMailbox {
MailboxCell(mailbox: currentMailbox, isSelected: true)
.mailboxCellStyle(.account)
}

ForEach(otherMailboxes) { mailbox in
MailboxCell(mailbox: mailbox)
.mailboxCellStyle(.account)
}
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.top, 24)
}
}
78 changes: 78 additions & 0 deletions Mail/Components/UnavailableMailboxListView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
Infomaniak Mail - iOS App
Copyright (C) 2022 Infomaniak Network SA
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import MailCore
import MailResources
import RealmSwift
import SwiftUI

struct UnavailableMailboxListView: View {
@Environment(\.window) private var window

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

@ObservedResults(
Mailbox.self,
configuration: MailboxInfosManager.instance.realmConfiguration,
where: { $0.userId == AccountManager.instance.currentUserId && $0.isPasswordValid == false },
sortDescriptor: SortDescriptor(keyPath: \Mailbox.mailboxId)
) private var passwordBlockedMailboxes

@ObservedResults(
Mailbox.self,
configuration: MailboxInfosManager.instance.realmConfiguration,
where: { $0.userId == AccountManager.instance.currentUserId && $0.isLocked == true },
sortDescriptor: SortDescriptor(keyPath: \Mailbox.mailboxId)
) private var lockedMailboxes

var body: some View {
VStack(alignment: .leading, spacing: 32) {
if !passwordBlockedMailboxes.isEmpty {
VStack(alignment: .leading, spacing: 12) {
Text(MailResourcesStrings.Localizable.blockedPasswordTitlePlural)
ForEach(passwordBlockedMailboxes) { mailbox in
MailboxCell(mailbox: mailbox)
.mailboxCellStyle(.setPassword)
}
}
}

if !lockedMailboxes.isEmpty {
VStack(alignment: .leading, spacing: 12) {
Text(MailResourcesStrings.Localizable.lockedMailboxTitlePlural)
ForEach(lockedMailboxes) { mailbox in
MailboxesManagementButtonView(
icon: MailResourcesAsset.envelope,
text: mailbox.email,
isSelected: false,
isInMaintenance: false
)
}
}
}
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.top, 24)
}
}

struct UnavailableMailboxListView_Previews: PreviewProvider {
static var previews: some View {
UnavailableMailboxListView()
}
}
34 changes: 31 additions & 3 deletions Mail/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import CocoaLumberjackSwift
import InfomaniakCore
import InfomaniakCoreUI
import InfomaniakDI
Expand Down Expand Up @@ -69,7 +70,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, AccountManagerDelegate
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
(UIApplication.shared.delegate as? AppDelegate)?.refreshCacheData()
refreshCacheData()

if UserDefaults.shared.isAppLockEnabled && appLockHelper.isAppLocked {
showLockView()
Expand Down Expand Up @@ -130,7 +131,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, AccountManagerDelegate

func switchAccount(_ account: Account, mailbox: Mailbox? = nil) {
accountManager.switchAccount(newAccount: account)
(UIApplication.shared.delegate as? AppDelegate)?.refreshCacheData()
refreshCacheData()

if let mailbox = mailbox {
switchMailbox(mailbox)
Expand Down Expand Up @@ -161,6 +162,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, AccountManagerDelegate
func showMainView(animated: Bool = true) {
if let mailboxManager = accountManager.currentMailboxManager {
showMainView(mailboxManager: mailboxManager, animated: animated)
} else if accountManager.mailboxes.allSatisfy({ !$0.isAvailable }) {
setRootView(UnavailableMailboxesView(), animated: animated)
} else {
showNoMailboxView(animated: animated)
}
Expand All @@ -170,6 +173,28 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, AccountManagerDelegate
setRootView(LockedAppView(), animated: false)
}

func refreshCacheData() {
guard let currentAccount = AccountManager.instance.currentAccount else {
return
}

Task {
do {
let mailboxIdBeforeSwitching = accountManager.currentMailboxId
try await accountManager.updateUser(for: currentAccount)
accountManager.enableBugTrackerIfAvailable()

try await accountManager.currentContactManager?.fetchContactsAndAddressBooks()

if mailboxIdBeforeSwitching != accountManager.currentMailboxId {
showMainView()
}
} catch {
DDLogError("Error while updating user account: \(error)")
}
}
}

// MARK: - Open URLs

func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
Expand All @@ -181,7 +206,10 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, AccountManagerDelegate
guard let urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: true) else { return false }

if Constants.isMailTo(url) {
NotificationCenter.default.post(name: .onOpenedMailTo, object: IdentifiableURLComponents(urlComponents: urlComponents))
NotificationCenter.default.post(
name: .onOpenedMailTo,
object: IdentifiableURLComponents(urlComponents: urlComponents)
)
}

return true
Expand Down
27 changes: 19 additions & 8 deletions Mail/Views/Menu Drawer/MailboxManagement/MailboxCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,18 @@ struct MailboxCell: View {
@Environment(\.mailboxCellStyle) private var style: Style
@Environment(\.window) private var window

let mailbox: Mailbox
@State private var isShowingLockedView = false
@State private var isShowingUpdatePasswordView = false

private var isSelected: Bool {
return AccountManager.instance.currentMailboxManager?.mailbox.objectId == mailbox.objectId
}
let mailbox: Mailbox
var isSelected = false

private var detailNumber: Int? {
return mailbox.unseenMessages > 0 ? mailbox.unseenMessages : nil
}

enum Style {
case menuDrawer, account
case menuDrawer, account, setPassword
}

var body: some View {
Expand All @@ -64,27 +64,38 @@ struct MailboxCell: View {
text: mailbox.email,
detailNumber: detailNumber,
isSelected: isSelected,
isPasswordValid: mailbox.isPasswordValid
isInMaintenance: !mailbox.isAvailable
) {
guard !isSelected else { return }
guard mailbox.isPasswordValid else {
IKSnackBar.showSnackBar(message: MailResourcesStrings.Localizable.frelatedMailbox)
isShowingUpdatePasswordView = true
return
}
guard !mailbox.isLocked else {
isShowingLockedView = true
return
}
@InjectService var matomo: MatomoUtils
switch style {
case .setPassword: break
case .menuDrawer:
matomo.track(eventWithCategory: .menuDrawer, name: "switchMailbox")
case .account:
matomo.track(eventWithCategory: .account, name: "switchMailbox")
}
(window?.windowScene?.delegate as? SceneDelegate)?.switchMailbox(mailbox)
}
.floatingPanel(isPresented: $isShowingLockedView) {
LockedMailboxView(lockedMailbox: mailbox)
}
.sheet(isPresented: $isShowingUpdatePasswordView) {
UpdateMailboxPasswordView(mailbox: mailbox)
}
}
}

struct MailboxCell_Previews: PreviewProvider {
static var previews: some View {
MailboxCell(mailbox: PreviewHelper.sampleMailbox)
MailboxCell(mailbox: PreviewHelper.sampleMailbox, isSelected: true)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,28 +27,30 @@ struct MailboxesManagementButtonView: View {
let icon: Image
let text: String
let detailNumber: Int?
let handleAction: () -> Void
let handleAction: (() -> Void)?
let isSelected: Bool
let isPasswordValid: Bool
let isInMaintenance: Bool

init(
icon: MailResourcesImages,
text: String,
detailNumber: Int? = nil,
isSelected: Bool,
isPasswordValid: Bool,
handleAction: @escaping () -> Void
isInMaintenance: Bool,
handleAction: (() -> Void)? = nil
) {
self.icon = icon.swiftUIImage
self.text = text
self.detailNumber = detailNumber
self.isSelected = isSelected
self.isPasswordValid = isPasswordValid
self.isInMaintenance = isInMaintenance
self.handleAction = handleAction
}

var body: some View {
Button(action: handleAction) {
Button {
handleAction?()
} label: {
HStack {
HStack(spacing: 16) {
icon
Expand All @@ -62,10 +64,15 @@ struct MailboxesManagementButtonView: View {
}
.frame(maxWidth: .infinity, alignment: .leading)

if !isPasswordValid {
if isInMaintenance && style != .setPassword {
MailResourcesAsset.warning.swiftUIImage
} else {
switch style {
case .setPassword:
MailResourcesAsset.arrowRight.swiftUIImage
.resizable()
.frame(width: 12, height: 12)
.foregroundColor(MailResourcesAsset.textPrimaryColor.swiftUIColor)
case .menuDrawer:
if let detailNumber {
Text(detailNumber < 100 ? "\(detailNumber)" : "99+")
Expand All @@ -87,17 +94,13 @@ struct MailboxesManagementButtonView: View {

struct MailboxesManagementButtonView_Previews: PreviewProvider {
static var previews: some View {
MailboxesManagementButtonView(icon: MailResourcesAsset.folder, text: "Hello", isSelected: false, isPasswordValid: true) {
/* Empty for test */
}
MailboxesManagementButtonView(icon: MailResourcesAsset.folder, text: "Hello", isSelected: false, isInMaintenance: true)
MailboxesManagementButtonView(
icon: MailResourcesAsset.folder,
text: "Hello",
detailNumber: 10,
isSelected: false,
isPasswordValid: true
) {
/* Empty for test */
}
isInMaintenance: true
)
}
}
Loading

0 comments on commit df514b8

Please sign in to comment.