From 520f63f74a325a85cd8b33568c2fb5d2332543ec Mon Sep 17 00:00:00 2001 From: cheykrym Date: Tue, 9 Dec 2025 22:44:25 +0300 Subject: [PATCH] fix button when delete accounts --- yobble/Network/APIModels.swift | 2 +- yobble/Network/ContactsService.swift | 2 +- yobble/Resources/Localizable.xcstrings | 1 + yobble/Views/Tab/ContactsTab.swift | 71 ++++++++++++++----- .../Views/Tab/Settings/BlockedUsersView.swift | 61 +++++++++++----- 5 files changed, 98 insertions(+), 39 deletions(-) diff --git a/yobble/Network/APIModels.swift b/yobble/Network/APIModels.swift index 2c935ca..72f9c33 100644 --- a/yobble/Network/APIModels.swift +++ b/yobble/Network/APIModels.swift @@ -32,7 +32,7 @@ struct MessagePayload: Decodable { struct BlockedUserInfo: Decodable { let userId: UUID - let login: String + let login: String? let fullName: String? let customName: String? let createdAt: Date diff --git a/yobble/Network/ContactsService.swift b/yobble/Network/ContactsService.swift index aa7d6f1..130800d 100644 --- a/yobble/Network/ContactsService.swift +++ b/yobble/Network/ContactsService.swift @@ -18,7 +18,7 @@ enum ContactsServiceError: LocalizedError { struct ContactPayload: Decodable { let userId: UUID - let login: String + let login: String? let fullName: String? let customName: String? let friendCode: Bool diff --git a/yobble/Resources/Localizable.xcstrings b/yobble/Resources/Localizable.xcstrings index a3f5df9..b57af6d 100644 --- a/yobble/Resources/Localizable.xcstrings +++ b/yobble/Resources/Localizable.xcstrings @@ -1377,6 +1377,7 @@ } }, "Неизвестный пользователь" : { + "comment" : "Deleted user display name", "localizations" : { "en" : { "stringUnit" : { diff --git a/yobble/Views/Tab/ContactsTab.swift b/yobble/Views/Tab/ContactsTab.swift index d6b28e1..248876c 100644 --- a/yobble/Views/Tab/ContactsTab.swift +++ b/yobble/Views/Tab/ContactsTab.swift @@ -32,6 +32,7 @@ struct ContactsTab: View { .contentShape(Rectangle()) } .buttonStyle(.plain) +// .disabled(contact.isDeleted) .contextMenu { Button { handleContactAction(.edit, for: contact) @@ -41,6 +42,7 @@ struct ContactsTab: View { systemImage: "square.and.pencil" ) } +// .disabled(contact.isDeleted) Button { handleContactAction(.block, for: contact) @@ -50,6 +52,7 @@ struct ContactsTab: View { systemImage: "hand.raised.fill" ) } +// .disabled(contact.isDeleted) Button(role: .destructive) { handleContactAction(.delete, for: contact) @@ -59,6 +62,7 @@ struct ContactsTab: View { systemImage: "trash" ) } +// .disabled(contact.isDeleted) } .listRowInsets(EdgeInsets(top: 0, leading: 12, bottom: 0, trailing: 12)) .onAppear { @@ -238,19 +242,35 @@ private struct ContactRow: View { var body: some View { HStack(alignment: .top, spacing: 10) { Circle() - .fill(Color.accentColor.opacity(0.15)) + .fill(contact.isDeleted ? Color(.systemGray5) : Color.accentColor.opacity(0.15)) .frame(width: 40, height: 40) .overlay( - Text(contact.initials) - .font(.headline) - .foregroundColor(.accentColor) + Group { + if contact.isDeleted { + Image(systemName: "person.slash") + .font(.headline) + .foregroundColor(Color(.systemGray2)) + } else { + Text(contact.initials) + .font(.headline) + .foregroundColor(.accentColor) + } + } ) VStack(alignment: .leading, spacing: 3) { HStack(alignment: .firstTextBaseline) { - Text(contact.displayName) - .font(.subheadline.weight(.semibold)) - .foregroundColor(.primary) + if #available(iOS 16.0, *) { + Text(contact.displayName) + .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() Text(contact.formattedCreatedAt) .font(.caption2) @@ -285,7 +305,7 @@ private struct ContactRow: View { private struct Contact: Identifiable, Equatable { let id: UUID - let login: String + let login: String? let fullName: String? let customName: String? let friendCode: Bool @@ -294,7 +314,13 @@ private struct Contact: Identifiable, Equatable { let displayName: String let handle: String? + var isDeleted: Bool { + login?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ?? true + } + var initials: String { + if isDeleted { return "" } + let nameSource: String? if let customName, !customName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { 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 { @@ -327,18 +353,25 @@ private struct Contact: Identifiable, Equatable { self.friendCode = payload.friendCode self.createdAt = payload.createdAt - 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 - } + let isUserDeleted = payload.login?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ?? true - if !payload.login.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { - self.handle = "@\(payload.login)" - } else { + if isUserDeleted { + self.displayName = NSLocalizedString("Неизвестный пользователь", comment: "Deleted user display name") 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 + } } } diff --git a/yobble/Views/Tab/Settings/BlockedUsersView.swift b/yobble/Views/Tab/Settings/BlockedUsersView.swift index dad00c4..536520b 100644 --- a/yobble/Views/Tab/Settings/BlockedUsersView.swift +++ b/yobble/Views/Tab/Settings/BlockedUsersView.swift @@ -102,16 +102,31 @@ struct BlockedUsersView: View { private func userRow(_ user: BlockedUser, index: Int) -> some View { HStack(spacing: 12) { Circle() - .fill(Color.accentColor.opacity(0.15)) + .fill(user.isDeleted ? Color(.systemGray5) : Color.accentColor.opacity(0.15)) .frame(width: 44, height: 44) .overlay( - Text(user.initials) - .font(.headline) - .foregroundColor(.accentColor) + Group { + if user.isDeleted { + Image(systemName: "person.slash") + .font(.headline) + .foregroundColor(Color(.systemGray2)) + } else { + Text(user.initials) + .font(.headline) + .foregroundColor(.accentColor) + } + } ) VStack(alignment: .leading, spacing: 4) { - Text(user.displayName) - .font(.body) + if #available(iOS 16.0, *) { + Text(user.displayName) + .font(.body) + .strikethrough(user.isDeleted, color: .secondary) + } else { + Text(user.displayName) + .font(.body) + .strikethrough(user.isDeleted) + } if let handle = user.handle { Text(handle) .font(.caption) @@ -128,6 +143,7 @@ struct BlockedUsersView: View { } label: { Label(NSLocalizedString("Разблокировать", comment: ""), systemImage: "person.crop.circle.badge.xmark") } +// .disabled(removingUserIds.contains(user.id) || user.isDeleted) .disabled(removingUserIds.contains(user.id)) } .onAppear { @@ -218,7 +234,7 @@ struct BlockedUsersView: View { private struct BlockedUser: Identifiable, Equatable { let id: UUID - let login: String + let login: String? let fullName: String? let customName: String? let createdAt: Date @@ -226,7 +242,13 @@ private struct BlockedUser: Identifiable, Equatable { private(set) var displayName: String private(set) var handle: String? + var isDeleted: Bool { + login?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ?? true + } + var initials: String { + if isDeleted { return "" } + let nameSource: String? if let customName, !customName.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { 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) { @@ -254,18 +276,21 @@ private struct BlockedUser: Identifiable, Equatable { self.customName = payload.customName self.createdAt = payload.createdAt - 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 - } + let isUserDeleted = payload.login?.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty ?? true - if !payload.login.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { - self.handle = "@\(payload.login)" - } else { + if isUserDeleted { + self.displayName = NSLocalizedString("Неизвестный пользователь", comment: "Deleted user display name") 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!)" } } }