Refactor code structure for improved readability and maintainability

This commit is contained in:
2026-04-19 00:46:00 +02:00
parent ce19d00de3
commit a11d88d365
14 changed files with 2947 additions and 76 deletions
+10 -2
View File
@@ -13,6 +13,7 @@ final class AppViewModel {
var composeDraft = ComposeDraft()
var threads: [MailThread] = []
var isLoading = false
var isSending = false
var errorMessage: String?
var mailboxNavigationToken = UUID()
var threadNavigationToken = UUID()
@@ -158,6 +159,7 @@ final class AppViewModel {
func beginBackendControl() async {
guard !isListeningForBackendCommands else { return }
isListeningForBackendCommands = true
defer { isListeningForBackendCommands = false }
for await command in controlService.commands() {
apply(command: command)
@@ -206,17 +208,23 @@ final class AppViewModel {
}
}
func sendCurrentDraft() async {
func sendCurrentDraft() async -> Bool {
guard !isSending else { return false }
let draft = composeDraft
isComposing = false
isSending = true
defer { isSending = false }
do {
let sentThread = try await service.send(draft: draft)
threads.insert(sentThread, at: 0)
selectedMailbox = .sent
openThread(withID: sentThread.id)
isComposing = false
return true
} catch {
errorMessage = "Unable to send message."
return false
}
}
@@ -919,6 +919,7 @@ private struct ComposeView: View {
ComposeFieldCard(title: "Subject") {
TextField("What's this about?", text: $model.composeDraft.subject)
.textFieldStyle(.plain)
.disabled(model.isSending)
.accessibilityIdentifier("compose.subject")
}
@@ -926,6 +927,7 @@ private struct ComposeView: View {
TextEditor(text: $model.composeDraft.body)
.scrollContentBackground(.hidden)
.frame(minHeight: 240)
.disabled(model.isSending)
.accessibilityIdentifier("compose.body")
}
@@ -937,23 +939,23 @@ private struct ComposeView: View {
}
}
.navigationTitle("Compose")
.navigationBarTitleDisplayMode(usesCompactComposeLayout ? .inline : .automatic)
.composeNavigationTitleDisplayMode(isCompact: usesCompactComposeLayout)
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button("Cancel") {
dismiss()
}
.disabled(model.isSending)
.accessibilityIdentifier("compose.cancel")
}
ToolbarItem(placement: .confirmationAction) {
Button("Send") {
Button(model.isSending ? "Sending…" : "Send") {
Task {
await model.sendCurrentDraft()
dismiss()
_ = await model.sendCurrentDraft()
}
}
.disabled(model.composeDraft.to.isEmpty || model.composeDraft.body.isEmpty)
.disabled(model.isSending || model.composeDraft.to.isEmpty || model.composeDraft.body.isEmpty)
.accessibilityIdentifier("compose.send")
}
}
@@ -968,11 +970,13 @@ private struct ComposeView: View {
.textContentType(.emailAddress)
.keyboardType(.emailAddress)
.textInputAutocapitalization(.never)
.disabled(model.isSending)
.accessibilityIdentifier("compose.to")
#else
TextField("name@example.com", text: $model.composeDraft.to)
.textFieldStyle(.plain)
.textContentType(.emailAddress)
.disabled(model.isSending)
.accessibilityIdentifier("compose.to")
#endif
}
@@ -986,6 +990,17 @@ private struct ComposeView: View {
}
}
private extension View {
@ViewBuilder
func composeNavigationTitleDisplayMode(isCompact: Bool) -> some View {
#if os(iOS)
navigationBarTitleDisplayMode(isCompact ? .inline : .automatic)
#else
self
#endif
}
}
private struct ComposeFieldCard<Content: View>: View {
let title: String
let content: Content