ContactListModel.cpp 7.9 KB
Newer Older
atraczyk's avatar
atraczyk committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/***************************************************************************
 * Copyright (C) 2016 by Savoir-faire Linux                                *
 * Author: Jäger Nicolas <nicolas.jager@savoirfairelinux.com>              *
 * Author: Traczyk Andreas <andreas.traczyk@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, see <http://www.gnu.org/licenses/>.   *
 **************************************************************************/
19

20
21
#include "pch.h"
#include "ContactListModel.h"
atraczyk's avatar
atraczyk committed
22

23
24
#include "fileutils.h"

25
using namespace Windows::ApplicationModel::Core;
atraczyk's avatar
atraczyk committed
26
27
using namespace Windows::Data::Json;
using namespace Windows::Storage;
28
29
30
using namespace Windows::Storage::Streams;
using namespace Windows::UI::Core;

atraczyk's avatar
atraczyk committed
31
32
33
using namespace RingClientUWP;
using namespace ViewModel;

34
ContactListModel::ContactListModel(String^ account) : m_Owner(account)
atraczyk's avatar
atraczyk committed
35
36
37
{
    contactsList_ = ref new Vector<Contact^>();
    openContactsFromFile();
38
39

    /* connect delegates. */
40
41
    RingD::instance->registeredNameFound +=
        ref new RingClientUWP::RegisteredNameFound(this, &ContactListModel::OnregisteredNameFound);
atraczyk's avatar
atraczyk committed
42
43
}

44
Contact^ // refacto : remove "byName"
45
ContactListModel::findContactByName(String^ name)
atraczyk's avatar
atraczyk committed
46
{
47
    auto trimmedName = Utils::Trim(name);
atraczyk's avatar
atraczyk committed
48
    for each (Contact^ contact in contactsList_)
Nicolas Jager's avatar
Nicolas Jager committed
49
        if (contact->_name == trimmedName)
atraczyk's avatar
atraczyk committed
50
51
52
53
54
            return contact;

    return nullptr;
}

55
56
Contact^
ContactListModel::findContactByRingId(String^ ringId)
Nicolas Jager's avatar
Nicolas Jager committed
57
58
59
60
61
62
63
64
{
    for each (Contact^ contact in contactsList_)
        if (contact->ringID_ == ringId)
            return contact;

    return nullptr;
}

atraczyk's avatar
atraczyk committed
65
Contact^
66
ContactListModel::addNewContact(String^ name, String^ ringId, ContactStatus contactStatus)
atraczyk's avatar
atraczyk committed
67
{
68
69
    auto trimmedName = Utils::Trim(name);
    if (contactsList_ && !findContactByName(trimmedName)) {
Nicolas Jager's avatar
Nicolas Jager committed
70
        //if (contactsList_ && !findContactByName(trimmedName) && !findContactByRingId(ringId)) {
71
        Contact^ contact = ref new Contact(m_Owner, trimmedName, ringId, nullptr, 0, contactStatus);
atraczyk's avatar
atraczyk committed
72
73
        contactsList_->Append(contact);
        saveContactsToFile();
74
        AccountsViewModel::instance->raiseContactAdded(m_Owner, contact);
atraczyk's avatar
atraczyk committed
75
76
77
78
79
80
81
        return contact;
    }

    return nullptr;
}

void
82
ContactListModel::saveContactsToFile()
atraczyk's avatar
atraczyk committed
83
84
{
    StorageFolder^ localfolder = ApplicationData::Current->LocalFolder;
85
    String^ contactsFile = localfolder->Path + "\\" + ".profile\\" + m_Owner + "\\contacts.json";
86

87
    if (ring::fileutils::recursive_mkdir(Utils::toString(localfolder->Path + "\\" + ".profile\\" + m_Owner).c_str())) {
88
89
90
91
92
93
        std::ofstream file(Utils::toString(contactsFile).c_str());
        if (file.is_open())
        {
            file << Utils::toString(Stringify());
            file.close();
        }
atraczyk's avatar
atraczyk committed
94
95
96
97
    }
}

void
98
ContactListModel::openContactsFromFile()
atraczyk's avatar
atraczyk committed
99
{
100
    StorageFolder^ localfolder = ApplicationData::Current->LocalFolder;
101
    String^ contactsFile = localfolder->Path + "\\" + ".profile\\" + m_Owner + "\\contacts.json";
102
103
104

    String^ fileContents = Utils::toPlatformString(Utils::getStringFromFile(Utils::toString(contactsFile)));

105
    CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(CoreDispatcherPriority::High,
106
107
108
109
    ref new DispatchedHandler([=]() {
        if (fileContents != nullptr)
            Destringify(fileContents);
    }));
atraczyk's avatar
atraczyk committed
110
111
112
}

String^
113
ContactListModel::Stringify()
atraczyk's avatar
atraczyk committed
114
115
116
{
    JsonArray^ jsonArray = ref new JsonArray();

atraczyk's avatar
atraczyk committed
117
    for (int i = contactsList_->Size - 1; i >= 0; i--) {
atraczyk's avatar
atraczyk committed
118
119
120
121
122
123
124
125
126
127
        jsonArray->Append(contactsList_->GetAt(i)->ToJsonObject());
    }

    JsonObject^ jsonObject = ref new JsonObject();
    jsonObject->SetNamedValue(contactListKey, jsonArray);

    return jsonObject->Stringify();
}

void
128
ContactListModel::Destringify(String^ data)
atraczyk's avatar
atraczyk committed
129
{
130
131
    JsonObject^     jsonObject = JsonObject::Parse(data);
    String^         name;
atraczyk's avatar
atraczyk committed
132
    String^         displayname;
133
134
135
    String^         ringid;
    String^         guid;
    unsigned int    unreadmessages;
136
    String^			accountIdAssociated;
atraczyk's avatar
atraczyk committed
137
    String^         vcardUID;
Nicolas Jager's avatar
Nicolas Jager committed
138
    String^			lastTime;
atraczyk's avatar
atraczyk committed
139
140

    JsonArray^ contactlist = jsonObject->GetNamedArray(contactListKey, ref new JsonArray());
atraczyk's avatar
atraczyk committed
141
    for (int i = contactlist->Size - 1; i >= 0; i--) {
atraczyk's avatar
atraczyk committed
142
143
144
145
146
        IJsonValue^ contact = contactlist->GetAt(i);
        if (contact->ValueType == JsonValueType::Object) {
            JsonObject^ jsonContactObject = contact->GetObject();
            JsonObject^ contactObject = jsonContactObject->GetNamedObject(contactKey, nullptr);
            if (contactObject != nullptr) {
147
                name = contactObject->GetNamedString(nameKey);
atraczyk's avatar
atraczyk committed
148
                displayname = contactObject->GetNamedString(displayNameKey);
149
150
151
                ringid = contactObject->GetNamedString(ringIDKey);
                guid = contactObject->GetNamedString(GUIDKey);
                unreadmessages = static_cast<uint16_t>(contactObject->GetNamedNumber(unreadMessagesKey));
152
                accountIdAssociated = contactObject->GetNamedString(accountIdAssociatedKey);
atraczyk's avatar
atraczyk committed
153
                vcardUID = contactObject->GetNamedString(vcardUIDKey);
Nicolas Jager's avatar
Nicolas Jager committed
154
155
156

                if (contactObject->HasKey(lastTimeKey))
                    lastTime = contactObject->GetNamedString(lastTimeKey);
atraczyk's avatar
atraczyk committed
157
            }
158
            auto contact = ref new Contact(m_Owner, name, ringid, guid, unreadmessages, ContactStatus::READY);
atraczyk's avatar
atraczyk committed
159
            contact->_displayName = displayname;
160
            contact->_accountIdAssociated = accountIdAssociated;
atraczyk's avatar
atraczyk committed
161
162
            // contact image
            contact->_vcardUID = vcardUID;
Nicolas Jager's avatar
Nicolas Jager committed
163
164
165
            if (lastTime)
                contact->_lastTime = lastTime;

atraczyk's avatar
atraczyk committed
166
            std::string contactImageFile = RingD::instance->getLocalFolder() + ".vcards\\"
Nicolas Jager's avatar
Nicolas Jager committed
167
                                           + Utils::toString(contact->_vcardUID) + ".png";
atraczyk's avatar
atraczyk committed
168
169
170
            if (Utils::fileExists(contactImageFile)) {
                contact->_avatarImage = Utils::toPlatformString(contactImageFile);
            }
171
            contactsList_->Append(contact);
172
            AccountsViewModel::instance->raiseContactAdded(m_Owner, contact);
atraczyk's avatar
atraczyk committed
173
174
175
        }
    }
}
176

177
178
void
ContactListModel::deleteContact(Contact ^ contact)
179
180
181
182
183
184
185
186
187
188
189
190
191
{
    unsigned int index;
    auto itemsList = SmartPanelItemsViewModel::instance->itemsList;
    auto item = SmartPanelItemsViewModel::instance->_selectedItem;

    if (contactsList_->IndexOf(contact, &index)) {
        contact->deleteConversationFile();
        contactsList_->RemoveAt(index);
    }

    saveContactsToFile();
}

atraczyk's avatar
atraczyk committed
192
void
193
ContactListModel::modifyContact(Contact^ contact)
atraczyk's avatar
atraczyk committed
194
{
195
    AccountsViewModel::instance->raiseContactDataModified(m_Owner, contact);
Nicolas Jager's avatar
Nicolas Jager committed
196
197
}

198
199
void
ContactListModel::OnregisteredNameFound(RingClientUWP::LookupStatus status, const std::string &address, const std::string &name)
Nicolas Jager's avatar
Nicolas Jager committed
200
201
202
203
204
205
206
207
208
{
    if (status == LookupStatus::SUCCESS) {
        for each (Contact^ contact in contactsList_)
            if (contact->ringID_ == Utils::toPlatformString(address)) {
                contact->_name = Utils::toPlatformString(name);
                saveContactsToFile();
            }
    }
}