conversation view: catch exceptions when accessing message
Change-Id: If37ba4974aee4c30ddc30baaa12af5846089b6be
diff --git a/src/MessagesVC.mm b/src/MessagesVC.mm
index 3da0f0d..754c94d 100644
--- a/src/MessagesVC.mm
+++ b/src/MessagesVC.mm
@@ -680,82 +680,84 @@
- (CGFloat)tableView:(NSTableView *)tableView heightOfRow:(NSInteger)row
{
- double someWidth = tableView.frame.size.width * 0.7;
+ try {
+ double someWidth = tableView.frame.size.width * 0.7;
- auto* conv = [self getCurrentConversation];
+ auto* conv = [self getCurrentConversation];
- if (conv == nil)
- return HEIGHT_DEFAULT;
+ if (conv == nil)
+ return HEIGHT_DEFAULT;
- auto size = [conversationView numberOfRows] - 1;
- if (row >= size) {
- //last item peer composing view
- if (peerComposingMessage) {
- return HEIGHT_FOR_COMPOSING_INDICATOR;
+ auto size = [conversationView numberOfRows] - 1;
+ if (row >= size) {
+ //last item peer composing view
+ if (peerComposingMessage) {
+ return HEIGHT_FOR_COMPOSING_INDICATOR;
+ }
+ return 1;
}
+
+ auto it = conv->interactions.begin();
+
+ std::advance(it, row);
+
+ if (it == conv->interactions.end()) {
+ return HEIGHT_DEFAULT;
+ }
+
+ auto interaction = it->second;
+
+ MessageSequencing sequence = [self computeSequencingFor:row];
+
+ bool shouldDisplayTime = (sequence == FIRST_WITH_TIME || sequence == SINGLE_WITH_TIME) ? YES : NO;
+
+ if(interaction.type == lrc::api::interaction::Type::DATA_TRANSFER) {
+ if( interaction.status == lrc::api::interaction::Status::TRANSFER_FINISHED) {
+ NSString* name = interaction.body.toNSString();
+ NSImage* image = [self getImageForFilePath:name];
+ if (([name rangeOfString:@"/"].location == NSNotFound)) {
+ image = [self getImageForFilePath:[self getDataTransferPath:it->first]];
+ }
+ if (image != nil) {
+ CGFloat widthScaleFactor = MAX_TRANSFERED_IMAGE_SIZE / image.size.width;
+ CGFloat heightScaleFactor = MAX_TRANSFERED_IMAGE_SIZE / image.size.height;
+ CGFloat heigt = 0;
+ if((widthScaleFactor >= 1) && (heightScaleFactor >= 1)) {
+ heigt = image.size.height;
+ } else {
+ CGFloat scale = MIN(widthScaleFactor, heightScaleFactor);
+ heigt = image.size.height * scale;
+ }
+ return heigt + TIME_BOX_HEIGHT;
+ }
+ }
+ return BUBBLE_HEIGHT_FOR_TRANSFERED_FILE + TIME_BOX_HEIGHT;
+ }
+
+ if(interaction.type == lrc::api::interaction::Type::CONTACT || interaction.type == lrc::api::interaction::Type::CALL)
+ return GENERIC_CELL_HEIGHT;
+
+ NSString *text = interaction.body.toNSString();
+ text = [text removeEmptyLinesAtBorders];
+
+ CGSize messageSize = [self sizeFor: text maxWidth:tableView.frame.size.width * 0.7];
+ CGFloat singleLignMessageHeight = 15;
+
+ bool shouldApplyPadding = (sequence == FIRST_WITHOUT_TIME || sequence == SINGLE_WITHOUT_TIME) ? YES : NO;
+
+ if (shouldDisplayTime) {
+ return MAX(messageSize.height + TIME_BOX_HEIGHT + MESSAGE_TEXT_PADDING * 2,
+ TIME_BOX_HEIGHT + MESSAGE_TEXT_PADDING * 2 + singleLignMessageHeight);
+ }
+ if(shouldApplyPadding) {
+ return MAX(messageSize.height + MESSAGE_TEXT_PADDING * 2 + 15,
+ singleLignMessageHeight + MESSAGE_TEXT_PADDING * 2 + 15);
+ }
+ return MAX(messageSize.height + MESSAGE_TEXT_PADDING * 2,
+ singleLignMessageHeight + MESSAGE_TEXT_PADDING * 2);
+ } catch (std::out_of_range& e) {
return 1;
}
-
- auto it = conv->interactions.begin();
-
- std::advance(it, row);
-
- if (it == conv->interactions.end()) {
- return HEIGHT_DEFAULT;
- }
-
- auto interaction = it->second;
-
- MessageSequencing sequence = [self computeSequencingFor:row];
-
- bool shouldDisplayTime = (sequence == FIRST_WITH_TIME || sequence == SINGLE_WITH_TIME) ? YES : NO;
-
-
- if(interaction.type == lrc::api::interaction::Type::DATA_TRANSFER) {
-
- if( interaction.status == lrc::api::interaction::Status::TRANSFER_FINISHED) {
- NSString* name = interaction.body.toNSString();
- NSImage* image = [self getImageForFilePath:name];
- if (([name rangeOfString:@"/"].location == NSNotFound)) {
- image = [self getImageForFilePath:[self getDataTransferPath:it->first]];
- }
- if (image != nil) {
- CGFloat widthScaleFactor = MAX_TRANSFERED_IMAGE_SIZE / image.size.width;
- CGFloat heightScaleFactor = MAX_TRANSFERED_IMAGE_SIZE / image.size.height;
- CGFloat heigt = 0;
- if((widthScaleFactor >= 1) && (heightScaleFactor >= 1)) {
- heigt = image.size.height;
- } else {
- CGFloat scale = MIN(widthScaleFactor, heightScaleFactor);
- heigt = image.size.height * scale;
- }
- return heigt + TIME_BOX_HEIGHT;
- }
- }
- return BUBBLE_HEIGHT_FOR_TRANSFERED_FILE + TIME_BOX_HEIGHT;
- }
-
- if(interaction.type == lrc::api::interaction::Type::CONTACT || interaction.type == lrc::api::interaction::Type::CALL)
- return GENERIC_CELL_HEIGHT;
-
- NSString *text = interaction.body.toNSString();
- text = [text removeEmptyLinesAtBorders];
-
- CGSize messageSize = [self sizeFor: text maxWidth:tableView.frame.size.width * 0.7];
- CGFloat singleLignMessageHeight = 15;
-
- bool shouldApplyPadding = (sequence == FIRST_WITHOUT_TIME || sequence == SINGLE_WITHOUT_TIME) ? YES : NO;
-
- if (shouldDisplayTime) {
- return MAX(messageSize.height + TIME_BOX_HEIGHT + MESSAGE_TEXT_PADDING * 2,
- TIME_BOX_HEIGHT + MESSAGE_TEXT_PADDING * 2 + singleLignMessageHeight);
- }
- if(shouldApplyPadding) {
- return MAX(messageSize.height + MESSAGE_TEXT_PADDING * 2 + 15,
- singleLignMessageHeight + MESSAGE_TEXT_PADDING * 2 + 15);
- }
- return MAX(messageSize.height + MESSAGE_TEXT_PADDING * 2,
- singleLignMessageHeight + MESSAGE_TEXT_PADDING * 2);
}
#pragma mark - message view parameters
@@ -789,93 +791,97 @@
}
-(MessageSequencing) computeSequencingFor:(NSInteger) row {
- if (row >= conversationView.numberOfRows - 1) {
- return SINGLE_WITHOUT_TIME;
- }
- auto* conv = [self getCurrentConversation];
- if (conv == nil)
- return SINGLE_WITHOUT_TIME;
- auto it = conv->interactions.begin();
- std::advance(it, row);
- if (it == conv->interactions.end()) {
- return SINGLE_WITHOUT_TIME;
- }
- auto interaction = it->second;
- if (interaction.type != lrc::api::interaction::Type::TEXT) {
- return SINGLE_WITH_TIME;
- }
- // first message in comversation
- if (row == 0) {
+ try {
+ if (row >= conversationView.numberOfRows - 1) {
+ return SINGLE_WITHOUT_TIME;
+ }
+ auto* conv = [self getCurrentConversation];
+ if (conv == nil)
+ return SINGLE_WITHOUT_TIME;
+ auto it = conv->interactions.begin();
+ std::advance(it, row);
if (it == conv->interactions.end()) {
+ return SINGLE_WITHOUT_TIME;
+ }
+ auto interaction = it->second;
+ if (interaction.type != lrc::api::interaction::Type::TEXT) {
return SINGLE_WITH_TIME;
}
- auto nextIt = it;
- nextIt++;
- if (nextIt == conv->interactions.end()) {
+ // first message in comversation
+ if (row == 0) {
+ if (it == conv->interactions.end()) {
+ return SINGLE_WITH_TIME;
+ }
+ auto nextIt = it;
+ nextIt++;
+ if (nextIt == conv->interactions.end()) {
+ return SINGLE_WITH_TIME;
+ }
+ auto nextInteraction = nextIt->second;
+ if ([self sequenceChangedFrom:interaction to: nextInteraction]) {
+ return SINGLE_WITH_TIME;
+ }
+ return FIRST_WITH_TIME;
+ }
+ // last message in comversation
+ if (row == conversationView.numberOfRows - 2) {
+ if(it == conv->interactions.begin()) {
+ return SINGLE_WITH_TIME;
+ }
+ auto previousIt = it;
+ previousIt--;
+ auto previousInteraction = previousIt->second;
+ bool timeChanged = [self sequenceTimeChangedFrom:interaction to:previousInteraction];
+ bool authorChanged = [self sequenceAuthorChangedFrom:interaction to:previousInteraction];
+ if (!timeChanged && !authorChanged) {
+ return LAST_IN_SEQUENCE;
+ }
+ if (!timeChanged && authorChanged) {
+ return SINGLE_WITHOUT_TIME;
+ }
return SINGLE_WITH_TIME;
}
- auto nextInteraction = nextIt->second;
- if ([self sequenceChangedFrom:interaction to: nextInteraction]) {
+ // single message in comversation
+ if(it == conv->interactions.begin() || it == conv->interactions.end()) {
return SINGLE_WITH_TIME;
}
- return FIRST_WITH_TIME;
- }
- // last message in comversation
- if (row == conversationView.numberOfRows - 2) {
- if(it == conv->interactions.begin()) {
- return SINGLE_WITH_TIME;
- }
+ // message in the middle of conversation
auto previousIt = it;
previousIt--;
auto previousInteraction = previousIt->second;
- bool timeChanged = [self sequenceTimeChangedFrom:interaction to:previousInteraction];
- bool authorChanged = [self sequenceAuthorChangedFrom:interaction to:previousInteraction];
- if (!timeChanged && !authorChanged) {
- return LAST_IN_SEQUENCE;
- }
- if (!timeChanged && authorChanged) {
+ auto nextIt = it;
+ nextIt++;
+ if (nextIt == conv->interactions.end()) {
return SINGLE_WITHOUT_TIME;
}
- return SINGLE_WITH_TIME;
- }
- // single message in comversation
- if(it == conv->interactions.begin() || it == conv->interactions.end()) {
- return SINGLE_WITH_TIME;
- }
- // message in the middle of conversation
- auto previousIt = it;
- previousIt--;
- auto previousInteraction = previousIt->second;
- auto nextIt = it;
- nextIt++;
- if (nextIt == conv->interactions.end()) {
+ auto nextInteraction = nextIt->second;
+
+ bool timeChanged = [self sequenceTimeChangedFrom:interaction to:previousInteraction];
+ bool authorChanged = [self sequenceAuthorChangedFrom:interaction to:previousInteraction];
+ bool sequenceWillChange = [self sequenceChangedFrom:interaction to: nextInteraction];
+ if (previousInteraction.type == lrc::api::interaction::Type::DATA_TRANSFER) {
+ if(!sequenceWillChange) {
+ return FIRST_WITH_TIME;
+ }
+ return SINGLE_WITH_TIME;
+ }
+ if (!sequenceWillChange) {
+ if (!timeChanged && !authorChanged) {
+ return MIDDLE_IN_SEQUENCE;
+ }
+ if (timeChanged) {
+ return FIRST_WITH_TIME;
+ }
+ return FIRST_WITHOUT_TIME;
+ } if (!timeChanged && !authorChanged) {
+ return LAST_IN_SEQUENCE;
+ } if (timeChanged) {
+ return SINGLE_WITH_TIME;
+ }
+ return SINGLE_WITHOUT_TIME;
+ } catch (std::out_of_range& e) {
return SINGLE_WITHOUT_TIME;
}
- auto nextInteraction = nextIt->second;
-
- bool timeChanged = [self sequenceTimeChangedFrom:interaction to:previousInteraction];
- bool authorChanged = [self sequenceAuthorChangedFrom:interaction to:previousInteraction];
- bool sequenceWillChange = [self sequenceChangedFrom:interaction to: nextInteraction];
- if (previousInteraction.type == lrc::api::interaction::Type::DATA_TRANSFER) {
- if(!sequenceWillChange) {
- return FIRST_WITH_TIME;
- }
- return SINGLE_WITH_TIME;
- }
- if (!sequenceWillChange) {
- if (!timeChanged && !authorChanged) {
- return MIDDLE_IN_SEQUENCE;
- }
- if (timeChanged) {
- return FIRST_WITH_TIME;
- }
- return FIRST_WITHOUT_TIME;
- } if (!timeChanged && !authorChanged) {
- return LAST_IN_SEQUENCE;
- } if (timeChanged) {
- return SINGLE_WITH_TIME;
- }
- return SINGLE_WITHOUT_TIME;
}
-(bool) sequenceChangedFrom:(lrc::api::interaction::Info) firstInteraction to:(lrc::api::interaction::Info) secondInteraction {