diff --git a/Riot/Categories/MXKRoomBubbleTableViewCell+Riot.h b/Riot/Categories/MXKRoomBubbleTableViewCell+Riot.h index c9f58e2aa..260d79c51 100644 --- a/Riot/Categories/MXKRoomBubbleTableViewCell+Riot.h +++ b/Riot/Categories/MXKRoomBubbleTableViewCell+Riot.h @@ -90,6 +90,14 @@ extern NSString *const kMXKRoomBubbleCellTapOnReceiptsContainer; */ - (CGRect)componentFrameInTableViewForIndex:(NSInteger)componentIndex; +/** + Calculate surrounding component frame in table view. This frame goes over user name for first visible component for example. + + @param componentIndex index of the component in bubble message data + @return Component surrounding frame in table view if component exist or CGRectNull. + */ +- (CGRect)surroundingFrameInTableViewForComponentIndex:(NSInteger)componentIndex; + /** Calculate the component frame in the contentView of the tableview cell. diff --git a/Riot/Categories/MXKRoomBubbleTableViewCell+Riot.m b/Riot/Categories/MXKRoomBubbleTableViewCell+Riot.m index 2efb265c6..82389e987 100644 --- a/Riot/Categories/MXKRoomBubbleTableViewCell+Riot.m +++ b/Riot/Categories/MXKRoomBubbleTableViewCell+Riot.m @@ -473,6 +473,66 @@ NSString *const kMXKRoomBubbleCellTapOnReceiptsContainer = @"kMXKRoomBubbleCellT return [self.contentView convertRect:componentFrameInContentView toView:self.superview]; } +- (CGRect)surroundingFrameInTableViewForComponentIndex:(NSInteger)componentIndex +{ + CGRect surroundingFrame; + + CGRect componentFrameInContentView = [self componentFrameInContentViewForIndex:componentIndex]; + MXKRoomBubbleTableViewCell *roomBubbleTableViewCell = self; + MXKRoomBubbleCellData *bubbleCellData = roomBubbleTableViewCell.bubbleData; + + NSInteger firstVisibleComponentIndex = NSNotFound; + NSInteger lastMostRecentComponentIndex = NSNotFound; + + if ([bubbleCellData isKindOfClass:[RoomBubbleCellData class]]) + { + RoomBubbleCellData *roomBubbleCellData = (RoomBubbleCellData*)bubbleCellData; + firstVisibleComponentIndex = [roomBubbleCellData firstVisibleComponentIndex]; + + if (roomBubbleCellData.containsLastMessage + && roomBubbleCellData.mostRecentComponentIndex != NSNotFound + && roomBubbleCellData.firstVisibleComponentIndex != roomBubbleCellData.mostRecentComponentIndex + && componentIndex == roomBubbleCellData.mostRecentComponentIndex) + { + lastMostRecentComponentIndex = roomBubbleCellData.mostRecentComponentIndex; + } + } + + // Do not overlap timestamp for last message + if (lastMostRecentComponentIndex != NSNotFound) + { + CGFloat componentBottomY = componentFrameInContentView.origin.y + componentFrameInContentView.size.height; + + CGFloat x = 0; + CGFloat y = componentFrameInContentView.origin.y - RoomBubbleCellLayout.timestampLabelHeight; + CGFloat width = roomBubbleTableViewCell.contentView.frame.size.width; + CGFloat height = componentBottomY - y; + + surroundingFrame = CGRectMake(x, y, width, height); + } // Do not overlap user name label for first visible component + else if (!CGRectEqualToRect(componentFrameInContentView, CGRectNull) + && firstVisibleComponentIndex != NSNotFound + && componentIndex <= firstVisibleComponentIndex + && roomBubbleTableViewCell.userNameLabel + && roomBubbleTableViewCell.userNameLabel.isHidden == NO) + { + CGFloat componentBottomY = componentFrameInContentView.origin.y + componentFrameInContentView.size.height; + + CGFloat x = 0; + CGFloat y = roomBubbleTableViewCell.userNameLabel.frame.origin.y; + CGFloat width = roomBubbleTableViewCell.contentView.frame.size.width; + CGFloat height = componentBottomY - y; + + surroundingFrame = CGRectMake(x, y, width, height); + } + else + { + surroundingFrame = componentFrameInContentView; + } + + return [self.contentView convertRect:surroundingFrame toView:self.superview]; +} + - (CGRect)componentFrameInContentViewForIndex:(NSInteger)componentIndex { MXKRoomBubbleTableViewCell *roomBubbleTableViewCell = self; diff --git a/Riot/Modules/Room/CellData/RoomBubbleCellData.h b/Riot/Modules/Room/CellData/RoomBubbleCellData.h index e03035abb..777063a59 100644 --- a/Riot/Modules/Room/CellData/RoomBubbleCellData.h +++ b/Riot/Modules/Room/CellData/RoomBubbleCellData.h @@ -80,6 +80,10 @@ typedef NS_ENUM(NSInteger, RoomBubbleCellDataTag) */ - (void)updateAdditionalContentHeightIfNeeded; +/** + The index of the first visible component. NSNotFound by default. + */ +- (NSInteger)firstVisibleComponentIndex; #pragma mark - Show all reactions diff --git a/Riot/Modules/Room/CellData/RoomBubbleCellData.m b/Riot/Modules/Room/CellData/RoomBubbleCellData.m index 44f219b2f..5fda69f74 100644 --- a/Riot/Modules/Room/CellData/RoomBubbleCellData.m +++ b/Riot/Modules/Room/CellData/RoomBubbleCellData.m @@ -277,6 +277,31 @@ static NSAttributedString *timestampVerticalWhitespace = nil; return currentAttributedTextMsg; } +- (NSInteger)firstVisibleComponentIndex +{ + __block NSInteger firstVisibleComponentIndex = NSNotFound; + + if (self.attachment && self.bubbleComponents.count) + { + firstVisibleComponentIndex = 0; + } + else + { + [self.bubbleComponents enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + + MXKRoomBubbleComponent *component = (MXKRoomBubbleComponent*)obj; + + if (component.attributedTextMessage) + { + firstVisibleComponentIndex = idx; + *stop = YES; + } + }]; + } + + return firstVisibleComponentIndex; +} + - (void)refreshBubbleComponentsPosition { // CAUTION: This method must be called on the main thread. diff --git a/Riot/Modules/Room/RoomViewController.m b/Riot/Modules/Room/RoomViewController.m index 84961aa83..106c5a99a 100644 --- a/Riot/Modules/Room/RoomViewController.m +++ b/Riot/Modules/Room/RoomViewController.m @@ -5177,7 +5177,7 @@ if (bubbleComponents.count > 0) { NSInteger selectedComponentIndex = foundComponentIndex != NSNotFound ? foundComponentIndex : 0; - bubbleComponentFrame = [roomBubbleTableViewCell componentFrameInTableViewForIndex:selectedComponentIndex]; + bubbleComponentFrame = [roomBubbleTableViewCell surroundingFrameInTableViewForComponentIndex:selectedComponentIndex]; } else {