add avtars

This commit is contained in:
cheykrym 2025-12-09 22:55:46 +03:00
parent 520f63f74a
commit fc7561a9c2
2 changed files with 71 additions and 23 deletions

View File

@ -167,6 +167,7 @@ struct ChatProfile: Decodable {
let bio: String?
let lastSeen: Int?
let createdAt: Date?
let avatars: Avatars?
let stories: [JSONValue]
let permissions: ChatPermissions?
let profilePermissions: ChatProfilePermissions?
@ -181,6 +182,7 @@ struct ChatProfile: Decodable {
case bio
case lastSeen
case createdAt
case avatars
case stories
case permissions
case profilePermissions
@ -198,6 +200,7 @@ struct ChatProfile: Decodable {
self.bio = try container.decodeIfPresent(String.self, forKey: .bio)
self.lastSeen = try container.decodeIfPresent(Int.self, forKey: .lastSeen)
self.createdAt = try container.decodeIfPresent(Date.self, forKey: .createdAt)
self.avatars = try container.decodeIfPresent(Avatars.self, forKey: .avatars)
self.stories = try container.decodeIfPresent([JSONValue].self, forKey: .stories) ?? []
self.permissions = try container.decodeIfPresent(ChatPermissions.self, forKey: .permissions)
self.profilePermissions = try container.decodeIfPresent(ChatProfilePermissions.self, forKey: .profilePermissions)
@ -217,6 +220,7 @@ extension ChatProfile {
bio: String? = nil,
lastSeen: Int? = nil,
createdAt: Date? = nil,
avatars: Avatars? = nil,
stories: [JSONValue] = [],
permissions: ChatPermissions? = nil,
profilePermissions: ChatProfilePermissions? = nil,
@ -230,6 +234,7 @@ extension ChatProfile {
self.bio = bio
self.lastSeen = lastSeen
self.createdAt = createdAt
self.avatars = avatars
self.stories = stories
self.permissions = permissions
self.profilePermissions = profilePermissions
@ -238,6 +243,19 @@ extension ChatProfile {
}
}
struct AvatarInfo: Decodable {
let fileId: String
let mime: String?
let size: Int?
let width: Int?
let height: Int?
let createdAt: Date?
}
struct Avatars: Decodable {
let current: AvatarInfo?
}
struct ChatPermissions: Decodable {
let youCanSendMessage: Bool
let youCanPublicInvitePermission: Bool

View File

@ -1024,25 +1024,42 @@ private struct ChatRowView: View {
return message.isViewed == true ? Color.accentColor : Color.secondary
}
private var avatarUrl: URL? {
guard let chatData = chat.chatData,
let fileId = chatData.avatars?.current?.fileId else {
return nil
}
let userId = chatData.userId
return URL(string: "\(AppConfig.API_SERVER)/v1/storage/download/avatar/\(userId)?file_id=\(fileId)")
}
var body: some View {
HStack(spacing: 12) {
Circle()
.fill(avatarBackgroundColor)
if #available(iOS 15.0, *) {
if let url = avatarUrl {
AsyncImage(url: url) { phase in
switch phase {
case .empty:
placeholderAvatar
case .success(let image):
image
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: avatarSize, height: avatarSize)
.clipShape(Circle())
case .failure:
placeholderAvatar
@unknown default:
placeholderAvatar
}
}
.frame(width: avatarSize, height: avatarSize)
.overlay(
Group {
if isDeletedUser {
Image(systemName: deletedUserSymbolName)
.symbolRenderingMode(.hierarchical)
.font(.system(size: avatarSize * 0.45, weight: .semibold))
.foregroundColor(avatarTextColor)
} else {
Text(initial)
.font(.system(size: avatarSize * 0.5, weight: .semibold))
.foregroundColor(avatarTextColor)
placeholderAvatar
}
} else {
placeholderAvatar
}
)
VStack(alignment: .leading, spacing: 4) {
if let officialName = officialDisplayName {
@ -1066,14 +1083,6 @@ private struct ChatRowView: View {
.foregroundColor(Color.accentColor)
.font(.caption)
}
// if let login = loginDisplay {
// Text(login)
// .font(.footnote)
// .foregroundColor(.secondary)
// .lineLimit(1)
// .truncationMode(.tail)
// }
} else {
if #available(iOS 16.0, *) {
Text(title)
@ -1131,6 +1140,27 @@ private struct ChatRowView: View {
.padding(.vertical, 8)
}
@ViewBuilder
private var placeholderAvatar: some View {
Circle()
.fill(avatarBackgroundColor)
.frame(width: avatarSize, height: avatarSize)
.overlay(
Group {
if isDeletedUser {
Image(systemName: deletedUserSymbolName)
.symbolRenderingMode(.hierarchical)
.font(.system(size: avatarSize * 0.45, weight: .semibold))
.foregroundColor(avatarTextColor)
} else {
Text(initial)
.font(.system(size: avatarSize * 0.5, weight: .semibold))
.foregroundColor(avatarTextColor)
}
}
)
}
private static func formattedTimestamp(for date: Date) -> String {
let calendar = Calendar.current
let locale = Locale.current