mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 21:33:26 +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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user