Add verification state change messages.

// FREEBIE
This commit is contained in:
Matthew Chen 2017-06-07 16:51:22 -04:00
parent 7335fc4d01
commit bc63a72c25
14 changed files with 177 additions and 82 deletions

View File

@ -136,7 +136,7 @@ CHECKOUT OPTIONS:
:commit: 7054e4b13ee5bcd6d524adb6dc9a726e8c466308
:git: https://github.com/WhisperSystems/JSQMessagesViewController.git
SignalServiceKit:
:commit: fba94754a6382b7fa55835ac25c7dd9931e594d8
:commit: f2f654af194c9b232ccf2b3d382f8a096bffcd00
:git: https://github.com/WhisperSystems/SignalServiceKit.git
SocketRocket:
:commit: 877ac7438be3ad0b45ef5ca3969574e4b97112bf

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "system_message_verified@1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "system_message_verified@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "system_message_verified@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -52,8 +52,6 @@
#import <SignalServiceKit/OWSDispatch.h>
#import <SignalServiceKit/OWSEndSessionMessage.h>
#import <SignalServiceKit/OWSError.h>
#import <SignalServiceKit/OWSFingerprint.h>
#import <SignalServiceKit/OWSFingerprintBuilder.h>
#import <SignalServiceKit/OWSGetMessagesRequest.h>
#import <SignalServiceKit/OWSGetProfileRequest.h>
#import <SignalServiceKit/OWSIdentityManager.h>

View File

@ -72,10 +72,9 @@
#import <SignalServiceKit/OWSAttachmentsProcessor.h>
#import <SignalServiceKit/OWSBlockingManager.h>
#import <SignalServiceKit/OWSDisappearingMessagesConfiguration.h>
#import <SignalServiceKit/OWSFingerprint.h>
#import <SignalServiceKit/OWSFingerprintBuilder.h>
#import <SignalServiceKit/OWSMessageSender.h>
#import <SignalServiceKit/OWSUnknownContactBlockOfferMessage.h>
#import <SignalServiceKit/OWSVerificationStateChangeMessage.h>
#import <SignalServiceKit/SignalRecipient.h>
#import <SignalServiceKit/TSAccountManager.h>
#import <SignalServiceKit/TSGroupModel.h>
@ -1175,19 +1174,12 @@ typedef enum : NSUInteger {
completion:completionHandler];
}
- (void)showFingerprintWithTheirIdentityKey:(NSData *)theirIdentityKey theirSignalId:(NSString *)theirSignalId
- (void)showFingerprintWithRecipientId:(NSString *)recipientId
{
// Ensure keyboard isn't hiding the "safety numbers changed" interaction when we
// return from FingerprintViewController.
[self dismissKeyBoard];
OWSFingerprintBuilder *builder =
[[OWSFingerprintBuilder alloc] initWithStorageManager:self.storageManager contactsManager:self.contactsManager];
OWSFingerprint *fingerprint =
[builder fingerprintWithTheirSignalId:theirSignalId theirIdentityKey:theirIdentityKey];
NSString *contactName = [self.contactsManager displayNameForPhoneIdentifier:theirSignalId];
UIViewController *viewController =
[[UIStoryboard main] instantiateViewControllerWithIdentifier:@"FingerprintViewController"];
if (![viewController isKindOfClass:[FingerprintViewController class]]) {
@ -1196,8 +1188,7 @@ typedef enum : NSUInteger {
return;
}
FingerprintViewController *fingerprintViewController = (FingerprintViewController *)viewController;
[fingerprintViewController configureWithFingerprint:fingerprint contactName:contactName];
[fingerprintViewController configureWithRecipientId:recipientId];
[self presentViewController:fingerprintViewController animated:YES completion:nil];
}
@ -2248,18 +2239,7 @@ typedef enum : NSUInteger {
{
NSParameterAssert(signalId != nil);
OWSFingerprintBuilder *fingerprintBuilder =
[[OWSFingerprintBuilder alloc] initWithStorageManager:self.storageManager contactsManager:self.contactsManager];
OWSFingerprint *fingerprint = [fingerprintBuilder fingerprintWithTheirSignalId:signalId];
FingerprintViewController *fingerprintViewController =
[[UIStoryboard main] instantiateViewControllerWithIdentifier:@"FingerprintViewController"];
NSString *contactName = [self.contactsManager displayNameForPhoneIdentifier:signalId];
[fingerprintViewController configureWithFingerprint:fingerprint contactName:contactName];
[self presentViewController:fingerprintViewController animated:YES completion:nil];
[self showFingerprintWithRecipientId:signalId];
}
- (void)handleInfoMessageTap:(TSInfoMessage *)message
@ -2286,6 +2266,9 @@ typedef enum : NSUInteger {
case TSInfoMessageTypeDisappearingMessagesUpdate:
[self showConversationSettings];
return;
case TSInfoMessageVerificationStateChange:
[self showFingerprintWithRecipientId:((OWSVerificationStateChangeMessage *)message).recipientId];
break;
}
DDLogInfo(@"%@ Unhandled tap for info message:%@", self.tag, message);
@ -2345,8 +2328,7 @@ typedef enum : NSUInteger {
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
DDLogInfo(@"%@ Remote Key Changed actions: Show fingerprint display", self.tag);
[self showFingerprintWithTheirIdentityKey:errorMessage.newIdentityKey
theirSignalId:errorMessage.theirSignalId];
[self showFingerprintWithRecipientId:errorMessage.theirSignalId];
}];
[actionSheetController addAction:showSafteyNumberAction];

View File

@ -10,6 +10,7 @@
#import <AxolotlKit/PreKeyBundle.h>
#import <SignalServiceKit/OWSDisappearingConfigurationUpdateInfoMessage.h>
#import <SignalServiceKit/OWSDisappearingMessagesConfiguration.h>
#import <SignalServiceKit/OWSVerificationStateChangeMessage.h>
#import <SignalServiceKit/TSCall.h>
#import <SignalServiceKit/TSInvalidIdentityKeyReceivingErrorMessage.h>
#import <SignalServiceKit/TSStorageManager+SessionStore.h>
@ -640,6 +641,39 @@ NS_ASSUME_NONNULL_BEGIN
inThread:thread
messageType:TSInfoMessageTypeGroupQuit]];
[result addObject:[[OWSVerificationStateChangeMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
thread:thread
recipientId:@"+19174054215"
verificationState:OWSVerificationStateDefault
isLocalChange:YES]];
[result addObject:[[OWSVerificationStateChangeMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
thread:thread
recipientId:@"+19174054215"
verificationState:OWSVerificationStateVerified
isLocalChange:YES]];
[result
addObject:[[OWSVerificationStateChangeMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
thread:thread
recipientId:@"+19174054215"
verificationState:OWSVerificationStateNoLongerVerified
isLocalChange:YES]];
[result addObject:[[OWSVerificationStateChangeMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
thread:thread
recipientId:@"+19174054215"
verificationState:OWSVerificationStateDefault
isLocalChange:NO]];
[result addObject:[[OWSVerificationStateChangeMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
thread:thread
recipientId:@"+19174054215"
verificationState:OWSVerificationStateVerified
isLocalChange:NO]];
[result
addObject:[[OWSVerificationStateChangeMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
thread:thread
recipientId:@"+19174054215"
verificationState:OWSVerificationStateNoLongerVerified
isLocalChange:NO]];
[result addObject:[TSErrorMessage missingSessionWithEnvelope:[self createEnvelopeForThread:thread]
withTransaction:transaction]];
[result addObject:[TSErrorMessage invalidKeyExceptionWithEnvelope:[self createEnvelopeForThread:thread]

View File

@ -13,8 +13,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nullable) OWSConversationSettingsTableViewController *dismissDelegate;
- (void)configureWithFingerprint:(OWSFingerprint *)fingerprint
contactName:(NSString *)contactName NS_SWIFT_NAME(configure(fingerprint:contactName:));
- (void)configureWithRecipientId:(NSString *)recipientId NS_SWIFT_NAME(configure(recipientId:));
- (void)controller:(OWSQRCodeScanningViewController *)controller didDetectQRCodeWithData:(NSData *)data;

View File

@ -11,6 +11,7 @@
#import <SignalServiceKit/NSDate+millisecondTimeStamp.h>
#import <SignalServiceKit/OWSError.h>
#import <SignalServiceKit/OWSFingerprint.h>
#import <SignalServiceKit/OWSFingerprintBuilder.h>
#import <SignalServiceKit/OWSIdentityManager.h>
#import <SignalServiceKit/TSInfoMessage.h>
#import <SignalServiceKit/TSStorageManager+SessionStore.h>
@ -20,34 +21,46 @@ NS_ASSUME_NONNULL_BEGIN
@interface FingerprintViewController () <OWSHighlightableLabelDelegate, OWSCompareSafetyNumbersActivityDelegate>
@property (strong, nonatomic) TSStorageManager *storageManager;
@property (strong, nonatomic) OWSFingerprint *fingerprint;
@property (strong, nonatomic) NSString *contactName;
@property (strong, nonatomic) OWSQRCodeScanningViewController *qrScanningController;
@property (nonatomic) TSStorageManager *storageManager;
@property (nonatomic) OWSFingerprint *fingerprint;
@property (nonatomic) NSString *contactName;
@property (nonatomic) OWSQRCodeScanningViewController *qrScanningController;
@property (strong, nonatomic) IBOutlet UINavigationBar *modalNavigationBar;
@property (strong, nonatomic) IBOutlet UIBarButtonItem *dismissModalButton;
@property (strong, nonatomic) IBOutlet UIBarButtonItem *shareButton;
@property (strong, nonatomic) IBOutlet UIView *qrScanningView;
@property (strong, nonatomic) IBOutlet UILabel *scanningInstructions;
@property (strong, nonatomic) IBOutlet UIView *scanningContainer;
@property (strong, nonatomic) IBOutlet UIView *instructionsContainer;
@property (strong, nonatomic) IBOutlet UIView *qrContainer;
@property (strong, nonatomic) IBOutlet UIView *privacyVerificationQRCodeFrame;
@property (strong, nonatomic) IBOutlet UIImageView *privacyVerificationQRCode;
@property (strong, nonatomic) IBOutlet OWSHighlightableLabel *privacyVerificationFingerprint;
@property (strong, nonatomic) IBOutlet UILabel *instructionsLabel;
@property (strong, nonatomic) IBOutlet UIButton *scanButton;
@property (nonatomic) IBOutlet UINavigationBar *modalNavigationBar;
@property (nonatomic) IBOutlet UIBarButtonItem *dismissModalButton;
@property (nonatomic) IBOutlet UIBarButtonItem *shareButton;
@property (nonatomic) IBOutlet UIView *qrScanningView;
@property (nonatomic) IBOutlet UILabel *scanningInstructions;
@property (nonatomic) IBOutlet UIView *scanningContainer;
@property (nonatomic) IBOutlet UIView *instructionsContainer;
@property (nonatomic) IBOutlet UIView *qrContainer;
@property (nonatomic) IBOutlet UIView *privacyVerificationQRCodeFrame;
@property (nonatomic) IBOutlet UIImageView *privacyVerificationQRCode;
@property (nonatomic) IBOutlet OWSHighlightableLabel *privacyVerificationFingerprint;
@property (nonatomic) IBOutlet UILabel *instructionsLabel;
@property (nonatomic) IBOutlet UIButton *scanButton;
@end
@implementation FingerprintViewController
- (void)configureWithFingerprint:(OWSFingerprint *)fingerprint
contactName:(NSString *)contactName
- (void)configureWithRecipientId:(NSString *)recipientId
{
self.fingerprint = fingerprint;
self.contactName = contactName;
OWSAssert(recipientId.length > 0);
self.storageManager = [TSStorageManager sharedManager];
OWSContactsManager *contactsManager = [Environment getCurrent].contactsManager;
self.contactName = [contactsManager displayNameForPhoneIdentifier:recipientId];
OWSRecipientIdentity *_Nullable recipientIdentity =
[[OWSIdentityManager sharedManager] recipientIdentityForRecipientId:recipientId];
OWSAssert(recipientIdentity);
OWSFingerprintBuilder *builder =
[[OWSFingerprintBuilder alloc] initWithStorageManager:self.storageManager contactsManager:contactsManager];
self.fingerprint =
[builder fingerprintWithTheirSignalId:recipientId theirIdentityKey:recipientIdentity.identityKey];
}
- (void)viewDidLoad
@ -63,8 +76,6 @@ NS_ASSUME_NONNULL_BEGIN
self.modalNavigationBar.shadowImage = [UIImage new];
self.modalNavigationBar.translucent = YES;
self.storageManager = [TSStorageManager sharedManager];
// HACK to get full width preview layer
CGRect oldFrame = self.qrScanningView.frame;
CGRect newFrame = CGRectMake(oldFrame.origin.x,

View File

@ -21,8 +21,6 @@
#import <SignalServiceKit/NSDate+millisecondTimeStamp.h>
#import <SignalServiceKit/OWSDisappearingConfigurationUpdateInfoMessage.h>
#import <SignalServiceKit/OWSDisappearingMessagesConfiguration.h>
#import <SignalServiceKit/OWSFingerprint.h>
#import <SignalServiceKit/OWSFingerprintBuilder.h>
#import <SignalServiceKit/OWSMessageSender.h>
#import <SignalServiceKit/OWSNotifyRemoteOfUpdatedDisappearingConfigurationJob.h>
#import <SignalServiceKit/TSGroupThread.h>
@ -226,18 +224,8 @@ NS_ASSUME_NONNULL_BEGIN
}
FingerprintViewController *fingerprintViewController = [[UIStoryboard main]
instantiateViewControllerWithIdentifier:@"FingerprintViewController"];
OWSFingerprintBuilder *fingerprintBuilder =
[[OWSFingerprintBuilder alloc] initWithStorageManager:strongSelf.storageManager
contactsManager:strongSelf.contactsManager];
OWSFingerprint *fingerprint =
[fingerprintBuilder fingerprintWithTheirSignalId:strongSelf.thread.contactIdentifier];
[fingerprintViewController configureWithFingerprint:fingerprint
contactName:[strongSelf threadName]];
[fingerprintViewController configureWithRecipientId:strongSelf.thread.contactIdentifier];
fingerprintViewController.dismissDelegate = strongSelf;
[strongSelf presentViewController:fingerprintViewController animated:YES completion:nil];
}]];
}

View File

@ -84,10 +84,7 @@ class SafetyNumberConfirmationAlert: NSObject {
public func presentSafetyNumberViewController(theirIdentityKey: Data, theirRecipientId: String, theirDisplayName: String, completion: (() -> Void)? = nil) {
let fingerprintViewController = UIStoryboard.instantiateFingerprintViewController()
let fingerprintBuilder = OWSFingerprintBuilder(storageManager: self.storageManager, contactsManager: self.contactsManager)
let fingerprint = fingerprintBuilder.fingerprint(withTheirSignalId: theirRecipientId, theirIdentityKey: theirIdentityKey)
fingerprintViewController.configure(fingerprint: fingerprint, contactName: theirDisplayName)
fingerprintViewController.configure(recipientId: theirRecipientId)
UIApplication.shared.frontmostViewController?.present(fingerprintViewController, animated: true, completion: completion)
}

View File

@ -3,12 +3,15 @@
//
#import "OWSSystemMessageCell.h"
#import "Environment.h"
#import "NSBundle+JSQMessages.h"
#import "OWSContactsManager.h"
#import "TSUnreadIndicatorInteraction.h"
#import "UIColor+OWS.h"
#import "UIFont+OWS.h"
#import "UIView+OWS.h"
#import <JSQMessagesViewController/UIView+JSQMessages.h>
#import <SignalServiceKit/OWSVerificationStateChangeMessage.h>
#import <SignalServiceKit/TSCall.h>
#import <SignalServiceKit/TSErrorMessage.h>
#import <SignalServiceKit/TSInfoMessage.h>
@ -81,13 +84,13 @@
UIImage *icon = [self iconForInteraction:self.interaction];
self.imageView.image = [icon imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
self.imageView.tintColor = [self iconColorForInteraction:self.interaction];
self.titleLabel.text = [OWSSystemMessageCell titleForInteraction:self.interaction];
self.titleLabel.textColor = [self textColorForInteraction:self.interaction];
self.titleLabel.textColor = [OWSSystemMessageCell textColor];
[OWSSystemMessageCell applyTitleForInteraction:self.interaction label:self.titleLabel];
[self setNeedsLayout];
}
- (UIColor *)textColorForInteraction:(TSInteraction *)interaction
+ (UIColor *)textColor
{
return [UIColor colorWithRGBHex:0x303030];
}
@ -134,6 +137,9 @@
case TSInfoMessageTypeDisappearingMessagesUpdate:
result = [UIImage imageNamed:@"system_message_timer"];
break;
case TSInfoMessageVerificationStateChange:
result = [UIImage imageNamed:@"system_message_verified"];
break;
}
} else if ([interaction isKindOfClass:[TSCall class]]) {
result = [UIImage imageNamed:@"system_message_call"];
@ -145,19 +151,66 @@
return result;
}
+ (NSString *)titleForInteraction:(TSInteraction *)interaction
+ (void)applyTitleForInteraction:(TSInteraction *)interaction label:(UILabel *)label
{
OWSAssert(interaction);
OWSAssert(label);
// TODO: Should we move the copy generation into this view?
if ([interaction isKindOfClass:[TSErrorMessage class]]) {
return interaction.description;
label.text = interaction.description;
} else if ([interaction isKindOfClass:[TSInfoMessage class]]) {
return interaction.description;
if ([interaction isKindOfClass:[OWSVerificationStateChangeMessage class]]) {
OWSVerificationStateChangeMessage *message = (OWSVerificationStateChangeMessage *)interaction;
UIFont *titleFont = [self titleFont];
NSMutableAttributedString *title = [NSMutableAttributedString new];
BOOL isVerified = message.verificationState == OWSVerificationStateVerified;
// if (isVerified) {
// [title
// appendAttributedString:[[NSAttributedString alloc]
// initWithString:@"\uf00c "
// attributes:@{
// NSFontAttributeName : [UIFont
// ows_fontAwesomeFont:titleFont.pointSize],
// NSForegroundColorAttributeName : [UIColor
// ows_signalBrandBlueColor],
//// NSBaselineOffsetAttributeName : @(-1.f),
// }]];
// }
NSString *displayName =
[[Environment getCurrent].contactsManager displayNameForPhoneIdentifier:message.recipientId];
NSString *titleFormat = (isVerified
? (message.isLocalChange
? NSLocalizedString(@"VERIFICATION_STATE_CHANGE_FORMAT_VERIFIED_LOCAL",
@"Format for info message indicating that the verification state was verified on "
@"this device. Embeds {{user's name or phone number}}.")
: NSLocalizedString(@"VERIFICATION_STATE_CHANGE_FORMAT_VERIFIED_OTHER_DEVICE",
@"Format for info message indicating that the verification state was verified on "
@"another device. Embeds {{user's name or phone number}}."))
: (message.isLocalChange
? NSLocalizedString(@"VERIFICATION_STATE_CHANGE_FORMAT_NOT_VERIFIED_LOCAL",
@"Format for info message indicating that the verification state was unverified on "
@"this device. Embeds {{user's name or phone number}}.")
: NSLocalizedString(@"VERIFICATION_STATE_CHANGE_FORMAT_NOT_VERIFIED_OTHER_DEVICE",
@"Format for info message indicating that the verification state was unverified on "
@"another device. Embeds {{user's name or phone number}}.")));
[title appendAttributedString:[[NSAttributedString alloc]
initWithString:[NSString stringWithFormat:titleFormat, displayName]
attributes:@{
NSFontAttributeName : titleFont,
NSForegroundColorAttributeName : [self textColor],
}]];
label.attributedText = title;
} else {
label.text = interaction.description;
}
} else if ([interaction isKindOfClass:[TSCall class]]) {
return interaction.description;
label.text = interaction.description;
} else {
OWSFail(@"Unknown interaction type: %@", [interaction class]);
return nil;
label.text = nil;
}
}
@ -216,13 +269,11 @@
result.height += self.topVMargin;
result.height += self.bottomVMargin;
NSString *title = [self titleForInteraction:interaction];
// Creating a UILabel to measure the layout is expensive, but it's the only
// reliable way to do it.
UILabel *label = [UILabel new];
label.font = [self titleFont];
label.text = title;
[OWSSystemMessageCell applyTitleForInteraction:interaction label:label];
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
CGFloat maxTitleWidth = (collectionViewWidth - ([self hMargin] * 2.f + [self hSpacing] + [self iconSize]));

View File

@ -1390,6 +1390,18 @@
/* Label indicating the phone number currently being verified. */
"VERIFICATION_PHONE_NUMBER_FORMAT" = "Enter the verification code we sent to %@.";
/* Format for info message indicating that the verification state was unverified on this device. Embeds {{user's name or phone number}}. */
"VERIFICATION_STATE_CHANGE_FORMAT_NOT_VERIFIED_LOCAL" = "You unverified %@.";
/* Format for info message indicating that the verification state was unverified on another device. Embeds {{user's name or phone number}}. */
"VERIFICATION_STATE_CHANGE_FORMAT_NOT_VERIFIED_OTHER_DEVICE" = "You unverified %@ on another device.";
/* Format for info message indicating that the verification state was verified on this device. Embeds {{user's name or phone number}}. */
"VERIFICATION_STATE_CHANGE_FORMAT_VERIFIED_LOCAL" = "You verified %@.";
/* Format for info message indicating that the verification state was verified on another device. Embeds {{user's name or phone number}}. */
"VERIFICATION_STATE_CHANGE_FORMAT_VERIFIED_OTHER_DEVICE" = "You verified %@ on another device.";
/* Action sheet item
table cell label in conversation settings */
"VERIFY_PRIVACY" = "Show Safety Number";