diff --git a/yobble/Views/Tab/Settings/EditProfileView.swift b/yobble/Views/Tab/Settings/EditProfileView.swift index 4d57b80..6520360 100644 --- a/yobble/Views/Tab/Settings/EditProfileView.swift +++ b/yobble/Views/Tab/Settings/EditProfileView.swift @@ -154,11 +154,27 @@ struct EditProfileView: View { .fill(Color.secondary.opacity(0.2)) .frame(width: 120, height: 120) .overlay( - Image(systemName: "person.fill") - .font(.system(size: 60)) + Text(profileInitials) + .font(.system(size: 48, weight: .semibold)) .foregroundColor(.gray) ) } + + private var profileInitials: String { + if let initials = initials(from: displayName) { + return initials + } + if let profile = profile, + let name = profile.fullName?.trimmingCharacters(in: .whitespacesAndNewlines), + !name.isEmpty, + let initials = initials(from: name) { + return initials + } + if let username = profile?.login.trimmingCharacters(in: .whitespacesAndNewlines), !username.isEmpty { + return String(username.prefix(1)).uppercased() + } + return "?" + } private func avatarUrl(for profile: ProfileDataPayload, fileId: String) -> URL? { return URL(string: "\(AppConfig.API_SERVER)/v1/storage/download/avatar/\(profile.userId)?file_id=\(fileId)") @@ -360,6 +376,15 @@ struct EditProfileView: View { } } +private func initials(from text: String) -> String? { + let components = text + .split { $0.isWhitespace } + .filter { !$0.isEmpty } + let letters = components.prefix(2).compactMap { $0.first } + guard !letters.isEmpty else { return nil } + return letters.map { String($0).uppercased() }.joined() +} + struct ImagePicker: UIViewControllerRepresentable { @Binding var image: UIImage? var allowsEditing: Bool = false