Commit 210b4c75 authored by Ronan's avatar Ronan

feat(ChatModel): increase chat model creation, fetch chat message content when it is necessary

parent 98da222a
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <QDateTime> #include <QDateTime>
#include <QDesktopServices> #include <QDesktopServices>
#include <QElapsedTimer>
#include <QFileInfo> #include <QFileInfo>
#include <QMimeDatabase> #include <QMimeDatabase>
#include <QTimer> #include <QTimer>
...@@ -132,6 +133,46 @@ static inline void removeFileMessageThumbnail (const shared_ptr<linphone::ChatMe ...@@ -132,6 +133,46 @@ static inline void removeFileMessageThumbnail (const shared_ptr<linphone::ChatMe
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
static inline void fillMessageEntry (QVariantMap &dest, const shared_ptr<linphone::ChatMessage> &message) {
dest["content"] = Utils::coreStringToAppString(message->getText());
dest["isOutgoing"] = message->isOutgoing() || message->getState() == linphone::ChatMessage::State::Idle;
// Old workaround.
// It can exist messages with a not delivered status. It's a linphone core bug.
linphone::ChatMessage::State state = message->getState();
if (state == linphone::ChatMessage::State::InProgress)
dest["status"] = ChatModel::MessageStatusNotDelivered;
else
dest["status"] = static_cast<ChatModel::MessageStatus>(message->getState());
shared_ptr<const linphone::Content> content = message->getFileTransferInformation();
if (content) {
dest["fileSize"] = quint64(content->getSize());
dest["fileName"] = Utils::coreStringToAppString(content->getName());
dest["wasDownloaded"] = ::fileWasDownloaded(message);
fillThumbnailProperty(dest, message);
}
}
static inline void fillCallStartEntry (QVariantMap &dest, const shared_ptr<linphone::CallLog> &callLog) {
dest["type"] = ChatModel::CallEntry;
dest["timestamp"] = QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000);
dest["isOutgoing"] = callLog->getDir() == linphone::Call::Dir::Outgoing;
dest["status"] = static_cast<ChatModel::CallStatus>(callLog->getStatus());
dest["isStart"] = true;
}
static inline void fillCallEndEntry (QVariantMap &dest, const shared_ptr<linphone::CallLog> &callLog) {
dest["type"] = ChatModel::CallEntry;
dest["timestamp"] = QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000);
dest["isOutgoing"] = callLog->getDir() == linphone::Call::Dir::Outgoing;
dest["status"] = static_cast<ChatModel::CallStatus>(callLog->getStatus());
dest["isStart"] = false;
}
// -----------------------------------------------------------------------------
class ChatModel::MessageHandlers : public linphone::ChatMessageListener { class ChatModel::MessageHandlers : public linphone::ChatMessageListener {
friend class ChatModel; friend class ChatModel;
...@@ -247,8 +288,12 @@ QVariant ChatModel::data (const QModelIndex &index, int role) const { ...@@ -247,8 +288,12 @@ QVariant ChatModel::data (const QModelIndex &index, int role) const {
return QVariant(); return QVariant();
switch (role) { switch (role) {
case Roles::ChatEntry: case Roles::ChatEntry: {
return QVariant::fromValue(mEntries[row].first); auto &data = mEntries[row].first;
if (!data.contains("status"))
fillMessageEntry(data, static_pointer_cast<linphone::ChatMessage>(mEntries[row].second));
return QVariant::fromValue(data);
}
case Roles::SectionDate: case Roles::SectionDate:
return QVariant::fromValue(mEntries[row].first["timestamp"].toDate()); return QVariant::fromValue(mEntries[row].first["timestamp"].toDate());
} }
...@@ -309,24 +354,27 @@ void ChatModel::setSipAddresses (const QString &peerAddress, const QString &loca ...@@ -309,24 +354,27 @@ void ChatModel::setSipAddresses (const QString &peerAddress, const QString &loca
// Get messages. // Get messages.
mEntries.clear(); mEntries.clear();
for (auto &message : mChatRoom->getHistory(0)) {
QVariantMap map;
fillMessageEntry(map, message); QElapsedTimer timer;
timer.start();
// Old workaround. for (auto &message : mChatRoom->getHistory(0))
// It can exist messages with a not delivered status. It's a linphone core bug. mEntries << qMakePair(
if (message->getState() == linphone::ChatMessage::State::InProgress) QVariantMap{
map["status"] = MessageStatusNotDelivered; { "type", EntryType::MessageEntry },
{ "timestamp", QDateTime::fromMSecsSinceEpoch(message->getTime() * 1000) }
mEntries << qMakePair(map, static_pointer_cast<void>(message)); },
} static_pointer_cast<void>(message)
);
// Get calls. // Get calls.
// TODO: Add an API to find with local and peer addresses. // TODO: Add an API to find with local and peer addresses.
for (auto &callLog : core->getCallHistoryForAddress(mChatRoom->getPeerAddress())) for (auto &callLog : core->getCallHistoryForAddress(mChatRoom->getPeerAddress()))
if (mChatRoom->getLocalAddress()->weakEqual(callLog->getLocalAddress())) if (mChatRoom->getLocalAddress()->weakEqual(callLog->getLocalAddress()))
insertCall(callLog); insertCall(callLog);
qInfo() << QStringLiteral("ChatModel (%1, %2) loaded in %3 milliseconds.")
.arg(peerAddress).arg(localAddress).arg(timer.elapsed());
} }
bool ChatModel::getIsRemoteComposing () const { bool ChatModel::getIsRemoteComposing () const {
...@@ -474,7 +522,7 @@ void ChatModel::downloadFile (int id) { ...@@ -474,7 +522,7 @@ void ChatModel::downloadFile (int id) {
message->setFileTransferFilepath(Utils::appStringToCoreString(safeFilePath)); message->setFileTransferFilepath(Utils::appStringToCoreString(safeFilePath));
message->setListener(mMessageHandlers); message->setListener(mMessageHandlers);
if (message->downloadFile() < 0) if (!message->downloadFile())
qWarning() << QStringLiteral("Unable to download file of entry %1.").arg(id); qWarning() << QStringLiteral("Unable to download file of entry %1.").arg(id);
} }
...@@ -536,45 +584,6 @@ const ChatModel::ChatEntryData ChatModel::getFileMessageEntry (int id) { ...@@ -536,45 +584,6 @@ const ChatModel::ChatEntryData ChatModel::getFileMessageEntry (int id) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void ChatModel::fillMessageEntry (QVariantMap &dest, const shared_ptr<linphone::ChatMessage> &message) {
dest["type"] = EntryType::MessageEntry;
dest["timestamp"] = QDateTime::fromMSecsSinceEpoch(message->getTime() * 1000);
dest["content"] = Utils::coreStringToAppString(message->getText());
dest["isOutgoing"] = message->isOutgoing() || message->getState() == linphone::ChatMessage::State::Idle;
dest["status"] = static_cast<MessageStatus>(message->getState());
shared_ptr<const linphone::Content> content = message->getFileTransferInformation();
if (content) {
dest["fileSize"] = quint64(content->getSize());
dest["fileName"] = Utils::coreStringToAppString(content->getName());
dest["wasDownloaded"] = ::fileWasDownloaded(message);
fillThumbnailProperty(dest, message);
}
}
void ChatModel::fillCallStartEntry (QVariantMap &dest, const shared_ptr<linphone::CallLog> &callLog) {
QDateTime timestamp = QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000);
dest["type"] = EntryType::CallEntry;
dest["timestamp"] = timestamp;
dest["isOutgoing"] = callLog->getDir() == linphone::Call::Dir::Outgoing;
dest["status"] = static_cast<CallStatus>(callLog->getStatus());
dest["isStart"] = true;
}
void ChatModel::fillCallEndEntry (QVariantMap &dest, const shared_ptr<linphone::CallLog> &callLog) {
QDateTime timestamp = QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000);
dest["type"] = EntryType::CallEntry;
dest["timestamp"] = timestamp;
dest["isOutgoing"] = callLog->getDir() == linphone::Call::Dir::Outgoing;
dest["status"] = static_cast<CallStatus>(callLog->getStatus());
dest["isStart"] = false;
}
// -----------------------------------------------------------------------------
void ChatModel::removeEntry (ChatEntryData &entry) { void ChatModel::removeEntry (ChatEntryData &entry) {
int type = entry.first["type"].toInt(); int type = entry.first["type"].toInt();
...@@ -663,11 +672,13 @@ void ChatModel::insertMessageAtEnd (const shared_ptr<linphone::ChatMessage> &mes ...@@ -663,11 +672,13 @@ void ChatModel::insertMessageAtEnd (const shared_ptr<linphone::ChatMessage> &mes
int row = mEntries.count(); int row = mEntries.count();
beginInsertRows(QModelIndex(), row, row); beginInsertRows(QModelIndex(), row, row);
mEntries << qMakePair(
QVariantMap map; QVariantMap{
fillMessageEntry(map, message); { "type", EntryType::MessageEntry },
mEntries << qMakePair(map, static_pointer_cast<void>(message)); { "timestamp", QDateTime::fromMSecsSinceEpoch(message->getTime() * 1000) }
},
static_pointer_cast<void>(message)
);
endInsertRows(); endInsertRows();
} }
......
...@@ -124,10 +124,6 @@ private: ...@@ -124,10 +124,6 @@ private:
const ChatEntryData getFileMessageEntry (int id); const ChatEntryData getFileMessageEntry (int id);
void fillMessageEntry (QVariantMap &dest, const std::shared_ptr<linphone::ChatMessage> &message);
void fillCallStartEntry (QVariantMap &dest, const std::shared_ptr<linphone::CallLog> &callLog);
void fillCallEndEntry (QVariantMap &dest, const std::shared_ptr<linphone::CallLog> &callLog);
void removeEntry (ChatEntryData &entry); void removeEntry (ChatEntryData &entry);
void insertCall (const std::shared_ptr<linphone::CallLog> &callLog); void insertCall (const std::shared_ptr<linphone::CallLog> &callLog);
...@@ -139,7 +135,7 @@ private: ...@@ -139,7 +135,7 @@ private:
bool mIsRemoteComposing = false; bool mIsRemoteComposing = false;
QList<ChatEntryData> mEntries; mutable QList<ChatEntryData> mEntries;
std::shared_ptr<linphone::ChatRoom> mChatRoom; std::shared_ptr<linphone::ChatRoom> mChatRoom;
std::shared_ptr<CoreHandlers> mCoreHandlers; std::shared_ptr<CoreHandlers> mCoreHandlers;
......
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