blob: 7ac6dc8a57ce03c2e9909e88acc5f2c4effd9e21 [file] [log] [blame]
atraczykb724d332016-08-30 15:25:59 -04001/***************************************************************************
2 * Copyright (C) 2016 by Savoir-faire Linux *
3 * Author: Jäger Nicolas <nicolas.jager@savoirfairelinux.com> *
4 * Author: Traczyk Andreas <andreas.traczyk@savoirfairelinux.com> *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 3 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 **************************************************************************/
atraczykb724d332016-08-30 15:25:59 -040019#include "pch.h"
Nicolas Jager6e30ad82016-08-26 13:00:27 -040020
atraczykb724d332016-08-30 15:25:59 -040021#include "ContactsViewModel.h"
22
Nicolas Jager6e30ad82016-08-26 13:00:27 -040023using namespace Windows::ApplicationModel::Core;
atraczykb724d332016-08-30 15:25:59 -040024using namespace Windows::Data::Json;
25using namespace Windows::Storage;
Nicolas Jager6e30ad82016-08-26 13:00:27 -040026using namespace Windows::Storage::Streams;
27using namespace Windows::UI::Core;
28
atraczykb724d332016-08-30 15:25:59 -040029
30using namespace RingClientUWP;
31using namespace ViewModel;
32
33ContactsViewModel::ContactsViewModel()
34{
35 contactsList_ = ref new Vector<Contact^>();
36 openContactsFromFile();
Nicolas Jager6e30ad82016-08-26 13:00:27 -040037
38 /* connect delegates. */
39 RingD::instance->incomingAccountMessage += ref new IncomingAccountMessage([&](String^ accountId,
40 String^ from, String^ payload) {
41 auto contact = findContactByName(from);
42
43 if (contact == nullptr)
44 contact = addNewContact(from, from); // contact checked inside addNewContact.
45
Nicolas Jager0788e962016-08-26 15:41:06 -040046 bool isNotSelected = (contact != ContactsViewModel::instance->selectedContact) ? true : false;
47
Nicolas Jager6e30ad82016-08-26 13:00:27 -040048 if (contact == nullptr) {
49 ERR_("contact not handled!");
50 return;
51 }
52
Nicolas Jager93abfea2016-08-30 12:33:07 -040053 contact->_conversation->addMessage(""/* date not yet used*/, MSG_FROM_CONTACT, payload);
Nicolas Jager0788e962016-08-26 15:41:06 -040054
atraczykf5be5462016-08-31 14:23:06 -040055 /* save contacts conversation to disk */
56 contact->saveConversationToFile();
57
atraczyka535ee12016-08-31 17:36:05 -040058 if (contact->ringID_ == from && isNotSelected) {
59 // increment contact's unread message count
60 contact->addNotifyNewConversationMessage();
atraczykcac45522016-08-31 18:42:36 -040061 // update the xaml for all contacts
Nicolas Jager0788e962016-08-26 15:41:06 -040062 notifyNewConversationMessage();
atraczykcac45522016-08-31 18:42:36 -040063 // save to disk
64 saveContactsToFile();
atraczyka535ee12016-08-31 17:36:05 -040065 }
Nicolas Jager6e30ad82016-08-26 13:00:27 -040066 });
Nicolas Jagerd76940f2016-08-31 14:44:04 -040067 CallsViewModel::instance->callRecieved += ref new RingClientUWP::CallRecieved([&](
68 Call^ call) {
69 auto from = call->from;
70 auto contact = findContactByName(from);
71
72 if (contact == nullptr)
73 contact = addNewContact(from, from); // contact checked inside addNewContact.
74
75 bool isNotSelected = (contact != ContactsViewModel::instance->selectedContact) ? true : false;
76
77 if (contact == nullptr) {
78 ERR_("contact not handled!");
79 return;
80 }
81 contact->_call = call;
Nicolas Jagerf6a10322016-09-06 08:17:49 -040082 contact->_contactBarHeight = 50;
83
Nicolas Jagerd76940f2016-08-31 14:44:04 -040084 });
Nicolas Jager6e30ad82016-08-26 13:00:27 -040085
atraczykb724d332016-08-30 15:25:59 -040086}
87
88Contact^
Nicolas Jager6e30ad82016-08-26 13:00:27 -040089ContactsViewModel::findContactByName(String^ name)
atraczykb724d332016-08-30 15:25:59 -040090{
91 for each (Contact^ contact in contactsList_)
92 if (contact->name_ == name)
93 return contact;
94
95 return nullptr;
96}
97
98Contact^
99ContactsViewModel::addNewContact(String^ name, String^ ringId)
100{
Nicolas Jager2647eaa2016-08-31 12:08:15 -0400101 auto trimedName = Utils::Trim(name);
102 if (contactsList_ && !findContactByName(trimedName)) {
atraczykcac45522016-08-31 18:42:36 -0400103 Contact^ contact = ref new Contact(trimedName, trimedName, nullptr, 0);
atraczykb724d332016-08-30 15:25:59 -0400104 contactsList_->Append(contact);
105 saveContactsToFile();
106 return contact;
107 }
108
109 return nullptr;
110}
111
112void
113ContactsViewModel::saveContactsToFile()
114{
115 StorageFolder^ localfolder = ApplicationData::Current->LocalFolder;
116 String^ contactsFile = ".profile\\contacts.json";
117
118 try {
119 create_task(localfolder->CreateFileAsync(contactsFile
120 , Windows::Storage::CreationCollisionOption::ReplaceExisting))
121 .then([&](StorageFile^ newFile) {
122 try {
123 FileIO::WriteTextAsync(newFile, Stringify());
124 }
125 catch (Exception^ e) {
126 RingDebug::instance->print("Exception while writing to contacts file");
127 }
128 });
129 }
130 catch (Exception^ e) {
131 RingDebug::instance->print("Exception while opening contacts file");
132 }
133}
134
135void
136ContactsViewModel::openContactsFromFile()
137{
138 String^ contactsFile = ".profile\\contacts.json";
139
140 Utils::fileExists(ApplicationData::Current->LocalFolder,
Nicolas Jager6e30ad82016-08-26 13:00:27 -0400141 contactsFile)
142 .then([this,contactsFile](bool contacts_file_exists)
atraczykb724d332016-08-30 15:25:59 -0400143 {
144 if (contacts_file_exists) {
145 try {
146 create_task(ApplicationData::Current->LocalFolder->GetFileAsync(contactsFile))
Nicolas Jager6e30ad82016-08-26 13:00:27 -0400147 .then([this](StorageFile^ file)
atraczykb724d332016-08-30 15:25:59 -0400148 {
149 create_task(FileIO::ReadTextAsync(file))
Nicolas Jager6e30ad82016-08-26 13:00:27 -0400150 .then([this](String^ fileContents) {
atraczykb724d332016-08-30 15:25:59 -0400151 if (fileContents != nullptr)
152 Destringify(fileContents);
153 });
154 });
155 }
156 catch (Exception^ e) {
157 RingDebug::instance->print("Exception while opening contacts file");
158 }
159 }
160 });
161}
162
163String^
164ContactsViewModel::Stringify()
165{
166 JsonArray^ jsonArray = ref new JsonArray();
167
168 for (unsigned int i = 0; i < contactsList_->Size; i++) {
169 jsonArray->Append(contactsList_->GetAt(i)->ToJsonObject());
170 }
171
172 JsonObject^ jsonObject = ref new JsonObject();
173 jsonObject->SetNamedValue(contactListKey, jsonArray);
174
175 return jsonObject->Stringify();
176}
177
178void
179ContactsViewModel::Destringify(String^ data)
180{
atraczykcac45522016-08-31 18:42:36 -0400181 JsonObject^ jsonObject = JsonObject::Parse(data);
182 String^ name;
183 String^ ringid;
184 String^ guid;
185 unsigned int unreadmessages;
atraczykb724d332016-08-30 15:25:59 -0400186
187 JsonArray^ contactlist = jsonObject->GetNamedArray(contactListKey, ref new JsonArray());
188 for (unsigned int i = 0; i < contactlist->Size; i++) {
189 IJsonValue^ contact = contactlist->GetAt(i);
190 if (contact->ValueType == JsonValueType::Object) {
191 JsonObject^ jsonContactObject = contact->GetObject();
192 JsonObject^ contactObject = jsonContactObject->GetNamedObject(contactKey, nullptr);
193 if (contactObject != nullptr) {
atraczykcac45522016-08-31 18:42:36 -0400194 name = contactObject->GetNamedString(nameKey);
195 ringid = contactObject->GetNamedString(ringIDKey);
196 guid = contactObject->GetNamedString(GUIDKey);
197 unreadmessages = static_cast<uint16_t>(contactObject->GetNamedNumber(unreadMessagesKey));
atraczykb724d332016-08-30 15:25:59 -0400198 }
atraczykcac45522016-08-31 18:42:36 -0400199 contactsList_->Append(ref new Contact(name, ringid, guid, unreadmessages));
atraczykb724d332016-08-30 15:25:59 -0400200 }
201 }
202}