diff --git a/Mlem/Models/Content/User/UserModel.swift b/Mlem/Models/Content/User/UserModel.swift index 201bd7097..3ecb321ea 100644 --- a/Mlem/Models/Content/User/UserModel.swift +++ b/Mlem/Models/Content/User/UserModel.swift @@ -97,33 +97,33 @@ struct UserModel { } // Once we've done other model types we should stop this from relying on API types - func getFlair( + func getFlairs( postContext: APIPost? = nil, commentContext: APIComment? = nil, communityContext: GetCommunityResponse? = nil - ) -> UserFlair? { + ) -> [UserFlair] { + var ret: [UserFlair] = .init() + if let post = postContext, post.creatorId == self.userId { + ret.append(.op) + } if isAdmin { - return .admin + ret.append(.admin) } - if isBot { - return .bot + if UserModel.developerNames.contains(profileUrl.absoluteString) { + ret.append(.developer) } if let comment = commentContext, comment.distinguished { - return .moderator - } - if let community = communityContext, community.moderators.contains(where: { $0.moderator.id == person.id }) { - return .moderator + ret.append(.moderator) + } else if let community = communityContext, community.moderators.contains(where: { $0.moderator.id == userId }) { + ret.append(.moderator) } - if let post = postContext, post.creatorId == self.userId { - return .op + if isBot { + ret.append(.bot) } if banned { - return .banned - } - if UserModel.developerNames.contains(profileUrl.absoluteString) { - return .developer + ret.append(.banned) } - return nil + return ret } } diff --git a/Mlem/Models/UserFlair.swift b/Mlem/Models/UserFlair.swift index b08b401b5..fc9a921e1 100644 --- a/Mlem/Models/UserFlair.swift +++ b/Mlem/Models/UserFlair.swift @@ -18,7 +18,7 @@ enum UserFlair { var color: Color { switch self { case .admin: - return .pink + return .teal case .moderator: return .green case .op: diff --git a/Mlem/Views/Shared/Links/User/UserLabelView.swift b/Mlem/Views/Shared/Links/User/UserLabelView.swift index e4c2b318d..bc4ee3b44 100644 --- a/Mlem/Views/Shared/Links/User/UserLabelView.swift +++ b/Mlem/Views/Shared/Links/User/UserLabelView.swift @@ -82,31 +82,58 @@ struct UserLabelView: View { @ViewBuilder private var userName: some View { - let flair = user.getFlair( + let flairs = user.getFlairs( postContext: postContext, commentContext: commentContext, communityContext: communityContext ) HStack(spacing: 4) { - if let flair = flair { - Image(systemName: flair.icon) - .font(.footnote) - .imageScale(serverInstanceLocation == .bottom ? .large : .small) - .foregroundColor(flair.color) + if serverInstanceLocation == .bottom { + if flairs.count == 1, let first = flairs.first { + userFlairIcon(with: first) + .imageScale(.large) + } else if !flairs.isEmpty { + HStack(spacing: 2) { + LazyHGrid(rows: [GridItem(), GridItem()], alignment: .center) { + ForEach(flairs.dropLast(flairs.count % 2), id: \.self) { flair in + userFlairIcon(with: flair) + .imageScale(.medium) + } + } + if flairs.count % 2 != 0 { + userFlairIcon(with: flairs.last!) + .imageScale(.medium) + } + } + .padding(2) + .padding(.trailing, 4) + } + + } else { + if flairs.count == 1, let first = flairs.first { + userFlairIcon(with: first) + .imageScale(.small) + } else if !flairs.isEmpty { + ForEach(flairs, id: \.self) { flair in + userFlairIcon(with: flair) + .imageScale(.small) + } + .padding(.trailing, 4) + } } switch serverInstanceLocation { case .disabled: - userName(with: flair) + userName(with: flairs) case .bottom: VStack(alignment: .leading) { - userName(with: flair) + userName(with: flairs) userInstance } case .trailing: HStack(spacing: 0) { - userName(with: flair) + userName(with: flairs) userInstance } } @@ -114,11 +141,19 @@ struct UserLabelView: View { } @ViewBuilder - private func userName(with flair: UserFlair?) -> some View { + private func userFlairIcon(with flair: UserFlair) -> some View { + Image(systemName: flair.icon) + .bold() + .font(.footnote) + .foregroundColor(flair.color) + } + + @ViewBuilder + private func userName(with flairs: [UserFlair]) -> some View { Text(user.displayName) .bold() .font(.footnote) - .foregroundColor(flair?.color ?? .gray) + .foregroundColor(flairs.count == 1 ? flairs.first!.color : .gray) } @ViewBuilder diff --git a/Mlem/Views/Tabs/Search/UserResultView.swift b/Mlem/Views/Tabs/Search/UserResultView.swift index cf2d3f9a7..7e337f414 100644 --- a/Mlem/Views/Tabs/Search/UserResultView.swift +++ b/Mlem/Views/Tabs/Search/UserResultView.swift @@ -33,16 +33,17 @@ struct UserResultView: View { NavigationLink(value: NavigationRoute.userProfile(user)) { HStack(spacing: 10) { AvatarView(user: user, avatarSize: 48) - let flair = user.getFlair() + let flairs = user.getFlairs() VStack(alignment: .leading, spacing: 4) { HStack(spacing: 4) { - if let flair = flair { + ForEach(flairs, id: \.self) { flair in Image(systemName: flair.icon) .imageScale(.small) + .foregroundStyle(flair.color) } Text(user.name) + .foregroundStyle(flairs.count == 1 ? flairs.first!.color : .primary) } - .foregroundStyle(flair?.color ?? .primary) Text(caption) .font(.footnote) .foregroundStyle(.secondary)