pEpForiOS/UI/Handshake/ViewModel/HandshakePartnerTableViewCellViewModel.swift
author buff <andreas@pep-project.org>
Wed, 15 May 2019 10:47:37 +0200
branchIOS-1521+IOS-1495
changeset 8620 81e20eeddbe0
parent 8525 70d607f356db
child 8706 4a0b9b1fe61a
permissions -rw-r--r--
IOS-1521 reminder for root of CdCrash
     1 //
     2 //  HandshakePartnerTableViewCellViewModel.swift
     3 //  pEpForiOS
     4 //
     5 //  Created by Dirk Zimmermann on 26.04.17.
     6 //  Copyright © 2017 p≡p Security S.A. All rights reserved.
     7 //
     8 
     9 import Foundation
    10 import pEpIOSToolbox
    11 import MessageModel
    12 import PEPObjCAdapterFramework
    13 import PEPObjCAdapterFramework
    14 
    15 class HandshakePartnerTableViewCellViewModel {
    16     enum ExpandedState {
    17         case notExpanded
    18         case expanded
    19     }
    20 
    21     /**
    22      The background changes depending on the position in the list, alternating between
    23      light and dark.
    24      */
    25     var backgroundColorDark = true
    26 
    27     /** Do we show the trustwords for this identity? */
    28     var showTrustwords: Bool {
    29         switch partnerColor {
    30         case .yellow:
    31             return true
    32         default:
    33             return false
    34         }
    35     }
    36 
    37     /** Show the button for start/stop trusting? */
    38     var showStopStartTrustButton: Bool {
    39         return partnerColor == .green || partnerColor == PEPColor.red ||
    40             partnerRating == .haveNoKey
    41     }
    42 
    43     var expandedState: ExpandedState
    44 
    45     /**
    46      The rating of the partner.
    47      */
    48     var partnerRating: PEPRating
    49 
    50     /**
    51      The color of the partner.
    52      */
    53     var partnerColor: PEPColor
    54 
    55     var trustwordsLanguage: String{
    56         didSet{
    57             updateTrustwords(session: session)
    58         }
    59     }
    60     var trustwordsFull = false
    61 
    62     var ownName: String {
    63         return pEpSelf.userName ?? pEpSelf.address
    64     }
    65 
    66     var partnerName: String {
    67         return pEpPartner.userName ?? pEpPartner.address
    68     }
    69 
    70     var partnerImage = ObservableValue<UIImage>()
    71     var trustwords: String?
    72 
    73     /**
    74      pEp session usable on the main thread.
    75      */
    76     let session: PEPSession
    77 
    78     var isPartnerpEpUser = false
    79 
    80     /**
    81      Have to store this for some future access from the owning VC.
    82      */
    83     let ownIdentity: Identity
    84 
    85     /**
    86      Cache the updated own identity.
    87      */
    88     let pEpSelf: PEPIdentity
    89 
    90     /**
    91      Cache the updated partner identity.
    92      */
    93     var pEpPartner: PEPIdentity
    94 
    95     lazy var contactImageTool = IdentityImageTool()
    96 
    97     init(ownIdentity: Identity, partner: Identity, session: PEPSession) {
    98         self.expandedState = .notExpanded
    99         self.trustwordsLanguage = "en"
   100         self.session = session
   101         self.partnerRating = PEPUtil.pEpRating(identity: partner, session: session)
   102         self.partnerColor = partnerRating.pEpColor()
   103         self.ownIdentity = ownIdentity
   104 
   105         pEpSelf = ownIdentity.updatedIdentity(session: session)
   106         pEpPartner = partner.updatedIdentity(session: session)
   107 
   108         do {
   109             isPartnerpEpUser = try session.isPEPUser(pEpPartner).boolValue
   110         } catch let err as NSError {
   111             Log.shared.error("%{public}@", err.localizedDescription)
   112             isPartnerpEpUser = false
   113         }
   114         setPartnerImage(for: partner)
   115         updateTrustwords(session: session)
   116     }
   117 
   118     private func setPartnerImage(`for` partnerIdentity: Identity) {
   119         if let cachedContactImage =
   120             contactImageTool.cachedIdentityImage(for: IdentityImageTool.IdentityKey(identity: partnerIdentity)) {
   121             partnerImage.value = cachedContactImage
   122         } else {
   123             DispatchQueue.global().async { [weak self] in
   124                 guard let me = self else {
   125                     Log.shared.errorAndCrash("Lost myself")
   126                     return
   127                 } //!!!: needs session (partnerIdentity?)
   128                 let contactImage = me.contactImageTool.identityImage(for: IdentityImageTool.IdentityKey(identity: partnerIdentity))
   129                 me.partnerImage.value = contactImage
   130             }
   131         }
   132     }
   133 
   134     func updateTrustwords(session: PEPSession = PEPSession()) {
   135         if !isPartnerpEpUser,
   136             let fprSelf = pEpSelf.fingerPrint,
   137             let fprPartner = pEpPartner.fingerPrint {
   138             let fprPrettySelf = fprSelf.prettyFingerPrint()
   139             let fprPrettyPartner = fprPartner.prettyFingerPrint()
   140             self.trustwords =
   141                 "\(partnerName):\n\(fprPrettyPartner)\n\n" + "\(ownName):\n\(fprPrettySelf)"
   142         } else {
   143             self.trustwords = determineTrustwords(identitySelf: pEpSelf,
   144                                                   identityPartner: pEpPartner)
   145         }
   146     }
   147 
   148     func determineTrustwords(identitySelf: PEPIdentity, identityPartner: PEPIdentity) -> String? {
   149         do {
   150             return try session.getTrustwordsIdentity1(
   151                 identitySelf,
   152                 identity2: identityPartner,
   153                 language: trustwordsLanguage,
   154                 full: trustwordsFull)
   155         } catch let err as NSError {
   156             Log.shared.error("%{public}@", err.localizedDescription)
   157             return nil
   158         }
   159     }
   160 
   161     func toggleTrustwordsLength() {
   162         trustwordsFull = !trustwordsFull
   163         updateTrustwords(session: session)
   164     }
   165 
   166     func invokeTrustAction(action: (PEPIdentity) -> ()) {
   167         let theBackup = PEPIdentity(identity: pEpPartner)
   168         action(pEpPartner)
   169         pEpPartner = theBackup
   170 
   171         do {
   172             partnerRating = try session.rating(for: pEpPartner).pEpRating
   173             partnerColor = PEPUtil.pEpColor(pEpRating: partnerRating)
   174         } catch let error as NSError {
   175             assertionFailure("\(error)")
   176         }
   177 
   178         updateTrustwords(session: session)
   179     }
   180 
   181     public func confirmTrust() {
   182         invokeTrustAction() { thePartner in
   183             do {
   184                 try session.trustPersonalKey(thePartner)
   185             } catch let error as NSError {
   186                 assertionFailure("\(error)")
   187             }
   188         }
   189     }
   190 
   191     public func denyTrust() {
   192         invokeTrustAction() { thePartner in
   193             do {
   194                 try session.keyMistrusted(thePartner)
   195             } catch let error as NSError {
   196                 assertionFailure("\(error)")
   197             }
   198         }
   199     }
   200 
   201     /**
   202      Used for undoing a trust or mistrust.
   203      - Note: Since undoLastMistrust is currently not implemented with all consequences,
   204      it is not used.
   205      */
   206     public func resetOrUndoTrustOrMistrust() {
   207         invokeTrustAction() { thePartner in
   208             do {
   209                 try session.keyResetTrust(thePartner)
   210             } catch let error as NSError {
   211                 assertionFailure("\(error)")
   212             }
   213         }
   214     }
   215 }