Update verified status in safety number confirmation sheet

This commit is contained in:
Sasha Weiss 2023-04-06 12:11:52 -07:00 committed by GitHub
parent e5fd132778
commit c7f4fcd860
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 102 additions and 34 deletions

View File

@ -5446,6 +5446,9 @@
/* Title for the 'safety number confirmation' view */
"SAFETY_NUMBER_CONFIRMATION_TITLE" = "Safety Number Changes";
/* Text explaining that the given contact has had their safety number verified. */
"SAFETY_NUMBER_CONFIRMATION_VERIFIED" = "Verified";
/* View safety number action for the 'safety number confirmation' view */
"SAFETY_NUMBER_CONFIRMATION_VIEW_ACTION" = "View";

View File

@ -17,10 +17,12 @@ public class SafetyNumberConfirmationSheet: UIViewController {
struct Item {
let address: SignalServiceAddress
let displayName: String?
let verificationState: OWSVerificationState?
let displayName: String
let verificationState: OWSVerificationState
}
var items = [Item]()
private var confirmationItems: [Item]
let confirmAction: ActionSheetAction
let cancelAction: ActionSheetAction
let completionHandler: (Bool) -> Void
@ -34,36 +36,82 @@ public class SafetyNumberConfirmationSheet: UIViewController {
self.init(addressesToConfirm: addresses, confirmationText: confirmationText, completionHandler: completionHandler)
}
public init(addressesToConfirm addresses: [SignalServiceAddress],
confirmationText: String,
cancelText: String = CommonStrings.cancelButton,
theme: Theme.ActionSheet = .translucentDark,
completionHandler: @escaping (Bool) -> Void) {
public init(
addressesToConfirm: [SignalServiceAddress],
confirmationText: String,
cancelText: String = CommonStrings.cancelButton,
theme: Theme.ActionSheet = .translucentDark,
completionHandler: @escaping (Bool) -> Void
) {
assert(!addressesToConfirm.isEmpty)
self.confirmationItems = Self.databaseStorage.read { transaction in
Self.buildConfirmationItems(
addressesToConfirm: addressesToConfirm,
transaction: transaction
)
}
assert(!addresses.isEmpty)
self.confirmAction = ActionSheetAction(title: confirmationText, style: .default)
self.cancelAction = ActionSheetAction(title: cancelText, style: .cancel)
self.completionHandler = completionHandler
self.theme = theme
super.init(nibName: nil, bundle: nil)
modalPresentationStyle = .custom
transitioningDelegate = self
SDSDatabaseStorage.shared.read { transaction in
self.items = addresses.map {
return Item(
address: $0,
displayName: Self.contactsManager.displayName(for: $0, transaction: transaction),
verificationState: Self.identityManager.verificationState(for: $0, transaction: transaction)
)
}
}
observeIdentityChangeNotification()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
fileprivate static func buildConfirmationItems(
addressesToConfirm: [SignalServiceAddress],
transaction: SDSAnyReadTransaction
) -> [Item] {
addressesToConfirm.map { address in
return Item(
address: address,
displayName: contactsManager.displayName(for: address, transaction: transaction),
verificationState: identityManager.verificationState(for: address, transaction: transaction)
)
}
}
// MARK: - Identity change notification
private func observeIdentityChangeNotification() {
NotificationCenter.default.addObserver(
self,
selector: #selector(identityStateDidChange),
name: .identityStateDidChange,
object: nil
)
}
/// Rebuild our confirmation items and reload the table, to ensure we
/// reflect the latest identity state after the user may have verified
/// one of the addresses we presented.
@objc
private func identityStateDidChange() {
databaseStorage.read { transaction in
let addressesToConfirm = confirmationItems.map { $0.address }
confirmationItems = Self.buildConfirmationItems(
addressesToConfirm: addressesToConfirm,
transaction: transaction
)
}
tableView.reloadData()
}
// MARK: - Present if necessary
@objc
public class func presentIfNecessary(address: SignalServiceAddress, confirmationText: String, completion: @escaping (Bool) -> Void) -> Bool {
return presentIfNecessary(addresses: [address], confirmationText: confirmationText, completion: completion)
@ -186,7 +234,7 @@ public class SafetyNumberConfirmationSheet: UIViewController {
confirmAction.button.releaseAction = { [weak self] in
guard let self = self else { return }
let identityManager = self.identityManager
let unconfirmedAddresses = self.items.map { $0.address }
let unconfirmedAddresses = self.confirmationItems.map { $0.address }
self.databaseStorage.asyncWrite(block: { writeTx in
for address in unconfirmedAddresses {
@ -259,14 +307,14 @@ public class SafetyNumberConfirmationSheet: UIViewController {
var minimizedHeight: CGFloat {
// We want to show, at most, 3.5 rows when minimized. When we have
// less than 4 rows, we will match our size to the number of rows.
let compactTableViewHeight = min(CGFloat(items.count), 3.5) * cellHeight
let compactTableViewHeight = min(CGFloat(confirmationItems.count), 3.5) * cellHeight
let preferredMinimizedHeight = baseStackViewHeight + compactTableViewHeight + view.safeAreaInsets.bottom
return min(maximizedHeight, preferredMinimizedHeight)
}
var maximizedHeight: CGFloat {
let tableViewHeight = CGFloat(items.count) * cellHeight
let tableViewHeight = CGFloat(confirmationItems.count) * cellHeight
let preferredMaximizedHeight = baseStackViewHeight + tableViewHeight + view.safeAreaInsets.bottom
let maxPermittedHeight = CurrentAppContext().frame.height - view.safeAreaInsets.top - 16
@ -479,7 +527,7 @@ extension SafetyNumberConfirmationSheet: UITableViewDelegate, UITableViewDataSou
}
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
return confirmationItems.count
}
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
@ -490,7 +538,7 @@ extension SafetyNumberConfirmationSheet: UITableViewDelegate, UITableViewDataSou
return cell
}
guard let item = items[safe: indexPath.row] else {
guard let item = confirmationItems[safe: indexPath.row] else {
return cell
}
@ -546,19 +594,22 @@ private class SafetyNumberCell: ContactTableViewCell {
configuration.accessoryView = ContactCellAccessoryView(accessoryView: buttonWrapper,
size: buttonSize)
if let verificationState = item.verificationState, verificationState == .noLongerVerified {
let previouslyVerified = NSMutableAttributedString()
previouslyVerified.appendTemplatedImage(named: "check-12", font: UIFont.ows_regularFont(withSize: 11))
previouslyVerified.append(" ")
previouslyVerified.append(
OWSLocalizedString("SAFETY_NUMBER_CONFIRMATION_PREVIOUSLY_VERIFIED",
comment: "Text explaining that the given contact previously had their safety number verified.")
)
configuration.attributedSubtitle = previouslyVerified
} else if let displayName = item.displayName {
switch item.verificationState {
case .noLongerVerified:
configuration.attributedSubtitle = .prefixedWithCheck(text: OWSLocalizedString(
"SAFETY_NUMBER_CONFIRMATION_PREVIOUSLY_VERIFIED",
comment: "Text explaining that the given contact previously had their safety number verified."
))
case .verified:
configuration.attributedSubtitle = .prefixedWithCheck(text: OWSLocalizedString(
"SAFETY_NUMBER_CONFIRMATION_VERIFIED",
comment: "Text explaining that the given contact has had their safety number verified."
))
case .`default`:
if let phoneNumber = item.address.phoneNumber {
let formattedPhoneNumber = PhoneNumber.bestEffortLocalizedPhoneNumber(withE164: phoneNumber)
if displayName != formattedPhoneNumber {
if item.displayName != formattedPhoneNumber {
configuration.attributedSubtitle = NSAttributedString(string: formattedPhoneNumber)
}
}
@ -578,6 +629,20 @@ private class SafetyNumberCell: ContactTableViewCell {
}
}
private extension NSAttributedString {
static func prefixedWithCheck(
text: String
) -> NSAttributedString {
let string = NSMutableAttributedString()
string.appendTemplatedImage(named: "check-12", font: UIFont.ows_regularFont(withSize: 11))
string.append(" ")
string.append(text)
return string
}
}
// MARK: -
extension SafetyNumberConfirmationSheet: UIGestureRecognizerDelegate {
public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {