Commit 057db033 authored by Sylvain Berfini's avatar Sylvain Berfini 🎩
Browse files

Moved from a list of Content to a list of Content* to be able to cast content...

Moved from a list of Content to a list of Content* to be able to cast content to specialized version
parent ba89633e
......@@ -294,10 +294,10 @@ LinphoneStatus linphone_chat_message_put_char(LinphoneChatMessage *msg, uint32_t
}
void linphone_chat_message_add_text_content(LinphoneChatMessage *msg, const char *c_content) {
LinphonePrivate::Content content;
LinphonePrivate::Content *content = new LinphonePrivate::Content();
LinphonePrivate::ContentType contentType = LinphonePrivate::ContentType::PlainText;
content.setContentType(contentType);
content.setBody(L_C_TO_STRING(c_content));
content->setContentType(contentType);
content->setBody(L_C_TO_STRING(c_content));
L_GET_CPP_PTR_FROM_C_OBJECT(msg)->addContent(content);
}
......@@ -306,11 +306,11 @@ bool_t linphone_chat_message_has_text_content(const LinphoneChatMessage *msg) {
}
const char * linphone_chat_message_get_text_content(const LinphoneChatMessage *msg) {
LinphonePrivate::Content content = L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getTextContent();
if (content == LinphonePrivate::Content::Empty) {
const LinphonePrivate::Content *content = L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getTextContent();
if (*content == LinphonePrivate::Content::Empty) {
return NULL;
}
return L_STRING_TO_C(content.getBodyAsString());
return L_STRING_TO_C(content->getBodyAsString());
}
// =============================================================================
......
......@@ -140,7 +140,7 @@ private:
std::string rttMessage;
bool isSecured = false;
bool isReadOnly = false;
std::list<Content > contents;
std::list<Content* > contents;
Content internalContent;
FileContent *currentFileContentToTransfer;
std::unordered_map<std::string, std::string> customHeaders;
......@@ -170,7 +170,7 @@ private:
belle_http_request_listener_callbacks_t *cbs
);
void releaseHttpRequest();
void createFileTransferInformationsFromVndGsmaRcsFtHttpXml(FileTransferContent &content);
void createFileTransferInformationsFromVndGsmaRcsFtHttpXml(FileTransferContent* content);
L_DECLARE_PUBLIC(ChatMessage);
};
......
......@@ -159,8 +159,8 @@ string ChatMessagePrivate::getSalCustomHeaderValue (const string &name) {
const ContentType &ChatMessagePrivate::getContentType () {
if (direction == ChatMessage::Direction::Incoming) {
if (contents.size() > 0) {
Content content = contents.front();
cContentType = content.getContentType();
Content *content = contents.front();
cContentType = content->getContentType();
} else {
cContentType = internalContent.getContentType();
}
......@@ -169,8 +169,8 @@ const ContentType &ChatMessagePrivate::getContentType () {
cContentType = internalContent.getContentType();
} else {
if (contents.size() > 0) {
Content content = contents.front();
cContentType = content.getContentType();
Content *content = contents.front();
cContentType = content->getContentType();
}
}
}
......@@ -184,21 +184,23 @@ void ChatMessagePrivate::setContentType (const ContentType &contentType) {
const string &ChatMessagePrivate::getText () {
L_Q();
if (direction == ChatMessage::Direction::Incoming) {
if (contents.size() > 0) {
Content content = contents.front();
cText = content.getBodyAsString();
if (q->hasTextContent()) {
cText = q->getTextContent()->getBodyAsString();
} else if (contents.size() > 0) {
Content *content = contents.front();
cText = content->getBodyAsString();
} else {
cText = internalContent.getBodyAsString();
}
} else {
if (q->hasTextContent()) {
cText = q->getTextContent().getBodyAsString();
cText = q->getTextContent()->getBodyAsString();
} else if (!internalContent.isEmpty()) {
cText = internalContent.getBodyAsString();
} else {
if (contents.size() > 0) {
Content content = contents.front();
cText = content.getBodyAsString();
Content *content = contents.front();
cText = content->getBodyAsString();
}
}
}
......@@ -212,7 +214,7 @@ void ChatMessagePrivate::setText (const string &text) {
LinphoneContent *ChatMessagePrivate::getFileTransferInformation () const {
L_Q();
if (q->hasFileTransferContent()) {
return q->getFileTransferContent().toLinphoneContent();
return q->getFileTransferContent()->toLinphoneContent();
}
return NULL;
}
......@@ -221,13 +223,13 @@ void ChatMessagePrivate::setFileTransferInformation (const LinphoneContent *c_co
L_Q();
// Create a FileContent, it will create the FileTransferContent at upload time
FileContent fileContent;
FileContent *fileContent = new FileContent();
ContentType contentType(linphone_content_get_type(c_content), linphone_content_get_subtype(c_content));
fileContent.setContentType(contentType);
fileContent.setFileSize(linphone_content_get_size(c_content));
fileContent.setFileName(linphone_content_get_name(c_content));
fileContent->setContentType(contentType);
fileContent->setFileSize(linphone_content_get_size(c_content));
fileContent->setFileName(linphone_content_get_name(c_content));
if (linphone_content_get_string_buffer(c_content) != NULL) {
fileContent.setBody(linphone_content_get_string_buffer(c_content));
fileContent->setBody(linphone_content_get_string_buffer(c_content));
}
q->addContent(fileContent);
......@@ -236,9 +238,9 @@ void ChatMessagePrivate::setFileTransferInformation (const LinphoneContent *c_co
int ChatMessagePrivate::downloadFile () {
L_Q();
for (Content& content : contents) {
if (content.getContentType() == ContentType::FileTransfer) {
return q->downloadFile(static_cast<FileTransferContent&>(content));
for (Content *content : contents) {
if (content->getContentType() == ContentType::FileTransfer) {
return q->downloadFile((FileTransferContent*)content);
}
}
......@@ -641,13 +643,14 @@ void ChatMessagePrivate::onRecvEnd (belle_sip_user_body_handler_t *bh) {
if (retval <= 0 && state != ChatMessage::State::FileTransferError) {
// Remove the FileTransferContent from the message and store the FileContent
FileContent fileContent = *currentFileContentToTransfer;
FileContent *fileContent = currentFileContentToTransfer;
q->addContent(fileContent);
for (Content &content : contents) {
if (content.getContentType() == ContentType::FileTransfer) {
FileTransferContent fileTransferContent = static_cast<FileTransferContent&>(content);
if (fileTransferContent.getFileContent() == fileContent) {
for (Content *content : contents) {
if (content->getContentType() == ContentType::FileTransfer) {
FileTransferContent *fileTransferContent = (FileTransferContent*)content;
if (fileTransferContent->getFileContent() == fileContent) {
q->removeContent(content);
free(fileTransferContent);
break;
}
}
......@@ -811,12 +814,12 @@ void ChatMessagePrivate::processResponseFromPostFile (const belle_http_response_
setText(body);
}
setContentType(ContentType::FileTransfer);*/
FileContent fileContent = *currentFileContentToTransfer;
FileContent *fileContent = currentFileContentToTransfer;
FileTransferContent fileTransferContent;
fileTransferContent.setContentType(ContentType::FileTransfer);
fileTransferContent.setFileContent(fileContent);
fileTransferContent.setBody(body);
FileTransferContent *fileTransferContent = new FileTransferContent();
fileTransferContent->setContentType(ContentType::FileTransfer);
fileTransferContent->setFileContent(fileContent);
fileTransferContent->setBody(body);
q->removeContent(fileContent);
q->addContent(fileTransferContent);
......@@ -845,8 +848,8 @@ static void _chat_process_response_headers_from_get_file (void *data, const bell
d->processResponseHeadersFromGetFile(event);
}
static FileContent createFileTransferInformationFromHeaders (const belle_sip_message_t *m) {
FileContent content;
static FileContent* createFileTransferInformationFromHeaders (const belle_sip_message_t *m) {
FileContent *fileContent = new FileContent();
belle_sip_header_content_length_t *content_length_hdr = BELLE_SIP_HEADER_CONTENT_LENGTH(belle_sip_message_get_header(m, "Content-Length"));
belle_sip_header_content_type_t *content_type_hdr = BELLE_SIP_HEADER_CONTENT_TYPE(belle_sip_message_get_header(m, "Content-Type"));
......@@ -857,14 +860,14 @@ static FileContent createFileTransferInformationFromHeaders (const belle_sip_mes
subtype = belle_sip_header_content_type_get_subtype(content_type_hdr);
lInfo() << "Extracted content type " << type << " / " << subtype << " from header";
ContentType contentType(type, subtype);
content.setContentType(contentType);
fileContent->setContentType(contentType);
}
if (content_length_hdr) {
content.setFileSize(belle_sip_header_content_length_get_content_length(content_length_hdr));
lInfo() << "Extracted content length " << content.getFileSize() << " from header";
fileContent->setFileSize(belle_sip_header_content_length_get_content_length(content_length_hdr));
lInfo() << "Extracted content length " << fileContent->getFileSize() << " from header";
}
return content;
return fileContent;
}
void ChatMessagePrivate::processResponseHeadersFromGetFile (const belle_http_response_event_t *event) {
......@@ -879,7 +882,7 @@ void ChatMessagePrivate::processResponseHeadersFromGetFile (const belle_http_res
if (currentFileContentToTransfer == nullptr) {
lWarning() << "No file transfer information for msg [" << this << "]: creating...";
FileContent content = createFileTransferInformationFromHeaders(response);
FileContent *content = createFileTransferInformationFromHeaders(response);
q->addContent(content);
} else {
belle_sip_header_content_length_t *content_length_hdr = BELLE_SIP_HEADER_CONTENT_LENGTH(belle_sip_message_get_header(response, "Content-Length"));
......@@ -1067,13 +1070,13 @@ int ChatMessagePrivate::uploadFile () {
return err;
}
void ChatMessagePrivate::createFileTransferInformationsFromVndGsmaRcsFtHttpXml (FileTransferContent &fileTransferContent) {
void ChatMessagePrivate::createFileTransferInformationsFromVndGsmaRcsFtHttpXml (FileTransferContent *fileTransferContent) {
xmlChar *file_url = nullptr;
xmlDocPtr xmlMessageBody;
xmlNodePtr cur;
/* parse the msg body to get all informations from it */
xmlMessageBody = xmlParseDoc((const xmlChar *)fileTransferContent.getBodyAsString().c_str());
FileContent fileContent;
xmlMessageBody = xmlParseDoc((const xmlChar *)fileTransferContent->getBodyAsString().c_str());
FileContent *fileContent = new FileContent();
cur = xmlDocGetRootElement(xmlMessageBody);
if (cur != nullptr) {
......@@ -1088,13 +1091,13 @@ void ChatMessagePrivate::createFileTransferInformationsFromVndGsmaRcsFtHttpXml (
if (!xmlStrcmp(cur->name, (const xmlChar *)"file-size")) {
xmlChar *fileSizeString = xmlNodeListGetString(xmlMessageBody, cur->xmlChildrenNode, 1);
size_t size = (size_t)strtol((const char *)fileSizeString, nullptr, 10);
fileContent.setFileSize(size);
fileContent->setFileSize(size);
xmlFree(fileSizeString);
}
if (!xmlStrcmp(cur->name, (const xmlChar *)"file-name")) {
xmlChar *filename = xmlNodeListGetString(xmlMessageBody, cur->xmlChildrenNode, 1);
fileContent.setFileName((char *)filename);
fileContent->setFileName((char *)filename);
xmlFree(filename);
}
if (!xmlStrcmp(cur->name, (const xmlChar *)"content-type")) {
......@@ -1108,7 +1111,7 @@ void ChatMessagePrivate::createFileTransferInformationsFromVndGsmaRcsFtHttpXml (
type = ms_strndup((char *)content_type, contentTypeIndex);
subtype = ms_strdup(((char *)content_type + contentTypeIndex + 1));
ContentType contentType(type, subtype);
fileContent.setContentType(contentType);
fileContent->setContentType(contentType);
ms_free(subtype);
ms_free(type);
ms_free(content_type);
......@@ -1144,11 +1147,11 @@ void ChatMessagePrivate::createFileTransferInformationsFromVndGsmaRcsFtHttpXml (
}
xmlFreeDoc(xmlMessageBody);
fileContent.setFilePath(fileTransferContent.getFilePath()); // Copy file path from file transfer content to file content for file body handler
fileTransferContent.setFileUrl(string((const char *)file_url)); // Set file url in the file transfer content for the download
fileContent->setFilePath(fileTransferContent->getFilePath()); // Copy file path from file transfer content to file content for file body handler
fileTransferContent->setFileUrl(string((const char *)file_url)); // Set file url in the file transfer content for the download
// Link the FileContent to the FileTransferContent
fileTransferContent.setFileContent(fileContent);
fileTransferContent->setFileContent(fileContent);
xmlFree(file_url);
}
......@@ -1186,7 +1189,7 @@ LinphoneReason ChatMessagePrivate::receive () {
if (contents.size() == 0) {
// All previous modifiers only altered the internal content, let's fill the content list
contents.push_back(internalContent);
contents.push_back(&internalContent);
}
// ---------------------------------------
......@@ -1195,12 +1198,12 @@ LinphoneReason ChatMessagePrivate::receive () {
if (errorCode <= 0) {
bool foundSupportContentType = false;
for (const auto &c : contents) {
if (linphone_core_is_content_type_supported(core->getCCore(), c.getContentType().asString().c_str())) {
for (Content *c : contents) {
if (linphone_core_is_content_type_supported(core->getCCore(), c->getContentType().asString().c_str())) {
foundSupportContentType = true;
break;
} else
lError() << "Unsupported content-type: " << c.getContentType().asString();
lError() << "Unsupported content-type: " << c->getContentType().asString();
}
if (!foundSupportContentType) {
......@@ -1225,8 +1228,8 @@ LinphoneReason ChatMessagePrivate::receive () {
}
bool messageToBeStored = false;
for (Content &c : contents) {
if (c.getContentType() == ContentType::FileTransfer || c.getContentType() == ContentType::PlainText) {
for (Content *c : contents) {
if (c->getContentType() == ContentType::FileTransfer || c->getContentType() == ContentType::PlainText) {
messageToBeStored = true;
}
}
......@@ -1247,8 +1250,8 @@ void ChatMessagePrivate::send () {
} else {
currentFileContentToTransfer = nullptr;
// For each FileContent, upload it and create a FileTransferContent
for (Content &content : contents) {
ContentType contentType = content.getContentType();
for (Content *content : contents) {
ContentType contentType = content->getContentType();
//TODO Improve
if (contentType != ContentType::FileTransfer && contentType != ContentType::PlainText &&
contentType != ContentType::ExternalBody && contentType != ContentType::Imdn &&
......@@ -1256,7 +1259,8 @@ void ChatMessagePrivate::send () {
contentType != ContentType::Sdp && contentType != ContentType::ConferenceInfo &&
contentType != ContentType::Cpim) {
lInfo() << "Found content with type " << contentType.asString() << ", set it for file upload";
currentFileContentToTransfer = (FileContent *)&content;
FileContent *fileContent = (FileContent *)content;
currentFileContentToTransfer = fileContent;
break;
}
}
......@@ -1355,7 +1359,7 @@ void ChatMessagePrivate::send () {
// ---------------------------------------
if (internalContent.isEmpty()) {
internalContent = contents.front();
internalContent = *(contents.front());
}
if (!externalBodyUrl.empty()) { // Deprecated way of sending files
......@@ -1372,12 +1376,13 @@ void ChatMessagePrivate::send () {
}
}
for (Content &content : contents) {
for (Content *content : contents) {
// Restore FileContents and remove FileTransferContents
if (content.getContentType() == ContentType::FileTransfer) {
FileTransferContent fileTransferContent = static_cast<FileTransferContent&>(content);
if (content->getContentType() == ContentType::FileTransfer) {
FileTransferContent *fileTransferContent = (FileTransferContent *)content;
q->removeContent(content);
q->addContent(fileTransferContent.getFileContent());
free(fileTransferContent);
q->addContent(fileTransferContent->getFileContent());
}
}
......@@ -1513,26 +1518,19 @@ bool ChatMessage::isReadOnly () const {
return d->isReadOnly;
}
const list<Content> &ChatMessage::getContents () const {
const list<Content *> &ChatMessage::getContents () const {
L_D();
return d->contents;
}
void ChatMessage::addContent (Content &&content) {
L_D();
if (d->isReadOnly) return;
d->contents.push_back(move(content));
}
void ChatMessage::addContent (const Content &content) {
void ChatMessage::addContent (Content *content) {
L_D();
if (d->isReadOnly) return;
d->contents.push_back(content);
}
void ChatMessage::removeContent (const Content &content) {
void ChatMessage::removeContent (Content *content) {
L_D();
if (d->isReadOnly) return;
......@@ -1632,7 +1630,7 @@ void ChatMessage::sendDisplayNotification () {
d->sendImdn(Imdn::Type::Display, LinphoneReasonNone);
}
int ChatMessage::downloadFile(FileTransferContent& fileTransferContent) {
int ChatMessage::downloadFile(FileTransferContent *fileTransferContent) {
L_D();
if (d->httpRequest) {
......@@ -1640,14 +1638,14 @@ int ChatMessage::downloadFile(FileTransferContent& fileTransferContent) {
return -1;
}
if (fileTransferContent.getContentType() != ContentType::FileTransfer) {
if (fileTransferContent->getContentType() != ContentType::FileTransfer) {
lError() << "linphone_chat_message_download_file(): content type is not FileTransfer";
return -1;
}
d->createFileTransferInformationsFromVndGsmaRcsFtHttpXml(fileTransferContent);
FileContent fileContent = fileTransferContent.getFileContent();
d->currentFileContentToTransfer = &fileContent;
FileContent *fileContent = fileTransferContent->getFileContent();
d->currentFileContentToTransfer = fileContent;
if (d->currentFileContentToTransfer == nullptr) {
return -1;
}
......@@ -1657,7 +1655,7 @@ int ChatMessage::downloadFile(FileTransferContent& fileTransferContent) {
cbs.process_response = _chat_message_process_response_from_get_file;
cbs.process_io_error = _chat_message_process_io_error_download;
cbs.process_auth_requested = _chat_message_process_auth_requested_download;
int err = d->startHttpTransfer(fileTransferContent.getFileUrl(), "GET", &cbs); // File URL has been set by createFileTransferInformationsFromVndGsmaRcsFtHttpXml
int err = d->startHttpTransfer(fileTransferContent->getFileUrl(), "GET", &cbs); // File URL has been set by createFileTransferInformationsFromVndGsmaRcsFtHttpXml
if (err == -1) return -1;
// start the download, status is In Progress
......@@ -1746,42 +1744,42 @@ int ChatMessage::putCharacter (uint32_t character) {
bool ChatMessage::hasTextContent() const {
L_D();
for (const auto &c : d->contents) {
if (c.getContentType() == ContentType::PlainText) {
for (const Content *c : d->contents) {
if (c->getContentType() == ContentType::PlainText) {
return true;
}
}
return false;
}
const Content &ChatMessage::getTextContent() const {
const Content* ChatMessage::getTextContent() const {
L_D();
for (const auto &c : d->contents) {
if (c.getContentType() == ContentType::PlainText) {
for (const Content *c : d->contents) {
if (c->getContentType() == ContentType::PlainText) {
return c;
}
}
return Content::Empty;
return &Content::Empty;
}
bool ChatMessage::hasFileTransferContent() const {
L_D();
for (const auto &c : d->contents) {
if (c.getContentType() == ContentType::FileTransfer) {
for (const Content *c : d->contents) {
if (c->getContentType() == ContentType::FileTransfer) {
return true;
}
}
return false;
}
const Content &ChatMessage::getFileTransferContent() const {
const Content* ChatMessage::getFileTransferContent() const {
L_D();
for (const auto &c : d->contents) {
if (c.getContentType() == ContentType::FileTransfer) {
for (const Content *c : d->contents) {
if (c->getContentType() == ContentType::FileTransfer) {
return c;
}
}
return Content::Empty;
return &Content::Empty;
}
const string &ChatMessage::getFileTransferFilepath () const {
......
......@@ -96,16 +96,15 @@ public:
bool isRead () const;
bool isReadOnly () const;
const std::list<Content> &getContents () const;
void addContent (Content &&content);
void addContent (const Content &content);
void removeContent (const Content &content);
const std::list<Content *> &getContents () const;
void addContent (Content *content);
void removeContent (Content *content);
bool hasTextContent() const;
const Content &getTextContent() const;
const Content* getTextContent() const;
bool hasFileTransferContent() const;
const Content &getFileTransferContent() const;
const Content* getFileTransferContent() const;
const Content &getInternalContent () const;
void setInternalContent (const Content &content);
......@@ -114,7 +113,7 @@ public:
void addCustomHeader (const std::string &headerName, const std::string &headerValue);
void removeCustomHeader (const std::string &headerName);
int downloadFile (FileTransferContent& content);
int downloadFile (FileTransferContent *content);
private:
L_DECLARE_PRIVATE(ChatMessage);
......
......@@ -118,9 +118,9 @@ void ChatRoomPrivate::sendImdn (const string &payload, LinphoneReason reason) {
msg->setFromAddress(Address(identity));
msg->setToAddress(peerAddress);
Content content;
content.setContentType("message/imdn+xml");
content.setBody(payload);
Content *content = new Content();
content->setContentType("message/imdn+xml");
content->setBody(payload);
msg->addContent(content);
/* Do not try to encrypt the notification when it is reporting an error (maybe it should be bypassed only for some reasons). */
......@@ -163,9 +163,9 @@ void ChatRoomPrivate::sendIsComposingNotification () {
string payload = isComposingHandler->marshal(isComposing);
if (!payload.empty()) {
shared_ptr<ChatMessage> msg = q->createMessage();
Content content;
content.setContentType("application/im-iscomposing+xml");
content.setBody(payload);
Content *content = new Content();
content->setContentType("application/im-iscomposing+xml");
content->setBody(payload);
msg->addContent(content);
msg->getPrivate()->send();
}
......@@ -465,9 +465,9 @@ shared_ptr<ChatMessage> ChatRoom::createFileTransferMessage (const LinphoneConte
shared_ptr<ChatMessage> ChatRoom::createMessage (const string &message) {
shared_ptr<ChatMessage> chatMessage = createMessage();
Content content;
content.setContentType(ContentType::PlainText);
content.setBody(message);
Content *content = new Content();
content->setContentType(ContentType::PlainText);
content->setBody(message);
chatMessage->addContent(content);
return chatMessage;
}
......
......@@ -46,10 +46,10 @@ ChatMessageModifier::Result CpimChatMessageModifier::encode (const shared_ptr<Ch
cpimToHeader.setValue(cpimAddressAsString(message->getToAddress()));
cpimMessage.addMessageHeader(cpimToHeader);
Content content;
const Content *content;
if (!message->getInternalContent().isEmpty()) {
// Another ChatMessageModifier was called before this one, we apply our changes on the private content
content = message->getInternalContent();
content = &(message->getInternalContent());
} else {
// We're the first ChatMessageModifier to be called, we'll create the private content from the public one
// We take the first one because if there is more of them, the multipart modifier should have been called first
......@@ -59,10 +59,10 @@ ChatMessageModifier::Result CpimChatMessageModifier::encode (const shared_ptr<Ch
Cpim::GenericHeader contentTypeHeader;
contentTypeHeader.setName("Content-Type");
contentTypeHeader.setValue(content.getContentType().asString());
contentTypeHeader.setValue(content->getContentType().asString());
cpimMessage.addContentHeader(contentTypeHeader);
const string contentBody = content.getBodyAsString();
const string contentBody = content->getBodyAsString();
cpimMessage.setContent(contentBody);
if (!cpimMessage.isValid()) {
......@@ -80,18 +80,18 @@ ChatMessageModifier::Result CpimChatMessageModifier::encode (const shared_ptr<Ch
}
ChatMessageModifier::Result CpimChatMessageModifier::decode (const shared_ptr<ChatMessage> &message, int &errorCode) {
Content content;
const Content *content;
if (!message->getInternalContent().isEmpty())
content = message->getInternalContent();
content = &(message->getInternalContent());
else
content = message->getContents().front();
if (content.getContentType() != ContentType::Cpim) {
lError() << "[CPIM] Message is not CPIM but " << content.getContentType().asString();
if (content->getContentType() != ContentType::Cpim) {
lError() << "[CPIM] Message is not CPIM but " << content->getContentType().asString();
return ChatMessageModifier::Result::Skipped;
}
const string contentBody = content.getBodyAsString();
const string contentBody = content->getBodyAsString();
const shared_ptr<const Cpim::Message> cpimMessage = Cpim::Message::createFromString(contentBody);
if (!cpimMessage || !cpimMessage->isValid()) {
lError() << "[CPIM] Message is invalid: " << contentBody;
......
......@@ -24,6 +24,7 @@
#include "chat/chat-message/chat-message.h"
#include "chat/chat-room/chat-room.h"