RoomBubbleCellData: Handle key verification cells. Add key verification property and add key verification cell data tags.

This commit is contained in:
SBiOSoftWhare 2020-01-14 19:46:02 +01:00
parent c8a68fb2d8
commit d9408dda33
2 changed files with 167 additions and 25 deletions

View file

@ -22,9 +22,10 @@ typedef NS_ENUM(NSInteger, RoomBubbleCellDataTag)
RoomBubbleCellDataTagMessage = 0, // Default value used for messages
RoomBubbleCellDataTagMembership,
RoomBubbleCellDataTagRoomCreateWithPredecessor,
RoomBubbleCellDataTagDeviceKeyVerificationRequestIncomingApproval,
RoomBubbleCellDataTagDeviceKeyVerificationRequest,
RoomBubbleCellDataTagDeviceKeyVerificationConclusion
RoomBubbleCellDataTagKeyVerificationNoDisplay,
RoomBubbleCellDataTagKeyVerificationRequestIncomingApproval,
RoomBubbleCellDataTagKeyVerificationRequest,
RoomBubbleCellDataTagKeyVerificationConclusion
};
/**
@ -73,6 +74,16 @@ typedef NS_ENUM(NSInteger, RoomBubbleCellDataTag)
*/
@property(nonatomic, readonly) CGFloat additionalContentHeight;
/**
MXKeyVerification object associated to key verifcation event when using key verification by direct message.
*/
@property(nonatomic, strong) MXKeyVerification *keyVerification;
/**
Indicate if there is a pending operation that updates `keyVerification` property.
*/
@property(nonatomic) BOOL isKeyVerificationOperationPending;
/**
Indicate to update additional content height.
*/

View file

@ -86,23 +86,11 @@ static NSAttributedString *timestampVerticalWhitespace = nil;
}
}
break;
case MXEventTypeKeyVerificationCancel:
case MXEventTypeKeyVerificationDone:
self.tag = RoomBubbleCellDataTagDeviceKeyVerificationConclusion;
break;
case MXEventTypeRoomMessage:
{
NSString *msgType = event.content[@"msgtype"];
if ([msgType isEqualToString:kMXMessageTypeKeyVerificationRequest])
{
self.tag = RoomBubbleCellDataTagDeviceKeyVerificationRequest;
}
}
break;
default:
break;
}
[self keyVerificationDidUpdate];
// Increase maximum number of components
self.maxComponentCount = 20;
@ -167,6 +155,16 @@ static NSAttributedString *timestampVerticalWhitespace = nil;
return attributedTextMessage;
}
- (BOOL)hasNoDisplay
{
if (self.tag == RoomBubbleCellDataTagKeyVerificationNoDisplay)
{
return YES;
}
return [super hasNoDisplay];
}
#pragma mark - Bubble collapsing
- (BOOL)collapseWith:(id<MXKRoomBubbleCellDataStoring>)cellData
@ -683,21 +681,154 @@ static NSAttributedString *timestampVerticalWhitespace = nil;
- (BOOL)addEvent:(MXEvent*)event andRoomState:(MXRoomState*)roomState
{
if (self.tag == RoomBubbleCellDataTagMembership || event.eventType == MXEventTypeRoomMember)
BOOL shouldAddEvent = YES;
switch (self.tag)
{
// One single bubble per membership event
return NO;
case RoomBubbleCellDataTagKeyVerificationNoDisplay:
case RoomBubbleCellDataTagKeyVerificationRequest:
case RoomBubbleCellDataTagKeyVerificationRequestIncomingApproval:
case RoomBubbleCellDataTagKeyVerificationConclusion:
shouldAddEvent = NO;
break;
case RoomBubbleCellDataTagRoomCreateWithPredecessor:
// We do not want to merge room create event cells with other cell types
shouldAddEvent = NO;
break;
case RoomBubbleCellDataTagMembership:
// One single bubble per membership event
shouldAddEvent = NO;
break;
default:
break;
}
if (self.tag == RoomBubbleCellDataTagRoomCreateWithPredecessor || event.eventType == MXEventTypeRoomCreate)
if (shouldAddEvent)
{
// We do not want to merge room create event cells with other cell types
return NO;
switch (event.eventType)
{
case MXEventTypeRoomMessage:
{
NSString *messageType = event.content[@"msgtype"];
if ([messageType isEqualToString:kMXMessageTypeKeyVerificationRequest])
{
shouldAddEvent = NO;
}
}
break;
case MXEventTypeKeyVerificationStart:
case MXEventTypeKeyVerificationAccept:
case MXEventTypeKeyVerificationKey:
case MXEventTypeKeyVerificationMac:
case MXEventTypeKeyVerificationDone:
case MXEventTypeKeyVerificationCancel:
shouldAddEvent = NO;
break;
case MXEventTypeRoomMember:
shouldAddEvent = NO;
break;
case MXEventTypeRoomCreate:
shouldAddEvent = NO;
break;
default:
break;
}
}
return [super addEvent:event andRoomState:roomState];
if (shouldAddEvent)
{
shouldAddEvent = [super addEvent:event andRoomState:roomState];
}
return shouldAddEvent;
}
- (void)setKeyVerification:(MXKeyVerification *)keyVerification
{
_keyVerification = keyVerification;
[self keyVerificationDidUpdate];
}
- (void)keyVerificationDidUpdate
{
MXEvent *event = self.getFirstBubbleComponentWithDisplay.event;
MXKeyVerification *keyVerification = _keyVerification;
if (!event)
{
return;
}
switch (event.eventType)
{
case MXEventTypeKeyVerificationCancel:
{
RoomBubbleCellDataTag cellDataTag;
MXTransactionCancelCode *transactionCancelCode = keyVerification.transaction.reasonCancelCode;
if (transactionCancelCode
&& ([transactionCancelCode isEqual:[MXTransactionCancelCode mismatchedSas]]
|| [transactionCancelCode isEqual:[MXTransactionCancelCode mismatchedKeys]]
|| [transactionCancelCode isEqual:[MXTransactionCancelCode mismatchedCommitment]]
)
)
{
cellDataTag = RoomBubbleCellDataTagKeyVerificationConclusion;
}
else
{
cellDataTag = RoomBubbleCellDataTagKeyVerificationNoDisplay;
}
self.tag = cellDataTag;
}
break;
case MXEventTypeKeyVerificationDone:
{
RoomBubbleCellDataTag cellDataTag;
// Avoid to display incoming and outgoing done, only display the incoming one.
if (self.isIncoming && keyVerification && (keyVerification.state == MXKeyVerificationStateVerified))
{
cellDataTag = RoomBubbleCellDataTagKeyVerificationConclusion;
}
else
{
cellDataTag = RoomBubbleCellDataTagKeyVerificationNoDisplay;
}
self.tag = cellDataTag;
}
break;
case MXEventTypeRoomMessage:
{
NSString *msgType = event.content[@"msgtype"];
if ([msgType isEqualToString:kMXMessageTypeKeyVerificationRequest])
{
RoomBubbleCellDataTag cellDataTag;
if (self.isIncoming && !self.isKeyVerificationOperationPending && keyVerification && keyVerification.state == MXKeyVerificationRequestStatePending)
{
cellDataTag = RoomBubbleCellDataTagKeyVerificationRequestIncomingApproval;
}
else
{
cellDataTag = RoomBubbleCellDataTagKeyVerificationRequest;
}
self.tag = cellDataTag;
}
}
break;
default:
break;
}
}
#pragma mark - Show all reactions