Commit 735554d4 authored by Ronan Abhamon's avatar Ronan Abhamon

feat(src/components/chat/ChatModel): can send messages (but crash with wrapper/listener)

parent 41aa40e1
#include <bctoolbox/logging.h>
#include <bctoolbox/port.h>
#include <linphone/linphonecore.h>
#include <QDateTime>
......
......@@ -13,30 +13,66 @@ using namespace std;
// =============================================================================
class ChatModel::MessageHandlers : public linphone::ChatMessageListener {
void onFileTransferRecv (
const shared_ptr<linphone::ChatMessage> &message,
const shared_ptr<linphone::Content> &content,
const shared_ptr<linphone::Buffer> &buffer
) override {
qDebug() << "Not yet implemented";
}
shared_ptr<linphone::Buffer> onFileTransferSend (
const shared_ptr<linphone::ChatMessage> &message,
const shared_ptr<linphone::Content> &content,
size_t offset,
size_t size
) override {
qDebug() << "Not yet implemented";
}
void onFileTransferProgressIndication (
const shared_ptr<linphone::ChatMessage> &message,
const shared_ptr<linphone::Content> &content,
size_t offset,
size_t total
) override {
qDebug() << "Not yet implemented";
}
void onMsgStateChanged (const shared_ptr<linphone::ChatMessage> &message, linphone::ChatMessageState state) override {
ChatModel *chat = static_cast<ChatModel *>(message->getUserData());
auto it = find_if(chat->m_entries.begin(), chat->m_entries.end(), [&message](const ChatEntryData &pair) {
return pair.second == message;
});
if (it == chat->m_entries.end())
return;
(*it).first["state"] = state;
int row = distance(chat->m_entries.begin(), it);
emit chat->dataChanged(chat->index(row, 0), chat->index(row, 0));
}
};
// -----------------------------------------------------------------------------
ChatModel::ChatModel (QObject *parent) : QAbstractListModel(parent) {
QObject::connect(
this, &ChatModel::allEntriesRemoved,
CoreManager::getInstance()->getSipAddressesModel(), &SipAddressesModel::handleAllHistoryEntriesRemoved
);
m_handlers = CoreManager::getInstance()->getHandlers();
m_core_handlers = CoreManager::getInstance()->getHandlers();
QObject::connect(
&(*m_handlers), &CoreHandlers::receivedMessage,
&(*m_core_handlers), &CoreHandlers::receivedMessage,
this, [this](
const std::shared_ptr<linphone::ChatRoom> &room,
const std::shared_ptr<linphone::ChatMessage> &message
const shared_ptr<linphone::ChatRoom> &room,
const shared_ptr<linphone::ChatMessage> &message
) {
if (m_chat_room == room) {
int row = rowCount();
beginInsertRows(QModelIndex(), row, row);
QVariantMap map;
fillMessageEntry(map, message);
m_entries << qMakePair(map, static_pointer_cast<void>(message));
endInsertRows();
}
if (m_chat_room == room)
insertMessageAtEnd(message);
}
);
}
......@@ -189,6 +225,14 @@ void ChatModel::removeAllEntries () {
emit allEntriesRemoved();
}
void ChatModel::sendMessage (const QString &message) {
shared_ptr<linphone::ChatMessage> _message = m_chat_room->createMessage(::Utils::qStringToLinphoneString(message));
_message->setUserData(this);
_message->setListener(m_message_handlers);
m_chat_room->sendChatMessage(_message);
insertMessageAtEnd(_message);
}
// -----------------------------------------------------------------------------
void ChatModel::fillMessageEntry (
......@@ -246,11 +290,9 @@ void ChatModel::removeEntry (ChatEntryData &pair) {
shared_ptr<void> linphone_ptr = pair.second;
QTimer::singleShot(
0, this, [this, linphone_ptr]() {
auto it = find_if(
m_entries.begin(), m_entries.end(), [linphone_ptr](const ChatEntryData &pair) {
auto it = find_if(m_entries.begin(), m_entries.end(), [linphone_ptr](const ChatEntryData &pair) {
return pair.second == linphone_ptr;
}
);
});
if (it != m_entries.end())
removeEntry(static_cast<int>(distance(m_entries.begin(), it)));
......@@ -264,3 +306,15 @@ void ChatModel::removeEntry (ChatEntryData &pair) {
qWarning() << QStringLiteral("Unknown chat entry type: %1.").arg(type);
}
}
void ChatModel::insertMessageAtEnd (const shared_ptr<linphone::ChatMessage> &message) {
int row = rowCount();
beginInsertRows(QModelIndex(), row, row);
QVariantMap map;
fillMessageEntry(map, message);
m_entries << qMakePair(map, static_pointer_cast<void>(message));
endInsertRows();
}
......@@ -11,6 +11,8 @@
class CoreHandlers;
class ChatModel : public QAbstractListModel {
class MessageHandlers;
Q_OBJECT;
Q_PROPERTY(QString sipAddress READ getSipAddress WRITE setSipAddress NOTIFY sipAddressChanged);
......@@ -39,6 +41,14 @@ public:
Q_ENUM(CallStatus);
enum MessageState {
MessageStateDelivered = linphone::ChatMessageStateDelivered,
MessageStateInProgress = linphone::ChatMessageStateInProgress,
MessageStateNotDelivered = linphone::ChatMessageStateNotDelivered
};
Q_ENUM(MessageState);
ChatModel (QObject *parent = Q_NULLPTR);
~ChatModel () = default;
......@@ -53,8 +63,10 @@ public:
QString getSipAddress () const;
void setSipAddress (const QString &sip_address);
Q_INVOKABLE void removeEntry (int id);
Q_INVOKABLE void removeAllEntries ();
void removeEntry (int id);
void removeAllEntries ();
void sendMessage (const QString &message);
signals:
void sipAddressChanged (const QString &sip_address);
......@@ -78,10 +90,13 @@ private:
void removeEntry (ChatEntryData &pair);
void insertMessageAtEnd (const std::shared_ptr<linphone::ChatMessage> &message);
QList<ChatEntryData> m_entries;
std::shared_ptr<linphone::ChatRoom> m_chat_room;
std::shared_ptr<CoreHandlers> m_handlers;
std::shared_ptr<CoreHandlers> m_core_handlers;
std::shared_ptr<MessageHandlers> m_message_handlers;
};
#endif // CHAT_MODEL_H_
......@@ -51,6 +51,10 @@ public:
static_cast<ChatModel *>(m_chat_model_filter.sourceModel())->removeAllEntries();
}
Q_INVOKABLE void sendMessage (const QString &message) {
static_cast<ChatModel *>(m_chat_model_filter.sourceModel())->sendMessage(message);
}
signals:
void sipAddressChanged (const QString &sipAddress);
void moreEntriesLoaded (int n);
......
......@@ -8,10 +8,12 @@ import Common.Styles 1.0
Item {
property alias placeholderText: textArea.placeholderText
property alias text: textArea.text
// ---------------------------------------------------------------------------
signal dropped (var files)
signal validText (string text)
// ---------------------------------------------------------------------------
......@@ -36,9 +38,13 @@ Item {
// Text area.
Flickable {
anchors.fill: parent
boundsBehavior: Flickable.StopAtBounds
ScrollBar.vertical: ForceScrollBar {
id: scrollBar
}
TextArea.flickable: TextArea {
id: textArea
......@@ -49,12 +55,11 @@ Item {
rightPadding: fileChooserButton.width +
fileChooserButton.anchors.rightMargin +
DroppableTextAreaStyle.fileChooserButton.margins
selectByMouse: true
wrapMode: TextArea.Wrap
}
anchors.fill: parent
// Necessary, else `placeHolderText` can get out of the component.
clip: true
Keys.onReturnPressed: text.length !== 0 && validText(text)
}
}
// Handle click to select files.
......
......@@ -15,6 +15,10 @@ ColumnLayout {
// ---------------------------------------------------------------------------
signal messageToSend (string text)
// ---------------------------------------------------------------------------
spacing: 0
ScrollableListView {
......@@ -212,6 +216,11 @@ ColumnLayout {
DroppableTextArea {
anchors.fill: parent
placeholderText: qsTr('newMessagePlaceholder')
onValidText: {
this.text = ''
proxyModel.sendMessage(text)
}
}
}
}
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