Merge pull request #2429 from vector-im/reactions_placeholder

Reactions: Add placeholder for reactions list under message
This commit is contained in:
manuroe
2019-05-17 13:08:22 +02:00
committed by GitHub
2 changed files with 98 additions and 23 deletions
+45 -21
View File
@@ -1,5 +1,6 @@
/*
Copyright 2015 OpenMarket Ltd
Copyright 2019 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -210,11 +211,7 @@ static NSAttributedString *readReceiptVerticalWhitespace = nil;
currentAttributedTextMsg = [[NSMutableAttributedString alloc] initWithAttributedString:componentString];
}
if (self.readReceipts[component.event.eventId].count)
{
// Add vertical whitespace in case of read receipts
[currentAttributedTextMsg appendAttributedString:[RoomBubbleCellData readReceiptVerticalWhitespace]];
}
[self addVerticalWhitespaceToString:currentAttributedTextMsg forEvent:component.event.eventId];
// The first non empty component has been handled.
break;
@@ -246,11 +243,7 @@ static NSAttributedString *readReceiptVerticalWhitespace = nil;
// Append attributed text
[currentAttributedTextMsg appendAttributedString:componentString];
if (self.readReceipts[component.event.eventId].count)
{
// Add vertical whitespace in case of read receipts
[currentAttributedTextMsg appendAttributedString:[RoomBubbleCellData readReceiptVerticalWhitespace]];
}
[self addVerticalWhitespaceToString:currentAttributedTextMsg forEvent:component.event.eventId];
}
}
@@ -266,7 +259,7 @@ static NSAttributedString *readReceiptVerticalWhitespace = nil;
// Check whether there is at least one component.
if (bubbleComponents.count)
{
BOOL hasReadReceipts = NO;
BOOL hasReadReceiptsOrReactions = NO;
// Set position of the first component
CGFloat positionY = (self.attachment == nil || self.attachment.type == MXKAttachmentTypeFile || self.attachment.type == MXKAttachmentTypeAudio) ? MXKROOMBUBBLECELLDATA_TEXTVIEW_DEFAULT_VERTICAL_INSET : 0;
@@ -281,7 +274,8 @@ static NSAttributedString *readReceiptVerticalWhitespace = nil;
if (component.attributedTextMessage)
{
hasReadReceipts = (self.readReceipts[component.event.eventId].count > 0);
hasReadReceiptsOrReactions = (self.reactions[component.event.eventId].reactions.count > 0);
hasReadReceiptsOrReactions |= (self.readReceipts[component.event.eventId].count > 0);
break;
}
}
@@ -306,9 +300,9 @@ static NSAttributedString *readReceiptVerticalWhitespace = nil;
}
// Vertical whitespace is added in case of read receipts
if (hasReadReceipts)
if (hasReadReceiptsOrReactions)
{
[attributedString appendAttributedString:[RoomBubbleCellData readReceiptVerticalWhitespace]];
[self addVerticalWhitespaceToString:attributedString forEvent:component.event.eventId];
}
[attributedString appendAttributedString:[MXKRoomBubbleCellDataWithAppendingMode messageSeparator]];
@@ -344,13 +338,9 @@ static NSAttributedString *readReceiptVerticalWhitespace = nil;
positionY = MXKROOMBUBBLECELLDATA_TEXTVIEW_DEFAULT_VERTICAL_INSET + (cumulatedHeight - [self rawTextHeight:componentString]);
component.position = CGPointMake(0, positionY);
// Add vertical whitespace in case of read receipts.
if (self.readReceipts[component.event.eventId].count)
{
[attributedString appendAttributedString:[RoomBubbleCellData readReceiptVerticalWhitespace]];
}
[self addVerticalWhitespaceToString:attributedString forEvent:component.event.eventId];
[attributedString appendAttributedString:[MXKRoomBubbleCellDataWithAppendingMode messageSeparator]];
}
else
@@ -363,6 +353,25 @@ static NSAttributedString *readReceiptVerticalWhitespace = nil;
}
}
- (void)addVerticalWhitespaceToString:(NSMutableAttributedString *)attributedString forEvent:(NSString *)eventId
{
// Add vertical whitespace in case of read receipts.
NSUInteger reactionCount = self.reactions[eventId].reactions.count;
if (reactionCount)
{
// TODO: Set right height: 22 + 8
// TODO: Set right dynamic line count: reactionCount / 6
CGFloat height = (22 + 8) * ((reactionCount / 6) + 1);
[attributedString appendAttributedString:[RoomBubbleCellData verticalWhitespaceForHeight: height]];
}
// Add vertical whitespace in case of read receipts.
if (self.readReceipts[eventId].count)
{
[attributedString appendAttributedString:[RoomBubbleCellData readReceiptVerticalWhitespace]];
}
}
- (void)setContainsLastMessage:(BOOL)containsLastMessage
{
// Check whether there is something to do
@@ -482,6 +491,21 @@ static NSAttributedString *readReceiptVerticalWhitespace = nil;
return readReceiptVerticalWhitespace;
}
+ (NSAttributedString *)verticalWhitespaceForHeight:(CGFloat)height
{
NSUInteger returns = height / 6;
NSMutableString *returnString = [NSMutableString string];
for (NSUInteger i = 0; i < returns; i++)
{
[returnString appendString:@"\n"];
}
return [[NSAttributedString alloc] initWithString:returnString attributes:@{NSForegroundColorAttributeName : [UIColor blackColor],
NSFontAttributeName: [UIFont systemFontOfSize:4]}];
}
- (BOOL)hasSameSenderAsBubbleCellData:(id<MXKRoomBubbleCellDataStoring>)bubbleCellData
{
if (self.tag == RoomBubbleCellDataTagMembership || bubbleCellData.tag == RoomBubbleCellDataTagMembership)
+53 -2
View File
@@ -265,7 +265,7 @@
// Handle read receipts and read marker display.
// Ignore the read receipts on the bubble without actual display.
// Ignore the read receipts on collapsed bubbles
if ((self.showBubbleReceipts && cellData.readReceipts.count && !isCollapsableCellCollapsed) || self.showReadMarker)
if ((((self.showBubbleReceipts && cellData.readReceipts.count) || cellData.reactions.count) && !isCollapsableCellCollapsed) || self.showReadMarker)
{
// Read receipts container are inserted here on the right side into the content view.
// Some vertical whitespaces are added in message text view (see RoomBubbleCellData class) to insert correctly multiple receipts.
@@ -277,6 +277,8 @@
if (component.event.sentState != MXEventSentStateFailed)
{
MXKReceiptSendersContainer* avatarsContainer;
// Handle read receipts (if any)
if (self.showBubbleReceipts && cellData.readReceipts.count && !isCollapsableCellCollapsed)
{
@@ -307,7 +309,7 @@
if (roomMembers.count)
{
// Define the read receipts container, positioned on the right border of the bubble cell (Note the right margin 6 pts).
MXKReceiptSendersContainer* avatarsContainer = [[MXKReceiptSendersContainer alloc] initWithFrame:CGRectMake(bubbleCell.frame.size.width - 156, bottomPositionY - 13, 150, 12) andMediaManager:self.mxSession.mediaManager];
avatarsContainer = [[MXKReceiptSendersContainer alloc] initWithFrame:CGRectMake(bubbleCell.frame.size.width - 156, bottomPositionY - 13, 150, 12) andMediaManager:self.mxSession.mediaManager];
// Custom avatar display
avatarsContainer.maxDisplayedAvatars = 5;
@@ -376,6 +378,55 @@
[NSLayoutConstraint activateConstraints:@[widthConstraint, heightConstraint, topConstraint, trailingConstraint]];
}
}
MXAggregatedReactions* reactions = cellData.reactions[component.event.eventId];
if (reactions && !isCollapsableCellCollapsed)
{
// TODO: Use final ReactionsView
UITextView* reactionsContainer = [UITextView new];
reactionsContainer.translatesAutoresizingMaskIntoConstraints = NO;
[bubbleCell.contentView addSubview:reactionsContainer];
reactionsContainer.layer.borderColor = UIColor.orangeColor.CGColor;
reactionsContainer.layer.borderWidth = 1;
if (!bubbleCell.tmpSubviews)
{
bubbleCell.tmpSubviews = [NSMutableArray array];
}
[bubbleCell.tmpSubviews addObject:reactionsContainer];
// At the bottom, we have read receipts or nothing
NSLayoutConstraint *bottomConstraint;
if (avatarsContainer)
{
bottomConstraint = [reactionsContainer.bottomAnchor constraintEqualToAnchor:avatarsContainer.topAnchor];
}
else
{
bottomConstraint = [reactionsContainer.bottomAnchor constraintEqualToAnchor:reactionsContainer.superview.topAnchor constant:bottomPositionY];
}
// TODO: To refine
CGFloat viewHeight = 22;
// Force receipts container size
[NSLayoutConstraint activateConstraints:
@[
[reactionsContainer.leadingAnchor constraintEqualToAnchor:reactionsContainer.superview.leadingAnchor constant:50],
[reactionsContainer.trailingAnchor constraintEqualToAnchor:reactionsContainer.superview.trailingAnchor constant:-6],
[reactionsContainer.heightAnchor constraintEqualToConstant:viewHeight],
bottomConstraint
]];
// TODO: To remove
NSMutableString *reactionsString = [NSMutableString string];
for (MXReactionCount *reactionCount in reactions.reactions)
{
[reactionsString appendFormat:@"%@: %@ ", reactionCount.reaction, @(reactionCount.count)];
}
reactionsContainer.text = reactionsString;
}
// Check whether the read marker must be displayed here.
if (self.showReadMarker)