Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions FlowCrypt/Common UI/AttachmentManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import UIKit
import Combine

@MainActor
protocol AttachmentManagerType {
func open(_ attachment: MessageAttachment)
}
Expand Down Expand Up @@ -49,13 +50,19 @@ extension AttachmentManager: AttachmentManagerType {
.sinkFuture(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tomholub I think we should use async/await here instead of Combine for code consistency across project, and for better threads handling with @MainActor, can be done in another issue

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree - I've asked @ekievsky to do it as part of #1031

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will also file another issue to look over the remaining ones after that, if any

receiveValue: {},
receiveError: { [weak self] error in
self?.controller?.showToast(
"\("message_attachment_saved_with_error".localized) \(error.localizedDescription)"
)
self?.handle(error)
}
)
.store(in: &self.cancellable)
}

private func handle(_ error: Error) {
Task {
await controller?.showToast(
"\("message_attachment_saved_with_error".localized) \(error.localizedDescription)"
)
}
}
}

// MARK: - FilesManagerPresenter
Expand Down
8 changes: 4 additions & 4 deletions FlowCrypt/Common UI/Refreshable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import Foundation

protocol Refreshable {

func startRefreshing()
}
@MainActor
protocol Refreshable {
func startRefreshing()
}
2 changes: 0 additions & 2 deletions FlowCrypt/Controllers/Compose/ComposeViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ private struct ComposedDraft: Equatable {
* - User can be redirected here from *InboxViewController* by tapping on *+*
* - Or from *ThreadDetailsViewController* controller by tapping on *reply*
**/
@MainActor
final class ComposeViewController: TableNodeViewController {
private lazy var logger = Logger.nested(Self.self)

Expand Down Expand Up @@ -932,7 +931,6 @@ extension ComposeViewController: PHPickerViewControllerDelegate {
})
}
}

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ final class InboxViewContainerController: TableNodeViewController {
let folderService: FoldersServiceType
let decorator: InboxViewControllerContainerDecorator

@MainActor private var state: State = .loading {
private var state: State = .loading {
didSet { handleNewState() }
}

Expand Down Expand Up @@ -68,7 +68,7 @@ final class InboxViewContainerController: TableNodeViewController {
}
}

@MainActor private func handleFetched(folders: [FolderViewModel]) {
private func handleFetched(folders: [FolderViewModel]) {
guard folders.isNotEmpty else {
state = .empty
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Foundation
import UIKit

class InboxViewControllerFactory {
@MainActor
static func make(with viewModel: InboxViewModel) -> InboxViewController {
guard let currentAuthType = DataService.shared.currentAuthType else {
fatalError("Internal inconsistency")
Expand Down
1 change: 1 addition & 0 deletions FlowCrypt/Controllers/Inbox/InboxViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import FlowCryptCommon
import FlowCryptUI
import Foundation

@MainActor
final class InboxViewController: ASDKViewController<ASDisplayNode> {
private lazy var logger = Logger.nested(Self.self)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import UIKit

@MainActor
protocol MsgListViewController {
func open(with message: InboxRenderable, path: String)

Expand All @@ -30,11 +31,9 @@ extension MsgListViewController where Self: UIViewController {
private func openDraft(with message: Message) {
guard let email = DataService.shared.email else { return }

Task {
let controller = await ComposeViewController(email: email)
await controller.updateWithMessage(message: message)
await navigationController?.pushViewController(controller, animated: true)
}
let controller = ComposeViewController(email: email)
controller.updateWithMessage(message: message)
navigationController?.pushViewController(controller, animated: true)
}

private func openMsg(with message: Message, path: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ enum BackupOption: Int, CaseIterable, Equatable {
}
}

@MainActor
final class BackupOptionsViewController: ASDKViewController<TableNode> {
enum Parts: Int, CaseIterable {
case email, download, action, info
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import AsyncDisplayKit
import FlowCryptUI

@MainActor
final class BackupViewController: ASDKViewController<TableNode> {
private enum Parts: Int, CaseIterable {
case info, action
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import AsyncDisplayKit
import FlowCryptUI
import Foundation

@MainActor
final class BackupSelectKeyViewController: ASDKViewController<TableNode> {
private let backupService: BackupServiceType
private let service: ServiceActor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import FlowCryptUI
* - User can proceed to importing keys *SetupManuallyImportKeyViewController*
* - User can see detail information for the key in *KeyDetailViewController*
*/
@MainActor
final class KeySettingsViewController: TableNodeViewController {
private var keys: [KeyDetails] = []
private let decorator: KeySettingsViewDecorator
Expand Down
1 change: 1 addition & 0 deletions FlowCrypt/Controllers/Setup/PassPhraseSaveable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import FlowCryptUI

@MainActor
protocol PassPhraseSaveable {
var storageMethod: StorageMethod { get set }
var passPhraseIndexes: [IndexPath] { get }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ enum CreateKeyError: Error {
* - Here user can enter a pass phrase (can be saved in memory or in encrypted storage) and generate a key
* - After key is generated, user will be redirected to **main flow** (inbox view)
*/
@MainActor
final class SetupGenerateKeyViewController: SetupCreatePassphraseAbstractViewController {

private let backupService: BackupServiceType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,7 @@ final class SetupManuallyImportKeyViewController: TableNodeViewController {
}

private func updateSubtitle() {
DispatchQueue.main.async {
self.node.reloadRows(at: [Parts.description.indexPath], with: .fade)
}
node.reloadRows(at: [Parts.description.indexPath], with: .fade)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -509,13 +509,9 @@ extension SetupImapViewController {
do {
try await self.imap.connectImap(session: imapSessionToCheck)
try await self.imap.connectSmtp(session: smtpSession)
DispatchQueue.main.async {
self.handleSuccessfulConnection()
}
handleSuccessfulConnection()
} catch {
DispatchQueue.main.async {
self.handleConnection(error: error)
}
handleConnection(error: error)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import ENSwiftSideMenu
import FlowCryptUI
import UIKit

@MainActor
protocol SideMenuViewController {
func didOpen()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import FlowCryptUI
* On tap on each folder user should be redirected to `InboxViewController` with selected folder
* On settings tap user will be redirected to `SettingsViewController`
*/
@MainActor
final class MyMenuViewController: ASDKViewController<ASDisplayNode> {
private enum Constants {
static let allMail = "folder_all_mail".localized
Expand Down Expand Up @@ -174,13 +175,9 @@ extension MyMenuViewController {
Task {
do {
let folders = try await foldersProvider.fetchFolders(isForceReload: true)
DispatchQueue.main.async {
self.handleNewFolders(with: folders)
}
handleNewFolders(with: folders)
} catch {
DispatchQueue.main.async {
self.handleError(with: error)
}
handleError(with: error)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import UIKit

@MainActor
protocol NavigationChildController {
var navigationItem: UINavigationItem { get }
var shouldShowBackButton: Bool { get }
Expand Down
27 changes: 11 additions & 16 deletions FlowCrypt/Controllers/Threads/MessageActionsHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import UIKit
import FlowCryptUI
import FlowCryptCommon

@MainActor
protocol MessageActionsHandler: AnyObject {
var currentFolderPath: String { get }
var trashFolderProvider: TrashFolderProviderType { get }
Expand All @@ -33,9 +34,7 @@ extension MessageActionsHandler where Self: UIViewController {
Task {
do {
let path = try await trashFolderProvider.getTrashFolderPath()
DispatchQueue.main.async {
self.setupNavigationBarItems(with: path)
}
setupNavigationBarItems(with: path)
} catch {
// todo - handle?
logger.logError("setupNavigationBar: \(error)")
Expand Down Expand Up @@ -95,22 +94,18 @@ extension MessageActionsHandler where Self: UIViewController {
Task {
do {
let trashPath = try await trashFolderProvider.getTrashFolderPath()
DispatchQueue.main.async {
guard let trashPath = trashPath else {
return
}
if self.currentFolderPath.caseInsensitiveCompare(trashPath) == .orderedSame {
self.awaitUserConfirmation { [weak self] in
self?.permanentlyDelete()
}
} else {
self.moveToTrash(with: trashPath)
guard let trashPath = trashPath else {
return
}
if self.currentFolderPath.caseInsensitiveCompare(trashPath) == .orderedSame {
self.awaitUserConfirmation { [weak self] in
self?.permanentlyDelete()
}
} else {
self.moveToTrash(with: trashPath)
}
} catch {
DispatchQueue.main.async {
self.showToast(error.localizedDescription)
}
showToast(error.localizedDescription)
}
}
}
Expand Down
55 changes: 26 additions & 29 deletions FlowCrypt/Extensions/UIViewController+Spinner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// Created by Roma Sosnovsky on 25/10/21
// Copyright © 2017-present FlowCrypt a. s. All rights reserved.
//

import MBProgressHUD
import UIKit

Expand All @@ -14,47 +14,44 @@ extension UIViewController {
MBProgressHUD.forView(view) ?? MBProgressHUD.showAdded(to: view, animated: true)
}

@MainActor
func showSpinner(_ message: String = "loading_title".localized, isUserInteractionEnabled: Bool = false) {
DispatchQueue.main.async {
guard self.view.subviews.first(where: { $0 is MBProgressHUD }) == nil else {
// hud is already shown
return
}
self.view.isUserInteractionEnabled = isUserInteractionEnabled

let spinner = MBProgressHUD.showAdded(to: self.view, animated: true)
spinner.label.text = message
spinner.isUserInteractionEnabled = isUserInteractionEnabled
guard self.view.subviews.first(where: { $0 is MBProgressHUD }) == nil else {
// hud is already shown
return
}
self.view.isUserInteractionEnabled = isUserInteractionEnabled

let spinner = MBProgressHUD.showAdded(to: self.view, animated: true)
spinner.label.text = message
spinner.isUserInteractionEnabled = isUserInteractionEnabled
}

@MainActor
func updateSpinner(label: String = "compose_uploading".localized,
progress: Float? = nil,
systemImageName: String? = nil) {
DispatchQueue.main.async {
if let progress = progress {
if progress >= 1, let imageName = systemImageName {
self.updateSpinner(label: "compose_sent".localized,
systemImageName: imageName)
} else {
self.showProgressHUD(progress: progress, label: label)
}
} else if let imageName = systemImageName {
self.showProgressHUDWithCustomImage(imageName: imageName, label: label)
if let progress = progress {
if progress >= 1, let imageName = systemImageName {
self.updateSpinner(label: "compose_sent".localized,
systemImageName: imageName)
} else {
self.currentProgressHUD.mode = .indeterminate
self.currentProgressHUD.label.text = label
self.showProgressHUD(progress: progress, label: label)
}
} else if let imageName = systemImageName {
self.showProgressHUDWithCustomImage(imageName: imageName, label: label)
} else {
self.currentProgressHUD.mode = .indeterminate
self.currentProgressHUD.label.text = label
}
}

@MainActor
func hideSpinner() {
DispatchQueue.main.async {
self.view.subviews
.compactMap { $0 as? MBProgressHUD }
.forEach { $0.hide(animated: true) }
self.view.isUserInteractionEnabled = true
}
self.view.subviews
.compactMap { $0 as? MBProgressHUD }
.forEach { $0.hide(animated: true) }
self.view.isUserInteractionEnabled = true
}
}

Expand Down
Loading