mirror of
https://github.com/vector-im/element-ios.git
synced 2024-09-28 23:32:41 +00:00
Merge branch 'develop' into hide_push_content_on_pin_protection
This commit is contained in:
commit
1b44bc8bf2
14 changed files with 182 additions and 47 deletions
27
CHANGES.rst
27
CHANGES.rst
|
@ -5,6 +5,7 @@ Changes to be released in next version
|
|||
*
|
||||
|
||||
🙌 Improvements
|
||||
* Pin: Implement not allowed PINs feature. There is no restriction by default.
|
||||
* Push: Do not show notification content and disable replies when protection set.
|
||||
|
||||
🐛 Bugfix
|
||||
|
@ -22,6 +23,32 @@ Changes to be released in next version
|
|||
Others
|
||||
*
|
||||
|
||||
Changes in 1.0.12 (2020-09-16)
|
||||
|
||||
✨ Features
|
||||
*
|
||||
|
||||
🙌 Improvements
|
||||
*
|
||||
|
||||
🐛 Bugfix
|
||||
*
|
||||
|
||||
⚠️ API Changes
|
||||
*
|
||||
|
||||
🗣 Translations
|
||||
*
|
||||
|
||||
🧱 Build
|
||||
*
|
||||
|
||||
Others
|
||||
*
|
||||
|
||||
Improvements:
|
||||
* Upgrade MatrixKit version ([v0.12.20](https://github.com/matrix-org/matrix-ios-kit/releases/tag/v0.12.20)).
|
||||
|
||||
Changes in 1.0.11 (2020-09-15)
|
||||
=================================================
|
||||
|
||||
|
|
|
@ -168,6 +168,10 @@ final class BuildSettings: NSObject {
|
|||
|
||||
static let allowLocalContactsAccess: Bool = true
|
||||
|
||||
// MARK: - Feature Specifics
|
||||
|
||||
/// Not allowed pin codes. User won't be able to select one of the pin in the list.
|
||||
static let notAllowedPINs: [String] = []
|
||||
|
||||
// MARK: - General Settings Screen
|
||||
|
||||
|
|
2
Podfile
2
Podfile
|
@ -11,7 +11,7 @@ use_frameworks!
|
|||
# - `{ {kit spec hash} => {sdk spec hash}` to depend on specific pod options (:git => …, :podspec => …) for each repo. Used by Fastfile during CI
|
||||
#
|
||||
# Warning: our internal tooling depends on the name of this variable name, so be sure not to change it
|
||||
$matrixKitVersion = '= 0.12.19'
|
||||
$matrixKitVersion = '= 0.12.20'
|
||||
# $matrixKitVersion = :local
|
||||
# $matrixKitVersion = {'develop' => 'develop'}
|
||||
|
||||
|
|
16
Podfile.lock
16
Podfile.lock
|
@ -52,21 +52,21 @@ PODS:
|
|||
- MatomoTracker (7.2.1):
|
||||
- MatomoTracker/Core (= 7.2.1)
|
||||
- MatomoTracker/Core (7.2.1)
|
||||
- MatrixKit (0.12.19):
|
||||
- MatrixKit (0.12.20):
|
||||
- cmark (~> 0.24.1)
|
||||
- DTCoreText (~> 1.6.23)
|
||||
- HPGrowingTextView (~> 1.1)
|
||||
- libPhoneNumber-iOS (~> 0.9.13)
|
||||
- MatrixKit/Core (= 0.12.19)
|
||||
- MatrixKit/Core (= 0.12.20)
|
||||
- MatrixSDK (= 0.16.15)
|
||||
- MatrixKit/AppExtension (0.12.19):
|
||||
- MatrixKit/AppExtension (0.12.20):
|
||||
- cmark (~> 0.24.1)
|
||||
- DTCoreText (~> 1.6.23)
|
||||
- DTCoreText/Extension
|
||||
- HPGrowingTextView (~> 1.1)
|
||||
- libPhoneNumber-iOS (~> 0.9.13)
|
||||
- MatrixSDK (= 0.16.15)
|
||||
- MatrixKit/Core (0.12.19):
|
||||
- MatrixKit/Core (0.12.20):
|
||||
- cmark (~> 0.24.1)
|
||||
- DTCoreText (~> 1.6.23)
|
||||
- HPGrowingTextView (~> 1.1)
|
||||
|
@ -114,8 +114,8 @@ DEPENDENCIES:
|
|||
- KeychainAccess (~> 4.2)
|
||||
- KTCenterFlowLayout (~> 1.3.1)
|
||||
- MatomoTracker (~> 7.2.0)
|
||||
- MatrixKit (= 0.12.19)
|
||||
- MatrixKit/AppExtension (= 0.12.19)
|
||||
- MatrixKit (= 0.12.20)
|
||||
- MatrixKit/AppExtension (= 0.12.20)
|
||||
- MatrixSDK
|
||||
- MatrixSDK/JingleCallStack
|
||||
- MatrixSDK/SwiftSupport
|
||||
|
@ -169,7 +169,7 @@ SPEC CHECKSUMS:
|
|||
libbase58: 7c040313537b8c44b6e2d15586af8e21f7354efd
|
||||
libPhoneNumber-iOS: 0a32a9525cf8744fe02c5206eb30d571e38f7d75
|
||||
MatomoTracker: 246b6b0693cf39b356134dec7561f719d3538b96
|
||||
MatrixKit: cb6531c0fc3b7053de61cb68066bffd4604c3a4b
|
||||
MatrixKit: d7a0a05d6c880c493c3823f4bc203b1550994b33
|
||||
MatrixSDK: 23ad718d0ca1175c8af12a8ad58f1e08d8aed46d
|
||||
OLMKit: 4ee0159d63feeb86d836fdcfefe418e163511639
|
||||
Realm: 4eb04d7487bd43c0581256f40b424eafb711deff
|
||||
|
@ -179,6 +179,6 @@ SPEC CHECKSUMS:
|
|||
zxcvbn-ios: fef98b7c80f1512ff0eec47ac1fa399fc00f7e3c
|
||||
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
|
||||
|
||||
PODFILE CHECKSUM: 052370fece898176579a88e1d3ccde44e015dfa9
|
||||
PODFILE CHECKSUM: 42729c01dc00e56b55fe47af73f2a3a13fa43fb4
|
||||
|
||||
COCOAPODS: 1.9.3
|
||||
|
|
|
@ -7100,7 +7100,7 @@
|
|||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1.0.12;
|
||||
CURRENT_PROJECT_VERSION = 1.0.13;
|
||||
DEFINES_MODULE = YES;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
|
@ -7120,7 +7120,7 @@
|
|||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 1.0.12;
|
||||
MARKETING_VERSION = 1.0.13;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -7159,7 +7159,7 @@
|
|||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CURRENT_PROJECT_VERSION = 1.0.12;
|
||||
CURRENT_PROJECT_VERSION = 1.0.13;
|
||||
DEFINES_MODULE = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
|
@ -7172,7 +7172,7 @@
|
|||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 1.0.12;
|
||||
MARKETING_VERSION = 1.0.13;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
|
|
|
@ -1437,6 +1437,7 @@
|
|||
"pin_protection_settings_section_footer" = "To reset your PIN, you'll need to re-login and create a new one.";
|
||||
"pin_protection_settings_enabled_forced" = "PIN enabled";
|
||||
"pin_protection_settings_enable_pin" = "Enable PIN";
|
||||
"pin_protection_not_allowed_pin" = "For security reasons, this PIN isn’t available. Please try another PIN";
|
||||
|
||||
// MARK: - Biometrics Protection
|
||||
|
||||
|
|
|
@ -2070,6 +2070,10 @@ internal enum VectorL10n {
|
|||
internal static var pinProtectionMismatchTooManyTimesErrorMessage: String {
|
||||
return VectorL10n.tr("Vector", "pin_protection_mismatch_too_many_times_error_message")
|
||||
}
|
||||
/// For security reasons, this PIN isn’t available. Please try another PIN
|
||||
internal static var pinProtectionNotAllowedPin: String {
|
||||
return VectorL10n.tr("Vector", "pin_protection_not_allowed_pin")
|
||||
}
|
||||
/// Reset
|
||||
internal static var pinProtectionResetAlertActionReset: String {
|
||||
return VectorL10n.tr("Vector", "pin_protection_reset_alert_action_reset")
|
||||
|
|
|
@ -63,41 +63,75 @@
|
|||
<constraint firstItem="UHg-qE-anw" firstAttribute="top" secondItem="ztg-5t-ECh" secondAttribute="top" constant="8" id="uj5-KC-7FD"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="24" translatesAutoresizingMaskIntoConstraints="NO" id="xi9-P9-8WP">
|
||||
<rect key="frame" x="103.66666666666669" y="171.66666666666666" width="168" height="24"/>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="l5x-qO-sdf">
|
||||
<rect key="frame" x="2" y="153.33333333333334" width="371" height="78.666666666666657"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="selection_untick" translatesAutoresizingMaskIntoConstraints="NO" id="Gwx-8X-ZWk">
|
||||
<rect key="frame" x="0.0" y="0.0" width="24" height="24"/>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="24" translatesAutoresizingMaskIntoConstraints="NO" id="xi9-P9-8WP">
|
||||
<rect key="frame" x="101.66666666666669" y="0.0" width="168" height="24"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="selection_untick" translatesAutoresizingMaskIntoConstraints="NO" id="Gwx-8X-ZWk">
|
||||
<rect key="frame" x="0.0" y="0.0" width="24" height="24"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="24" id="aek-t8-dK4"/>
|
||||
<constraint firstAttribute="width" constant="24" id="cJN-ZQ-6aQ"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" tag="1" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="selection_untick" translatesAutoresizingMaskIntoConstraints="NO" id="qDY-R1-l5l">
|
||||
<rect key="frame" x="47.999999999999986" y="0.0" width="24" height="24"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="24" id="QDg-LP-R4J"/>
|
||||
<constraint firstAttribute="height" constant="24" id="f4G-d8-hoA"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" tag="2" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="selection_untick" translatesAutoresizingMaskIntoConstraints="NO" id="X0l-q3-fXm">
|
||||
<rect key="frame" x="95.999999999999986" y="0.0" width="24" height="24"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="24" id="HQA-9R-8bC"/>
|
||||
<constraint firstAttribute="height" constant="24" id="Zjd-RW-DiW"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" tag="3" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="selection_untick" translatesAutoresizingMaskIntoConstraints="NO" id="o1F-px-ZT5">
|
||||
<rect key="frame" x="144" y="0.0" width="24" height="24"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="24" id="FA6-QR-ld2"/>
|
||||
<constraint firstAttribute="width" constant="24" id="TcR-MF-wE3"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="CBc-7Z-a5Z">
|
||||
<rect key="frame" x="0.0" y="23.999999999999996" width="371" height="54.666666666666657"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Q0w-RD-JD3">
|
||||
<rect key="frame" x="0.0" y="8" width="371" height="2"/>
|
||||
<color key="backgroundColor" systemColor="systemRedColor" red="1" green="0.23137254900000001" blue="0.18823529410000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="2" id="thx-rI-kOC"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="For security reasons, this PIN isn't available. Please try another PIN" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="H5g-FI-xEj">
|
||||
<rect key="frame" x="8" y="18" width="355" height="28.666666666666671"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="12"/>
|
||||
<color key="textColor" systemColor="systemRedColor" red="1" green="0.23137254900000001" blue="0.18823529410000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="24" id="aek-t8-dK4"/>
|
||||
<constraint firstAttribute="width" constant="24" id="cJN-ZQ-6aQ"/>
|
||||
<constraint firstItem="H5g-FI-xEj" firstAttribute="top" secondItem="Q0w-RD-JD3" secondAttribute="bottom" constant="8" id="Ass-T4-TrH"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Q0w-RD-JD3" secondAttribute="trailing" id="KBv-AB-wkc"/>
|
||||
<constraint firstAttribute="trailing" secondItem="H5g-FI-xEj" secondAttribute="trailing" constant="8" id="SK3-JE-bIK"/>
|
||||
<constraint firstItem="Q0w-RD-JD3" firstAttribute="leading" secondItem="CBc-7Z-a5Z" secondAttribute="leading" id="ZwL-3A-TND"/>
|
||||
<constraint firstItem="Q0w-RD-JD3" firstAttribute="top" secondItem="CBc-7Z-a5Z" secondAttribute="top" constant="8" id="fgi-r2-9bD"/>
|
||||
<constraint firstItem="H5g-FI-xEj" firstAttribute="leading" secondItem="CBc-7Z-a5Z" secondAttribute="leading" constant="8" id="idG-Mm-XPq"/>
|
||||
<constraint firstAttribute="bottom" secondItem="H5g-FI-xEj" secondAttribute="bottom" constant="8" id="xhM-lP-67t"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" tag="1" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="selection_untick" translatesAutoresizingMaskIntoConstraints="NO" id="qDY-R1-l5l">
|
||||
<rect key="frame" x="47.999999999999986" y="0.0" width="24" height="24"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="24" id="QDg-LP-R4J"/>
|
||||
<constraint firstAttribute="height" constant="24" id="f4G-d8-hoA"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" tag="2" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="selection_untick" translatesAutoresizingMaskIntoConstraints="NO" id="X0l-q3-fXm">
|
||||
<rect key="frame" x="95.999999999999986" y="0.0" width="24" height="24"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="24" id="HQA-9R-8bC"/>
|
||||
<constraint firstAttribute="height" constant="24" id="Zjd-RW-DiW"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" tag="3" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="selection_untick" translatesAutoresizingMaskIntoConstraints="NO" id="o1F-px-ZT5">
|
||||
<rect key="frame" x="144" y="0.0" width="24" height="24"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="24" id="FA6-QR-ld2"/>
|
||||
<constraint firstAttribute="width" constant="24" id="TcR-MF-wE3"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
</view>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" alignment="center" spacing="21" translatesAutoresizingMaskIntoConstraints="NO" id="W0M-eq-abZ">
|
||||
<rect key="frame" x="65.666666666666686" y="281.33333333333331" width="244" height="302.99999999999994"/>
|
||||
<rect key="frame" x="65.666666666666686" y="299.66666666666669" width="244" height="303.00000000000006"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="32" translatesAutoresizingMaskIntoConstraints="NO" id="Uqh-o2-7HP">
|
||||
<rect key="frame" x="0.0" y="0.0" width="244" height="60"/>
|
||||
|
@ -182,7 +216,7 @@
|
|||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="32" translatesAutoresizingMaskIntoConstraints="NO" id="YeU-UN-Uo0">
|
||||
<rect key="frame" x="0.0" y="162" width="244" height="60"/>
|
||||
<rect key="frame" x="0.0" y="161.99999999999994" width="244" height="60"/>
|
||||
<subviews>
|
||||
<button opaque="NO" tag="7" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Lnz-5u-oFb">
|
||||
<rect key="frame" x="0.0" y="0.0" width="60" height="60"/>
|
||||
|
@ -223,7 +257,7 @@
|
|||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="32" translatesAutoresizingMaskIntoConstraints="NO" id="Nrp-tS-u1k">
|
||||
<rect key="frame" x="0.0" y="243.00000000000006" width="244" height="60"/>
|
||||
<rect key="frame" x="0.0" y="242.99999999999994" width="244" height="60"/>
|
||||
<subviews>
|
||||
<button opaque="NO" userInteractionEnabled="NO" tag="-99" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DEv-rc-fGB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="60" height="60"/>
|
||||
|
@ -310,6 +344,9 @@
|
|||
<outlet property="informationLabel" destination="bxI-mu-qng" id="pbX-aZ-inC"/>
|
||||
<outlet property="logoImageView" destination="UHg-qE-anw" id="8C0-pd-i3b"/>
|
||||
<outlet property="mainStackView" destination="DMT-DS-IA8" id="qYw-KO-M4k"/>
|
||||
<outlet property="notAllowedPinLabel" destination="H5g-FI-xEj" id="QYZ-bo-QLC"/>
|
||||
<outlet property="notAllowedPinLineView" destination="Q0w-RD-JD3" id="pJ4-2x-eTq"/>
|
||||
<outlet property="notAllowedPinView" destination="CBc-7Z-a5Z" id="ySo-7J-MBK"/>
|
||||
<outlet property="placeholderStackView" destination="xi9-P9-8WP" id="ynl-7M-Rpb"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
|
|
|
@ -35,6 +35,9 @@ final class EnterPinCodeViewController: UIViewController {
|
|||
@IBOutlet private weak var inactiveLogoImageView: UIImageView!
|
||||
@IBOutlet private weak var logoImageView: UIImageView!
|
||||
@IBOutlet private weak var placeholderStackView: UIStackView!
|
||||
@IBOutlet private weak var notAllowedPinView: UIView!
|
||||
@IBOutlet private weak var notAllowedPinLineView: UIView!
|
||||
@IBOutlet private weak var notAllowedPinLabel: UILabel!
|
||||
@IBOutlet private weak var digitsStackView: UIStackView!
|
||||
@IBOutlet private weak var informationLabel: UILabel!
|
||||
@IBOutlet private weak var forgotPinButton: UIButton!
|
||||
|
@ -116,6 +119,8 @@ final class EnterPinCodeViewController: UIViewController {
|
|||
}
|
||||
|
||||
self.informationLabel.textColor = theme.textPrimaryColor
|
||||
self.notAllowedPinLineView.backgroundColor = theme.noticeColor
|
||||
self.notAllowedPinLabel.textColor = theme.noticeColor
|
||||
|
||||
updateThemesOfAllImages(in: placeholderStackView, with: theme)
|
||||
updateThemesOfAllButtons(in: digitsStackView, with: theme)
|
||||
|
@ -157,6 +162,8 @@ final class EnterPinCodeViewController: UIViewController {
|
|||
|
||||
self.title = ""
|
||||
|
||||
notAllowedPinLabel.text = VectorL10n.pinProtectionNotAllowedPin
|
||||
|
||||
placeholderStackView.vc_removeAllArrangedSubviews()
|
||||
for i in 0..<PinCodePreferences.shared.numberOfDigits {
|
||||
let imageView = UIImageView(image: Asset.Images.selectionUntick.image)
|
||||
|
@ -183,6 +190,8 @@ final class EnterPinCodeViewController: UIViewController {
|
|||
switch viewState {
|
||||
case .choosePin:
|
||||
self.renderChoosePin()
|
||||
case .notAllowedPin:
|
||||
self.renderNotAllowedPin()
|
||||
case .confirmPin:
|
||||
self.renderConfirmPin()
|
||||
case .pinsDontMatch:
|
||||
|
@ -208,12 +217,25 @@ final class EnterPinCodeViewController: UIViewController {
|
|||
self.logoImageView.isHidden = true
|
||||
self.informationLabel.text = VectorL10n.pinProtectionChoosePin
|
||||
self.forgotPinButton.isHidden = true
|
||||
self.notAllowedPinView.isHidden = true
|
||||
}
|
||||
|
||||
private func renderNotAllowedPin() {
|
||||
self.inactiveView.isHidden = true
|
||||
self.mainStackView.isHidden = false
|
||||
self.logoImageView.isHidden = true
|
||||
self.informationLabel.text = VectorL10n.pinProtectionChoosePin
|
||||
self.forgotPinButton.isHidden = true
|
||||
self.notAllowedPinView.isHidden = false
|
||||
|
||||
renderPlaceholdersCount(.max, error: true)
|
||||
}
|
||||
|
||||
private func renderConfirmPin() {
|
||||
self.inactiveView.isHidden = true
|
||||
self.mainStackView.isHidden = false
|
||||
self.informationLabel.text = VectorL10n.pinProtectionConfirmPin
|
||||
self.notAllowedPinView.isHidden = true
|
||||
|
||||
// reset placeholders
|
||||
renderPlaceholdersCount(0)
|
||||
|
@ -236,11 +258,13 @@ final class EnterPinCodeViewController: UIViewController {
|
|||
self.logoImageView.isHidden = false
|
||||
self.informationLabel.text = VectorL10n.pinProtectionEnterPin
|
||||
self.forgotPinButton.isHidden = false
|
||||
self.notAllowedPinView.isHidden = true
|
||||
}
|
||||
|
||||
private func renderWrongPin() {
|
||||
self.inactiveView.isHidden = true
|
||||
self.mainStackView.isHidden = false
|
||||
self.notAllowedPinView.isHidden = true
|
||||
self.placeholderStackView.vc_shake()
|
||||
}
|
||||
|
||||
|
@ -276,19 +300,25 @@ final class EnterPinCodeViewController: UIViewController {
|
|||
self.logoImageView.isHidden = true
|
||||
self.informationLabel.text = VectorL10n.pinProtectionConfirmPinToDisable
|
||||
self.forgotPinButton.isHidden = true
|
||||
self.notAllowedPinView.isHidden = true
|
||||
}
|
||||
|
||||
private func renderInactive() {
|
||||
self.hideCancelButton()
|
||||
self.inactiveView.isHidden = false
|
||||
self.mainStackView.isHidden = true
|
||||
self.notAllowedPinView.isHidden = true
|
||||
}
|
||||
|
||||
private func renderPlaceholdersCount(_ count: Int) {
|
||||
private func renderPlaceholdersCount(_ count: Int, error: Bool = false) {
|
||||
UIView.animate(withDuration: 0.3) {
|
||||
for case let imageView as UIImageView in self.placeholderStackView.arrangedSubviews {
|
||||
if imageView.tag < count {
|
||||
imageView.image = Asset.Images.placeholder.image
|
||||
if error {
|
||||
imageView.image = Asset.Images.placeholder.image.vc_tintedImage(usingColor: self.theme.noticeColor)
|
||||
} else {
|
||||
imageView.image = Asset.Images.placeholder.image
|
||||
}
|
||||
} else {
|
||||
imageView.image = Asset.Images.selectionUntick.image
|
||||
}
|
||||
|
|
|
@ -84,9 +84,28 @@ final class EnterPinCodeViewModel: EnterPinCodeViewModelType {
|
|||
return
|
||||
} else {
|
||||
currentPin.removeLast()
|
||||
|
||||
// switch to setPin if blocked
|
||||
if viewMode == .notAllowedPin {
|
||||
// clear error UI
|
||||
update(viewState: .choosePin)
|
||||
// switch to normal flow
|
||||
viewMode = .setPin
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// a digit tapped
|
||||
|
||||
// switch to setPin if blocked
|
||||
if viewMode == .notAllowedPin {
|
||||
// clear old pin first
|
||||
currentPin.removeAll()
|
||||
// clear error UI
|
||||
update(viewState: .choosePin)
|
||||
// switch to normal flow
|
||||
viewMode = .setPin
|
||||
}
|
||||
// add new digit
|
||||
currentPin += String(tag)
|
||||
|
||||
if currentPin.count == pinCodePreferences.numberOfDigits {
|
||||
|
@ -94,6 +113,12 @@ final class EnterPinCodeViewModel: EnterPinCodeViewModelType {
|
|||
case .setPin:
|
||||
// choosing pin
|
||||
if firstPin.isEmpty {
|
||||
// check if this PIN is allowed
|
||||
if pinCodePreferences.notAllowedPINs.contains(currentPin) {
|
||||
viewMode = .notAllowedPin
|
||||
update(viewState: .notAllowedPin)
|
||||
return
|
||||
}
|
||||
// go to next screen
|
||||
firstPin = currentPin
|
||||
currentPin.removeAll()
|
||||
|
|
|
@ -21,6 +21,7 @@ import Foundation
|
|||
/// EnterPinCodeViewController view state
|
||||
enum EnterPinCodeViewState {
|
||||
case choosePin // creating pin for the first time, enter for first
|
||||
case notAllowedPin // creating pin for the first time, provided pin is not allowed
|
||||
case confirmPin // creating pin for the first time, confirm
|
||||
case pinsDontMatch // pins don't match
|
||||
case unlock // after pin has been set, enter pin to unlock
|
||||
|
|
|
@ -51,6 +51,11 @@ final class PinCodePreferences: NSObject {
|
|||
return BuildSettings.forcePinProtection
|
||||
}
|
||||
|
||||
/// Not allowed pin codes. User won't be able to select one of the pin in the list.
|
||||
var notAllowedPINs: [String] {
|
||||
return BuildSettings.notAllowedPINs
|
||||
}
|
||||
|
||||
var isBiometricsAvailable: Bool {
|
||||
return LAContext().canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: nil)
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ final class SetPinCoordinator: SetPinCoordinatorType {
|
|||
} else {
|
||||
return createEnterPinCodeCoordinator()
|
||||
}
|
||||
case .setPin, .confirmPinToDeactivate:
|
||||
case .setPin, .notAllowedPin, .confirmPinToDeactivate:
|
||||
return createEnterPinCodeCoordinator()
|
||||
case .setupBiometricsAfterLogin, .setupBiometricsFromSettings, .confirmBiometricsToDeactivate:
|
||||
return createSetupBiometricsCoordinator()
|
||||
|
|
|
@ -20,6 +20,7 @@ import Foundation
|
|||
|
||||
@objc enum SetPinCoordinatorViewMode: Int {
|
||||
case setPin
|
||||
case notAllowedPin
|
||||
case unlock
|
||||
case confirmPinToDeactivate
|
||||
case setupBiometricsAfterLogin
|
||||
|
|
Loading…
Reference in a new issue