From 0afd48f5b52adf409275262c1ae8f24adc40e358 Mon Sep 17 00:00:00 2001 From: manuroe Date: Thu, 16 May 2019 18:27:48 +0200 Subject: [PATCH 1/2] RoomBubbleCellData: Do readReceiptVerticalWhitespace thing in one place --- .../Room/CellData/RoomBubbleCellData.m | 32 +++++++++---------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/Riot/Modules/Room/CellData/RoomBubbleCellData.m b/Riot/Modules/Room/CellData/RoomBubbleCellData.m index 2b953e464..edc154f3f 100644 --- a/Riot/Modules/Room/CellData/RoomBubbleCellData.m +++ b/Riot/Modules/Room/CellData/RoomBubbleCellData.m @@ -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]; } } @@ -344,13 +337,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 +352,15 @@ static NSAttributedString *readReceiptVerticalWhitespace = nil; } } +- (void)addverticalWhitespaceToString:(NSMutableAttributedString *)attributedString forEvent:(NSString *)eventId +{ + // 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 From 8fb8cb85cbbeb0b5e3462cc95e740a39891ac2a3 Mon Sep 17 00:00:00 2001 From: manuroe Date: Fri, 17 May 2019 01:28:45 +0200 Subject: [PATCH 2/2] Reactions: Add placeholder for reactions list under message --- .../Room/CellData/RoomBubbleCellData.m | 42 +++++++++++--- .../Modules/Room/DataSources/RoomDataSource.m | 55 ++++++++++++++++++- 2 files changed, 87 insertions(+), 10 deletions(-) diff --git a/Riot/Modules/Room/CellData/RoomBubbleCellData.m b/Riot/Modules/Room/CellData/RoomBubbleCellData.m index edc154f3f..df44185b8 100644 --- a/Riot/Modules/Room/CellData/RoomBubbleCellData.m +++ b/Riot/Modules/Room/CellData/RoomBubbleCellData.m @@ -211,7 +211,7 @@ static NSAttributedString *readReceiptVerticalWhitespace = nil; currentAttributedTextMsg = [[NSMutableAttributedString alloc] initWithAttributedString:componentString]; } - [self addverticalWhitespaceToString:currentAttributedTextMsg forEvent:component.event.eventId]; + [self addVerticalWhitespaceToString:currentAttributedTextMsg forEvent:component.event.eventId]; // The first non empty component has been handled. break; @@ -243,7 +243,7 @@ static NSAttributedString *readReceiptVerticalWhitespace = nil; // Append attributed text [currentAttributedTextMsg appendAttributedString:componentString]; - [self addverticalWhitespaceToString:currentAttributedTextMsg forEvent:component.event.eventId]; + [self addVerticalWhitespaceToString:currentAttributedTextMsg forEvent:component.event.eventId]; } } @@ -259,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; @@ -274,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; } } @@ -299,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]]; @@ -338,7 +339,7 @@ static NSAttributedString *readReceiptVerticalWhitespace = nil; component.position = CGPointMake(0, positionY); - [self addverticalWhitespaceToString:attributedString forEvent:component.event.eventId]; + [self addVerticalWhitespaceToString:attributedString forEvent:component.event.eventId]; [attributedString appendAttributedString:[MXKRoomBubbleCellDataWithAppendingMode messageSeparator]]; } @@ -352,8 +353,18 @@ static NSAttributedString *readReceiptVerticalWhitespace = nil; } } -- (void)addverticalWhitespaceToString:(NSMutableAttributedString *)attributedString forEvent:(NSString *)eventId +- (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) { @@ -480,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)bubbleCellData { if (self.tag == RoomBubbleCellDataTagMembership || bubbleCellData.tag == RoomBubbleCellDataTagMembership) diff --git a/Riot/Modules/Room/DataSources/RoomDataSource.m b/Riot/Modules/Room/DataSources/RoomDataSource.m index c7f2e74aa..1dee9902f 100644 --- a/Riot/Modules/Room/DataSources/RoomDataSource.m +++ b/Riot/Modules/Room/DataSources/RoomDataSource.m @@ -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)