mirror of
https://github.com/ProtonMail/ios-mail.git
synced 2026-06-14 09:54:45 +00:00
Streamline DraftPresenter interface
This commit is contained in:
committed by
MargeBot
parent
61b7ab4842
commit
9e34499739
@@ -508,9 +508,11 @@ extension MailboxModel {
|
||||
|
||||
func createDraft() {
|
||||
Task {
|
||||
await draftPresenter.openNewDraft(onError: {
|
||||
toast = .error(message: $0.localizedDescription)
|
||||
})
|
||||
do {
|
||||
try await draftPresenter.openNewDraft()
|
||||
} catch {
|
||||
toast = .error(message: error.localizedDescription)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,9 +44,9 @@ struct DraftPresenter: ContactsDraftPresenter {
|
||||
self.undoScheduleSendProvider = undoScheduleSendProvider
|
||||
}
|
||||
|
||||
func openNewDraft(onError: (DraftOpenError) -> Void) async {
|
||||
func openNewDraft() async throws(DraftOpenError) {
|
||||
AppLogger.log(message: "open new draft", category: .composer)
|
||||
await openNewDraft(createMode: .empty, onError: onError)
|
||||
try await openNewDraft(createMode: .empty, updateDraft: .none)
|
||||
}
|
||||
|
||||
func openDraft(withId messageId: ID, lastScheduledTime: UInt64? = nil) {
|
||||
@@ -54,7 +54,7 @@ struct DraftPresenter: ContactsDraftPresenter {
|
||||
draftToPresentSubject.send(.openDraftId(messageId: messageId, lastScheduledTime: lastScheduledTime))
|
||||
}
|
||||
|
||||
func openDraft(with recipient: SingleRecipientEntry) async throws {
|
||||
func openDraft(with recipient: SingleRecipientEntry) async throws(DraftOpenError) {
|
||||
AppLogger.log(message: "open new draft with single recipient", category: .composer)
|
||||
|
||||
try await openNewEmptyDraft { toRecipients in
|
||||
@@ -62,7 +62,7 @@ struct DraftPresenter: ContactsDraftPresenter {
|
||||
}
|
||||
}
|
||||
|
||||
func openDraft(with group: ContactGroupItem) async throws {
|
||||
func openDraft(with group: ContactGroupItem) async throws(DraftOpenError) {
|
||||
AppLogger.log(message: "open new draft with contact group details", category: .composer)
|
||||
|
||||
try await openNewEmptyDraft { toRecipients in
|
||||
@@ -125,15 +125,9 @@ struct DraftPresenter: ContactsDraftPresenter {
|
||||
try await openNewDraft(createMode: .fromIosShareExtension, updateDraft: .none)
|
||||
}
|
||||
|
||||
func handleReplyAction(for messageId: ID, action: ReplyAction, onError: (DraftOpenError) -> Void) async {
|
||||
switch action {
|
||||
case .reply:
|
||||
await openReplyDraft(for: messageId, onError: onError)
|
||||
case .replyAll:
|
||||
await openReplyAllDraft(for: messageId, onError: onError)
|
||||
case .forward:
|
||||
await openForwardDraft(for: messageId, onError: onError)
|
||||
}
|
||||
func handleReplyAction(for messageId: ID, action: ReplyAction) async throws(DraftOpenError) {
|
||||
AppLogger.log(message: action.logDescription, category: .composer)
|
||||
try await openNewDraft(createMode: action.createMode(messageId: messageId), updateDraft: .none)
|
||||
}
|
||||
|
||||
func undoSentMessageAndOpenDraft(for messageId: ID) async throws(DraftUndoSendError) {
|
||||
@@ -152,32 +146,6 @@ struct DraftPresenter: ContactsDraftPresenter {
|
||||
|
||||
extension DraftPresenter {
|
||||
|
||||
private func openReplyDraft(for messageId: ID, onError: (DraftOpenError) -> Void) async {
|
||||
AppLogger.log(message: "open reply draft", category: .composer)
|
||||
await openNewDraft(createMode: .reply(messageId), onError: onError)
|
||||
}
|
||||
|
||||
private func openReplyAllDraft(for messageId: ID, onError: (DraftOpenError) -> Void) async {
|
||||
AppLogger.log(message: "open reply all draft", category: .composer)
|
||||
await openNewDraft(createMode: .replyAll(messageId), onError: onError)
|
||||
}
|
||||
|
||||
private func openForwardDraft(for messageId: ID, onError: (DraftOpenError) -> Void) async {
|
||||
AppLogger.log(message: "open forward draft", category: .composer)
|
||||
await openNewDraft(createMode: .forward(messageId), onError: onError)
|
||||
}
|
||||
|
||||
private func openNewDraft(
|
||||
createMode: DraftCreateMode,
|
||||
onError: (DraftOpenError) -> Void
|
||||
) async {
|
||||
do {
|
||||
try await openNewDraft(createMode: createMode, updateDraft: .none)
|
||||
} catch {
|
||||
onError(error)
|
||||
}
|
||||
}
|
||||
|
||||
private func openNewDraft(
|
||||
createMode: DraftCreateMode,
|
||||
updateDraft: ((Draft) -> Void)?
|
||||
@@ -192,7 +160,7 @@ extension DraftPresenter {
|
||||
}
|
||||
}
|
||||
|
||||
private func openNewEmptyDraft(updateToRecipients: @escaping (ComposerRecipientList) -> Void) async throws {
|
||||
private func openNewEmptyDraft(updateToRecipients: @escaping (ComposerRecipientList) -> Void) async throws(DraftOpenError) {
|
||||
let updateDraft: (Draft) -> Void = { draft in
|
||||
updateToRecipients(draft.toRecipients())
|
||||
}
|
||||
@@ -202,6 +170,24 @@ extension DraftPresenter {
|
||||
|
||||
}
|
||||
|
||||
private extension ReplyAction {
|
||||
var logDescription: String {
|
||||
switch self {
|
||||
case .reply: "open reply draft"
|
||||
case .replyAll: "open reply all draft"
|
||||
case .forward: "open forward draft"
|
||||
}
|
||||
}
|
||||
|
||||
func createMode(messageId: ID) -> DraftCreateMode {
|
||||
switch self {
|
||||
case .reply: .reply(messageId)
|
||||
case .replyAll: .replyAll(messageId)
|
||||
case .forward: .forward(messageId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension DraftPresenter {
|
||||
|
||||
static func dummy(
|
||||
|
||||
@@ -772,11 +772,11 @@ extension ConversationDetailModel {
|
||||
|
||||
private func onReplyAction(messageId: ID, action: ReplyAction, toastStateStore: ToastStateStore) {
|
||||
Task {
|
||||
await draftPresenter.handleReplyAction(
|
||||
for: messageId, action: action,
|
||||
onError: { error in
|
||||
toastStateStore.present(toast: .error(message: error.localizedDescription))
|
||||
})
|
||||
do {
|
||||
try await draftPresenter.handleReplyAction(for: messageId, action: action)
|
||||
} catch {
|
||||
toastStateStore.present(toast: .error(message: error.localizedDescription))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ import XCTest
|
||||
|
||||
final class DraftPresenterTests: BaseTestCase, @unchecked Sendable {
|
||||
private var sut: DraftPresenter!
|
||||
private let emptyErrorCallback: (DraftOpenError) -> Void = { _ in }
|
||||
private var cancellables: Set<AnyCancellable>!
|
||||
|
||||
override func setUp() {
|
||||
@@ -59,11 +58,11 @@ final class DraftPresenterTests: BaseTestCase, @unchecked Sendable {
|
||||
// MARK: openNewDraft
|
||||
|
||||
@MainActor
|
||||
func testOpenNewDraft_whenDraftIsCreated_itShouldPublishADraftToPresent() async {
|
||||
func testOpenNewDraft_whenDraftIsCreated_itShouldPublishADraftToPresent() async throws {
|
||||
var capturedDraftToPresent: [DraftToPresent] = []
|
||||
sut.draftToPresent.sink { capturedDraftToPresent.append($0) }.store(in: &cancellables)
|
||||
|
||||
await sut.openNewDraft(onError: emptyErrorCallback)
|
||||
try await sut.openNewDraft()
|
||||
XCTAssertEqual(capturedDraftToPresent.count, 1)
|
||||
}
|
||||
|
||||
@@ -73,9 +72,12 @@ final class DraftPresenterTests: BaseTestCase, @unchecked Sendable {
|
||||
var capturedDraftToPresent: [DraftToPresent] = []
|
||||
sut.draftToPresent.sink { capturedDraftToPresent.append($0) }.store(in: &cancellables)
|
||||
|
||||
await sut.openNewDraft(onError: { error in
|
||||
do {
|
||||
try await sut.openNewDraft()
|
||||
XCTFail("Expected error")
|
||||
} catch {
|
||||
XCTAssertEqual(error, .other(.network))
|
||||
})
|
||||
}
|
||||
XCTAssertEqual(capturedDraftToPresent.count, 0)
|
||||
}
|
||||
|
||||
@@ -107,12 +109,13 @@ final class DraftPresenterTests: BaseTestCase, @unchecked Sendable {
|
||||
|
||||
let recipient = SingleRecipientEntry(name: "John Maxon", email: "john.maxon@pm.me")
|
||||
|
||||
await XCTAssertAsyncThrowsError(try await sut.openDraft(with: recipient)) { error in
|
||||
let draftOpenError = error as? DraftOpenError
|
||||
|
||||
XCTAssertEqual(capturedDraftToPresent.count, 0)
|
||||
XCTAssertEqual(draftOpenError, .reason(.messageIsNotADraft))
|
||||
do {
|
||||
try await sut.openDraft(with: recipient)
|
||||
XCTFail("Expected error")
|
||||
} catch {
|
||||
XCTAssertEqual(error, .reason(.messageIsNotADraft))
|
||||
}
|
||||
XCTAssertEqual(capturedDraftToPresent.count, 0)
|
||||
}
|
||||
|
||||
// MARK: - Open new draft with contact group
|
||||
@@ -177,12 +180,13 @@ final class DraftPresenterTests: BaseTestCase, @unchecked Sendable {
|
||||
]
|
||||
)
|
||||
|
||||
await XCTAssertAsyncThrowsError(try await sut.openDraft(with: group)) { error in
|
||||
let draftOpenError = error as? DraftOpenError
|
||||
|
||||
XCTAssertEqual(capturedDraftToPresent.count, 0)
|
||||
XCTAssertEqual(draftOpenError, .reason(.messageDoesNotExist))
|
||||
do {
|
||||
try await sut.openDraft(with: group)
|
||||
XCTFail("Expected error")
|
||||
} catch {
|
||||
XCTAssertEqual(error, .reason(.messageDoesNotExist))
|
||||
}
|
||||
XCTAssertEqual(capturedDraftToPresent.count, 0)
|
||||
}
|
||||
|
||||
// MARK: - Open new draft with mailto:
|
||||
@@ -218,12 +222,12 @@ final class DraftPresenterTests: BaseTestCase, @unchecked Sendable {
|
||||
// MARK: handleReplyAction
|
||||
|
||||
@MainActor
|
||||
func testHandleReplyAction_whenDraftForMessageReplyIsCreated_itShouldPublishADraftToPresent() async {
|
||||
func testHandleReplyAction_whenDraftForMessageReplyIsCreated_itShouldPublishADraftToPresent() async throws {
|
||||
var capturedDraftToPresent: [DraftToPresent] = []
|
||||
sut.draftToPresent.sink { capturedDraftToPresent.append($0) }.store(in: &cancellables)
|
||||
|
||||
let dummyMessageId: ID = .random()
|
||||
await sut.handleReplyAction(for: dummyMessageId, action: .reply, onError: emptyErrorCallback)
|
||||
try await sut.handleReplyAction(for: dummyMessageId, action: .reply)
|
||||
XCTAssertEqual(capturedDraftToPresent.count, 1)
|
||||
}
|
||||
|
||||
@@ -234,11 +238,12 @@ final class DraftPresenterTests: BaseTestCase, @unchecked Sendable {
|
||||
sut.draftToPresent.sink { capturedDraftToPresent.append($0) }.store(in: &cancellables)
|
||||
|
||||
let dummyMessageId: ID = .random()
|
||||
await sut.handleReplyAction(
|
||||
for: dummyMessageId, action: .reply,
|
||||
onError: { error in
|
||||
XCTAssertEqual(error, .other(.network))
|
||||
})
|
||||
do {
|
||||
try await sut.handleReplyAction(for: dummyMessageId, action: .reply)
|
||||
XCTFail("Expected error")
|
||||
} catch {
|
||||
XCTAssertEqual(error, .other(.network))
|
||||
}
|
||||
XCTAssertEqual(capturedDraftToPresent.count, 0)
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,6 @@ public final class ShareScreenModel: ObservableObject {
|
||||
},
|
||||
makeNewDraft: {
|
||||
try await DraftStubWriter().createDraftStub(basedOn: $1)
|
||||
// TODO: do not create the draft here, open composer faster and load the draft there
|
||||
return try await newDraft(session: $0, createMode: .fromIosShareExtension).get()
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user