Merge pull request #3559 from vector-im/element_3336

Wait for first sync complete to get account data before stopping loading screen
This commit is contained in:
ismailgulek 2020-08-21 21:07:25 +03:00 committed by GitHub
commit 09e6ef76f2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 119 additions and 18 deletions

View file

@ -13,6 +13,7 @@ Improvements:
Bugfix:
* Fix biometry name null case (#3551).
* Avoid email validation link to redirect to web app (#3513).
* Wait for first sync complete before stopping loading screen (#3336).
API Change:
*

View file

@ -848,6 +848,7 @@
ECAE7AE524EC0E01002FA813 /* TableViewSections.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECAE7AE424EC0E01002FA813 /* TableViewSections.swift */; };
ECAE7AE724EC15F7002FA813 /* Section.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECAE7AE624EC15F7002FA813 /* Section.swift */; };
ECAE7AE924EC1888002FA813 /* Row.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECAE7AE824EC1888002FA813 /* Row.swift */; };
ECAE7AEE24EFDD1F002FA813 /* MXSessionState.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECAE7AED24EFDD1F002FA813 /* MXSessionState.swift */; };
ECB101302477CFDB00CF8C11 /* UITableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECB1012C2477CFDB00CF8C11 /* UITableView.swift */; };
ECB101312477CFDB00CF8C11 /* UILabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECB1012D2477CFDB00CF8C11 /* UILabel.swift */; };
ECB101322477CFDB00CF8C11 /* UIDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECB1012E2477CFDB00CF8C11 /* UIDevice.swift */; };
@ -1976,6 +1977,7 @@
ECAE7AE424EC0E01002FA813 /* TableViewSections.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewSections.swift; sourceTree = "<group>"; };
ECAE7AE624EC15F7002FA813 /* Section.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Section.swift; sourceTree = "<group>"; };
ECAE7AE824EC1888002FA813 /* Row.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Row.swift; sourceTree = "<group>"; };
ECAE7AED24EFDD1F002FA813 /* MXSessionState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MXSessionState.swift; sourceTree = "<group>"; };
ECB1012C2477CFDB00CF8C11 /* UITableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITableView.swift; sourceTree = "<group>"; };
ECB1012D2477CFDB00CF8C11 /* UILabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UILabel.swift; sourceTree = "<group>"; };
ECB1012E2477CFDB00CF8C11 /* UIDevice.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIDevice.swift; sourceTree = "<group>"; };
@ -4964,6 +4966,7 @@
B1DCC63322E72C1B00625807 /* UISearchBar.swift */,
B11291EB238D704C0077B478 /* FloatingPoint.swift */,
32FD757524D2C9BA00BA7B37 /* Bundle.swift */,
ECAE7AED24EFDD1F002FA813 /* MXSessionState.swift */,
);
path = Categories;
sourceTree = "<group>";
@ -5897,6 +5900,7 @@
F05927C91FDED836009F2A68 /* MXGroup+Riot.m in Sources */,
B1B5594520EF7BD000210D55 /* TableViewCellWithCollectionView.m in Sources */,
B1A6C109238828A6002882FD /* SlidingModalPresentationDelegate.swift in Sources */,
ECAE7AEE24EFDD1F002FA813 /* MXSessionState.swift in Sources */,
32DB557722FDADE50016329E /* ServiceTermsModalCoordinator.swift in Sources */,
B185145B24B8C98200EE19EA /* MajorUpdateViewController.swift in Sources */,
32DB557922FDADE50016329E /* ServiceTermsModalScreenViewModel.swift in Sources */,

View file

@ -1121,6 +1121,7 @@
"device_verification_self_verify_wait_recover_secrets_without_passphrase" = "Use Recovery Key";
"device_verification_self_verify_wait_recover_secrets_with_passphrase" = "Use Recovery Passphrase or Key";
"device_verification_self_verify_wait_recover_secrets_additional_information" = "If you can't accessing an existing session";
"device_verification_self_verify_wait_recover_secrets_checking_availability" = "Checking for other verification capabilities ...";
// MARK: Verify

View file

@ -0,0 +1,25 @@
//
// Copyright 2020 Vector Creations Ltd
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Foundation
extension MXSessionState: Comparable {
public static func < (lhs: MXSessionState, rhs: MXSessionState) -> Bool {
return lhs.rawValue < rhs.rawValue
}
}

View file

@ -926,6 +926,10 @@ internal enum VectorL10n {
internal static var deviceVerificationSelfVerifyWaitRecoverSecretsAdditionalInformation: String {
return VectorL10n.tr("Vector", "device_verification_self_verify_wait_recover_secrets_additional_information")
}
/// Checking for other verification capabilities ...
internal static var deviceVerificationSelfVerifyWaitRecoverSecretsCheckingAvailability: String {
return VectorL10n.tr("Vector", "device_verification_self_verify_wait_recover_secrets_checking_availability")
}
/// Use Recovery Passphrase or Key
internal static var deviceVerificationSelfVerifyWaitRecoverSecretsWithPassphrase: String {
return VectorL10n.tr("Vector", "device_verification_self_verify_wait_recover_secrets_with_passphrase")

View file

@ -1,11 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="79A-qb-tmk">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="79A-qb-tmk">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
@ -19,16 +17,16 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="asO-rj-82y">
<rect key="frame" x="0.0" y="20" width="375" height="647"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="tIM-sl-gwE">
<rect key="frame" x="0.0" y="0.0" width="375" height="412.5"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="527"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IlB-Ch-LEo">
<rect key="frame" x="0.0" y="0.0" width="375" height="412.5"/>
<rect key="frame" x="27.5" y="0.0" width="320" height="527"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="d5Y-pj-XsI">
<rect key="frame" x="20" y="20" width="335" height="84"/>
<rect key="frame" x="20" y="20" width="280" height="84"/>
<string key="text">Verify this session from one of your others sessions, granting it access to encrypted messages.
Use the latest Riot on your other devices:</string>
@ -37,7 +35,7 @@ Use the latest Riot on your other devices:</string>
<nil key="highlightedColor"/>
</label>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="ANK-XS-dY7">
<rect key="frame" x="27.5" y="144" width="320" height="95.5"/>
<rect key="frame" x="0.0" y="144" width="320" height="95.5"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" spacing="14" translatesAutoresizingMaskIntoConstraints="NO" id="3at-ql-vhb">
<rect key="frame" x="0.0" y="0.0" width="160" height="95.5"/>
@ -85,19 +83,43 @@ Riot X for Android</string>
</constraints>
</stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="or another cross-signing capable Matrix client" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="rFM-AQ-wAB">
<rect key="frame" x="20" y="259.5" width="335" height="14.5"/>
<rect key="frame" x="20" y="259.5" width="280" height="14.5"/>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/>
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="8oJ-o6-DLK">
<rect key="frame" x="20" y="294" width="335" height="118.5"/>
<rect key="frame" x="20" y="294" width="280" height="233"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="dXT-cL-ukJ">
<rect key="frame" x="0.0" y="0.0" width="280" height="114.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Checking for other verification capabilities ..." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="A4x-sK-d5C">
<rect key="frame" x="20" y="10" width="240" height="38.5"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<activityIndicatorView opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" style="medium" translatesAutoresizingMaskIntoConstraints="NO" id="esP-Lt-anU">
<rect key="frame" x="0.0" y="64.5" width="280" height="20"/>
</activityIndicatorView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="esP-Lt-anU" firstAttribute="leading" secondItem="dXT-cL-ukJ" secondAttribute="leading" id="1Rg-vU-DJm"/>
<constraint firstItem="A4x-sK-d5C" firstAttribute="top" secondItem="dXT-cL-ukJ" secondAttribute="top" constant="10" id="7We-Ox-BZt"/>
<constraint firstItem="A4x-sK-d5C" firstAttribute="leading" secondItem="dXT-cL-ukJ" secondAttribute="leading" constant="20" id="FuM-Cv-7mT"/>
<constraint firstAttribute="trailing" secondItem="A4x-sK-d5C" secondAttribute="trailing" constant="20" id="Lk0-BP-Fdw"/>
<constraint firstAttribute="trailing" secondItem="esP-Lt-anU" secondAttribute="trailing" id="SJY-m2-DP4"/>
<constraint firstItem="esP-Lt-anU" firstAttribute="top" secondItem="A4x-sK-d5C" secondAttribute="bottom" constant="16" id="Tif-UR-9I2"/>
<constraint firstAttribute="bottom" secondItem="esP-Lt-anU" secondAttribute="bottom" constant="30" id="gcZ-sx-3Ff"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="nf8-Ye-b9r">
<rect key="frame" x="0.0" y="0.0" width="335" height="118.5"/>
<rect key="frame" x="0.0" y="114.5" width="280" height="118.5"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="OEt-k0-vgM" customClass="RoundedButton" customModule="Riot" customModuleProvider="target">
<rect key="frame" x="0.0" y="10" width="335" height="44"/>
<rect key="frame" x="0.0" y="10" width="280" height="44"/>
<constraints>
<constraint firstAttribute="height" constant="44" id="7ws-Nc-I7y"/>
</constraints>
@ -110,7 +132,7 @@ Riot X for Android</string>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="If you can't accessing an existing session" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4Ou-cM-K9C">
<rect key="frame" x="20" y="64" width="295" height="24.5"/>
<rect key="frame" x="20" y="64" width="240" height="24.5"/>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/>
<color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
@ -189,6 +211,9 @@ Riot X for Android</string>
<outlet property="mobileClientImageView" destination="P0P-X4-uSQ" id="WtT-ix-yq8"/>
<outlet property="mobileClientLabel" destination="gLH-sE-KCq" id="jQ0-7U-mr8"/>
<outlet property="recoverSecretsAdditionalInformationLabel" destination="4Ou-cM-K9C" id="80N-lF-x2L"/>
<outlet property="recoverSecretsAvailabilityActivityIndicatorView" destination="esP-Lt-anU" id="4jv-GA-Hm9"/>
<outlet property="recoverSecretsAvailabilityLoadingContainerView" destination="dXT-cL-ukJ" id="rBM-Hj-c3o"/>
<outlet property="recoverSecretsAvailabilityLoadingLabel" destination="A4x-sK-d5C" id="n5k-IO-RkV"/>
<outlet property="recoverSecretsButton" destination="OEt-k0-vgM" id="RHU-ps-4m7"/>
<outlet property="recoverSecretsContainerView" destination="nf8-Ye-b9r" id="4az-pe-0Uc"/>
</connections>

View file

@ -40,7 +40,9 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController {
@IBOutlet private weak var additionalInformationLabel: UILabel!
@IBOutlet private weak var recoverSecretsAvailabilityLoadingContainerView: UIView!
@IBOutlet private weak var recoverSecretsAvailabilityLoadingLabel: UILabel!
@IBOutlet private weak var recoverSecretsAvailabilityActivityIndicatorView: UIActivityIndicatorView!
@IBOutlet private weak var recoverSecretsContainerView: UIView!
@IBOutlet private weak var recoverSecretsButton: RoundedButton!
@IBOutlet private weak var recoverSecretsAdditionalInformationLabel: UILabel!
@ -102,6 +104,8 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController {
self.mobileClientLabel.textColor = theme.textPrimaryColor
self.mobileClientImageView.tintColor = theme.tintColor
self.additionalInformationLabel.textColor = theme.textSecondaryColor
self.recoverSecretsAvailabilityLoadingLabel.textColor = theme.textSecondaryColor
self.recoverSecretsAvailabilityActivityIndicatorView.color = theme.tintColor
}
private func registerThemeServiceDidChangeThemeNotification() {
@ -141,6 +145,8 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController {
switch viewState {
case .loading:
self.renderLoading()
case .secretsRecoveryCheckingAvailability(let text):
self.renderSecretsRecoveryCheckingAvailability(withText: text)
case .loaded(let viewData):
self.renderLoaded(viewData: viewData)
case .cancelled(let reason):
@ -156,6 +162,13 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController {
self.activityPresenter.presentActivityIndicator(on: self.view, animated: true)
}
private func renderSecretsRecoveryCheckingAvailability(withText text: String?) {
self.recoverSecretsAvailabilityLoadingLabel.text = text
self.recoverSecretsAvailabilityActivityIndicatorView.startAnimating()
self.recoverSecretsAvailabilityLoadingContainerView.isHidden = false
self.recoverSecretsContainerView.isHidden = true
}
private func renderLoaded(viewData: KeyVerificationSelfVerifyWaitViewData) {
self.activityPresenter.removeCurrentActivityIndicator(animated: true)
@ -180,6 +193,8 @@ final class KeyVerificationSelfVerifyWaitViewController: UIViewController {
}
}
self.recoverSecretsAvailabilityLoadingContainerView.isHidden = true
self.recoverSecretsAvailabilityActivityIndicatorView.stopAnimating()
self.recoverSecretsContainerView.isHidden = hideRecoverSecrets
self.recoverSecretsButton.setTitle(recoverSecretsButtonTitle, for: .normal)
}

View file

@ -28,7 +28,7 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
private let keyVerificationService: KeyVerificationService
private let verificationManager: MXKeyVerificationManager
private let isNewSignIn: Bool
private let secretsRecoveryAvailability: SecretsRecoveryAvailability
private var secretsRecoveryAvailability: SecretsRecoveryAvailability
private var keyVerificationRequest: MXKeyVerificationRequest?
// MARK: Public
@ -62,7 +62,8 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
switch self.secretsRecoveryAvailability {
case .notAvailable:
fatalError("Should not happen: When recovery is not available button is hidden")
case .available(let secretsRecoveryMode): self.coordinatorDelegate?.keyVerificationSelfVerifyWaitViewModel(self, wantsToRecoverSecretsWith: secretsRecoveryMode)
case .available(let secretsRecoveryMode):
self.coordinatorDelegate?.keyVerificationSelfVerifyWaitViewModel(self, wantsToRecoverSecretsWith: secretsRecoveryMode)
}
}
}
@ -85,7 +86,31 @@ final class KeyVerificationSelfVerifyWaitViewModel: KeyVerificationSelfVerifyWai
}, failure: { [weak self] error in
self?.update(viewState: .error(error))
})
continueLoadData()
} else {
// be sure that session has completed its first sync
if session.state >= MXSessionStateRunning {
continueLoadData()
} else {
// show loader
self.update(viewState: .secretsRecoveryCheckingAvailability(VectorL10n.deviceVerificationSelfVerifyWaitRecoverSecretsCheckingAvailability))
NotificationCenter.default.addObserver(self, selector: #selector(sessionStateChanged), name: .mxSessionStateDidChange, object: session)
}
}
}
@objc
private func sessionStateChanged() {
if session.state >= MXSessionStateRunning {
NotificationCenter.default.removeObserver(self, name: .mxSessionStateDidChange, object: session)
continueLoadData()
}
}
private func continueLoadData() {
// update availability again
self.secretsRecoveryAvailability = session.crypto.recoveryService.vc_availability
let viewData = KeyVerificationSelfVerifyWaitViewData(isNewSignIn: self.isNewSignIn, secretsRecoveryAvailability: self.secretsRecoveryAvailability)

View file

@ -31,6 +31,7 @@ struct KeyVerificationSelfVerifyWaitViewData {
/// KeyVerificationSelfVerifyWaitViewController view state
enum KeyVerificationSelfVerifyWaitViewState {
case loading
case secretsRecoveryCheckingAvailability(_ text: String?)
case loaded(_ viewData: KeyVerificationSelfVerifyWaitViewData)
case cancelled(MXTransactionCancelCode)
case cancelledByMe(MXTransactionCancelCode)