Share dialog for Safety Numbers

// FREEBIE
This commit is contained in:
Michael Kirk 2016-11-15 12:51:55 -05:00
parent 9b2c03793c
commit 88d9ef987f
48 changed files with 142 additions and 58 deletions

View File

@ -46,7 +46,7 @@
458E383A1D6699FA0094BD24 /* OWSDeviceProvisioningURLParserTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 458E38391D6699FA0094BD24 /* OWSDeviceProvisioningURLParserTest.m */; };
459311FC1D75C948008DD4F0 /* OWSDeviceTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 459311FB1D75C948008DD4F0 /* OWSDeviceTableViewCell.m */; };
459C3F0D1C9B3A1B003ACF51 /* TSMessageAdapterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 459C3F0C1C9B3A1B003ACF51 /* TSMessageAdapterTest.m */; };
45B201761DAECBFE00C461E0 /* CopyableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45B201751DAECBFE00C461E0 /* CopyableLabel.swift */; };
45B201761DAECBFE00C461E0 /* HighlightableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45B201751DAECBFE00C461E0 /* HighlightableLabel.swift */; };
45BFFFA81D898AF0004A12A7 /* OWSStaleNotificationObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 45BFFFA71D898AF0004A12A7 /* OWSStaleNotificationObserver.m */; };
45BFFFA91D898AF0004A12A7 /* OWSStaleNotificationObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 45BFFFA71D898AF0004A12A7 /* OWSStaleNotificationObserver.m */; };
45C681B71D305A580050903A /* OWSCall.m in Sources */ = {isa = PBXBuildFile; fileRef = 45C681B61D305A580050903A /* OWSCall.m */; };
@ -597,7 +597,7 @@
4597E94F1D8313CB00040CDE /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = translations/bg.lproj/Localizable.strings; sourceTree = "<group>"; };
459C3F0C1C9B3A1B003ACF51 /* TSMessageAdapterTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TSMessageAdapterTest.m; path = "view controllers/Signals/TSMessageAdapters/TSMessageAdapterTest.m"; sourceTree = "<group>"; };
45B201741DAECBFD00C461E0 /* Signal-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Signal-Bridging-Header.h"; sourceTree = "<group>"; };
45B201751DAECBFE00C461E0 /* CopyableLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CopyableLabel.swift; sourceTree = "<group>"; };
45B201751DAECBFE00C461E0 /* HighlightableLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HighlightableLabel.swift; sourceTree = "<group>"; };
45BFFFA61D898AF0004A12A7 /* OWSStaleNotificationObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OWSStaleNotificationObserver.h; path = Observers/OWSStaleNotificationObserver.h; sourceTree = "<group>"; };
45BFFFA71D898AF0004A12A7 /* OWSStaleNotificationObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OWSStaleNotificationObserver.m; path = Observers/OWSStaleNotificationObserver.m; sourceTree = "<group>"; };
45C681B51D305A580050903A /* OWSCall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSCall.h; sourceTree = "<group>"; };
@ -1828,7 +1828,7 @@
76EB052B18170B33006006FC /* Views */ = {
isa = PBXGroup;
children = (
45B201751DAECBFE00C461E0 /* CopyableLabel.swift */,
45B201751DAECBFE00C461E0 /* HighlightableLabel.swift */,
45C681C11D305C9E0050903A /* OWSDisplayedMessageCollectionViewCell.h */,
45C681C21D305C9E0050903A /* OWSDisplayedMessageCollectionViewCell.m */,
45C681C31D305C9E0050903A /* OWSDisplayedMessageCollectionViewCell.xib */,
@ -3004,7 +3004,7 @@
76EB05C618170B33006006FC /* HelloAckPacket.m in Sources */,
76EB05E818170B33006006FC /* CallFailedServerMessage.m in Sources */,
76EB05FA18170B33006006FC /* CallConnectUtil_Responder.m in Sources */,
45B201761DAECBFE00C461E0 /* CopyableLabel.swift in Sources */,
45B201761DAECBFE00C461E0 /* HighlightableLabel.swift in Sources */,
76EB05AE18170B33006006FC /* SrtpStream.m in Sources */,
E197B61318BBEC1A00F073E5 /* DesiredBufferDepthController.m in Sources */,
76EB064818170B33006006FC /* Zid.m in Sources */,

View File

@ -38,7 +38,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>9992.6.5.7</string>
<string>9992.6.5.9</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LOGS_EMAIL</key>

View File

@ -56,7 +56,7 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
// Setting up environment
[Environment setCurrent:[Release releaseEnvironmentWithLogging:logger]];
[self setupAppearance];
[UIUtil applySignalAppearence];
[[PushManager sharedManager] registerPushKitNotificationFuture];
if (getenv("runningTests_dontStartApp")) {
@ -318,30 +318,6 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
}
}
- (void)setupAppearance {
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
[[UINavigationBar appearance] setBarTintColor:[UIColor ows_materialBlueColor]];
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
[[UIBarButtonItem appearanceWhenContainedIn:[UISearchBar class], nil] setTintColor:[UIColor ows_materialBlueColor]];
[[UIToolbar appearance] setTintColor:[UIColor ows_materialBlueColor]];
[[UIBarButtonItem appearance] setTintColor:[UIColor whiteColor]];
NSShadow *shadow = [NSShadow new];
[shadow setShadowColor:[UIColor clearColor]];
NSDictionary *navbarTitleTextAttributes = @{
NSForegroundColorAttributeName : [UIColor whiteColor],
NSShadowAttributeName : shadow,
};
[[UISwitch appearance] setOnTintColor:[UIColor ows_materialBlueColor]];
[[UINavigationBar appearance] setTitleTextAttributes:navbarTitleTextAttributes];
}
#pragma mark Push Notifications Delegate Methods
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {

View File

@ -200,7 +200,7 @@
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="B4o-Rc-z68" userLabel="Instructions Container">
<rect key="frame" x="0.0" y="333.5" width="375" height="289.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="12345 54432 83456 89456 24327 87547 90123 31523 91052 84930 89304 00234" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="e7E-iS-3Oc" userLabel="Privacy Verification Key Text" customClass="OWSCopyableLabel">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="12345 54432 83456 89456 24327 87547 90123 31523 91052 84930 89304 00234" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" adjustsLetterSpacingToFitWidth="YES" translatesAutoresizingMaskIntoConstraints="NO" id="e7E-iS-3Oc" userLabel="Privacy Verification Key Text" customClass="OWSHighlightableLabel">
<rect key="frame" x="36" y="0.0" width="303" height="70"/>
<gestureRecognizers/>
<constraints>
@ -301,14 +301,22 @@
<outlet property="scanButton" destination="RX6-CJ-FV1" id="BKY-4g-g3U"/>
<outlet property="scanningContainer" destination="8DU-2J-HAz" id="FH9-yo-8uI"/>
<outlet property="scanningInstructions" destination="NXP-Ue-iml" id="Iqf-NS-kzM"/>
<outlet property="shareButton" destination="k9L-LH-YS4" id="kPI-Du-1Lk"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="sd1-mY-rAe" userLabel="First Responder" sceneMemberID="firstResponder"/>
<barButtonItem image="btnCancel--white" id="kAa-FW-3Am" userLabel="Dismiss Button">
<barButtonItem systemItem="stop" id="kAa-FW-3Am" userLabel="Dismiss Button">
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
<action selector="closeButtonAction:" destination="urv-62-RsD" id="Odq-bS-LCh"/>
</connections>
</barButtonItem>
<barButtonItem systemItem="action" id="k9L-LH-YS4" userLabel="Share Button">
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
<action selector="didTapShareButton" destination="urv-62-RsD" id="Oqj-ag-vEG"/>
</connections>
</barButtonItem>
</objects>
<point key="canvasLocation" x="-1087" y="-2423"/>
</scene>
@ -417,7 +425,7 @@
<action selector="disappearingMessagesSwitchValueDidChange:" destination="4oU-Rv-yJi" eventType="valueChanged" id="3fF-JA-69e"/>
</connections>
</switch>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="table_ic_timer" translatesAutoresizingMaskIntoConstraints="NO" id="iRL-ZI-kXA">
<imageView opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="table_ic_timer" translatesAutoresizingMaskIntoConstraints="NO" id="iRL-ZI-kXA">
<rect key="frame" x="16" y="6" width="32" height="32"/>
<color key="tintColor" red="0.054901960780000002" green="0.054901960780000002" blue="0.054901960780000002" alpha="1" colorSpace="calibratedRGB"/>
<constraints>
@ -578,6 +586,9 @@
<outlet property="toggleDisappearingMessagesTitleLabel" destination="qbY-qJ-enK" id="gMK-F9-7Ss"/>
<outlet property="updateGroupCell" destination="XHr-b6-Gvn" id="JMz-e5-FNh"/>
<outlet property="verifyPrivacyCell" destination="Dzg-XO-ciX" id="kKQ-3F-uIp"/>
<outletCollection property="cellIcons" destination="eGH-Vc-aKx" id="QW6-1W-hpg"/>
<outletCollection property="cellIcons" destination="iRL-ZI-kXA" id="kct-Ug-2zB"/>
<outletCollection property="cellIcons" destination="X7n-1t-1Q7" id="sc6-6u-NOR"/>
</connections>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Ftx-dN-loa" userLabel="First Responder" sceneMemberID="firstResponder"/>

View File

@ -20,4 +20,7 @@ typedef void (^completionBlock)(void);
+ (void)removeRoundedBorderToImageView:(UIImageView *__strong *)imageView;
+ (completionBlock)modalCompletionBlock;
+ (void)applyDefaultSystemAppearence;
+ (void)applySignalAppearence;
@end

View File

@ -25,4 +25,38 @@
return block;
}
+ (void)applyDefaultSystemAppearence
{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
[[UINavigationBar appearance] setBarStyle:UIBarStyleDefault];
[[UIBarButtonItem appearance] setTintColor:[UIColor blackColor]];
NSDictionary *navbarTitleTextAttributes = @{ NSForegroundColorAttributeName : [UIColor blackColor] };
[[UINavigationBar appearance] setTitleTextAttributes:navbarTitleTextAttributes];
}
+ (void)applySignalAppearence
{
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
[[UINavigationBar appearance] setBarTintColor:[UIColor ows_materialBlueColor]];
[[UINavigationBar appearance] setTintColor:[UIColor whiteColor]];
[[UIBarButtonItem appearanceWhenContainedIn:[UISearchBar class], nil] setTintColor:[UIColor ows_materialBlueColor]];
[[UIToolbar appearance] setTintColor:[UIColor ows_materialBlueColor]];
[[UIBarButtonItem appearance] setTintColor:[UIColor whiteColor]];
NSShadow *shadow = [NSShadow new];
[shadow setShadowColor:[UIColor clearColor]];
NSDictionary *navbarTitleTextAttributes = @{
NSForegroundColorAttributeName : [UIColor whiteColor],
NSShadowAttributeName : shadow,
};
[[UISwitch appearance] setOnTintColor:[UIColor ows_materialBlueColor]];
[[UINavigationBar appearance] setTitleTextAttributes:navbarTitleTextAttributes];
}
@end

View File

@ -10,8 +10,9 @@
#import "DJWActionSheet+OWS.h"
#import "Environment.h"
#import "OWSConversationSettingsTableViewController.h"
#import "UIViewController+CameraPermissions.h"
#import "Signal-Swift.h"
#import "UIUtil.h"
#import "UIViewController+CameraPermissions.h"
#import <SignalServiceKit/NSDate+millisecondTimeStamp.h>
#import <SignalServiceKit/OWSFingerprint.h>
#import <SignalServiceKit/TSInfoMessage.h>
@ -22,7 +23,7 @@
NS_ASSUME_NONNULL_BEGIN
@interface FingerprintViewController ()
@interface FingerprintViewController () <OWSHighlightableLabelDelegate>
@property (strong, nonatomic) TSStorageManager *storageManager;
@property (strong, nonatomic) TSThread *thread;
@ -32,6 +33,7 @@ NS_ASSUME_NONNULL_BEGIN
@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;
@ -39,7 +41,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (strong, nonatomic) IBOutlet UIView *qrContainer;
@property (strong, nonatomic) IBOutlet UIView *privacyVerificationQRCodeFrame;
@property (strong, nonatomic) IBOutlet UIImageView *privacyVerificationQRCode;
@property (strong, nonatomic) IBOutlet OWSCopyableLabel *privacyVerificationFingerprint;
@property (strong, nonatomic) IBOutlet OWSHighlightableLabel *privacyVerificationFingerprint;
@property (strong, nonatomic) IBOutlet UILabel *instructionsLabel;
@property (strong, nonatomic) IBOutlet UIButton *scanButton;
@ -61,6 +63,7 @@ NS_ASSUME_NONNULL_BEGIN
[super viewDidLoad];
self.navigationItem.leftBarButtonItem = self.dismissModalButton;
self.navigationItem.rightBarButtonItem = self.shareButton;
[self.modalNavigationBar pushNavigationItem:self.navigationItem animated:NO];
// HACK for transparent navigation bar.
@ -96,6 +99,8 @@ NS_ASSUME_NONNULL_BEGIN
// Don't antialias QRCode
self.privacyVerificationQRCode.layer.magnificationFilter = kCAFilterNearest;
self.privacyVerificationFingerprint.delegate = self;
}
- (void)viewDidLayoutSubviews
@ -110,6 +115,12 @@ NS_ASSUME_NONNULL_BEGIN
self.privacyVerificationQRCodeFrame.layer.cornerRadius = self.privacyVerificationQRCodeFrame.frame.size.height / 2;
}
- (void)viewWillAppear:(BOOL)animated
{
// In case we're returning from activity view that needed default system styles.
[UIUtil applySignalAppearence];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:YES];
@ -128,12 +139,55 @@ NS_ASSUME_NONNULL_BEGIN
}
}
#pragma mark - HilightableLableDelegate
- (void)didHighlightLabelWithLabel:(OWSHighlightableLabel *)label completion:(nullable void (^)(void))completionHandler
{
[self showSharingActivityWithCompletion:completionHandler];
}
- (void)showSharingActivityWithCompletion:(nullable void (^)(void))completionHandler
{
DDLogDebug(@"%@ Sharing safety numbers", self.tag);
NSString *shareFormat = NSLocalizedString(@"SAFETY_NUMBER_SHARE_FORMAT", @"Snippet to share {{safety numbers}} with a friend. sent e.g. via sms");
NSString *shareString = [NSString stringWithFormat:shareFormat, self.fingerprint.displayableText];
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:@[shareString]
applicationActivities:nil];
void (^activityControllerCompletionHandler)(UIActivityType __nullable activityType, BOOL completed, NSArray * __nullable returnedItems, NSError * __nullable activityError) = ^void(UIActivityType __nullable activityType, BOOL completed, NSArray * __nullable returnedItems, NSError * __nullable activityError){
if (completionHandler) {
completionHandler();
}
[UIUtil applySignalAppearence];
};
activityController.completionWithItemsHandler = activityControllerCompletionHandler;
activityController.excludedActivityTypes = @[
UIActivityTypePostToFacebook,
UIActivityTypePostToWeibo,
UIActivityTypeAirDrop,
UIActivityTypePostToTwitter
];
[UIUtil applyDefaultSystemAppearence];
[self presentViewController:activityController animated:YES completion:nil];
}
#pragma mark - Action
- (IBAction)closeButtonAction:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)didTapShareButton
{
[self showSharingActivityWithCompletion:nil];
}
- (IBAction)didTouchUpInsideScanButton:(id)sender
{
[self showScanner];
@ -141,6 +195,11 @@ NS_ASSUME_NONNULL_BEGIN
- (void)showScanner
{
// Camera stops capturing when "sharing" while in capture mode.
// Also, it's less obvious whats being "shared" at this point,
// so just disable sharing when in capture mode.
self.shareButton.enabled = NO;
[self ows_askForCameraPermissions:^{
DDLogInfo(@"%@ Showing Scanner", self.tag);
self.qrScanningView.hidden = NO;
@ -160,8 +219,9 @@ NS_ASSUME_NONNULL_BEGIN
alertActionHandler:nil];
}
// pragma mark - OWSQRScannerDelegate
- (void)controller:(OWSQRCodeScanningViewController *)controller didDetectQRCodeWithData:(NSData *)data;
#pragma mark - OWSQRScannerDelegate
- (void)controller:(OWSQRCodeScanningViewController *)controller didDetectQRCodeWithData:(NSData *)data
{
[self verifyCombinedFingerprintData:data];
}

View File

@ -65,6 +65,7 @@ static NSString *const OWSConversationSettingsTableViewControllerSegueShowGroupM
@property (strong, nonatomic) IBOutlet UIImageView *avatar;
@property (strong, nonatomic) IBOutlet UILabel *nameLabel;
@property (strong, nonatomic) IBOutlet UILabel *signalIdLabel;
@property (strong, nonatomic) IBOutletCollection(UIImageView) NSArray *cellIcons;
@property (nonatomic) TSThread *thread;
@property (nonatomic) NSString *contactName;
@ -183,6 +184,13 @@ static NSString *const OWSConversationSettingsTableViewControllerSegueShowGroupM
self.disappearingMessagesDurationSlider.value = self.disappearingMessagesConfiguration.durationIndex;
[self toggleDisappearingMessages:self.disappearingMessagesConfiguration.isEnabled];
// RADAR http://www.openradar.me/23759908
// Finding that occasionally the tabel icons are not being tinted
// i.e. rendered as white making them invisible.
for (UIImageView *cellIcon in self.cellIcons) {
[cellIcon tintColorDidChange];
}
}
- (void)viewWillAppear:(BOOL)animated

View File

@ -3,13 +3,20 @@
import UIKit
@objc(OWSCopyableLabel)
class CopyableLabel : UILabel {
@objc(OWSHighlightableLabelDelegate)
protocol HighlightableLabelDelegate {
func didHighlightLabel(label:HighlightableLabel, completion: (()->())?) -> ()
}
@objc(OWSHighlightableLabel)
class HighlightableLabel : UILabel {
deinit {
NotificationCenter.default.removeObserver(self);
}
var delegate: HighlightableLabelDelegate?
override init(frame: CGRect) {
super.init(frame: frame)
setupGestureRecognizer()
@ -41,33 +48,18 @@ class CopyableLabel : UILabel {
func setupGestureRecognizer() {
isUserInteractionEnabled = true
let longpressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(showMenuGesture))
let longpressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(highlightGesture))
addGestureRecognizer(longpressGestureRecognizer)
NotificationCenter.default.addObserver(self, selector: #selector(hideBorder), name:NSNotification.Name.UIMenuControllerWillHideMenu, object: nil)
}
func showMenuGesture(gestureRecognizer: UILongPressGestureRecognizer) {
func highlightGesture(gestureRecognizer: UILongPressGestureRecognizer) {
guard gestureRecognizer.state == .began else {
return
}
becomeFirstResponder();
showBorder()
UIMenuController.shared.setTargetRect(self.frame, in: self.superview!)
UIMenuController.shared.setMenuVisible(true, animated: true)
self.delegate?.didHighlightLabel(label: self, completion:{ self.hideBorder() })
}
// MARK: UIResponder
override var canBecomeFirstResponder: Bool { return true }
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return action == #selector(UIResponder.copy(_:))
}
override func copy(_ sender: Any?) {
NSLog("Copied safety numbers.")
UIPasteboard.general.string = self.text
}
}