ContactRequestsViewModel.swift 7.22 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
 *  Copyright (C) 2017 Savoir-faire Linux Inc.
 *
 *  Author: Silbino Gonçalves Matado <silbino.gmatado@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 RxSwift
import Contacts
import SwiftyBeaver

25
26
27
28
29
30
31
class ContactRequestsViewModel: Stateable, ViewModel {

    // MARK: - Rx Stateable
    private let stateSubject = PublishSubject<State>()
    lazy var state: Observable<State> = {
        return self.stateSubject.asObservable()
    }()
32
33
34

    let contactsService: ContactsService
    let accountsService: AccountsService
35
    let conversationService: ConversationsService
36
    let nameService: NameService
37
    let presenceService: PresenceService
38
39

    fileprivate let disposeBag = DisposeBag()
40
    fileprivate let log = SwiftyBeaver.self
41

42
43
    fileprivate let injectionBag: InjectionBag

44
45
46
    required init(with injectionBag: InjectionBag) {
        self.contactsService = injectionBag.contactsService
        self.accountsService = injectionBag.accountService
47
        self.conversationService = injectionBag.conversationsService
48
        self.nameService = injectionBag.nameService
49
        self.presenceService = injectionBag.presenceService
50

51
52
        self.injectionBag = injectionBag

53
54
55
56
57
58
59
60
61
62
        self.contactsService.contactRequests
            .asObservable()
            .subscribe(onNext: {[unowned self] contactRequests in
                guard let account = self.accountsService.currentAccount else { return }
                guard let ringId = contactRequests.last?.ringId else { return }
                self.conversationService.generateMessage(ofType: GeneratedMessageType.receivedContactRequest,
                                                         forRindId: ringId,
                                                         forAccount: account)
            })
            .disposed(by: self.disposeBag)
63
64
65
66
67
68
69
70
71
72
73
74
75
    }

    lazy var contactRequestItems: Observable<[ContactRequestItem]> = {
        return self.contactsService.contactRequests
            .asObservable()
            .map({ [unowned self] contactRequests in
                return contactRequests
                    .filter { $0.accountId == self.accountsService.currentAccount?.id }
                    .sorted { $0.receivedDate > $1.receivedDate }
                    .map { contactRequest in
                        let item = ContactRequestItem(withContactRequest: contactRequest)
                        self.lookupUserName(withItem: item)
                        return item
76
                    }
77
78
79
80
            })
    }()

    lazy var hasInvitations: Observable<Bool> = {
81
82
83
84
85
        return self.contactsService.contactRequests
            .asObservable()
            .map({ items in
                return !items.isEmpty
            })
86
87
88
89
90
    }()

    func accept(withItem item: ContactRequestItem) -> Observable<Void> {
        let acceptCompleted = self.contactsService.accept(contactRequest: item.contactRequest, withAccount: self.accountsService.currentAccount!)

91
        let accountHelper = AccountModelHelper(withAccount: self.accountsService.currentAccount!)
92
93
        self.conversationService.saveMessage(withId: "",
                                             withContent: GeneratedMessageType.contactRequestAccepted.rawValue,
94
95
96
97
98
99
100
101
                                             byAuthor: accountHelper.ringId!,
                                             toConversationWith: item.contactRequest.ringId,
                                             currentAccountId: (self.accountsService.currentAccount?.id)!, generated: true)
            .subscribe(onCompleted: { [unowned self] in
                self.log.debug("Message saved")
            })
            .disposed(by: disposeBag)

102
103
104
105
        self.presenceService.subscribeBuddy(withAccountId: (self.accountsService.currentAccount?.id)!,
                                            withUri: item.contactRequest.ringId,
                                            withFlag: true)

106
        if let vCard = item.contactRequest.vCard {
Kateryna Kostiuk's avatar
Kateryna Kostiuk committed
107
            let saveVCardCompleted = self.contactsService.saveVCard(vCard: vCard, forContactWithRingId: item.contactRequest.ringId)
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
            return Observable<Void>.zip(acceptCompleted, saveVCardCompleted) { _, _ in
                return
            }
        } else {
            return acceptCompleted.asObservable()
        }
    }

    func discard(withItem item: ContactRequestItem) -> Observable<Void> {
        return self.contactsService.discard(contactRequest: item.contactRequest,
                                            withAccount: self.accountsService.currentAccount!)
    }

    func ban(withItem item: ContactRequestItem) -> Observable<Void> {
        let discardCompleted = self.contactsService.discard(contactRequest: item.contactRequest,
                                                            withAccount: self.accountsService.currentAccount!)

        let removeCompleted = self.contactsService.removeContact(withRingId: item.contactRequest.ringId,
                                                                 ban: true,
                                                                 withAccount: self.accountsService.currentAccount!)

        return Observable<Void>.zip(discardCompleted, removeCompleted) { _, _ in
            return
        }
    }

    fileprivate func lookupUserName(withItem item: ContactRequestItem) {

136
        self.nameService.usernameLookupStatus.asObservable()
137
138
139
140
            .filter({ lookupNameResponse in
                return lookupNameResponse.address == item.contactRequest.ringId
            })
            .subscribe(onNext: { lookupNameResponse in
141
                if lookupNameResponse.state == .found && !lookupNameResponse.name.isEmpty {
142
143
144
145
146
147
148
                    item.userName.value = lookupNameResponse.name
                } else {
                    item.userName.value = lookupNameResponse.address
                }
            })
            .disposed(by: self.disposeBag)

149
        self.nameService.lookupAddress(withAccount: (accountsService.currentAccount?.id)!,
150
151
152
                                              nameserver: "",
                                              address: item.contactRequest.ringId)
    }
153
154
155
156
157
158
159
160

    func showConversation (forRingId ringId: String) {
        let conversationViewModel = ConversationViewModel(with: self.injectionBag)
        let conversation = self.conversationService.findConversation(withRingId: ringId,
                                                                     withAccountId: (accountsService.currentAccount?.id)!)
        conversationViewModel.conversation = conversation
        self.stateSubject.onNext(ConversationsState.conversationDetail(conversationViewModel: conversationViewModel))
    }
161
}