Files
element-x-ios/ElementX/Sources/Other/SwiftUI/Views/JoinedMembersBadgeView.swift
T
Doug b46189d05f Add support for showing the user's own status over their avatar on the app's Settings button. (#5912)
* Add a common .inverseMask view modifier and use a blend mode for efficiency.

This also fixes the snapshot rendering 🎉

* Add support for the status emoji on the app's Setting button.

* Align the room header decoration icons with the status emoji.

* Add missing snapshots.
2026-07-22 14:53:32 +01:00

81 lines
2.6 KiB
Swift

//
// Copyright 2025 Element Creations Ltd.
// Copyright 2025 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
// Please see LICENSE files in the repository root for full details.
//
import Compound
import SwiftUI
struct JoinedMembersBadgeView: View {
let heroes: [UserProfile]
var shouldHideAvatars = false
let joinedCount: Int
let mediaProvider: MediaProviderProtocol?
var body: some View {
if heroes.isEmpty {
Label(title: title) {
CompoundIcon(\.userProfile, size: .small, relativeTo: .compound.bodyMD)
.foregroundStyle(.compound.textSecondary)
}
.font(.compound.bodyMD)
.foregroundStyle(.compound.textSecondary)
.labelStyle(.custom(spacing: 4))
.padding(.trailing, 8)
.background(.compound.bgSubtleSecondary, in: Capsule())
} else {
Label(title: title) {
heroesFacePile
}
.font(.compound.bodyMD)
.foregroundStyle(.compound.textSecondary)
.labelStyle(.custom(spacing: 6))
}
}
func title() -> Text {
Text("\(joinedCount)")
}
var heroesFacePile: some View {
HStack(spacing: -8) {
ForEach(heroes.prefix(3).reversed()) { hero in
LoadableAvatarImage(url: shouldHideAvatars ? nil : hero.avatarURL,
name: hero.displayName,
contentID: hero.id,
avatarSize: .user(on: .spaceHeader),
mediaProvider: mediaProvider)
.inverseMask {
if hero != heroes.first {
Circle()
.inset(by: -2)
.offset(x: 12)
}
}
}
}
}
}
// MARK: - Previews
struct JoinedMembersBadgeView_Previews: PreviewProvider, TestablePreview {
static let mediaProvider = MediaProviderMock(.init())
static var previews: some View {
VStack(spacing: 16) {
JoinedMembersBadgeView(heroes: [],
joinedCount: 123,
mediaProvider: mediaProvider)
JoinedMembersBadgeView(heroes: [.mockAlice, .mockBob, .mockCharlie, .mockDan],
joinedCount: 123,
mediaProvider: mediaProvider)
}
}
}