fix button when delete accounts

This commit is contained in:
cheykrym 2025-12-09 22:44:25 +03:00
parent fd96ca7cbc
commit 520f63f74a
5 changed files with 98 additions and 39 deletions

View File

@ -32,7 +32,7 @@ struct MessagePayload: Decodable {
struct BlockedUserInfo: Decodable { struct BlockedUserInfo: Decodable {
let userId: UUID let userId: UUID
let login: String let login: String?
let fullName: String? let fullName: String?
let customName: String? let customName: String?
let createdAt: Date let createdAt: Date

View File

@ -18,7 +18,7 @@ enum ContactsServiceError: LocalizedError {
struct ContactPayload: Decodable { struct ContactPayload: Decodable {
let userId: UUID let userId: UUID
let login: String let login: String?
let fullName: String? let fullName: String?
let customName: String? let customName: String?
let friendCode: Bool let friendCode: Bool

View File

@ -1377,6 +1377,7 @@
} }
}, },
"Неизвестный пользователь" : { "Неизвестный пользователь" : {
"comment" : "Deleted user display name",
"localizations" : { "localizations" : {
"en" : { "en" : {
"stringUnit" : { "stringUnit" : {

View File

@ -32,6 +32,7 @@ struct ContactsTab: View {
.contentShape(Rectangle()) .contentShape(Rectangle())
} }
.buttonStyle(.plain) .buttonStyle(.plain)
// .disabled(contact.isDeleted)
.contextMenu { .contextMenu {
Button { Button {
handleContactAction(.edit, for: contact) handleContactAction(.edit, for: contact)
@ -41,6 +42,7 @@ struct ContactsTab: View {
systemImage: "square.and.pencil" systemImage: "square.and.pencil"
) )
} }
// .disabled(contact.isDeleted)
Button { Button {
handleContactAction(.block, for: contact) handleContactAction(.block, for: contact)
@ -50,6 +52,7 @@ struct ContactsTab: View {
systemImage: "hand.raised.fill" systemImage: "hand.raised.fill"
) )
} }
// .disabled(contact.isDeleted)
Button(role: .destructive) { Button(role: .destructive) {
handleContactAction(.delete, for: contact) handleContactAction(.delete, for: contact)
@ -59,6 +62,7 @@ struct ContactsTab: View {
systemImage: "trash" systemImage: "trash"
) )
} }
// .disabled(contact.isDeleted)
} }
.listRowInsets(EdgeInsets(top: 0, leading: 12, bottom: 0, trailing: 12)) .listRowInsets(EdgeInsets(top: 0, leading: 12, bottom: 0, trailing: 12))
.onAppear { .onAppear {
@ -238,19 +242,35 @@ private struct ContactRow: View {
var body: some View { var body: some View {
HStack(alignment: .top, spacing: 10) { HStack(alignment: .top, spacing: 10) {
Circle() Circle()
.fill(Color.accentColor.opacity(0.15)) .fill(contact.isDeleted ? Color(.systemGray5) : Color.accentColor.opacity(0.15))
.frame(width: 40, height: 40) .frame(width: 40, height: 40)
.overlay( .overlay(
Text(contact.initials) Group {
.font(.headline) if contact.isDeleted {
.foregroundColor(.accentColor) Image(systemName: "person.slash")
.font(.headline)
.foregroundColor(Color(.systemGray2))
} else {
Text(contact.initials)
.font(.headline)
.foregroundColor(.accentColor)
}
}
) )
VStack(alignment: .leading, spacing: 3) { VStack(alignment: .leading, spacing: 3) {
HStack(alignment: .firstTextBaseline) { HStack(alignment: .firstTextBaseline) {
Text(contact.displayName) if #available(iOS 16.0, *) {
.font(.subheadline.weight(.semibold)) Text(contact.displayName)
.foregroundColor(.primary) .font(.subheadline.weight(.semibold))
.foregroundColor(.primary)
.strikethrough(contact.isDeleted, color: .secondary)
} else {
Text(contact.displayName)
.font(.subheadline.weight(.semibold))
.foregroundColor(.primary)
.strikethrough(contact.isDeleted)
}
Spacer() Spacer()
Text(contact.formattedCreatedAt) Text(contact.formattedCreatedAt)
.font(.caption2) .font(.caption2)
@ -285,7 +305,7 @@ private struct ContactRow: View {
private struct Contact: Identifiable, Equatable { private struct Contact: Identifiable, Equatable {
let id: UUID let id: UUID
let login: String let login: String?
let fullName: String? let fullName: String?
let customName: String? let customName: String?
let friendCode: Bool let friendCode: Bool
@ -294,7 +314,13 @@ private struct Contact: Identifiable, Equatable {
let displayName: String let displayName: String
let handle: String? let handle: String?
var isDeleted: Bool {
login?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ?? true
}
var initials: String { var initials: String {
if isDeleted { return "" }
let nameSource: String? let nameSource: String?
if let customName, !customName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { if let customName, !customName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
nameSource = customName nameSource = customName
@ -312,7 +338,7 @@ private struct Contact: Identifiable, Equatable {
} }
} }
return String(login.prefix(1)).uppercased() return String(login!.prefix(1)).uppercased()
} }
var formattedCreatedAt: String { var formattedCreatedAt: String {
@ -327,18 +353,25 @@ private struct Contact: Identifiable, Equatable {
self.friendCode = payload.friendCode self.friendCode = payload.friendCode
self.createdAt = payload.createdAt self.createdAt = payload.createdAt
if let customName = payload.customName, !customName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { let isUserDeleted = payload.login?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ?? true
self.displayName = customName
} else if let fullName = payload.fullName, !fullName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
self.displayName = fullName
} else {
self.displayName = payload.login
}
if !payload.login.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { if isUserDeleted {
self.handle = "@\(payload.login)" self.displayName = NSLocalizedString("Неизвестный пользователь", comment: "Deleted user display name")
} else {
self.handle = nil self.handle = nil
} else {
if let customName = payload.customName, !customName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
self.displayName = customName
} else if let fullName = payload.fullName, !fullName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
self.displayName = fullName
} else {
self.displayName = payload.login!
}
if let login = payload.login, !login.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
self.handle = "@\(login)"
} else {
self.handle = nil
}
} }
} }

View File

@ -102,16 +102,31 @@ struct BlockedUsersView: View {
private func userRow(_ user: BlockedUser, index: Int) -> some View { private func userRow(_ user: BlockedUser, index: Int) -> some View {
HStack(spacing: 12) { HStack(spacing: 12) {
Circle() Circle()
.fill(Color.accentColor.opacity(0.15)) .fill(user.isDeleted ? Color(.systemGray5) : Color.accentColor.opacity(0.15))
.frame(width: 44, height: 44) .frame(width: 44, height: 44)
.overlay( .overlay(
Text(user.initials) Group {
.font(.headline) if user.isDeleted {
.foregroundColor(.accentColor) Image(systemName: "person.slash")
.font(.headline)
.foregroundColor(Color(.systemGray2))
} else {
Text(user.initials)
.font(.headline)
.foregroundColor(.accentColor)
}
}
) )
VStack(alignment: .leading, spacing: 4) { VStack(alignment: .leading, spacing: 4) {
Text(user.displayName) if #available(iOS 16.0, *) {
.font(.body) Text(user.displayName)
.font(.body)
.strikethrough(user.isDeleted, color: .secondary)
} else {
Text(user.displayName)
.font(.body)
.strikethrough(user.isDeleted)
}
if let handle = user.handle { if let handle = user.handle {
Text(handle) Text(handle)
.font(.caption) .font(.caption)
@ -128,6 +143,7 @@ struct BlockedUsersView: View {
} label: { } label: {
Label(NSLocalizedString("Разблокировать", comment: ""), systemImage: "person.crop.circle.badge.xmark") Label(NSLocalizedString("Разблокировать", comment: ""), systemImage: "person.crop.circle.badge.xmark")
} }
// .disabled(removingUserIds.contains(user.id) || user.isDeleted)
.disabled(removingUserIds.contains(user.id)) .disabled(removingUserIds.contains(user.id))
} }
.onAppear { .onAppear {
@ -218,7 +234,7 @@ struct BlockedUsersView: View {
private struct BlockedUser: Identifiable, Equatable { private struct BlockedUser: Identifiable, Equatable {
let id: UUID let id: UUID
let login: String let login: String?
let fullName: String? let fullName: String?
let customName: String? let customName: String?
let createdAt: Date let createdAt: Date
@ -226,7 +242,13 @@ private struct BlockedUser: Identifiable, Equatable {
private(set) var displayName: String private(set) var displayName: String
private(set) var handle: String? private(set) var handle: String?
var isDeleted: Bool {
login?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ?? true
}
var initials: String { var initials: String {
if isDeleted { return "" }
let nameSource: String? let nameSource: String?
if let customName, !customName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { if let customName, !customName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
nameSource = customName nameSource = customName
@ -244,7 +266,7 @@ private struct BlockedUser: Identifiable, Equatable {
} }
} }
return String(login.prefix(1)).uppercased() return String(login!.prefix(1)).uppercased()
} }
init(payload: BlockedUserInfo) { init(payload: BlockedUserInfo) {
@ -254,18 +276,21 @@ private struct BlockedUser: Identifiable, Equatable {
self.customName = payload.customName self.customName = payload.customName
self.createdAt = payload.createdAt self.createdAt = payload.createdAt
if let customName = payload.customName, !customName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { let isUserDeleted = payload.login?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ?? true
self.displayName = customName
} else if let fullName = payload.fullName, !fullName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
self.displayName = fullName
} else {
self.displayName = payload.login
}
if !payload.login.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { if isUserDeleted {
self.handle = "@\(payload.login)" self.displayName = NSLocalizedString("Неизвестный пользователь", comment: "Deleted user display name")
} else {
self.handle = nil self.handle = nil
} else {
if let customName = payload.customName, !customName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
self.displayName = customName
} else if let fullName = payload.fullName, !fullName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
self.displayName = fullName
} else {
self.displayName = payload.login!
}
self.handle = "@\(payload.login!)"
} }
} }
} }