no contacts banner -> system settings

This commit is contained in:
Michael Kirk 2017-05-05 12:39:21 -04:00
parent f76bb8397f
commit a58a71f8f4
9 changed files with 181 additions and 38 deletions

View file

@ -138,6 +138,8 @@
458E38371D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 458E38361D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m */; }; 458E38371D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 458E38361D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m */; };
458E383A1D6699FA0094BD24 /* OWSDeviceProvisioningURLParserTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 458E38391D6699FA0094BD24 /* OWSDeviceProvisioningURLParserTest.m */; }; 458E383A1D6699FA0094BD24 /* OWSDeviceProvisioningURLParserTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 458E38391D6699FA0094BD24 /* OWSDeviceProvisioningURLParserTest.m */; };
459311FC1D75C948008DD4F0 /* OWSDeviceTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 459311FB1D75C948008DD4F0 /* OWSDeviceTableViewCell.m */; }; 459311FC1D75C948008DD4F0 /* OWSDeviceTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 459311FB1D75C948008DD4F0 /* OWSDeviceTableViewCell.m */; };
45A6DAD61EBBF85500893231 /* NotificationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45A6DAD51EBBF85500893231 /* NotificationView.swift */; };
45A6DAD71EBBF85500893231 /* NotificationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45A6DAD51EBBF85500893231 /* NotificationView.swift */; };
45AE48511E0732D6004D96C2 /* TurnServerInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */; }; 45AE48511E0732D6004D96C2 /* TurnServerInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */; };
45AE48521E0732D6004D96C2 /* TurnServerInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */; }; 45AE48521E0732D6004D96C2 /* TurnServerInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */; };
45B201761DAECBFE00C461E0 /* HighlightableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45B201751DAECBFE00C461E0 /* HighlightableLabel.swift */; }; 45B201761DAECBFE00C461E0 /* HighlightableLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45B201751DAECBFE00C461E0 /* HighlightableLabel.swift */; };
@ -146,8 +148,8 @@
45BD60821DE9547E00A8F436 /* Contacts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 45BD60811DE9547E00A8F436 /* Contacts.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 45BD60821DE9547E00A8F436 /* Contacts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 45BD60811DE9547E00A8F436 /* Contacts.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
45BFFFA81D898AF0004A12A7 /* OWSStaleNotificationObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 45BFFFA71D898AF0004A12A7 /* OWSStaleNotificationObserver.m */; }; 45BFFFA81D898AF0004A12A7 /* OWSStaleNotificationObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 45BFFFA71D898AF0004A12A7 /* OWSStaleNotificationObserver.m */; };
45BFFFA91D898AF0004A12A7 /* OWSStaleNotificationObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 45BFFFA71D898AF0004A12A7 /* OWSStaleNotificationObserver.m */; }; 45BFFFA91D898AF0004A12A7 /* OWSStaleNotificationObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 45BFFFA71D898AF0004A12A7 /* OWSStaleNotificationObserver.m */; };
45C0DC1B1E68FE9000E04C47 /* UIApplication+frontmostViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45C0DC1A1E68FE9000E04C47 /* UIApplication+frontmostViewController.swift */; }; 45C0DC1B1E68FE9000E04C47 /* UIApplication+OWS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45C0DC1A1E68FE9000E04C47 /* UIApplication+OWS.swift */; };
45C0DC1C1E68FE9000E04C47 /* UIApplication+frontmostViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45C0DC1A1E68FE9000E04C47 /* UIApplication+frontmostViewController.swift */; }; 45C0DC1C1E68FE9000E04C47 /* UIApplication+OWS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45C0DC1A1E68FE9000E04C47 /* UIApplication+OWS.swift */; };
45C0DC1E1E69011F00E04C47 /* UIStoryboard+OWS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45C0DC1D1E69011F00E04C47 /* UIStoryboard+OWS.swift */; }; 45C0DC1E1E69011F00E04C47 /* UIStoryboard+OWS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45C0DC1D1E69011F00E04C47 /* UIStoryboard+OWS.swift */; };
45C0DC1F1E69011F00E04C47 /* UIStoryboard+OWS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45C0DC1D1E69011F00E04C47 /* UIStoryboard+OWS.swift */; }; 45C0DC1F1E69011F00E04C47 /* UIStoryboard+OWS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45C0DC1D1E69011F00E04C47 /* UIStoryboard+OWS.swift */; };
45C681B71D305A580050903A /* OWSCall.m in Sources */ = {isa = PBXBuildFile; fileRef = 45C681B61D305A580050903A /* OWSCall.m */; }; 45C681B71D305A580050903A /* OWSCall.m in Sources */ = {isa = PBXBuildFile; fileRef = 45C681B61D305A580050903A /* OWSCall.m */; };
@ -542,6 +544,7 @@
459311FB1D75C948008DD4F0 /* OWSDeviceTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSDeviceTableViewCell.m; sourceTree = "<group>"; }; 459311FB1D75C948008DD4F0 /* OWSDeviceTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSDeviceTableViewCell.m; sourceTree = "<group>"; };
4597E94E1D8313C100040CDE /* sq */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sq; path = translations/sq.lproj/Localizable.strings; sourceTree = "<group>"; }; 4597E94E1D8313C100040CDE /* sq */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sq; path = translations/sq.lproj/Localizable.strings; sourceTree = "<group>"; };
4597E94F1D8313CB00040CDE /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = translations/bg.lproj/Localizable.strings; sourceTree = "<group>"; }; 4597E94F1D8313CB00040CDE /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = translations/bg.lproj/Localizable.strings; sourceTree = "<group>"; };
45A6DAD51EBBF85500893231 /* NotificationView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationView.swift; sourceTree = "<group>"; };
45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TurnServerInfo.swift; sourceTree = "<group>"; }; 45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TurnServerInfo.swift; sourceTree = "<group>"; };
45B201741DAECBFD00C461E0 /* Signal-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Signal-Bridging-Header.h"; sourceTree = "<group>"; }; 45B201741DAECBFD00C461E0 /* Signal-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Signal-Bridging-Header.h"; sourceTree = "<group>"; };
45B201751DAECBFE00C461E0 /* HighlightableLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HighlightableLabel.swift; sourceTree = "<group>"; }; 45B201751DAECBFE00C461E0 /* HighlightableLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HighlightableLabel.swift; sourceTree = "<group>"; };
@ -549,7 +552,7 @@
45BD60811DE9547E00A8F436 /* Contacts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Contacts.framework; path = System/Library/Frameworks/Contacts.framework; sourceTree = SDKROOT; }; 45BD60811DE9547E00A8F436 /* Contacts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Contacts.framework; path = System/Library/Frameworks/Contacts.framework; sourceTree = SDKROOT; };
45BFFFA61D898AF0004A12A7 /* OWSStaleNotificationObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OWSStaleNotificationObserver.h; path = Observers/OWSStaleNotificationObserver.h; 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>"; }; 45BFFFA71D898AF0004A12A7 /* OWSStaleNotificationObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OWSStaleNotificationObserver.m; path = Observers/OWSStaleNotificationObserver.m; sourceTree = "<group>"; };
45C0DC1A1E68FE9000E04C47 /* UIApplication+frontmostViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIApplication+frontmostViewController.swift"; sourceTree = "<group>"; }; 45C0DC1A1E68FE9000E04C47 /* UIApplication+OWS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIApplication+OWS.swift"; sourceTree = "<group>"; };
45C0DC1D1E69011F00E04C47 /* UIStoryboard+OWS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIStoryboard+OWS.swift"; sourceTree = "<group>"; }; 45C0DC1D1E69011F00E04C47 /* UIStoryboard+OWS.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIStoryboard+OWS.swift"; sourceTree = "<group>"; };
45C681B51D305A580050903A /* OWSCall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSCall.h; sourceTree = "<group>"; }; 45C681B51D305A580050903A /* OWSCall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSCall.h; sourceTree = "<group>"; };
45C681B61D305A580050903A /* OWSCall.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSCall.m; sourceTree = "<group>"; }; 45C681B61D305A580050903A /* OWSCall.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSCall.m; sourceTree = "<group>"; };
@ -1317,6 +1320,7 @@
34330AA11E79686200DF2FB9 /* OWSProgressView.h */, 34330AA11E79686200DF2FB9 /* OWSProgressView.h */,
34330AA21E79686200DF2FB9 /* OWSProgressView.m */, 34330AA21E79686200DF2FB9 /* OWSProgressView.m */,
452EA09D1EA7ABE00078744B /* AttachmentPointerView.swift */, 452EA09D1EA7ABE00078744B /* AttachmentPointerView.swift */,
45A6DAD51EBBF85500893231 /* NotificationView.swift */,
); );
name = Views; name = Views;
path = views; path = views;
@ -1616,7 +1620,7 @@
344F2F651E57A932000D9322 /* UIViewController+OWS.h */, 344F2F651E57A932000D9322 /* UIViewController+OWS.h */,
344F2F661E57A932000D9322 /* UIViewController+OWS.m */, 344F2F661E57A932000D9322 /* UIViewController+OWS.m */,
45BB93371E688E14001E3939 /* UIDevice+featureSupport.swift */, 45BB93371E688E14001E3939 /* UIDevice+featureSupport.swift */,
45C0DC1A1E68FE9000E04C47 /* UIApplication+frontmostViewController.swift */, 45C0DC1A1E68FE9000E04C47 /* UIApplication+OWS.swift */,
45C0DC1D1E69011F00E04C47 /* UIStoryboard+OWS.swift */, 45C0DC1D1E69011F00E04C47 /* UIStoryboard+OWS.swift */,
); );
name = "UI Categories"; name = "UI Categories";
@ -2066,6 +2070,7 @@
452EA0971EA662330078744B /* AttachmentPointerAdapter.swift in Sources */, 452EA0971EA662330078744B /* AttachmentPointerAdapter.swift in Sources */,
34DFCB851E8E04B500053165 /* AddToBlockListViewController.m in Sources */, 34DFCB851E8E04B500053165 /* AddToBlockListViewController.m in Sources */,
45855F371D9498A40084F340 /* OWSContactAvatarBuilder.m in Sources */, 45855F371D9498A40084F340 /* OWSContactAvatarBuilder.m in Sources */,
45A6DAD61EBBF85500893231 /* NotificationView.swift in Sources */,
45666EC61D99483D008FE134 /* OWSAvatarBuilder.m in Sources */, 45666EC61D99483D008FE134 /* OWSAvatarBuilder.m in Sources */,
45E615161E8C590B0018AD52 /* DisplayableTextFilter.swift in Sources */, 45E615161E8C590B0018AD52 /* DisplayableTextFilter.swift in Sources */,
34B3F88A1E8DF1700035BE1A /* OWSLinkDeviceViewController.m in Sources */, 34B3F88A1E8DF1700035BE1A /* OWSLinkDeviceViewController.m in Sources */,
@ -2092,7 +2097,7 @@
45F659821E1BE77000444429 /* NonCallKitCallUIAdaptee.swift in Sources */, 45F659821E1BE77000444429 /* NonCallKitCallUIAdaptee.swift in Sources */,
45AE48511E0732D6004D96C2 /* TurnServerInfo.swift in Sources */, 45AE48511E0732D6004D96C2 /* TurnServerInfo.swift in Sources */,
34B3F8771E8DF1700035BE1A /* ContactsPicker.swift in Sources */, 34B3F8771E8DF1700035BE1A /* ContactsPicker.swift in Sources */,
45C0DC1B1E68FE9000E04C47 /* UIApplication+frontmostViewController.swift in Sources */, 45C0DC1B1E68FE9000E04C47 /* UIApplication+OWS.swift in Sources */,
34535D821E256BE9008A4747 /* UIView+OWS.m in Sources */, 34535D821E256BE9008A4747 /* UIView+OWS.m in Sources */,
45F3AEB61DFDE7900080CE33 /* AvatarImageView.swift in Sources */, 45F3AEB61DFDE7900080CE33 /* AvatarImageView.swift in Sources */,
7038632718F70C0700D4A43F /* CryptoTools.m in Sources */, 7038632718F70C0700D4A43F /* CryptoTools.m in Sources */,
@ -2158,7 +2163,7 @@
456F6E251E24216100FD2210 /* DataChannelMessage.swift in Sources */, 456F6E251E24216100FD2210 /* DataChannelMessage.swift in Sources */,
452ECA4E1E087E7200E2F016 /* MessageFetcherJob.swift in Sources */, 452ECA4E1E087E7200E2F016 /* MessageFetcherJob.swift in Sources */,
45F170AD1E2F0351003FC1F2 /* CallAudioSession.swift in Sources */, 45F170AD1E2F0351003FC1F2 /* CallAudioSession.swift in Sources */,
45C0DC1C1E68FE9000E04C47 /* UIApplication+frontmostViewController.swift in Sources */, 45C0DC1C1E68FE9000E04C47 /* UIApplication+OWS.swift in Sources */,
45F170BC1E2FC5D3003FC1F2 /* CallAudioService.swift in Sources */, 45F170BC1E2FC5D3003FC1F2 /* CallAudioService.swift in Sources */,
456F6E2F1E261D1000FD2210 /* PeerConnectionClientTest.swift in Sources */, 456F6E2F1E261D1000FD2210 /* PeerConnectionClientTest.swift in Sources */,
452C46901E427E200087B011 /* OutboundCallInitiator.swift in Sources */, 452C46901E427E200087B011 /* OutboundCallInitiator.swift in Sources */,
@ -2226,6 +2231,7 @@
45E615171E8C59100018AD52 /* DisplayableTextFilter.swift in Sources */, 45E615171E8C59100018AD52 /* DisplayableTextFilter.swift in Sources */,
B660F6DF1C29868000687D6E /* QueueTest.m in Sources */, B660F6DF1C29868000687D6E /* QueueTest.m in Sources */,
B660F6BB1C29868000687D6E /* OWSContactsManagerTest.m in Sources */, B660F6BB1C29868000687D6E /* OWSContactsManagerTest.m in Sources */,
45A6DAD71EBBF85500893231 /* NotificationView.swift in Sources */,
B660F6DD1C29868000687D6E /* ObservableTest.m in Sources */, B660F6DD1C29868000687D6E /* ObservableTest.m in Sources */,
B660F6D21C29868000687D6E /* PushManagerTest.m in Sources */, B660F6D21C29868000687D6E /* PushManagerTest.m in Sources */,
45C0DC1F1E69011F00E04C47 /* UIStoryboard+OWS.swift in Sources */, 45C0DC1F1E69011F00E04C47 /* UIStoryboard+OWS.swift in Sources */,

View file

@ -30,27 +30,28 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<view userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lKc-rv-FH5" userLabel="empty state view"> <view userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="lKc-rv-FH5" userLabel="empty state view">
<rect key="frame" x="0.0" y="64" width="375" height="603"/> <rect key="frame" x="16" y="233.5" width="343" height="200.5"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="No Messages :( Tap Compose to send a message or invite a friend to Signal" textAlignment="center" lineBreakMode="wordWrap" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Srx-i1-WhD"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="No Messages :( Tap Compose to send a message or invite a friend to Signal" textAlignment="center" lineBreakMode="wordWrap" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Srx-i1-WhD">
<rect key="frame" x="38" y="107" width="300" height="200"/> <rect key="frame" x="0.0" y="0.0" width="343" height="200.5"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="200" id="GEd-dY-d8r"/> <constraint firstAttribute="height" constant="200" id="GEd-dY-d8r"/>
<constraint firstAttribute="width" constant="300" id="siA-1a-pO1"/>
</constraints> </constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
</subviews> </subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints> <constraints>
<constraint firstAttribute="centerX" secondItem="Srx-i1-WhD" secondAttribute="centerX" id="JId-fq-hNc"/> <constraint firstAttribute="trailing" secondItem="Srx-i1-WhD" secondAttribute="trailing" id="2nM-ny-Yf0"/>
<constraint firstAttribute="centerY" secondItem="Srx-i1-WhD" secondAttribute="centerY" constant="95" id="XST-YY-qXT"/> <constraint firstAttribute="bottom" secondItem="Srx-i1-WhD" secondAttribute="bottom" id="JxH-61-Mbg"/>
<constraint firstItem="Srx-i1-WhD" firstAttribute="top" secondItem="lKc-rv-FH5" secondAttribute="top" id="RXl-15-3Bf"/>
<constraint firstItem="Srx-i1-WhD" firstAttribute="leading" secondItem="lKc-rv-FH5" secondAttribute="leading" id="sPV-PU-NeI"/>
</constraints> </constraints>
</view> </view>
<tableView hidden="YES" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" showsHorizontalScrollIndicator="NO" dataMode="prototypes" style="plain" separatorStyle="default" allowsSelectionDuringEditing="YES" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="PaA-ol-uQT"> <tableView hidden="YES" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" showsHorizontalScrollIndicator="NO" dataMode="prototypes" style="plain" separatorStyle="default" allowsSelectionDuringEditing="YES" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="PaA-ol-uQT">
<rect key="frame" x="0.0" y="64" width="385" height="603"/> <rect key="frame" x="0.0" y="64" width="375" height="603"/>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<sections/> <sections/>
<connections> <connections>
@ -58,17 +59,26 @@
<outlet property="delegate" destination="MY2-bB-USa" id="vmj-PA-2Od"/> <outlet property="delegate" destination="MY2-bB-USa" id="vmj-PA-2Od"/>
</connections> </connections>
</tableView> </tableView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7iZ-hQ-Iik" userLabel="Missing Contacts Permission" customClass="NotificationView" customModule="Signal" customModuleProvider="target">
<rect key="frame" x="0.0" y="64" width="375" height="0.0"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints>
<constraint firstAttribute="height" id="b7U-Ma-c6S"/>
</constraints>
</view>
</subviews> </subviews>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
<constraints> <constraints>
<constraint firstItem="PaA-ol-uQT" firstAttribute="leading" secondItem="lKc-rv-FH5" secondAttribute="leading" id="0co-lj-Jsm"/> <constraint firstItem="PaA-ol-uQT" firstAttribute="leading" secondItem="EFA-Fu-XJm" secondAttribute="leadingMargin" constant="-16" id="0gf-ME-9L1"/>
<constraint firstAttribute="width" secondItem="lKc-rv-FH5" secondAttribute="width" id="Bu7-qv-yue"/> <constraint firstAttribute="trailingMargin" secondItem="lKc-rv-FH5" secondAttribute="trailing" id="2vI-V9-xoy"/>
<constraint firstItem="lKc-rv-FH5" firstAttribute="top" secondItem="lZK-q4-iwt" secondAttribute="bottom" id="KiY-Ag-0iP"/> <constraint firstAttribute="trailing" secondItem="7iZ-hQ-Iik" secondAttribute="trailing" id="4BJ-Md-OUO"/>
<constraint firstItem="lKc-rv-FH5" firstAttribute="centerY" secondItem="PaA-ol-uQT" secondAttribute="centerY" id="OOk-XM-IMs"/> <constraint firstItem="7iZ-hQ-Iik" firstAttribute="leading" secondItem="EFA-Fu-XJm" secondAttribute="leading" id="C4Q-v3-nmH"/>
<constraint firstAttribute="trailingMargin" secondItem="PaA-ol-uQT" secondAttribute="trailing" constant="-26" id="ZkG-Yf-ISG"/> <constraint firstAttribute="trailingMargin" secondItem="PaA-ol-uQT" secondAttribute="trailing" constant="-16" id="Clg-qg-Ldn"/>
<constraint firstItem="PaA-ol-uQT" firstAttribute="top" secondItem="lKc-rv-FH5" secondAttribute="top" id="gdn-tV-9au"/> <constraint firstItem="PaA-ol-uQT" firstAttribute="top" secondItem="7iZ-hQ-Iik" secondAttribute="bottom" id="IZB-M9-K0p"/>
<constraint firstItem="lKc-rv-FH5" firstAttribute="centerY" secondItem="EFA-Fu-XJm" secondAttribute="centerY" id="ToE-Bp-7ze"/>
<constraint firstItem="PaA-ol-uQT" firstAttribute="bottom" secondItem="7uh-gm-z8v" secondAttribute="top" id="jLN-Fv-npv"/> <constraint firstItem="PaA-ol-uQT" firstAttribute="bottom" secondItem="7uh-gm-z8v" secondAttribute="top" id="jLN-Fv-npv"/>
<constraint firstAttribute="trailingMargin" secondItem="PaA-ol-uQT" secondAttribute="trailing" constant="-26" id="mrL-SK-eKx"/> <constraint firstItem="7iZ-hQ-Iik" firstAttribute="top" secondItem="lZK-q4-iwt" secondAttribute="bottom" id="nfM-45-ZER"/>
<constraint firstAttribute="centerX" secondItem="lKc-rv-FH5" secondAttribute="centerX" id="obF-St-qwu"/> <constraint firstItem="lKc-rv-FH5" firstAttribute="leading" secondItem="EFA-Fu-XJm" secondAttribute="leadingMargin" id="yed-vX-e9v"/>
</constraints> </constraints>
</view> </view>
<navigationItem key="navigationItem" title="Conversations" id="Um0-0y-8lr"> <navigationItem key="navigationItem" title="Conversations" id="Um0-0y-8lr">
@ -90,6 +100,8 @@
</navigationItem> </navigationItem>
<connections> <connections>
<outlet property="emptyBoxLabel" destination="Srx-i1-WhD" id="wap-un-Cz5"/> <outlet property="emptyBoxLabel" destination="Srx-i1-WhD" id="wap-un-Cz5"/>
<outlet property="hideMissingContactsPermissionViewConstraint" destination="b7U-Ma-c6S" id="bcT-sh-weS"/>
<outlet property="missingContactsPermissionView" destination="7iZ-hQ-Iik" id="aWf-NH-kn6"/>
<outlet property="tableView" destination="PaA-ol-uQT" id="nQU-tR-wbL"/> <outlet property="tableView" destination="PaA-ol-uQT" id="nQU-tR-wbL"/>
<segue destination="Tyf-mN-gzf" kind="modal" identifier="ShowIncomingCallSegue" id="G2B-Fr-Ezs"/> <segue destination="Tyf-mN-gzf" kind="modal" identifier="ShowIncomingCallSegue" id="G2B-Fr-Ezs"/>
</connections> </connections>
@ -432,10 +444,10 @@
<color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.95686274510000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color key="backgroundColor" red="0.93725490199999995" green="0.93725490199999995" blue="0.95686274510000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<prototypes> <prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="ExistingDevice" rowHeight="72" id="XjV-oU-jSb" customClass="OWSDeviceTableViewCell"> <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" reuseIdentifier="ExistingDevice" rowHeight="72" id="XjV-oU-jSb" customClass="OWSDeviceTableViewCell">
<rect key="frame" x="0.0" y="56" width="375" height="72"/> <rect key="frame" x="0.0" y="55.5" width="375" height="72"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="XjV-oU-jSb" id="XqL-QG-IbY"> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="XjV-oU-jSb" id="XqL-QG-IbY">
<rect key="frame" x="0.0" y="0.0" width="375" height="71"/> <rect key="frame" x="0.0" y="0.0" width="375" height="71.5"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Signal on Chrome" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="57o-uV-YOg"> <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Signal on Chrome" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="57o-uV-YOg">
@ -476,10 +488,10 @@
</connections> </connections>
</tableViewCell> </tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="AddNewDevice" textLabel="w80-IJ-E6R" detailTextLabel="8ft-2u-wBF" style="IBUITableViewCellStyleSubtitle" id="6h2-gg-1C6"> <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" accessoryType="disclosureIndicator" indentationWidth="10" reuseIdentifier="AddNewDevice" textLabel="w80-IJ-E6R" detailTextLabel="8ft-2u-wBF" style="IBUITableViewCellStyleSubtitle" id="6h2-gg-1C6">
<rect key="frame" x="0.0" y="128" width="375" height="44"/> <rect key="frame" x="0.0" y="127.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="6h2-gg-1C6" id="RKi-c6-pzb"> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="6h2-gg-1C6" id="RKi-c6-pzb">
<rect key="frame" x="0.0" y="0.0" width="342" height="43"/> <rect key="frame" x="0.0" y="0.0" width="342" height="43.5"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Link New Device" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="w80-IJ-E6R"> <label opaque="NO" multipleTouchEnabled="YES" contentMode="left" text="Link New Device" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="w80-IJ-E6R">

View file

@ -16,4 +16,8 @@ extension UIApplication {
return viewController return viewController
} }
func openSystemSettings() {
openURL(URL(string: UIApplicationOpenSettingsURLString)!)
}
} }

View file

@ -9,6 +9,7 @@
#import "Environment.h" #import "Environment.h"
#import "OWSContactsManager.h" #import "OWSContactsManager.h"
#import "SignalsViewController.h" #import "SignalsViewController.h"
#import "Signal-Swift.h"
#import "UIUtil.h" #import "UIUtil.h"
#import "ViewControllerUtils.h" #import "ViewControllerUtils.h"
#import <AddressBookUI/AddressBookUI.h> #import <AddressBookUI/AddressBookUI.h>
@ -273,9 +274,7 @@ NS_ASSUME_NONNULL_BEGIN
@"Button text which opens the settings app") @"Button text which opens the settings app")
style:UIAlertActionStyleDefault style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) { handler:^(UIAlertAction *_Nonnull action) {
NSURL *settingsUrl = [NSURL [[UIApplication sharedApplication] openSystemSettings];
URLWithString:UIApplicationOpenSettingsURLString];
[[UIApplication sharedApplication] openURL:settingsUrl];
}]]; }]];
[self presentViewController:alertController animated:YES completion:nil]; [self presentViewController:alertController animated:YES completion:nil];

View file

@ -39,6 +39,7 @@ NSString *const SignalsViewControllerSegueShowIncomingCall = @"ShowIncomingCallS
@property (nonatomic) long inboxCount; @property (nonatomic) long inboxCount;
@property (nonatomic) UISegmentedControl *segmentedControl; @property (nonatomic) UISegmentedControl *segmentedControl;
@property (nonatomic) id previewingContext; @property (nonatomic) id previewingContext;
@property (nonatomic) NSSet<NSString *> *blockedPhoneNumberSet;
// Dependencies // Dependencies
@ -49,12 +50,17 @@ NSString *const SignalsViewControllerSegueShowIncomingCall = @"ShowIncomingCallS
@property (nonatomic, readonly) OWSMessageSender *messageSender; @property (nonatomic, readonly) OWSMessageSender *messageSender;
@property (nonatomic, readonly) OWSBlockingManager *blockingManager; @property (nonatomic, readonly) OWSBlockingManager *blockingManager;
@property (nonatomic) NSSet<NSString *> *blockedPhoneNumberSet; // Views
@property (weak, nonatomic) IBOutlet NotificationView *missingContactsPermissionView;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *hideMissingContactsPermissionViewConstraint;
@end @end
@implementation SignalsViewController @implementation SignalsViewController
#pragma mark - Init
- (instancetype)init - (instancetype)init
{ {
self = [super init]; self = [super init];
@ -105,11 +111,13 @@ NSString *const SignalsViewControllerSegueShowIncomingCall = @"ShowIncomingCallS
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];
} }
#pragma mark - Notifications
- (void)blockedPhoneNumbersDidChange:(id)notification - (void)blockedPhoneNumbersDidChange:(id)notification
{ {
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
_blockedPhoneNumberSet = [NSSet setWithArray:[_blockingManager blockedPhoneNumbers]]; _blockedPhoneNumberSet = [NSSet setWithArray:[_blockingManager blockedPhoneNumbers]];
[self.tableView reloadData]; [self.tableView reloadData];
}); });
} }
@ -121,6 +129,8 @@ NSString *const SignalsViewControllerSegueShowIncomingCall = @"ShowIncomingCallS
}); });
} }
#pragma mark - View Life Cycle
- (void)awakeFromNib - (void)awakeFromNib
{ {
[super awakeFromNib]; [super awakeFromNib];
@ -157,6 +167,15 @@ NSString *const SignalsViewControllerSegueShowIncomingCall = @"ShowIncomingCallS
navigationItem.leftBarButtonItem.accessibilityLabel = NSLocalizedString( navigationItem.leftBarButtonItem.accessibilityLabel = NSLocalizedString(
@"SETTINGS_BUTTON_ACCESSIBILITY", @"Accessibility hint for the settings button"); @"SETTINGS_BUTTON_ACCESSIBILITY", @"Accessibility hint for the settings button");
self.missingContactsPermissionView.text = NSLocalizedString(@"INBOX_VIEW_MISSING_CONTACTS_PERMISSION", @"Multi line label explainging how to show names instead of phone numbers in your inbox");
self.missingContactsPermissionView.tapAction = ^{
[[UIApplication sharedApplication] openSystemSettings];
};
// Should only have to do this once per load (e.g. vs did appear) since app restarts when permissions change.
self.hideMissingContactsPermissionViewConstraint.active = !self.shouldShowMissingContactsPermissionView;
if ([self.traitCollection respondsToSelector:@selector(forceTouchCapability)] && if ([self.traitCollection respondsToSelector:@selector(forceTouchCapability)] &&
(self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)) { (self.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable)) {
[self registerForPreviewingWithDelegate:self sourceView:self.tableView]; [self registerForPreviewingWithDelegate:self sourceView:self.tableView];
@ -328,6 +347,15 @@ NSString *const SignalsViewControllerSegueShowIncomingCall = @"ShowIncomingCallS
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero]; self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
} }
- (BOOL)shouldShowMissingContactsPermissionView
{
if ([TSContactThread numberOfKeysInCollection] == 0) {
return NO;
}
return !self.contactsManager.isSystemContactsAuthorized;
}
#pragma mark - Table View Data Source #pragma mark - Table View Data Source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
@ -338,7 +366,8 @@ NSString *const SignalsViewControllerSegueShowIncomingCall = @"ShowIncomingCallS
return (NSInteger)[self.threadMappings numberOfItemsInSection:(NSUInteger)section]; return (NSInteger)[self.threadMappings numberOfItemsInSection:(NSUInteger)section];
} }
- (InboxTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
InboxTableViewCell *cell = InboxTableViewCell *cell =
[self.tableView dequeueReusableCellWithIdentifier:NSStringFromClass([InboxTableViewCell class])]; [self.tableView dequeueReusableCellWithIdentifier:NSStringFromClass([InboxTableViewCell class])];
TSThread *thread = [self threadForIndexPath:indexPath]; TSThread *thread = [self threadForIndexPath:indexPath];

View file

@ -72,7 +72,7 @@ import Foundation
let dismissAction = UIAlertAction(title: dismiss, style: .cancel) let dismissAction = UIAlertAction(title: dismiss, style: .cancel)
let settingsString = NSLocalizedString("OPEN_SETTINGS_BUTTON", comment: "Button text which opens the settings app") let settingsString = NSLocalizedString("OPEN_SETTINGS_BUTTON", comment: "Button text which opens the settings app")
let settingsAction = UIAlertAction(title: settingsString, style: .default) { _ in let settingsAction = UIAlertAction(title: settingsString, style: .default) { _ in
UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!) UIApplication.shared.openSystemSettings()
} }
alertController.addAction(dismissAction) alertController.addAction(dismissAction)
alertController.addAction(settingsAction) alertController.addAction(settingsAction)

View file

@ -1,13 +1,11 @@
// //
// UIViewController+CameraPermissions.m // Copyright (c) 2017 Open Whisper Systems. All rights reserved.
// Signal
//
// Created by Jarosław Pawlak on 18.10.2016.
// Copyright © 2016 Open Whisper Systems. All rights reserved.
// //
#import "UIUtil.h" #import "UIUtil.h"
#import "UIViewController+CameraPermissions.h" #import "UIViewController+CameraPermissions.h"
#import <AVFoundation/AVFoundation.h> #import <AVFoundation/AVFoundation.h>
#import "Signal-Swift.h"
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -28,7 +26,7 @@ NS_ASSUME_NONNULL_BEGIN
NSString *settingsTitle = NSLocalizedString(@"OPEN_SETTINGS_BUTTON", @"Button text which opens the settings app"); NSString *settingsTitle = NSLocalizedString(@"OPEN_SETTINGS_BUTTON", @"Button text which opens the settings app");
UIAlertAction *openSettingsAction = [UIAlertAction actionWithTitle:settingsTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) { UIAlertAction *openSettingsAction = [UIAlertAction actionWithTitle:settingsTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]]; [[UIApplication sharedApplication] openSystemSettings];
if (alertActionHandler) { if (alertActionHandler) {
alertActionHandler(); alertActionHandler();
} }

View file

@ -0,0 +1,92 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
import Foundation
class NotificationView: UIView {
let TAG = "[NotificationView]"
let label = UILabel()
let defaultTapAction = {
Logger.debug("[NotificationView] tapped.")
}
var tapAction: () -> Void
var text: String? {
get {
return label.text
}
set(newText) {
label.text = newText
}
}
required init?(coder: NSCoder) {
self.tapAction = defaultTapAction
super.init(coder: coder)
setupSubviews()
}
override init(frame: CGRect) {
self.tapAction = defaultTapAction
super.init(frame: frame)
setupSubviews()
}
convenience init(tapAction: @escaping () -> Void) {
self.init(frame: .zero)
self.tapAction = tapAction
}
func setupSubviews() {
self.backgroundColor = UIColor.ows_infoMessageBorder().withAlphaComponent(0.20)
self.clipsToBounds = true
let container = UIView()
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(gestureRecognizer:)))
container.addGestureRecognizer(tapGesture)
self.addSubview(container)
container.autoPinWidthToSuperview(withMargin: 16)
container.autoPinHeightToSuperview(withMargin: 16)
// Label
label.font = UIFont.ows_regularFont(withSize: 14)
container.addSubview(label)
label.numberOfLines = 0
label.autoPinEdge(toSuperviewEdge: .top)
label.autoPinEdge(toSuperviewEdge: .left)
label.autoPinEdge(toSuperviewEdge: .bottom)
label.textColor = UIColor.black.withAlphaComponent(0.9)
// Icon
// TODO proper "push" image rather than this hack.
let sourceIconImage = #imageLiteral(resourceName: "NavBarBack")
let iconImage = UIImage(cgImage:sourceIconImage.cgImage!,
scale: sourceIconImage.scale,
orientation: .upMirrored).withRenderingMode(.alwaysTemplate)
let iconView = UIImageView(image: iconImage)
iconView.contentMode = .scaleAspectFit
iconView.tintColor = UIColor.black.withAlphaComponent(0.6)
container.addSubview(iconView)
iconView.autoPinEdge(toSuperviewEdge: .right)
iconView.autoPinEdge(.left, to: .right, of: label, withOffset: 28)
iconView.autoVCenterInSuperview()
iconView.autoSetDimension(.width, toSize: 13)
}
func handleTap(gestureRecognizer: UIGestureRecognizer) {
tapAction()
}
}

View file

@ -568,6 +568,9 @@
/* Call setup status label */ /* Call setup status label */
"IN_CALL_TERMINATED" = "Call Ended."; "IN_CALL_TERMINATED" = "Call Ended.";
/* Multi line label explainging how to show names instead of phone numbers in your inbox */
"INBOX_VIEW_MISSING_CONTACTS_PERMISSION" = "To see the names of your contacts, update your sytem settings to allow contact access.";
/* notification body */ /* notification body */
"INCOMING_CALL" = "Incoming call"; "INCOMING_CALL" = "Incoming call";