mirror of
https://github.com/element-hq/element-x-ios.git
synced 2025-03-10 21:39:12 +00:00
Reaction highlights (#1145)
* Highlight own reactions - Highlight own reactions on timeline and improve style. - Highlight reactions on message bottom sheet only when it our own. * Improve overlay background colours * pin to new sdk version * Remove the red used for debug. * Fix padding, overlap and only display count if > 1. - Fix reaction padding and overlap of reaction and bubble. - Only display count if greater than 1. - Return EmptyView for TimelineDeliveryStatus.cancelled. * Fix colors as per design recommendations. * Add Snapshot tests for reactions and documentation. - Add UITests for the timeline including reactions. - Add the reference snapshots. - Add documentation on how to run snapshot tests and update the reference snapshots. * Fix Package.resolved
This commit is contained in:
parent
41772b57eb
commit
13decc668a
@ -57,6 +57,14 @@ Git LFS is used to store UI test snapshots. `swift run tools setup-project` will
|
||||
git lfs install
|
||||
```
|
||||
|
||||
### Snapshot Tests
|
||||
|
||||
If you make changes to the UI you may cause existing UI Snapshot tests to fail. You can run the snapshot tests using `UITests` target. To update the reference snapshots, delete them from `element-x-ios/UITests/Sources/__Snapshots__/Application` and run the tests again.
|
||||
These are the devices we store snapshots for that you will need to run against:
|
||||
- iPhone 14
|
||||
- iPad (9th generation)
|
||||
|
||||
|
||||
### Githooks
|
||||
|
||||
The project uses its own shared githooks stored in the .githooks folder, you will need to configure git to use such folder, this is already done if you have run the setup tool with `swift run tools setup-project` otherwise you would need to run:
|
||||
|
@ -86,9 +86,8 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
|
||||
}
|
||||
|
||||
private var messageBubbleWithReactions: some View {
|
||||
// Figma has a spacing of -4 but it doesn't take into account
|
||||
// the centre aligned stroke width so we use -5 here
|
||||
VStack(alignment: alignment, spacing: -5) {
|
||||
// Figma overlaps reactions by 3
|
||||
VStack(alignment: alignment, spacing: -3) {
|
||||
messageBubble
|
||||
.accessibilityElement(children: .combine)
|
||||
|
||||
|
@ -44,23 +44,36 @@ struct TimelineReactionButton: View {
|
||||
HStack(spacing: 4) {
|
||||
Text(reaction.key)
|
||||
.font(.compound.bodyMD)
|
||||
Text(String(reaction.count))
|
||||
.font(.compound.bodyMD)
|
||||
.foregroundColor(.compound.textSecondary)
|
||||
if reaction.count > 1 {
|
||||
Text(String(reaction.count))
|
||||
.font(.compound.bodyMD)
|
||||
.foregroundColor(textColor)
|
||||
}
|
||||
}
|
||||
.padding(.vertical, 6)
|
||||
.padding(.horizontal, 8)
|
||||
.background(
|
||||
backgroundShape
|
||||
.strokeBorder(reaction.isHighlighted ? Color.compound.textSecondary : .compound.bgCanvasDefault, lineWidth: 2)
|
||||
.background(reaction.isHighlighted ? Color.compound.textPrimary.opacity(0.1) : .compound._bgReactionButton, in: backgroundShape)
|
||||
)
|
||||
.background(backgroundShape.fill(overlayBackgroundColor))
|
||||
.overlay(backgroundShape.strokeBorder(overlayBorderColor))
|
||||
.padding(2)
|
||||
.overlay(backgroundShape.strokeBorder(Color.compound.bgCanvasDefault, lineWidth: 2))
|
||||
.accessibilityElement(children: .combine)
|
||||
}
|
||||
|
||||
var backgroundShape: some InsettableShape {
|
||||
RoundedRectangle(cornerRadius: 12, style: .continuous)
|
||||
}
|
||||
|
||||
var textColor: Color {
|
||||
reaction.isHighlighted ? Color.compound.textPrimary : .compound.textSecondary
|
||||
}
|
||||
|
||||
var overlayBackgroundColor: Color {
|
||||
reaction.isHighlighted ? Color.compound.bgSubtlePrimary : .compound.bgSubtleSecondary
|
||||
}
|
||||
|
||||
var overlayBorderColor: Color {
|
||||
reaction.isHighlighted ? Color.compound.borderInteractivePrimary : .clear
|
||||
}
|
||||
}
|
||||
|
||||
struct TimelineReactionView_Previews: PreviewProvider {
|
||||
|
@ -163,7 +163,8 @@ public struct TimelineItemMenu: View {
|
||||
}
|
||||
|
||||
private func reactionBackgroundColor(for emoji: String) -> Color {
|
||||
if item.properties.reactions.first(where: { $0.key == emoji }) != nil {
|
||||
if let reaction = item.properties.reactions.first(where: { $0.key == emoji }),
|
||||
reaction.isHighlighted {
|
||||
return .compound.bgActionPrimaryRest
|
||||
} else {
|
||||
return .clear
|
||||
|
@ -322,7 +322,7 @@ struct RoomTimelineItemFactory: RoomTimelineItemFactoryProtocol {
|
||||
|
||||
private func aggregateReactions(_ reactions: [Reaction]) -> [AggregatedReaction] {
|
||||
reactions.map { reaction in
|
||||
let isHighlighted = false // reaction.details.contains(where: { $0.sender.id == userID })
|
||||
let isHighlighted = reaction.senders.contains(where: { $0 == userID })
|
||||
return AggregatedReaction(key: reaction.key, count: Int(reaction.count), isHighlighted: isHighlighted)
|
||||
}
|
||||
}
|
||||
|
@ -198,6 +198,17 @@ class MockScreen: Identifiable {
|
||||
let coordinator = RoomScreenCoordinator(parameters: parameters)
|
||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||
return navigationStackCoordinator
|
||||
case .roomSmallTimelineWithReactions:
|
||||
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||
let timelineController = MockRoomTimelineController()
|
||||
timelineController.timelineItems = RoomTimelineItemFixtures.default
|
||||
let parameters = RoomScreenCoordinatorParameters(roomProxy: RoomProxyMock(with: .init(displayName: "New room", avatarURL: URL.picturesDirectory)),
|
||||
timelineController: timelineController,
|
||||
mediaProvider: MockMediaProvider(),
|
||||
emojiProvider: EmojiProvider())
|
||||
let coordinator = RoomScreenCoordinator(parameters: parameters)
|
||||
navigationStackCoordinator.setRootCoordinator(coordinator)
|
||||
return navigationStackCoordinator
|
||||
case .roomSmallTimelineWithReadReceipts:
|
||||
ServiceLocator.shared.settings.readReceiptsEnabled = true
|
||||
let navigationStackCoordinator = NavigationStackCoordinator()
|
||||
|
@ -36,6 +36,7 @@ enum UITestsScreenIdentifier: String {
|
||||
case roomPlainNoAvatar
|
||||
case roomEncryptedWithAvatar
|
||||
case roomSmallTimeline
|
||||
case roomSmallTimelineWithReactions
|
||||
case roomSmallTimelineWithReadReceipts
|
||||
case roomSmallTimelineIncomingAndSmallPagination
|
||||
case roomSmallTimelineLargePagination
|
||||
|
@ -161,6 +161,12 @@ class RoomScreenUITests: XCTestCase {
|
||||
try await app.assertScreenshot(.roomSmallTimelineWithReadReceipts)
|
||||
}
|
||||
|
||||
func testTimelineReactions() async throws {
|
||||
let app = Application.launch(.roomSmallTimelineWithReactions)
|
||||
|
||||
try await app.assertScreenshot(.roomSmallTimelineWithReactions)
|
||||
}
|
||||
|
||||
// MARK: - Helper Methods
|
||||
|
||||
private func performOperation(_ operation: UITestsSignal, using client: UITestsSignalling.Client) async throws {
|
||||
|
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomSmallTimelineWithReactions.png
(Stored with Git LFS)
Normal file
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPad-9th-generation.roomSmallTimelineWithReactions.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomSmallTimelineWithReactions.png
(Stored with Git LFS)
Normal file
BIN
UITests/Sources/__Snapshots__/Application/en-GB-iPhone-14.roomSmallTimelineWithReactions.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomSmallTimelineWithReactions.png
(Stored with Git LFS)
Normal file
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPad-9th-generation.roomSmallTimelineWithReactions.png
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomSmallTimelineWithReactions.png
(Stored with Git LFS)
Normal file
BIN
UITests/Sources/__Snapshots__/Application/pseudo-iPhone-14.roomSmallTimelineWithReactions.png
(Stored with Git LFS)
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user