mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 00:49:44 +00:00
Reactions: Add more button (#1314)
* Add expand/collapse UI for reactions - Adds a CollapsibleFlowLayout for controlling the layout - Adds tests for this layout and some mocks for testing layouts generally - Improves the rendering of the reaction buttons which were not pixel perfect - Adds the UI for the expand collapse buttons including the count of hidden items in the collapsed state. * Add comment for reactionsCollapsed binding. * Add the add more button and change the layout to be reactions specific and account for the add more button specifics. * Update CollapsibleReactionLayout.swift * Rename lines to rows, to hopefully ease the incoming merge. * Add LayoutValueKey to organise subviews by item type. - create ReactionLayoutItemType to tag subviews with ReactionLayoutItem - Add LayoutValueKey support to the layout mocks - Fix some mistakes in the merge - Make the test code a bit more DRY - Make the animation of the addMore and collapse buttons consistent * Fix naming of the add more button label * Address comments and fix padding - Fix typos - Use pdf/svg for icon - Fix incorrect padding from a bad merge * Fix "Add more" button padding to match designs * Update snapshot test reference images. * Fix naming, add Preserves Vector Data
This commit is contained in:
+45
-17
@@ -24,25 +24,36 @@ struct TimelineReactionsView: View {
|
||||
private static let verticalSpacing: CGFloat = 4
|
||||
@EnvironmentObject private var context: RoomScreenViewModel.Context
|
||||
@Environment(\.layoutDirection) private var layoutDirection: LayoutDirection
|
||||
@Namespace private var animation
|
||||
|
||||
let itemID: TimelineItemIdentifier
|
||||
let reactions: [AggregatedReaction]
|
||||
@Binding var collapsed: Bool
|
||||
|
||||
var body: some View {
|
||||
CollapsibleFlowLayout(itemSpacing: 4, rowSpacing: 4, collapsed: collapsed, rowsBeforeCollapsible: 2) {
|
||||
CollapsibleReactionLayout(itemSpacing: 4, rowSpacing: 4, collapsed: collapsed, rowsBeforeCollapsible: 2) {
|
||||
ForEach(reactions, id: \.self) { reaction in
|
||||
TimelineReactionButton(itemID: itemID, reaction: reaction) { key in
|
||||
TimelineReactionButton(reaction: reaction) { key in
|
||||
context.send(viewAction: .toggleReaction(key: key, itemID: itemID))
|
||||
} showReactionSummary: { key in
|
||||
context.send(viewAction: .reactionSummary(itemID: itemID, key: key))
|
||||
}
|
||||
.reactionLayoutItem(.reaction)
|
||||
}
|
||||
Button {
|
||||
collapsed.toggle()
|
||||
} label: {
|
||||
TimelineCollapseButtonLabel(collapsed: collapsed)
|
||||
}
|
||||
.reactionLayoutItem(.expandCollapse)
|
||||
.animation(.easeOut, value: collapsed)
|
||||
Button {
|
||||
context.send(viewAction: .displayEmojiPicker(itemID: itemID))
|
||||
} label: {
|
||||
TimelineReactionAddMoreButtonLabel()
|
||||
}
|
||||
.animation(.easeOut, value: collapsed)
|
||||
.reactionLayoutItem(.addMore)
|
||||
}
|
||||
.coordinateSpace(name: Self.flowCoordinateSpace)
|
||||
}
|
||||
@@ -54,15 +65,11 @@ struct TimelineReactionButtonLabel<Content: View>: View {
|
||||
@ViewBuilder var content: () -> Content
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 4) {
|
||||
content()
|
||||
}
|
||||
.padding(.vertical, 6)
|
||||
.padding(.horizontal, 8)
|
||||
.background(backgroundShape.inset(by: 1).fill(overlayBackgroundColor))
|
||||
.overlay(backgroundShape.inset(by: 2.0).strokeBorder(overlayBorderColor))
|
||||
.overlay(backgroundShape.strokeBorder(Color.compound.bgCanvasDefault, lineWidth: 2))
|
||||
.accessibilityElement(children: .combine)
|
||||
content()
|
||||
.background(backgroundShape.inset(by: 1).fill(overlayBackgroundColor))
|
||||
.overlay(backgroundShape.inset(by: 2.0).strokeBorder(overlayBorderColor))
|
||||
.overlay(backgroundShape.strokeBorder(Color.compound.bgCanvasDefault, lineWidth: 2))
|
||||
.accessibilityElement(children: .combine)
|
||||
}
|
||||
|
||||
var backgroundShape: some InsettableShape {
|
||||
@@ -84,6 +91,8 @@ struct TimelineCollapseButtonLabel: View {
|
||||
var body: some View {
|
||||
TimelineReactionButtonLabel {
|
||||
Text(collapsed ? L10n.screenRoomReactionsShowMore : L10n.screenRoomReactionsShowLess)
|
||||
.padding(.vertical, 6)
|
||||
.padding(.horizontal, 8)
|
||||
.layoutPriority(1)
|
||||
.drawingGroup()
|
||||
.font(.compound.bodyMD)
|
||||
@@ -93,7 +102,6 @@ struct TimelineCollapseButtonLabel: View {
|
||||
}
|
||||
|
||||
struct TimelineReactionButton: View {
|
||||
let itemID: TimelineItemIdentifier
|
||||
let reaction: AggregatedReaction
|
||||
let toggleReaction: (String) -> Void
|
||||
let showReactionSummary: (String) -> Void
|
||||
@@ -110,13 +118,17 @@ struct TimelineReactionButton: View {
|
||||
|
||||
var label: some View {
|
||||
TimelineReactionButtonLabel(isHighlighted: reaction.isHighlighted) {
|
||||
Text(reaction.key)
|
||||
.font(.compound.bodyMD)
|
||||
if reaction.count > 1 {
|
||||
Text(String(reaction.count))
|
||||
HStack(spacing: 4) {
|
||||
Text(reaction.key)
|
||||
.font(.compound.bodyMD)
|
||||
.foregroundColor(textColor)
|
||||
if reaction.count > 1 {
|
||||
Text(String(reaction.count))
|
||||
.font(.compound.bodyMD)
|
||||
.foregroundColor(textColor)
|
||||
}
|
||||
}
|
||||
.padding(.vertical, 6)
|
||||
.padding(.horizontal, 8)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,6 +137,22 @@ struct TimelineReactionButton: View {
|
||||
}
|
||||
}
|
||||
|
||||
struct TimelineReactionAddMoreButtonLabel: View {
|
||||
@ScaledMetric private var addMoreButtonIconSize = 16
|
||||
|
||||
var body: some View {
|
||||
TimelineReactionButtonLabel {
|
||||
Image(asset: Asset.Images.timelineReactionAddMore)
|
||||
.resizable()
|
||||
.frame(width: addMoreButtonIconSize, height: addMoreButtonIconSize)
|
||||
// Vertical sizing is done by the layout so that the add more button
|
||||
// matches the height of the text based buttons.
|
||||
.padding(.horizontal, 10)
|
||||
.frame(maxHeight: .infinity, alignment: .center)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct TimelineReactionViewPreviewsContainer: View {
|
||||
@State private var collapseState1 = false
|
||||
@State private var collapseState2 = true
|
||||
|
||||
Reference in New Issue
Block a user