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