ContactViewModel.swift 7.94 KB
Newer Older
1
/*
2
 *  Copyright (C) 2018-2019 Savoir-faire Linux Inc.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
 *
 *  Author: Kateryna Kostiuk <kateryna.kostiuk@savoirfairelinux.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
 */

import UIKit
import Reusable
import RxSwift
import RxCocoa
import RxDataSources

struct ContactActions {
    let title: String
    let image: ImageAsset
}

class ContactViewModel: ViewModel, Stateable {
    private let disposeBag = DisposeBag()
    // MARK: - Rx Stateable
    private let stateSubject = PublishSubject<State>()
    lazy var state: Observable<State> = {
        return self.stateSubject.asObservable()
    }()
    private let contactService: ContactsService
    private let profileService: ProfilesService
    private let accountService: AccountsService
    private let conversationService: ConversationsService
Kateryna Kostiuk's avatar
Kateryna Kostiuk committed
43 44
    private let nameService: NameService
    var tableSection = Observable<[SectionModel<String, ContactActions>]>
45 46
        .just([SectionModel(model: "ProfileInfoCell",
                            items:
47 48 49
            [ ContactActions(title: L10n.ContactPage.startAudioCall, image: Asset.callButton),
              ContactActions(title: L10n.ContactPage.startVideoCall, image: Asset.videoRunning),
              ContactActions(title: L10n.ContactPage.sendMessage, image: Asset.conversationIcon)])])
50 51 52 53 54 55 56 57
    var conversation: ConversationModel! {
        didSet {
            if let profile = conversation.participantProfile, let alias = profile.alias, !alias.isEmpty {
                self.displayName.value = alias
            }
            if let contact = self.contactService.contact(withRingId: conversation.recipientRingId),
                let name = contact.userName {
                self.userName.value = name
Kateryna Kostiuk's avatar
Kateryna Kostiuk committed
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
            } else {
                self.userName.value = conversation.recipientRingId
                self.nameService.usernameLookupStatus
                    .filter({ [unowned self] lookupNameResponse in
                        return lookupNameResponse.address != nil &&
                            lookupNameResponse.address == self.conversation.recipientRingId
                    }).subscribe(onNext: { [unowned self] lookupNameResponse in
                        if let name = lookupNameResponse.name, !name.isEmpty {
                            self.userName.value = name
                        } else if let address = lookupNameResponse.address {
                            self.userName.value = address
                        }
                    }).disposed(by: disposeBag)

                self.nameService.lookupAddress(withAccount: "", nameserver: "", address: conversation.recipientRingId)
            }

            // add option block contact and clear conversation if contact exists
            if self.contactService.contact(withRingId: conversation.recipientRingId) != nil {
                self.tableSection = Observable<[SectionModel<String, ContactActions>]>
                    .just([SectionModel(model: "ProfileInfoCell",
                                        items:
80 81 82 83
                        [ ContactActions(title: L10n.ContactPage.startAudioCall, image: Asset.callButton),
                          ContactActions(title: L10n.ContactPage.startVideoCall, image: Asset.videoRunning),
                          ContactActions(title: L10n.ContactPage.sendMessage, image: Asset.conversationIcon),
                          ContactActions(title: L10n.ContactPage.clearConversation, image: Asset.clearConversation),
84
                          ContactActions(title: L10n.ContactPage.removeConversation, image: Asset.icConversationRemove),
85
                          ContactActions(title: L10n.ContactPage.blockContact, image: Asset.blockIcon)])])
86 87 88 89 90 91 92 93 94 95 96 97 98
            }
            self.contactService
                .getContactRequestVCard(forContactWithRingId: conversation.recipientRingId)
                .subscribe(onSuccess: { [unowned self] vCard in
                    if !VCardUtils.getName(from: vCard).isEmpty {
                        self.displayName.value = VCardUtils.getName(from: vCard)
                    }
                    guard let imageData = vCard.imageData else {
                        return
                    }
                    self.profileImageData.value = imageData
                })
                .disposed(by: self.disposeBag)
99 100
            self.profileService.getProfile(ringId: conversation.recipientRingId,
                                           createIfNotexists: false)
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
                .subscribe(onNext: { [unowned self] profile in
                    if let alias = profile.alias, !alias.isEmpty {
                        self.displayName.value = alias
                    }
                    if let photo = profile.photo,
                        let data = NSData(base64Encoded: photo, options: NSData.Base64DecodingOptions.ignoreUnknownCharacters) as Data? {
                        self.profileImageData.value = data
                    }
                }).disposed(by: disposeBag)
        }
    }
    var userName = Variable<String>("")
    var displayName = Variable<String>("")
    lazy var titleName: Observable<String> = {
        return Observable.combineLatest(userName.asObservable(),
                                        displayName.asObservable()) {(userName, displayname) in
                                            if displayname.isEmpty {
                                                return userName
                                            }
                                            return displayname
        }
    }()
    var profileImageData = Variable<Data?>(nil)
    required init (with injectionBag: InjectionBag) {
        self.contactService = injectionBag.contactsService
        self.profileService = injectionBag.profileService
        self.accountService = injectionBag.accountService
        self.conversationService = injectionBag.conversationsService
Kateryna Kostiuk's avatar
Kateryna Kostiuk committed
129
        self.nameService = injectionBag.nameService
130 131 132 133 134 135 136 137 138 139 140 141 142 143
    }
    func startCall() {
        self.stateSubject.onNext(ConversationState
            .startCall(contactRingId: conversation.recipientRingId,
                       userName: self.userName.value))
    }
    func startAudioCall() {
        self.stateSubject.onNext(ConversationState
            .startAudioCall(contactRingId: conversation.recipientRingId,
                            userName: self.userName.value))
    }

    func deleteConversation() {
        self.conversationService
144 145 146 147 148 149 150 151
            .clearHistory(conversation: conversation,
                                keepConversation: false)
    }

    func clearConversation() {
        self.conversationService
            .clearHistory(conversation: conversation,
                                keepConversation: true)
152 153 154 155 156 157 158 159 160 161 162
    }

    func blockContact() {
        let contactRingId = conversation.recipientRingId
        let accountId = conversation.accountId
        let removeCompleted = self.contactService.removeContact(withRingId: contactRingId,
                                                                ban: true,
                                                                withAccountId: accountId)
        removeCompleted.asObservable()
            .subscribe(onCompleted: { [unowned self] in
                self.conversationService
163 164
                    .clearHistory(conversation: self.conversation,
                                        keepConversation: false)
165 166 167
            }).disposed(by: self.disposeBag)
    }
}