diff --git a/Classes/ChatConversationTableView.m b/Classes/ChatConversationTableView.m
index 20842d192..40e6edde9 100644
--- a/Classes/ChatConversationTableView.m
+++ b/Classes/ChatConversationTableView.m
@@ -93,6 +93,7 @@
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:pos inSection:0];
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:@[ indexPath ] withRowAnimation:UITableViewRowAnimationFade];
+ [self.tableView reloadData];
[self.tableView endUpdates];
}
@@ -165,6 +166,51 @@
[self reloadData];
}
+- (BOOL)isFirstIndexInTableView:(NSIndexPath *)indexPath chat:(LinphoneChatMessage *)chat {
+ if (indexPath.row == 0)
+ return TRUE;
+
+ LinphoneEventLog *previousEvent = nil;
+ NSInteger indexOfPreviousEvent = indexPath.row - 1;
+ while (!previousEvent && indexOfPreviousEvent > -1) {
+ LinphoneEventLog *tmp = [[eventList objectAtIndex:indexOfPreviousEvent] pointerValue];
+ if (linphone_event_log_get_type(tmp) == LinphoneEventLogTypeConferenceChatMessage) {
+ previousEvent = tmp;
+ }
+ --indexOfPreviousEvent;
+ }
+ if (previousEvent) {
+ LinphoneChatMessage *previousChat = linphone_event_log_get_chat_message(previousEvent);
+ if (!linphone_address_equal(linphone_chat_message_get_from_address(previousChat), linphone_chat_message_get_from_address(chat))) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+- (BOOL)isLastIndexInTableView:(NSIndexPath *)indexPath chat:(LinphoneChatMessage *)chat {
+ LinphoneEventLog *nextEvent = nil;
+ NSInteger indexOfNextEvent = indexPath.row + 1;
+ while (!nextEvent && indexOfNextEvent < [eventList count]) {
+ LinphoneEventLog *tmp = [[eventList objectAtIndex:indexOfNextEvent] pointerValue];
+ if (linphone_event_log_get_type(tmp) == LinphoneEventLogTypeConferenceChatMessage) {
+ nextEvent = tmp;
+ }
+ ++indexOfNextEvent;
+ }
+
+ if (!nextEvent)
+ return TRUE;
+
+ LinphoneChatMessage *nextChat = linphone_event_log_get_chat_message(nextEvent);
+ if (!linphone_address_equal(linphone_chat_message_get_from_address(nextChat), linphone_chat_message_get_from_address(chat))) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
#pragma mark - UITableViewDataSource Functions
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
@@ -190,8 +236,11 @@
cell = [[NSClassFromString(kCellId) alloc] initWithIdentifier:kCellId];
}
[cell setEvent:event];
- if (chat)
- [cell update];
+ if (chat) {
+ cell.isFirst = [self isFirstIndexInTableView:indexPath chat:chat];
+ cell.isLast = [self isLastIndexInTableView:indexPath chat:chat];
+ [cell update];
+ }
[cell setChatRoomDelegate:_chatRoomDelegate];
[super accessoryForCell:cell atPath:indexPath];
@@ -216,7 +265,7 @@
[_chatRoomDelegate tableViewIsScrolling];
}
-static const CGFloat MESSAGE_SPACING_PERCENTAGE = 0.f;
+static const CGFloat MESSAGE_SPACING_PERCENTAGE = 1.f;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
LinphoneEventLog *event = [[eventList objectAtIndex:indexPath.row] pointerValue];
@@ -225,21 +274,11 @@ static const CGFloat MESSAGE_SPACING_PERCENTAGE = 0.f;
//If the message is followed by another one that is not from the same address, we add a little space under it
CGFloat height = 0;
- LinphoneEventLog *nextEvent = nil;
- NSInteger indexOfNextEvent = indexPath.row + 1;
- while (!nextEvent && indexOfNextEvent < [eventList count]) {
- LinphoneEventLog *tmp = [[eventList objectAtIndex:indexOfNextEvent] pointerValue];
- if (linphone_event_log_get_type(tmp) == LinphoneEventLogTypeConferenceChatMessage) {
- nextEvent = tmp;
- }
- ++indexOfNextEvent;
- }
- if (nextEvent) {
- LinphoneChatMessage *nextChat = linphone_event_log_get_chat_message(nextEvent);
- if (!linphone_address_equal(linphone_chat_message_get_from_address(nextChat), linphone_chat_message_get_from_address(chat))) {
- height += tableView.frame.size.height * MESSAGE_SPACING_PERCENTAGE / 100;
- }
- }
+ if ([self isLastIndexInTableView:indexPath chat:chat])
+ height += tableView.frame.size.height * MESSAGE_SPACING_PERCENTAGE / 100;
+ if (![self isFirstIndexInTableView:indexPath chat:chat])
+ height -= 20;
+
return [UIChatBubbleTextCell ViewHeightForMessage:chat withWidth:self.view.frame.size.width].height + height;
}
return [UIChatNotifiedEventCell height];
diff --git a/Classes/LinphoneUI/Base.lproj/UIChatBubbleTextCell.xib b/Classes/LinphoneUI/Base.lproj/UIChatBubbleTextCell.xib
index 3540175ea..71473db07 100644
--- a/Classes/LinphoneUI/Base.lproj/UIChatBubbleTextCell.xib
+++ b/Classes/LinphoneUI/Base.lproj/UIChatBubbleTextCell.xib
@@ -11,85 +11,54 @@
-
-
+
-
-
-
-
+
+
+
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -97,8 +66,7 @@
-
-
+
diff --git a/Classes/LinphoneUI/UIChatBubbleTextCell.h b/Classes/LinphoneUI/UIChatBubbleTextCell.h
index f5a4a25e4..382398711 100644
--- a/Classes/LinphoneUI/UIChatBubbleTextCell.h
+++ b/Classes/LinphoneUI/UIChatBubbleTextCell.h
@@ -30,17 +30,20 @@
@property(nonatomic, weak) IBOutlet UIImageView *backgroundColorImage;
@property(nonatomic, weak) IBOutlet UIRoundedImageView *avatarImage;
@property(nonatomic, weak) IBOutlet UILabel *contactDateLabel;
-@property(weak, nonatomic) IBOutlet UIActivityIndicatorView *statusInProgressSpinner;
+//@property(weak, nonatomic) IBOutlet UIActivityIndicatorView *statusInProgressSpinner;
@property(nonatomic, weak) IBOutlet UITextViewNoDefine *messageText;
-@property(weak, nonatomic) IBOutlet UIImageView *bottomBarColor;
+//@property(weak, nonatomic) IBOutlet UIImageView *bottomBarColor;
@property(nonatomic, strong) id chatRoomDelegate;
@property(strong, nonatomic) IBOutlet UIView *bubbleView;
@property(strong, nonatomic) IBOutlet UITapGestureRecognizer *resendRecognizer;
-@property(weak, nonatomic) IBOutlet UIImageView *LIMEKO;
+//@property(weak, nonatomic) IBOutlet UIImageView *LIMEKO;
@property(weak, nonatomic) IBOutlet UIImageView *imdmIcon;
-@property(weak, nonatomic) IBOutlet UILabel *imdmLabel;
-
+//@property(weak, nonatomic) IBOutlet UILabel *imdmLabel;
@property (nonatomic, strong) UIDocumentPickerViewController *documentPicker;
+@property (weak, nonatomic) IBOutlet UIView *innerView;
+
+@property(nonatomic) Boolean isFirst;
+@property(nonatomic) Boolean isLast;
+ (CGSize)ViewSizeForMessage:(LinphoneChatMessage *)chat withWidth:(int)width;
+ (CGSize)ViewHeightForMessageText:(LinphoneChatMessage *)chat withWidth:(int)width textForImdn:(NSString *)imdnText;
diff --git a/Classes/LinphoneUI/UIChatBubbleTextCell.m b/Classes/LinphoneUI/UIChatBubbleTextCell.m
index 75937c0a4..6e24788f1 100644
--- a/Classes/LinphoneUI/UIChatBubbleTextCell.m
+++ b/Classes/LinphoneUI/UIChatBubbleTextCell.m
@@ -44,8 +44,8 @@
UITapGestureRecognizer *limeRecognizer =
[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onLime)];
limeRecognizer.numberOfTapsRequired = 1;
- [_LIMEKO addGestureRecognizer:limeRecognizer];
- _LIMEKO.userInteractionEnabled = YES;
+ //[_LIMEKO addGestureRecognizer:limeRecognizer];
+ //_LIMEKO.userInteractionEnabled = YES;
UITapGestureRecognizer *resendRecognizer =
[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onResend)];
resendRecognizer.numberOfTapsRequired = 1;
@@ -54,8 +54,8 @@
UITapGestureRecognizer *resendRecognizer2 =
[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onResend)];
resendRecognizer2.numberOfTapsRequired = 1;
- [_imdmLabel addGestureRecognizer:resendRecognizer2];
- _imdmLabel.userInteractionEnabled = YES;
+ //[_imdmLabel addGestureRecognizer:resendRecognizer2];
+ //_imdmLabel.userInteractionEnabled = YES;
return self;
}
@@ -126,7 +126,7 @@
return;
}
- _statusInProgressSpinner.accessibilityLabel = @"Delivery in progress";
+ //_statusInProgressSpinner.accessibilityLabel = @"Delivery in progress";
if (_messageText && ![LinphoneManager getMessageAppDataForKey:@"localvideo" inMessage:_message]) {
LOGD(_messageText.text);
@@ -145,27 +145,83 @@
LinphoneChatMessageState state = linphone_chat_message_get_state(_message);
BOOL outgoing = linphone_chat_message_is_outgoing(_message);
+
+
+ _contactDateLabel.hidden = !_isFirst;
+ if (outgoing) {
+ _contactDateLabel.text = [LinphoneUtils timeToString:linphone_chat_message_get_time(_message)
+ withFormat:LinphoneDateChatBubble];
+ _contactDateLabel.textAlignment = NSTextAlignmentRight;
+ _avatarImage.hidden = TRUE;
+
+ } else {
+ [_avatarImage setImage:[FastAddressBook imageForAddress:linphone_chat_message_get_from_address(_message)]
+ bordered:NO
+ withRoundedRadius:YES];
+ _contactDateLabel.text = [self.class ContactDateForChat:_message];
+ _contactDateLabel.textAlignment = NSTextAlignmentLeft;
+ _avatarImage.hidden = !_isFirst;
+ }
+
- if (outgoing) {
- _avatarImage.image = [LinphoneUtils selfAvatar];
- } else {
- [_avatarImage setImage:[FastAddressBook imageForAddress:linphone_chat_message_get_from_address(_message)]
- bordered:NO
- withRoundedRadius:YES];
- }
- _contactDateLabel.text = [self.class ContactDateForChat:_message];
-
- _backgroundColorImage.image = _bottomBarColor.image =
+ _backgroundColorImage.image =
[UIImage imageNamed:(outgoing ? @"color_A.png" : @"color_D.png")];
- _contactDateLabel.textColor = [UIColor colorWithPatternImage:_backgroundColorImage.image];
+
+ // set maskedCorners
+ if (@available(iOS 11.0, *)) {
+ _backgroundColorImage.layer.cornerRadius = 10;
+ if (outgoing) {
+ _backgroundColorImage.layer.maskedCorners = kCALayerMinXMaxYCorner | kCALayerMinXMinYCorner;
+ if (_isFirst)
+ _backgroundColorImage.layer.maskedCorners = _backgroundColorImage.layer.maskedCorners | kCALayerMaxXMinYCorner;
+ if (_isLast)
+ _backgroundColorImage.layer.maskedCorners = _backgroundColorImage.layer.maskedCorners | kCALayerMaxXMaxYCorner;
+ } else {
+ _backgroundColorImage.layer.maskedCorners = kCALayerMaxXMinYCorner | kCALayerMaxXMaxYCorner;
+ if (_isFirst)
+ _backgroundColorImage.layer.maskedCorners = _backgroundColorImage.layer.maskedCorners | kCALayerMinXMinYCorner;
+ if (_isLast)
+ _backgroundColorImage.layer.maskedCorners = _backgroundColorImage.layer.maskedCorners | kCALayerMinXMaxYCorner;
+ }
+ _backgroundColorImage.layer.masksToBounds = YES;
+ } else {
+ // TODO it doesn't work for ios < 11.0
+ UIRectCorner corner;
+ if (outgoing) {
+ corner = UIRectCornerTopLeft | UIRectCornerBottomLeft;
+ if (_isFirst)
+ corner = corner | UIRectCornerTopRight;
+ if (_isLast)
+ corner = corner | UIRectCornerBottomRight;
+ } else {
+ corner = UIRectCornerTopRight | UIRectCornerBottomRight;
+ if (_isFirst)
+ corner = corner | UIRectCornerTopLeft;
+ if (_isLast)
+ corner = corner | UIRectCornerBottomLeft;
+ }
+ UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:_backgroundColorImage.frame byRoundingCorners:corner cornerRadii:CGSizeMake(10,10)];
+ CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
+ maskLayer.frame = _backgroundColorImage.frame;
+ maskLayer.path = maskPath.CGPath;
+ _backgroundColorImage.layer.mask = maskLayer;
+ }
+
+ // need space for dateLabel
+ CGRect frame = _innerView.frame;
+ frame.origin.y = _isFirst ? 20 : 0;
+ _innerView.frame = frame;
+
+
+ //_contactDateLabel.textColor = [UIColor colorWithPatternImage:_backgroundColorImage.image];
- if (outgoing && state == LinphoneChatMessageStateInProgress) {
+ /*if (outgoing && state == LinphoneChatMessageStateInProgress) {
[_statusInProgressSpinner startAnimating];
} else if (!outgoing && state == LinphoneChatMessageStateFileTransferError) {
[_statusInProgressSpinner stopAnimating];
} else {
[_statusInProgressSpinner stopAnimating];
- }
+ }*/
[_messageText setAccessibilityLabel:outgoing ? @"Outgoing message" : @"Incoming message"];
if (outgoing &&
@@ -175,12 +231,12 @@
} else
[self displayImdmStatus:LinphoneChatMessageStateInProgress];
- if (!outgoing && !linphone_chat_message_is_secured(_message) &&
+ /*if (!outgoing && !linphone_chat_message_is_secured(_message) &&
linphone_core_lime_enabled(LC) == LinphoneLimeMandatory) {
_LIMEKO.hidden = FALSE;
} else {
_LIMEKO.hidden = TRUE;
- }
+ }*/
}
- (void)setEditing:(BOOL)editing {
@@ -250,8 +306,8 @@
}
- (void)onLime {
- if (!_LIMEKO.hidden)
- [self displayLIMEWarning];
+ /*if (!_LIMEKO.hidden)
+ [self displayLIMEWarning];*/
}
- (void)onResend {
@@ -349,25 +405,25 @@ static void message_status(LinphoneChatMessage *msg, LinphoneChatMessageState st
- (void)displayImdmStatus:(LinphoneChatMessageState)state {
if (state == LinphoneChatMessageStateDeliveredToUser) {
[_imdmIcon setImage:[UIImage imageNamed:@"chat_delivered"]];
- [_imdmLabel setText:NSLocalizedString(@"Delivered", nil)];
- [_imdmLabel setTextColor:[UIColor grayColor]];
+ //[_imdmLabel setText:NSLocalizedString(@"Delivered", nil)];
+ //[_imdmLabel setTextColor:[UIColor grayColor]];
[_imdmIcon setHidden:FALSE];
- [_imdmLabel setHidden:FALSE];
+ //[_imdmLabel setHidden:FALSE];
} else if (state == LinphoneChatMessageStateDisplayed) {
[_imdmIcon setImage:[UIImage imageNamed:@"chat_read"]];
- [_imdmLabel setText:NSLocalizedString(@"Read", nil)];
- [_imdmLabel setTextColor:([UIColor colorWithRed:(24 / 255.0) green:(167 / 255.0) blue:(175 / 255.0) alpha:1.0])];
+ //[_imdmLabel setText:NSLocalizedString(@"Read", nil)];
+ //[_imdmLabel setTextColor:([UIColor colorWithRed:(24 / 255.0) green:(167 / 255.0) blue:(175 / 255.0) alpha:1.0])];
[_imdmIcon setHidden:FALSE];
- [_imdmLabel setHidden:FALSE];
+ //[_imdmLabel setHidden:FALSE];
} else if (state == LinphoneChatMessageStateNotDelivered || state == LinphoneChatMessageStateFileTransferError) {
[_imdmIcon setImage:[UIImage imageNamed:@"chat_error"]];
- [_imdmLabel setText:NSLocalizedString(@"Resend", nil)];
- [_imdmLabel setTextColor:[UIColor redColor]];
+ //[_imdmLabel setText:NSLocalizedString(@"Resend", nil)];
+ //[_imdmLabel setTextColor:[UIColor redColor]];
[_imdmIcon setHidden:FALSE];
- [_imdmLabel setHidden:FALSE];
+ //[_imdmLabel setHidden:FALSE];
} else {
[_imdmIcon setHidden:TRUE];
- [_imdmLabel setHidden:TRUE];
+ //[_imdmLabel setHidden:TRUE];
}
}
@@ -389,7 +445,7 @@ static void message_status(LinphoneChatMessage *msg, LinphoneChatMessageState st
static const CGFloat CELL_MIN_HEIGHT = 60.0f;
static const CGFloat CELL_MIN_WIDTH = 190.0f;
static const CGFloat CELL_MESSAGE_X_MARGIN = 78 + 10.0f;
-static const CGFloat CELL_MESSAGE_Y_MARGIN = 52; // 44;
+static const CGFloat CELL_MESSAGE_Y_MARGIN = 44; // 44;
+ (CGSize)ViewHeightForMessage:(LinphoneChatMessage *)chat withWidth:(int)width {
return [self ViewHeightForMessageText:chat withWidth:width textForImdn:nil];
@@ -480,6 +536,7 @@ static const CGFloat CELL_MESSAGE_Y_MARGIN = 52; // 44;
CGSize messageSize = [self ViewHeightForMessage:chat withWidth:width];
CGSize dateSize = [self computeBoundingBox:[self ContactDateForChat:chat] size:dateViewSize font:dateFont];
messageSize.width = MAX(MAX(messageSize.width, MIN(dateSize.width + CELL_MESSAGE_X_MARGIN, width)), CELL_MIN_WIDTH);
+ messageSize.width = MAX(MAX(messageSize.width, MIN(CELL_MESSAGE_X_MARGIN, width)), CELL_MIN_WIDTH);
return messageSize;
}
diff --git a/Resources/images/chat_delivered.png b/Resources/images/chat_delivered.png
index 9d741055d..356b8ecd1 100644
Binary files a/Resources/images/chat_delivered.png and b/Resources/images/chat_delivered.png differ
diff --git a/Resources/images/chat_error.png b/Resources/images/chat_error.png
index 3791317c2..b7789c9a0 100644
Binary files a/Resources/images/chat_error.png and b/Resources/images/chat_error.png differ
diff --git a/Resources/images/chat_read.png b/Resources/images/chat_read.png
index b7ae0d29a..8f8f467c1 100644
Binary files a/Resources/images/chat_read.png and b/Resources/images/chat_read.png differ