mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 12:07:55 +00:00
Stacked Avatars View (#3504)
* stacked avatars * fix tests * remove comment
This commit is contained in:
@@ -1012,6 +1012,7 @@
|
||||
E0FB26262689F04D66A949D7 /* TestablePreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1E227F34BE43B08E098796E /* TestablePreview.swift */; };
|
||||
E14E469CD97550D0FC58F3CA /* CancellableTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = AE52983FAFB4E0998C00EE8A /* CancellableTask.swift */; };
|
||||
E184FFAD32342D3D6E2F89AA /* PinnedEventsTimelineScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D53754227CEBD06358956D7 /* PinnedEventsTimelineScreenCoordinator.swift */; };
|
||||
E1C67E5D9E22135A8FEBBD60 /* StackedAvatarsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = A8558D41DD4B553A752C868A /* StackedAvatarsView.swift */; };
|
||||
E1DF24D085572A55C9758A2D /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E89E530A8E92EC44301CA1 /* Bundle.swift */; };
|
||||
E21FE4C5B614F311C0955859 /* UserProfileProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 51C454AE59914B551A6D02C0 /* UserProfileProxy.swift */; };
|
||||
E27C4D1A1F8BB77CA790B403 /* InviteUsersScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A861DA5932B128FE1DCB5CE2 /* InviteUsersScreenCoordinator.swift */; };
|
||||
@@ -1946,6 +1947,7 @@
|
||||
A7D452AF7B5F7E3A0A7DB54C /* SessionVerificationScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenViewModelProtocol.swift; sourceTree = "<group>"; };
|
||||
A7E37072597F67C4DD8CC2DB /* ComposerDraftServiceProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposerDraftServiceProtocol.swift; sourceTree = "<group>"; };
|
||||
A84D413BF49F0E980F010A6B /* LogViewerScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogViewerScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
A8558D41DD4B553A752C868A /* StackedAvatarsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StackedAvatarsView.swift; sourceTree = "<group>"; };
|
||||
A861DA5932B128FE1DCB5CE2 /* InviteUsersScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InviteUsersScreenCoordinator.swift; sourceTree = "<group>"; };
|
||||
A8DF55467ED4CE76B7AE9A33 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
A9873374E72AA53260AE90A2 /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = fa.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
@@ -2989,6 +2991,7 @@
|
||||
7EB58E4E8D6D634C246AD5C2 /* RoomInviterLabel.swift */,
|
||||
839E2C35DF3F9C7B54C3CE49 /* RoundedCornerShape.swift */,
|
||||
AEB5FF7A09B79B0C6B528F7C /* SFNumberedListView.swift */,
|
||||
A8558D41DD4B553A752C868A /* StackedAvatarsView.swift */,
|
||||
E10DA51DBC8C7E1460DBCCBD /* UserProfileListRow.swift */,
|
||||
AD529C89924EE32CE307F36F /* VisualListItem.swift */,
|
||||
);
|
||||
@@ -6952,6 +6955,7 @@
|
||||
F37629BAA5E8F50AAF2A131D /* SoftLogoutScreenViewModel.swift in Sources */,
|
||||
CF4044A8EED5C41BC0ED6ABE /* SoftLogoutScreenViewModelProtocol.swift in Sources */,
|
||||
DF004A5B2EABBD0574D06A04 /* SplashScreenCoordinator.swift in Sources */,
|
||||
E1C67E5D9E22135A8FEBBD60 /* StackedAvatarsView.swift in Sources */,
|
||||
3DAF325D8AE461F7CDB282BD /* StartChatScreen.swift in Sources */,
|
||||
6CD61FAF03E8986523C2ABB8 /* StartChatScreenCoordinator.swift in Sources */,
|
||||
C051475DFF4C8EBDDF4DC8E4 /* StartChatScreenModels.swift in Sources */,
|
||||
|
||||
@@ -46,6 +46,7 @@ enum UserAvatarSizeOnScreen {
|
||||
case editUserDetails
|
||||
case suggestions
|
||||
case blockedUsers
|
||||
case knockingUsers
|
||||
|
||||
var value: CGFloat {
|
||||
switch self {
|
||||
@@ -75,6 +76,8 @@ enum UserAvatarSizeOnScreen {
|
||||
return 96
|
||||
case .dmDetails:
|
||||
return 75
|
||||
case .knockingUsers:
|
||||
return 28
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// Copyright 2024 New Vector Ltd.
|
||||
//
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
// Please see LICENSE in the repository root for full details.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct StackedAvatarInfo {
|
||||
let url: URL?
|
||||
let name: String?
|
||||
let contentID: String
|
||||
}
|
||||
|
||||
struct StackedAvatarsView: View {
|
||||
let overlap: CGFloat
|
||||
let lineWidth: CGFloat
|
||||
var shouldStackFromLast = false
|
||||
let avatars: [StackedAvatarInfo]
|
||||
let avatarSize: AvatarSize
|
||||
let mediaProvider: MediaProviderProtocol?
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: -overlap) {
|
||||
ForEach(0..<avatars.count, id: \.self) { index in
|
||||
LoadableAvatarImage(url: avatars[index].url,
|
||||
name: avatars[index].name,
|
||||
contentID: avatars[index].contentID,
|
||||
avatarSize: avatarSize,
|
||||
mediaProvider: mediaProvider)
|
||||
.padding(lineWidth)
|
||||
.overlay {
|
||||
Circle()
|
||||
.strokeBorder(Color.compound.bgCanvasDefault, lineWidth: lineWidth)
|
||||
}
|
||||
.zIndex(shouldStackFromLast ? Double(index) : Double(avatars.count - index))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct StackedAvatarsView_Previews: PreviewProvider, TestablePreview {
|
||||
static let avatars: [StackedAvatarInfo] = [
|
||||
.init(url: nil, name: "Alice", contentID: "@alice:matrix.org"),
|
||||
.init(url: nil, name: "Bob", contentID: "@bob:matrix.org"),
|
||||
.init(url: nil, name: "Charlie", contentID: "@charlie:matrix.org"),
|
||||
.init(url: nil, name: "Dan", contentID: "@charlie:matrix.org")
|
||||
]
|
||||
|
||||
static var previews: some View {
|
||||
VStack(spacing: 10) {
|
||||
StackedAvatarsView(overlap: 16,
|
||||
lineWidth: 2,
|
||||
avatars: avatars,
|
||||
avatarSize: .user(on: .knockingUsers),
|
||||
mediaProvider: MediaProviderMock())
|
||||
StackedAvatarsView(overlap: 16,
|
||||
lineWidth: 2,
|
||||
shouldStackFromLast: true,
|
||||
avatars: avatars,
|
||||
avatarSize: .user(on: .knockingUsers),
|
||||
mediaProvider: MediaProviderMock())
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
-16
@@ -11,25 +11,22 @@ struct TimelineReadReceiptsView: View {
|
||||
let displayNumber = 3
|
||||
let timelineItem: EventBasedTimelineItemProtocol
|
||||
@EnvironmentObject private var context: TimelineViewModel.Context
|
||||
|
||||
var avatars: [StackedAvatarInfo] {
|
||||
timelineItem.properties.orderedReadReceipts.prefix(displayNumber).map { receipt in
|
||||
StackedAvatarInfo(url: context.viewState.members[receipt.userID]?.avatarURL,
|
||||
name: context.viewState.members[receipt.userID]?.displayName,
|
||||
contentID: receipt.userID)
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 2) {
|
||||
HStack(spacing: -4) {
|
||||
let receiptsToDisplay = timelineItem.properties.orderedReadReceipts.prefix(displayNumber)
|
||||
ForEach(0..<receiptsToDisplay.count, id: \.self) { index in
|
||||
let receipt = receiptsToDisplay[index]
|
||||
LoadableAvatarImage(url: context.viewState.members[receipt.userID]?.avatarURL,
|
||||
name: context.viewState.members[receipt.userID]?.displayName,
|
||||
contentID: receipt.userID,
|
||||
avatarSize: .user(on: .readReceipt),
|
||||
mediaProvider: context.mediaProvider)
|
||||
.overlay {
|
||||
RoundedRectangle(cornerRadius: .infinity)
|
||||
.stroke(Color.compound.bgCanvasDefault, lineWidth: 1)
|
||||
}
|
||||
.zIndex(Double(displayNumber - index))
|
||||
}
|
||||
}
|
||||
StackedAvatarsView(overlap: 6,
|
||||
lineWidth: 1,
|
||||
avatars: avatars, avatarSize: .user(on: .readReceipt),
|
||||
mediaProvider: context.mediaProvider)
|
||||
.padding(-1)
|
||||
if timelineItem.properties.orderedReadReceipts.count > displayNumber {
|
||||
Text("+\(remaining)")
|
||||
.font(.compound.bodySM)
|
||||
|
||||
@@ -785,6 +785,12 @@ extension PreviewTests {
|
||||
}
|
||||
}
|
||||
|
||||
func test_stackedAvatarsView() {
|
||||
for preview in StackedAvatarsView_Previews._allPreviews {
|
||||
assertSnapshots(matching: preview)
|
||||
}
|
||||
}
|
||||
|
||||
func test_startChatScreen() {
|
||||
for preview in StartChatScreen_Previews._allPreviews {
|
||||
assertSnapshots(matching: preview)
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:dbba95d7bded549e3b54dd8468f44f338f75df9dc2d384c800ca69d240c526bb
|
||||
size 295572
|
||||
oid sha256:033f43d5be47abd91cd5f36b93a8b32b0f9800e7a8a947e0c2cd4debd8b4c694
|
||||
size 295633
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0d28a596ca48a0cd680be7014adef2f2aac11aaf1592676da57b942bd3329708
|
||||
size 297527
|
||||
oid sha256:bc959ac1d5a22da8ca928d891e9f0a649dfa28b1cdfa7a91b0a74d2189cc38a3
|
||||
size 297711
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:fbfaf40b0602964736bbe6dc41beea21d1733c8ec0b84c82e0c547596c4032f0
|
||||
size 180515
|
||||
oid sha256:26de643c28b47f7fd0631c0c754d979c43fc51bc274e863fdb6acaf0ed299960
|
||||
size 180507
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9c928084fecfee3ff804ebc41d17b3433fe7dea94f7c0c82ef7c40175203061f
|
||||
size 178534
|
||||
oid sha256:58ae4f390371ef48aca7b5faeb4c75ba7bdfad4294797fd422c0d102036ee4a8
|
||||
size 178571
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f2cccb8af5d3b2f9caaa29584364834f3c58685da13e7b0ed9c305b9aed08954
|
||||
size 76364
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f2cccb8af5d3b2f9caaa29584364834f3c58685da13e7b0ed9c305b9aed08954
|
||||
size 76364
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4ccd3bb00ea04f0482ad6fe087b3421eff7273d5ffe659b13d26b079486f22ce
|
||||
size 35126
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4ccd3bb00ea04f0482ad6fe087b3421eff7273d5ffe659b13d26b079486f22ce
|
||||
size 35126
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:17403a44b5f71ef51b12a2392d3c8eed2b30cd4ddeb25188c29e738f8ed3c3fc
|
||||
size 285676
|
||||
oid sha256:7222cb8f9b8d5f35d70b7c9d6498825271f2f4701328789f29ce4434060df93b
|
||||
size 285869
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2f576e2c44ecda928a8afdbd29bf9c79631517d9c42d6b8a16b1dcdbac1885a9
|
||||
size 284180
|
||||
oid sha256:5c52b5f33ef60a009368a4f69841c64596c4cd3c0597206f7c6e77159b3182b9
|
||||
size 284251
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:fc726f43094e192a9f367c0ece419d581de5d43bab53275eaa73ae25969e65ab
|
||||
size 287326
|
||||
oid sha256:72f66b7d7cf29690fe5cbf3c7a624462369735231ffdab3d196c31eb285c1a3c
|
||||
size 287531
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:982eb9dd6ed5fe3c4c13811ae463b80f1b571fec18953d98d641d367cd705db0
|
||||
size 285493
|
||||
oid sha256:7c65adc9249fe0e725160eed2ad5854e7b719b7d3c5fad3b5501b9259db582c2
|
||||
size 285667
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1a39ebd070935b96d697dc0c70244962a8d55c6c9ce3e958808c35f8ed009506
|
||||
size 190461
|
||||
oid sha256:dd5ce3f8ce6de79110a64880e7d65132bd4eeb689562e65dda79b9fe39ef8148
|
||||
size 190473
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e4278c55045120935c02fe570409295a0eb0b984a103e5fd09d314bb2f4e09a6
|
||||
size 188620
|
||||
oid sha256:2edda65eb2b77d65105f17dada5fbe8be1f7610cce462e967ffe1513fdd878b0
|
||||
size 188590
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1eb05117714fb7853917a32dba87565ed0ad83b3097ca01703581dc0ec8e7b7a
|
||||
size 188275
|
||||
oid sha256:989002cd49c3455efc5d1f3982cf5b8efbe9527d6bef80464e01ac11452fe1c6
|
||||
size 188265
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a421129a41149ca0c3be3981ef169ddcbce8b0c57a0b94ea43a3fea2dc4202f8
|
||||
size 186287
|
||||
oid sha256:c0bce781f1031c33a6f2161d11f572ded92262d9e394bb82b4fdbfed15a9c41b
|
||||
size 186270
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:fd4120e82a247929c0b20e95e5e75889853c5aeb1ca529a4928657159781e1ba
|
||||
size 74341
|
||||
oid sha256:3832d15395990ba70d725f952594ba8525ae4d6e34b0c94a3518c1498c629ad7
|
||||
size 74883
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9d037477f4b7663cfbe5067f1782261da930f7ded80f39d44dc6ad64ada84b15
|
||||
size 74917
|
||||
oid sha256:d4bf1c97977129580a538593b9a418855a7293040b0f98c4c86eaf52f89922b3
|
||||
size 75388
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6b649638070c638275198e207be41db38c0ddae908bab0da10f2bd69d2c8054d
|
||||
size 33967
|
||||
oid sha256:1f8e0493510c102234ef73712d603f484bdee6db7393eb3ba9e4a890787fdb51
|
||||
size 34021
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:74ddd0f05b73833113d6814c5c2afe86e5429bbdb01a4e82d09f075208df4362
|
||||
size 34383
|
||||
oid sha256:40f28da9c6ca03946b234d0b9f33b30c69d03628b3e8f1d0ced8f06e36fc050a
|
||||
size 34494
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:dbba95d7bded549e3b54dd8468f44f338f75df9dc2d384c800ca69d240c526bb
|
||||
size 295572
|
||||
oid sha256:033f43d5be47abd91cd5f36b93a8b32b0f9800e7a8a947e0c2cd4debd8b4c694
|
||||
size 295633
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0d28a596ca48a0cd680be7014adef2f2aac11aaf1592676da57b942bd3329708
|
||||
size 297527
|
||||
oid sha256:bc959ac1d5a22da8ca928d891e9f0a649dfa28b1cdfa7a91b0a74d2189cc38a3
|
||||
size 297711
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:fbfaf40b0602964736bbe6dc41beea21d1733c8ec0b84c82e0c547596c4032f0
|
||||
size 180515
|
||||
oid sha256:26de643c28b47f7fd0631c0c754d979c43fc51bc274e863fdb6acaf0ed299960
|
||||
size 180507
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9c928084fecfee3ff804ebc41d17b3433fe7dea94f7c0c82ef7c40175203061f
|
||||
size 178534
|
||||
oid sha256:58ae4f390371ef48aca7b5faeb4c75ba7bdfad4294797fd422c0d102036ee4a8
|
||||
size 178571
|
||||
|
||||
Reference in New Issue
Block a user