Commit f5be5463 authored by atraczyk's avatar atraczyk

contacts/conversations: adds saving conversation to json

- adds saving contact specific conversation to a json file

- loads the json file into the conversation object when loading
  the contacts list

- generates a UID for the contact to avoid name collisions, which
  is stored in the contact data file

Change-Id: I8a7b757d09b270e65c4d264805934faf8466c09f
Tuleap: #980
parent 2647eaaf
......@@ -20,6 +20,8 @@
#include "Contact.h"
#include "ObjBase.h" // for CoCreateGuid
using namespace Windows::ApplicationModel::Core;
using namespace Platform;
using namespace Windows::Data::Json;
......@@ -29,11 +31,45 @@ using namespace RingClientUWP;
using namespace ViewModel;
Contact::Contact(String^ name,
String^ ringID)
String^ ringID,
String^ GUID)
{
name_ = name;
name_ = name;
ringID_ = ringID;
GUID_ = GUID;
if (GUID_ == nullptr)
GUID_ = Utils::GetNewGUID();
//RingDebug::instance->print(Utils::toString(GUID_).c_str());
// load conversation from disk
conversation_ = ref new Conversation();
StorageFolder^ localfolder = ApplicationData::Current->LocalFolder;
String^ messagesFile = ".messages\\" + GUID_ + ".json";
Utils::fileExists(ApplicationData::Current->LocalFolder,
messagesFile)
.then([this,messagesFile](bool messages_file_exists)
{
if (messages_file_exists) {
try {
create_task(ApplicationData::Current->LocalFolder->GetFileAsync(messagesFile))
.then([this](StorageFile^ file)
{
create_task(FileIO::ReadTextAsync(file))
.then([this](String^ fileContents) {
if (fileContents != nullptr)
DestringifyConversation(fileContents);
});
});
}
catch (Exception^ e) {
RingDebug::instance->print("Exception while opening messages file");
}
}
});
//conversation_ = ref new Conversation();
notificationNewMessage_ = Windows::UI::Xaml::Visibility::Collapsed;
unreadMessages_ = 0; // not saved on disk yet (TO DO)
......@@ -50,8 +86,6 @@ Contact::Contact(String^ name,
unreadMessages_ = 0;
}
});
}
void
......@@ -63,7 +97,6 @@ Contact::NotifyPropertyChanged(String^ propertyName)
ref new DispatchedHandler([this, propertyName]()
{
PropertyChanged(this, ref new PropertyChangedEventArgs(propertyName));
}));
}
......@@ -73,9 +106,72 @@ Contact::ToJsonObject()
JsonObject^ contactObject = ref new JsonObject();
contactObject->SetNamedValue(nameKey, JsonValue::CreateStringValue(name_));
contactObject->SetNamedValue(ringIDKey, JsonValue::CreateStringValue(ringID_));
contactObject->SetNamedValue(GUIDKey, JsonValue::CreateStringValue(GUID_));
JsonObject^ jsonObject = ref new JsonObject();
jsonObject->SetNamedValue(contactKey, contactObject);
return jsonObject;
}
String^
Contact::StringifyConversation()
{
JsonArray^ jsonArray = ref new JsonArray();
for (unsigned int i = 0; i < conversation_->_messages->Size; i++) {
jsonArray->Append(conversation_->_messages->GetAt(i)->ToJsonObject());
}
JsonObject^ jsonObject = ref new JsonObject();
jsonObject->SetNamedValue(conversationKey, jsonArray);
return jsonObject->Stringify();
}
void
Contact::DestringifyConversation(String^ data)
{
JsonObject^ jsonObject = JsonObject::Parse(data);
String^ date;
bool fromContact;
String^ payload;
JsonArray^ messageList = jsonObject->GetNamedArray(conversationKey, ref new JsonArray());
for (unsigned int i = 0; i < messageList->Size; i++) {
IJsonValue^ message = messageList->GetAt(i);
if (message->ValueType == JsonValueType::Object) {
JsonObject^ jsonMessageObject = message->GetObject();
JsonObject^ messageObject = jsonMessageObject->GetNamedObject(messageKey, nullptr);
if (messageObject != nullptr) {
date = messageObject->GetNamedString(dateKey, "");
fromContact = messageObject->GetNamedBoolean(fromContactKey, "");
payload = messageObject->GetNamedString(payloadKey, "");
}
conversation_->addMessage(date, fromContact, payload);
}
}
}
void
Contact::saveConversationToFile()
{
StorageFolder^ localfolder = ApplicationData::Current->LocalFolder;
String^ messagesFile = ".messages\\" + GUID_ + ".json";
try {
create_task(localfolder->CreateFileAsync(messagesFile
, Windows::Storage::CreationCollisionOption::ReplaceExisting))
.then([&](StorageFile^ file) {
try {
FileIO::WriteTextAsync(file, StringifyConversation());
}
catch (Exception^ e) {
RingDebug::instance->print("Exception while writing to conversation file");
}
});
}
catch (Exception^ e) {
RingDebug::instance->print("Exception while opening conversation file");
}
}
\ No newline at end of file
......@@ -25,6 +25,7 @@ using namespace Windows::UI::Xaml::Data;
/* strings required by Windows::Data::Json. Defined here on puprose */
String^ nameKey = "name";
String^ ringIDKey = "ringid";
String^ GUIDKey = "guid";
String^ contactKey = "contact";
String^ contactListKey = "contactlist";
......@@ -34,13 +35,15 @@ ref class Conversation;
public ref class Contact sealed : public INotifyPropertyChanged
{
public:
Contact(String^ name, String^ ringID);
Contact(String^ name, String^ ringID, String^ GUID);
JsonObject^ ToJsonObject();
virtual event PropertyChangedEventHandler^ PropertyChanged;
property String^ name_;
property String^ ringID_;
property String^ GUID_;
property Conversation^ _conversation
{
Conversation^ get()
......@@ -68,6 +71,11 @@ public:
}
}
internal:
void saveConversationToFile();
String^ StringifyConversation();
void DestringifyConversation(String^ data);
protected:
void NotifyPropertyChanged(String^ propertyName);
......
......@@ -52,6 +52,9 @@ ContactsViewModel::ContactsViewModel()
contact->_conversation->addMessage(""/* date not yet used*/, MSG_FROM_CONTACT, payload);
/* save contacts conversation to disk */
contact->saveConversationToFile();
if (contact->ringID_ == from && isNotSelected)
notifyNewConversationMessage();
});
......@@ -73,7 +76,7 @@ ContactsViewModel::addNewContact(String^ name, String^ ringId)
{
auto trimedName = Utils::Trim(name);
if (contactsList_ && !findContactByName(trimedName)) {
Contact^ contact = ref new Contact(trimedName, trimedName);
Contact^ contact = ref new Contact(trimedName, trimedName, nullptr);
contactsList_->Append(contact);
saveContactsToFile();
return contact;
......@@ -154,6 +157,7 @@ ContactsViewModel::Destringify(String^ data)
JsonObject^ jsonObject = JsonObject::Parse(data);
String^ name;
String^ ringid;
String^ guid;
JsonArray^ contactlist = jsonObject->GetNamedArray(contactListKey, ref new JsonArray());
for (unsigned int i = 0; i < contactlist->Size; i++) {
......@@ -164,8 +168,9 @@ ContactsViewModel::Destringify(String^ data)
if (contactObject != nullptr) {
name = contactObject->GetNamedString(nameKey, "");
ringid = contactObject->GetNamedString(ringIDKey, "");
guid = contactObject->GetNamedString(GUIDKey, "");
}
contactsList_->Append(ref new Contact(name, ringid));
contactsList_->Append(ref new Contact(name, ringid, guid));
}
}
}
......@@ -47,3 +47,17 @@ Conversation::addMessage(String^ date, bool fromContact, String^ payload)
// TODO store message on the disk
}
JsonObject^
ConversationMessage::ToJsonObject()
{
JsonObject^ messageObject = ref new JsonObject();
messageObject->SetNamedValue(dateKey, JsonValue::CreateStringValue(Date));
messageObject->SetNamedValue(fromContactKey, JsonValue::CreateBooleanValue(FromContact));
messageObject->SetNamedValue(payloadKey, JsonValue::CreateStringValue(Payload));
JsonObject^ jsonObject = ref new JsonObject();
jsonObject->SetNamedValue(messageKey, messageObject);
return jsonObject;
}
\ No newline at end of file
......@@ -20,6 +20,13 @@
using namespace Platform;
using namespace Windows::UI::Xaml::Data;
/* strings required by Windows::Data::Json. Defined here on puprose */
String^ conversationKey = "conversation";
String^ messageKey = "message";
String^ dateKey = "date";
String^ fromContactKey = "fromContact";
String^ payloadKey = "payload";
namespace RingClientUWP
{
public ref class ConversationMessage sealed
......@@ -28,6 +35,9 @@ public:
property String^ Date;
property bool FromContact;
property String^ Payload;
/* functions */
JsonObject^ ToJsonObject();
};
public ref class Conversation sealed
......
......@@ -90,6 +90,10 @@ void RingClientUWP::RingD::sendAccountTextMessage(String^ message)
/* conversation */
if (sent) {
contact->_conversation->addMessage(""/* date not yet used*/, MSG_FROM_ME, message);
/* save contacts conversation to disk */
contact->saveConversationToFile();
} else {
WNG_("message not sent, see daemon outputs");
}
......
/**************************************************************************
* Copyright (C) 2016 by Savoir-faire Linux *
* Author: Jäger Nicolas <nicolas.jager@savoirfairelinux.com> *
* Author: Traczyk Andreas <traczyk.andreas@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/>. *
**************************************************************************/
#pragma once
#include <pch.h>
......@@ -88,5 +106,18 @@ Platform::String^ Trim(Platform::String^ s)
return ref new Platform::String(first, static_cast<unsigned int>(last - first));
}
Platform::String^ GetNewGUID()
{
GUID result;
HRESULT hr = CoCreateGuid(&result);
if (SUCCEEDED(hr)) {
Guid guid(result);
return guid.ToString();
}
throw Exception::CreateException(hr);
}
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment