/*************************************************************************** * Copyright (C) 2016 by Savoir-faire Linux * * Author: Jäger Nicolas * * Author: Traczyk Andreas * * * * 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 . * **************************************************************************/ #include "pch.h" #include "ContactsViewModel.h" using namespace Windows::ApplicationModel::Core; using namespace Windows::Data::Json; using namespace Windows::Storage; using namespace Windows::Storage::Streams; using namespace Windows::UI::Core; using namespace RingClientUWP; using namespace ViewModel; ContactsViewModel::ContactsViewModel() { contactsList_ = ref new Vector(); openContactsFromFile(); /* connect delegates. */ RingD::instance->incomingAccountMessage += ref new IncomingAccountMessage([&](String^ accountId, String^ from, String^ payload) { auto contact = findContactByName(from); if (contact == nullptr) contact = addNewContact(from, from); // contact checked inside addNewContact. bool isNotSelected = (contact != ContactsViewModel::instance->selectedContact) ? true : false; if (contact == nullptr) { ERR_("contact not handled!"); return; } contact->_conversation->addMessage(""/* date not yet used*/, MSG_FROM_CONTACT, payload); /* save contacts conversation to disk */ contact->saveConversationToFile(); if (contact->ringID_ == from) { // increment contact's unread message count if(isNotSelected) contact->addNotifyNewConversationMessage(); // update the xaml for all contacts notifyNewConversationMessage(isNotSelected); // save to disk saveContactsToFile(); } }); } Contact^ // refacto : remove "byName" ContactsViewModel::findContactByName(String^ name) { auto trimmedName = Utils::Trim(name); for each (Contact^ contact in contactsList_) if (contact->name_ == trimmedName) return contact; return nullptr; } Contact^ ContactsViewModel::addNewContact(String^ name, String^ ringId) { auto trimmedName = Utils::Trim(name); if (contactsList_ && !findContactByName(trimmedName)) { Contact^ contact = ref new Contact(trimmedName, trimmedName, nullptr, 0); contactsList_->Append(contact); saveContactsToFile(); contactAdded(contact); return contact; } return nullptr; } void ContactsViewModel::saveContactsToFile() { StorageFolder^ localfolder = ApplicationData::Current->LocalFolder; String^ contactsFile = ".profile\\contacts.json"; try { create_task(localfolder->CreateFileAsync(contactsFile , Windows::Storage::CreationCollisionOption::ReplaceExisting)) .then([&](StorageFile^ newFile) { try { FileIO::WriteTextAsync(newFile, Stringify()); } catch (Exception^ e) { RingDebug::instance->print("Exception while writing to contacts file"); } }); } catch (Exception^ e) { RingDebug::instance->print("Exception while opening contacts file"); } } void ContactsViewModel::openContactsFromFile() { String^ contactsFile = ".profile\\contacts.json"; Utils::fileExists(ApplicationData::Current->LocalFolder, contactsFile) .then([this,contactsFile](bool contacts_file_exists) { if (contacts_file_exists) { try { create_task(ApplicationData::Current->LocalFolder->GetFileAsync(contactsFile)) .then([this](StorageFile^ file) { create_task(FileIO::ReadTextAsync(file)) .then([this](String^ fileContents) { if (fileContents != nullptr) Destringify(fileContents); }); }); } catch (Exception^ e) { RingDebug::instance->print("Exception while opening contacts file"); } } }); } String^ ContactsViewModel::Stringify() { JsonArray^ jsonArray = ref new JsonArray(); for (unsigned int i = 0; i < contactsList_->Size; i++) { jsonArray->Append(contactsList_->GetAt(i)->ToJsonObject()); } JsonObject^ jsonObject = ref new JsonObject(); jsonObject->SetNamedValue(contactListKey, jsonArray); return jsonObject->Stringify(); } void ContactsViewModel::Destringify(String^ data) { JsonObject^ jsonObject = JsonObject::Parse(data); String^ name; String^ ringid; String^ guid; unsigned int unreadmessages; JsonArray^ contactlist = jsonObject->GetNamedArray(contactListKey, ref new JsonArray()); for (unsigned int i = 0; i < contactlist->Size; i++) { IJsonValue^ contact = contactlist->GetAt(i); if (contact->ValueType == JsonValueType::Object) { JsonObject^ jsonContactObject = contact->GetObject(); JsonObject^ contactObject = jsonContactObject->GetNamedObject(contactKey, nullptr); if (contactObject != nullptr) { name = contactObject->GetNamedString(nameKey); ringid = contactObject->GetNamedString(ringIDKey); guid = contactObject->GetNamedString(GUIDKey); unreadmessages = static_cast(contactObject->GetNamedNumber(unreadMessagesKey)); } auto contact = ref new Contact(name, ringid, guid, unreadmessages); contactsList_->Append(contact); contactAdded(contact); } } }