57 lines
1.7 KiB
Swift
57 lines
1.7 KiB
Swift
import Contacts
|
|
import SwiftUI
|
|
|
|
struct ContactRowView: View {
|
|
let contact: CNContact
|
|
var isFavorite: Bool = false
|
|
|
|
var body: some View {
|
|
HStack(spacing: 12) {
|
|
avatar
|
|
Text(displayName)
|
|
.font(.body)
|
|
Spacer(minLength: 8)
|
|
if isFavorite {
|
|
Image(systemName: "star.fill")
|
|
.foregroundStyle(.yellow)
|
|
.accessibilityLabel(Text("contacts.favorite"))
|
|
}
|
|
}
|
|
.padding(.vertical, 6)
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
.contentShape(Rectangle())
|
|
}
|
|
|
|
private var displayName: String {
|
|
CNContactFormatter.string(from: contact, style: .fullName) ?? String(localized: "contacts.no_name")
|
|
}
|
|
|
|
private var initials: String {
|
|
let given = contact.givenName.prefix(1)
|
|
let family = contact.familyName.prefix(1)
|
|
let combined = String(given + family)
|
|
return combined.isEmpty ? "?" : combined.uppercased()
|
|
}
|
|
|
|
private var avatar: some View {
|
|
Group {
|
|
if let data = contact.thumbnailImageData,
|
|
let uiImage = UIImage(data: data) {
|
|
Image(uiImage: uiImage)
|
|
.resizable()
|
|
.scaledToFill()
|
|
} else {
|
|
ZStack {
|
|
Circle()
|
|
.fill(Color(.systemGray5))
|
|
Text(initials)
|
|
.font(.subheadline.weight(.medium))
|
|
.foregroundStyle(.secondary)
|
|
}
|
|
}
|
|
}
|
|
.frame(width: 36, height: 36)
|
|
.clipShape(Circle())
|
|
}
|
|
}
|