Alpha 2 Update
This commit is contained in:
committed by
Dr. Michael Kübler
parent
223bf746ef
commit
8e95cc3acd
@@ -0,0 +1,98 @@
|
||||
import SwiftUI
|
||||
|
||||
enum MessageCommand {
|
||||
case open, reply, forward, delete, read, unread
|
||||
}
|
||||
|
||||
struct ComposeDraft: Identifiable {
|
||||
let id = UUID()
|
||||
var accountID: UUID?
|
||||
var recipient = ""
|
||||
var subject = ""
|
||||
var body = ""
|
||||
var attachments: [MailAttachment] = []
|
||||
var isReply = false
|
||||
|
||||
static func from(_ message: MailMessage, accountID: UUID?, forwarding: Bool) -> ComposeDraft {
|
||||
let source = message.replyTo.isEmpty ? message.sender : message.replyTo
|
||||
let recipient: String
|
||||
if let start = source.firstIndex(of: "<"), let end = source[start...].firstIndex(of: ">") {
|
||||
recipient = String(source[source.index(after: start)..<end])
|
||||
} else { recipient = source }
|
||||
return ComposeDraft(accountID: accountID, recipient: forwarding ? "" : recipient,
|
||||
subject: (forwarding ? "Fwd: " : "Re: ") + message.subject,
|
||||
body: "\n\n" + (forwarding ? "Weitergeleitete Nachricht" : "Am \(message.date.formatted()) schrieb \(message.sender):") +
|
||||
"\nVon: \(message.sender)\nAn: \(message.recipient)\nBetreff: \(message.subject)\n\n" +
|
||||
message.body.components(separatedBy: "\n").map { forwarding ? $0 : "> " + $0 }.joined(separator: "\n"),
|
||||
attachments: forwarding ? message.attachments : [], isReply: !forwarding)
|
||||
}
|
||||
}
|
||||
|
||||
struct MessageActionButtons: View {
|
||||
let action: (MessageCommand) -> Void
|
||||
var body: some View {
|
||||
Button("Löschen…", systemImage: "trash") { action(.delete) }
|
||||
Button("Antworten…", systemImage: "arrowshape.turn.up.left") { action(.reply) }
|
||||
Button("Weiterleiten", systemImage: "arrowshape.turn.up.right") { action(.forward) }
|
||||
}
|
||||
}
|
||||
|
||||
struct MessageDetailWindow: View {
|
||||
let store: MailStore
|
||||
let messageID: String?
|
||||
@State private var draft: ComposeDraft?
|
||||
@State private var confirmingDelete = false
|
||||
@AppStorage("mailDeleteConfirmation") private var deleteConfirmation: MailDeleteConfirmation = .always
|
||||
|
||||
private var message: MailMessage? {
|
||||
_ = store.archiveRevision
|
||||
return messageID.flatMap { store.message(id: $0) }
|
||||
}
|
||||
var body: some View {
|
||||
MessageReader(message: message)
|
||||
.frame(minWidth: 600, minHeight: 450)
|
||||
.navigationTitle(message?.subject ?? "Nachricht")
|
||||
.toolbar {
|
||||
MessageActionButtons { command in
|
||||
guard let message else { return }
|
||||
switch command {
|
||||
case .reply, .forward:
|
||||
draft = .from(message, accountID: store.accountID(for: message.id), forwarding: command == .forward)
|
||||
case .delete:
|
||||
if deleteConfirmation.isRequired(count: 1) { confirmingDelete = true }
|
||||
else { Task { await store.deleteMessages(ids: [message.id]) } }
|
||||
default: break
|
||||
}
|
||||
}.disabled(message == nil || store.isBusy)
|
||||
}
|
||||
.sheet(item: $draft) { ComposeView(store: store, draft: $0) }
|
||||
.alert("Nachricht löschen?", isPresented: $confirmingDelete) {
|
||||
Button("Abbrechen", role: .cancel) {}
|
||||
Button("Löschen", role: .destructive) {
|
||||
if let messageID { Task { await store.deleteMessages(ids: [messageID]) } }
|
||||
}
|
||||
} message: {
|
||||
Text(store.selectionContainsTrash([messageID ?? ""])
|
||||
? "Die Nachricht wird auch auf dem Server endgültig gelöscht."
|
||||
: "Die Nachricht wird auch auf dem Server in den Papierkorb verschoben.")
|
||||
}
|
||||
.task(id: messageID) {
|
||||
if let message, !message.isRead { await store.setRead(ids: [message.id], read: true) }
|
||||
}
|
||||
.alert("MikeMail", isPresented: Binding(get: { store.error != nil }, set: { if !$0 { store.error = nil } })) {
|
||||
Button("OK") { store.error = nil }
|
||||
} message: { Text(store.error ?? "") }
|
||||
}
|
||||
}
|
||||
|
||||
struct UnreadBadge: View {
|
||||
let count: Int
|
||||
var body: some View {
|
||||
if count > 0 {
|
||||
Text(count.formatted()).font(.caption.bold()).monospacedDigit()
|
||||
.padding(.horizontal, 6).padding(.vertical, 2)
|
||||
.background(.quaternary, in: Capsule())
|
||||
.accessibilityLabel("\(count) ungelesen")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user