KasztelanKarta/Kasztelan/MessagesView.swift

81 lines
3.5 KiB
Swift

import Foundation
import SwiftUI
struct MessagesView: View {
@EnvironmentObject private var model: AppModel
var body: some View {
ScrollView {
LazyVStack(alignment: .leading, spacing: 12) {
Text(model.text("Wiadomości", "Messages")).font(.largeTitle.bold())
Text(model.text("Najnowsze wiadomości są wyświetlane na górze.", "The newest messages appear first."))
.foregroundStyle(.secondary)
.padding(.bottom, 4)
if model.messages.isEmpty {
VStack(spacing: 12) {
Image(systemName: "sparkles").font(.largeTitle).foregroundStyle(KTheme.orange)
Text(model.text("Nie masz jeszcze żadnych wiadomości.", "You do not have any messages yet."))
.multilineTextAlignment(.center)
}
.frame(maxWidth: .infinity)
.kasztelanPanel()
} else {
ForEach(model.messages) { message in
messageCard(message)
}
}
}
.padding(20)
}
.background(.clear)
.toolbar { AppToolbar() }
.toolbarBackground(.hidden, for: .navigationBar)
.refreshable { await model.refresh() }
.task { await model.refresh() }
}
private func messageCard(_ message: KasztelanMessage) -> some View {
VStack(alignment: .leading, spacing: 10) {
HStack(alignment: .top) {
Circle().fill(KTheme.orange).frame(width: 9, height: 9).padding(.top, 6)
VStack(alignment: .leading, spacing: 3) {
Text(message.title.isEmpty ? "Kasztelan" : message.title).font(.headline)
Text(messageDate(message.sentAt)).font(.caption).foregroundStyle(.secondary)
}
Spacer()
Button(role: .destructive) { model.deleteMessage(id: message.id) } label: {
Image(systemName: "xmark.circle.fill").foregroundStyle(.secondary)
}
.accessibilityLabel(model.text("Usuń wiadomość", "Delete message"))
}
Text(linkedMessage(message.text))
.tint(KTheme.orange)
.fixedSize(horizontal: false, vertical: true)
.textSelection(.enabled)
}
.kasztelanPanel()
}
private func messageDate(_ seconds: Int) -> String {
guard seconds > 0 else { return model.text("Teraz", "Now") }
let formatter = DateFormatter()
formatter.dateFormat = model.language == .pl ? "dd.MM.yyyy HH:mm" : "dd/MM/yyyy HH:mm"
return formatter.string(from: Date(timeIntervalSince1970: TimeInterval(seconds)))
}
private func linkedMessage(_ value: String) -> AttributedString {
let result = NSMutableAttributedString(string: value)
guard let detector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else {
return AttributedString(value)
}
let fullRange = NSRange(value.startIndex..<value.endIndex, in: value)
detector.enumerateMatches(in: value, options: [], range: fullRange) { match, _, _ in
guard let match, let url = match.url,
let scheme = url.scheme?.lowercased(),
scheme == "http" || scheme == "https" else { return }
result.addAttribute(.link, value: url, range: match.range)
}
return AttributedString(result)
}
}