import Foundation struct SearchDataPayload: Decodable { let users: [UserSearchResult] } struct UserSearchResult: Decodable, Identifiable { let userId: UUID let login: String let fullName: String? let customName: String? let createdAt: Date? let profile: SearchProfile? var id: UUID { userId } } struct SearchProfile: Decodable { let userId: UUID let login: String? let fullName: String? let customName: String? let bio: String? let lastSeen: Int? let createdAt: Date? } extension UserSearchResult { var displayName: String { if let custom = preferredCustomName { return custom } if let official = officialFullName { return official } if let profileCustom = trimmed(profile?.customName) { return profileCustom } if let profileFull = trimmed(profile?.fullName) { return profileFull } return loginHandle } var secondaryText: String? { // Отдельное поле для совместимости с существующими вызовами if let official = officialFullName, official != displayName { return official } if let profileLogin = trimmed(profile?.login), profileLogin != login { return "@\(profileLogin)" } return nil } var officialFullName: String? { trimmed(fullName) ?? trimmed(profile?.fullName) } var preferredCustomName: String? { trimmed(customName) ?? trimmed(profile?.customName) } var loginHandle: String { "@\(login)" } var secondaryLabelForSearch: String? { if let official = officialFullName { if let custom = preferredCustomName, custom != official { return custom } if official != loginHandle { return loginHandle } } if let secondary = secondaryText, secondary != displayName { return secondary } if displayName != loginHandle { return loginHandle } return nil } var avatarInitial: String { let source = officialFullName ?? preferredCustomName ?? trimmed(profile?.login) ?? login if let character = source.first(where: { !$0.isWhitespace && $0 != "@" }) { return String(character).uppercased() } return "?" } var isOfficial: Bool { officialFullName != nil } private func trimmed(_ value: String?) -> String? { guard let value = value?.trimmingCharacters(in: .whitespacesAndNewlines), !value.isEmpty else { return nil } return value } }