diff --git a/assets/images/chat_is_composing_0.svg b/assets/images/chat_is_composing_0.svg
new file mode 100644
index 000000000..7376ef009
--- /dev/null
+++ b/assets/images/chat_is_composing_0.svg
@@ -0,0 +1,15 @@
+
+
\ No newline at end of file
diff --git a/assets/images/chat_is_composing_1.svg b/assets/images/chat_is_composing_1.svg
new file mode 100644
index 000000000..e4f5348a9
--- /dev/null
+++ b/assets/images/chat_is_composing_1.svg
@@ -0,0 +1,15 @@
+
+
\ No newline at end of file
diff --git a/assets/images/chat_is_composing_2.svg b/assets/images/chat_is_composing_2.svg
new file mode 100644
index 000000000..c3194052c
--- /dev/null
+++ b/assets/images/chat_is_composing_2.svg
@@ -0,0 +1,15 @@
+
+
\ No newline at end of file
diff --git a/assets/images/chat_is_composing_3.svg b/assets/images/chat_is_composing_3.svg
new file mode 100644
index 000000000..ea8b790e8
--- /dev/null
+++ b/assets/images/chat_is_composing_3.svg
@@ -0,0 +1,15 @@
+
+
\ No newline at end of file
diff --git a/resources.qrc b/resources.qrc
index 921027113..c06c6dc99 100644
--- a/resources.qrc
+++ b/resources.qrc
@@ -60,6 +60,10 @@
assets/images/chat_delivered.svg
assets/images/chat_error.svg
assets/images/chat_hovered.svg
+ assets/images/chat_is_composing_0.svg
+ assets/images/chat_is_composing_1.svg
+ assets/images/chat_is_composing_2.svg
+ assets/images/chat_is_composing_3.svg
assets/images/chat_normal.svg
assets/images/chat_pressed.svg
assets/images/chat_read.svg
diff --git a/src/components/sip-addresses/SipAddressesModel.cpp b/src/components/sip-addresses/SipAddressesModel.cpp
index 23d11e441..6166872cd 100644
--- a/src/components/sip-addresses/SipAddressesModel.cpp
+++ b/src/components/sip-addresses/SipAddressesModel.cpp
@@ -48,10 +48,11 @@ SipAddressesModel::SipAddressesModel (QObject *parent) : QAbstractListModel(pare
QObject::connect(contacts, &ContactsListModel::sipAddressAdded, this, &SipAddressesModel::handleSipAddressAdded);
QObject::connect(contacts, &ContactsListModel::sipAddressRemoved, this, &SipAddressesModel::handleSipAddressRemoved);
- CoreHandlers *intHandlers = mCoreHandlers.get();
- QObject::connect(intHandlers, &CoreHandlers::messageReceived, this, &SipAddressesModel::handleMessageReceived);
- QObject::connect(intHandlers, &CoreHandlers::callStateChanged, this, &SipAddressesModel::handleCallStateChanged);
- QObject::connect(intHandlers, &CoreHandlers::presenceReceived, this, &SipAddressesModel::handlePresenceReceived);
+ CoreHandlers *coreHandlers = mCoreHandlers.get();
+ QObject::connect(coreHandlers, &CoreHandlers::messageReceived, this, &SipAddressesModel::handleMessageReceived);
+ QObject::connect(coreHandlers, &CoreHandlers::callStateChanged, this, &SipAddressesModel::handleCallStateChanged);
+ QObject::connect(coreHandlers, &CoreHandlers::presenceReceived, this, &SipAddressesModel::handlePresenceReceived);
+ QObject::connect(coreHandlers, &CoreHandlers::isComposingChanged, this, &SipAddressesModel::handlerIsComposingChanged);
}
// -----------------------------------------------------------------------------
@@ -348,6 +349,17 @@ void SipAddressesModel::handleMessagesCountReset (const QString &sipAddress) {
updateObservers(sipAddress, 0);
}
+void SipAddressesModel::handlerIsComposingChanged (const shared_ptr &chatRoom) {
+ auto it = mSipAddresses.find(::Utils::coreStringToAppString(chatRoom->getPeerAddress()->asStringUriOnly()));
+ if (it != mSipAddresses.end()) {
+ (*it)["isComposing"] = chatRoom->isRemoteComposing();
+
+ int row = mRefs.indexOf(&(*it));
+ Q_ASSERT(row != -1);
+ emit dataChanged(index(row, 0), index(row, 0));
+ }
+}
+
// -----------------------------------------------------------------------------
void SipAddressesModel::addOrUpdateSipAddress (QVariantMap &map, ContactModel *contact) {
diff --git a/src/components/sip-addresses/SipAddressesModel.hpp b/src/components/sip-addresses/SipAddressesModel.hpp
index c306e2d29..77fd80cdb 100644
--- a/src/components/sip-addresses/SipAddressesModel.hpp
+++ b/src/components/sip-addresses/SipAddressesModel.hpp
@@ -86,6 +86,8 @@ private:
void handleMessageSent (const std::shared_ptr &message);
void handleMessagesCountReset (const QString &sipAddress);
+ void handlerIsComposingChanged (const std::shared_ptr &chatRoom);
+
// ---------------------------------------------------------------------------
// A sip address exists in this list if a contact is linked to it, or a call, or a message.
diff --git a/ui/modules/Linphone/Contact/Contact.qml b/ui/modules/Linphone/Contact/Contact.qml
index c11dadb3d..48c3e459b 100644
--- a/ui/modules/Linphone/Contact/Contact.qml
+++ b/ui/modules/Linphone/Contact/Contact.qml
@@ -65,7 +65,9 @@ Rectangle {
Layout.alignment: Qt.AlignTop
count: Number(entry.unreadMessagesCount)
- visible: displayUnreadMessagesCount && entry.unreadMessagesCount > 0
+ isComposing: Boolean(entry.isComposing)
+
+ visible: item.displayUnreadMessagesCount
}
}
}
diff --git a/ui/modules/Linphone/Contact/MessagesCounter.qml b/ui/modules/Linphone/Contact/MessagesCounter.qml
index 7463ae990..5d7c11da6 100644
--- a/ui/modules/Linphone/Contact/MessagesCounter.qml
+++ b/ui/modules/Linphone/Contact/MessagesCounter.qml
@@ -10,6 +10,7 @@ Item {
id: messagesCounter
property int count
+ property bool isComposing
implicitHeight: counterIcon.height + MessagesCounterStyle.verticalMargins * 2
implicitWidth: counterIcon.width + MessagesCounterStyle.horizontalMargins * 2
@@ -17,10 +18,15 @@ Item {
Icon {
id: counterIcon
+ property int composingIndex: 0
+
anchors.centerIn: parent
- icon: 'chat_count'
+ icon: messagesCounter.isComposing
+ ? ('chat_is_composing_' + counterIcon.composingIndex)
+ : 'chat_count'
iconSize: MessagesCounterStyle.iconSize.message
+ visible: messagesCounter.count > 0 || messagesCounter.isComposing
Icon {
anchors {
@@ -30,6 +36,7 @@ Item {
icon: 'chat_amount'
iconSize: MessagesCounterStyle.iconSize.amount
+ visible: messagesCounter.count > 0
Text {
anchors.centerIn: parent
@@ -38,5 +45,19 @@ Item {
text: messagesCounter.count
}
}
+
+ Timer {
+ interval: 500
+ repeat: true
+ running: messagesCounter.isComposing
+
+ onRunningChanged: {
+ if (running) {
+ counterIcon.composingIndex = 0
+ }
+ }
+
+ onTriggered: counterIcon.composingIndex = (counterIcon.composingIndex + 1) % 4
+ }
}
}