add patch to search
This commit is contained in:
parent
26b8dfc71a
commit
a5b2c2702c
@ -27,28 +27,85 @@ struct SearchProfile: Decodable {
|
|||||||
|
|
||||||
extension UserSearchResult {
|
extension UserSearchResult {
|
||||||
var displayName: String {
|
var displayName: String {
|
||||||
if let customName = customName, !customName.isEmpty {
|
if let custom = preferredCustomName {
|
||||||
return customName
|
return custom
|
||||||
}
|
}
|
||||||
if let fullName = fullName, !fullName.isEmpty {
|
if let official = officialFullName {
|
||||||
return fullName
|
return official
|
||||||
}
|
}
|
||||||
if let profileName = profile?.customName, !profileName.isEmpty {
|
if let profileCustom = trimmed(profile?.customName) {
|
||||||
return profileName
|
return profileCustom
|
||||||
}
|
}
|
||||||
if let profileFullName = profile?.fullName, !profileFullName.isEmpty {
|
if let profileFull = trimmed(profile?.fullName) {
|
||||||
return profileFullName
|
return profileFull
|
||||||
}
|
}
|
||||||
return "@\(login)"
|
return loginHandle
|
||||||
}
|
}
|
||||||
|
|
||||||
var secondaryText: String? {
|
var secondaryText: String? {
|
||||||
if let fullName = fullName, !fullName.isEmpty, fullName != displayName {
|
// Отдельное поле для совместимости с существующими вызовами
|
||||||
return fullName
|
if let official = officialFullName, official != displayName {
|
||||||
|
return official
|
||||||
}
|
}
|
||||||
if let profileLogin = profile?.login, !profileLogin.isEmpty, profileLogin != login {
|
if let profileLogin = trimmed(profile?.login), profileLogin != login {
|
||||||
return "@\(profileLogin)"
|
return "@\(profileLogin)"
|
||||||
}
|
}
|
||||||
return nil
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -361,22 +361,42 @@ struct ChatsTab: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func globalSearchRow(for user: UserSearchResult) -> some View {
|
private func globalSearchRow(for user: UserSearchResult) -> some View {
|
||||||
VStack(alignment: .leading, spacing: 4) {
|
HStack(spacing: 12) {
|
||||||
Text(user.displayName)
|
Circle()
|
||||||
.font(.headline)
|
.fill(user.isOfficial ? Color.accentColor.opacity(0.85) : Color.accentColor.opacity(0.15))
|
||||||
|
.frame(width: 44, height: 44)
|
||||||
|
.overlay(
|
||||||
|
Text(user.avatarInitial)
|
||||||
|
.font(.headline)
|
||||||
|
.foregroundColor(user.isOfficial ? .white : Color.accentColor)
|
||||||
|
)
|
||||||
|
|
||||||
if user.displayName != "@\(user.login)" {
|
VStack(alignment: .leading, spacing: 4) {
|
||||||
Text("@\(user.login)")
|
HStack(spacing: 6) {
|
||||||
.font(.subheadline)
|
Text(user.displayName)
|
||||||
.foregroundColor(.secondary)
|
.fontWeight(user.isOfficial ? .semibold : .regular)
|
||||||
} else if let secondary = user.secondaryText {
|
.foregroundColor(.primary)
|
||||||
Text(secondary)
|
.lineLimit(1)
|
||||||
.font(.subheadline)
|
.truncationMode(.tail)
|
||||||
.foregroundColor(.secondary)
|
|
||||||
|
if user.isOfficial {
|
||||||
|
Image(systemName: "checkmark.seal.fill")
|
||||||
|
.foregroundColor(Color.accentColor)
|
||||||
|
.font(.caption)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let secondary = user.secondaryLabelForSearch {
|
||||||
|
Text(secondary)
|
||||||
|
.font(.footnote)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
.lineLimit(1)
|
||||||
|
.truncationMode(.tail)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
}
|
}
|
||||||
.padding(.vertical, 8)
|
.padding(.vertical, 8)
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
|
||||||
.listRowInsets(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16))
|
.listRowInsets(EdgeInsets(top: 8, leading: 16, bottom: 8, trailing: 16))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user