diff --git a/linphone-app/assets/images/menu_forward_custom.svg b/linphone-app/assets/images/menu_forward_custom.svg
new file mode 100644
index 000000000..069924dae
--- /dev/null
+++ b/linphone-app/assets/images/menu_forward_custom.svg
@@ -0,0 +1,49 @@
+
+
diff --git a/linphone-app/assets/images/menu_reply_custom.svg b/linphone-app/assets/images/menu_reply_custom.svg
new file mode 100644
index 000000000..4a17c45cc
--- /dev/null
+++ b/linphone-app/assets/images/menu_reply_custom.svg
@@ -0,0 +1,49 @@
+
+
diff --git a/linphone-app/assets/languages/da.ts b/linphone-app/assets/languages/da.ts
index e49100424..937dc2639 100644
--- a/linphone-app/assets/languages/da.ts
+++ b/linphone-app/assets/languages/da.ts
@@ -533,6 +533,16 @@ Server url ikke konfigureret.
'Hide delivery status' : Item menu that lead to IMDN of a message
+
+ menuForward
+ 'Forward' : Forward a message from menu
+
+
+
+ menuReply
+ 'Reply' : Reply to a message from menu
+
+
ChatNoticeModel
@@ -565,6 +575,22 @@ Server url ikke konfigureret.
+
+ ChatReplyMessage
+
+ headerReply
+ 'Reply' : Header on a message that contains a reply.
+
+
+
+
+ ChatReplyPreview
+
+ titleReply
+ 'Reply to %1' : Title for a reply preview to know who said what.
+
+
+
Cli
diff --git a/linphone-app/assets/languages/de.ts b/linphone-app/assets/languages/de.ts
index 7476a7702..21ba52830 100644
--- a/linphone-app/assets/languages/de.ts
+++ b/linphone-app/assets/languages/de.ts
@@ -533,6 +533,16 @@ Server URL ist nicht konfiguriert.
'Hide delivery status' : Item menu that lead to IMDN of a message
+
+ menuForward
+ 'Forward' : Forward a message from menu
+
+
+
+ menuReply
+ 'Reply' : Reply to a message from menu
+
+
ChatNoticeModel
@@ -565,6 +575,22 @@ Server URL ist nicht konfiguriert.
+
+ ChatReplyMessage
+
+ headerReply
+ 'Reply' : Header on a message that contains a reply.
+
+
+
+
+ ChatReplyPreview
+
+ titleReply
+ 'Reply to %1' : Title for a reply preview to know who said what.
+
+
+
Cli
diff --git a/linphone-app/assets/languages/en.ts b/linphone-app/assets/languages/en.ts
index 5b4616d2a..cbd882a41 100644
--- a/linphone-app/assets/languages/en.ts
+++ b/linphone-app/assets/languages/en.ts
@@ -533,6 +533,16 @@ Server URL not configured.
'Hide delivery status' : Item menu that lead to IMDN of a message
Hide delivery status
+
+ menuForward
+ 'Forward' : Forward a message from menu
+ Forward
+
+
+ menuReply
+ 'Reply' : Reply to a message from menu
+ Reply
+
ChatNoticeModel
@@ -565,6 +575,22 @@ Server URL not configured.
+
+ ChatReplyMessage
+
+ headerReply
+ 'Reply' : Header on a message that contains a reply.
+ Reply
+
+
+
+ ChatReplyPreview
+
+ titleReply
+ 'Reply to %1' : Title for a reply preview to know who said what.
+ Reply to %1
+
+
Cli
diff --git a/linphone-app/assets/languages/es.ts b/linphone-app/assets/languages/es.ts
index 980be9b5f..858ffca36 100644
--- a/linphone-app/assets/languages/es.ts
+++ b/linphone-app/assets/languages/es.ts
@@ -533,6 +533,16 @@ URL del servidor no configurada.
'Hide delivery status' : Item menu that lead to IMDN of a message
+
+ menuForward
+ 'Forward' : Forward a message from menu
+
+
+
+ menuReply
+ 'Reply' : Reply to a message from menu
+
+
ChatNoticeModel
@@ -565,6 +575,22 @@ URL del servidor no configurada.
+
+ ChatReplyMessage
+
+ headerReply
+ 'Reply' : Header on a message that contains a reply.
+
+
+
+
+ ChatReplyPreview
+
+ titleReply
+ 'Reply to %1' : Title for a reply preview to know who said what.
+
+
+
Cli
diff --git a/linphone-app/assets/languages/fr_FR.ts b/linphone-app/assets/languages/fr_FR.ts
index 176fb0a88..d933a195a 100644
--- a/linphone-app/assets/languages/fr_FR.ts
+++ b/linphone-app/assets/languages/fr_FR.ts
@@ -159,7 +159,7 @@
usernameStatusInvalidCharacters
- Caractères invalides détectés (regex : `%1`).
+ Caractères invalides détectés (regex : `%1`).
usernameStatusInvalid
@@ -175,7 +175,7 @@
passwordStatusInvalidCharacters
- Caractères invalides détectés (regex : `%1`).
+ Caractères invalides détectés (regex : `%1`).
passwordStatusMissingCharacters
@@ -533,6 +533,16 @@ URL du serveur non configurée.
'Hide delivery status' : Item menu that lead to IMDN of a message
Cacher le statut du message
+
+ menuForward
+ 'Forward' : Forward a message from menu
+
+
+
+ menuReply
+ 'Reply' : Reply to a message from menu
+
+
ChatNoticeModel
@@ -565,6 +575,22 @@ URL du serveur non configurée.
+
+ ChatReplyMessage
+
+ headerReply
+ 'Reply' : Header on a message that contains a reply.
+
+
+
+
+ ChatReplyPreview
+
+ titleReply
+ 'Reply to %1' : Title for a reply preview to know who said what.
+
+
+
Cli
@@ -978,7 +1004,7 @@ URL du serveur non configurée.
ephemeralNotInConference!
'Ephemeral message is only supported in conference based chat room!'
- Les messages éphémères ne sont disponibles que pour une conversation définie en mode conférence !
+ Les messages éphémères ne sont disponibles que pour une conversation définie en mode conférence !
Warning about not being in conference based chat room.
@@ -1917,7 +1943,7 @@ Cliquez ici : <a href="%1">%1</a>
serverTooltip
- Serveur LDAP. ie : ldap:// pour un serveur local ou ldap://ldap.example.org/
+ Serveur LDAP. ie : ldap:// pour un serveur local ou ldap://ldap.example.org/
bindDNLabel
diff --git a/linphone-app/assets/languages/hu.ts b/linphone-app/assets/languages/hu.ts
index 73e12b2cd..9f35ae17a 100644
--- a/linphone-app/assets/languages/hu.ts
+++ b/linphone-app/assets/languages/hu.ts
@@ -532,6 +532,16 @@ A kiszolgáló URL-je nincs konfigurálva.
'Hide delivery status' : Item menu that lead to IMDN of a message
Kézbesítési állapot elrejtése
+
+ menuForward
+ 'Forward' : Forward a message from menu
+
+
+
+ menuReply
+ 'Reply' : Reply to a message from menu
+
+
ChatNoticeModel
@@ -560,6 +570,22 @@ A kiszolgáló URL-je nincs konfigurálva.
+
+ ChatReplyMessage
+
+ headerReply
+ 'Reply' : Header on a message that contains a reply.
+
+
+
+
+ ChatReplyPreview
+
+ titleReply
+ 'Reply to %1' : Title for a reply preview to know who said what.
+
+
+
Cli
diff --git a/linphone-app/assets/languages/it.ts b/linphone-app/assets/languages/it.ts
index 6b58309e2..848f35fde 100644
--- a/linphone-app/assets/languages/it.ts
+++ b/linphone-app/assets/languages/it.ts
@@ -533,6 +533,16 @@ URL del server non configurato.
'Hide delivery status' : Item menu that lead to IMDN of a message
Nascondi lo stato del messaggio
+
+ menuForward
+ 'Forward' : Forward a message from menu
+
+
+
+ menuReply
+ 'Reply' : Reply to a message from menu
+
+
ChatNoticeModel
@@ -565,6 +575,22 @@ URL del server non configurato.
+
+ ChatReplyMessage
+
+ headerReply
+ 'Reply' : Header on a message that contains a reply.
+
+
+
+
+ ChatReplyPreview
+
+ titleReply
+ 'Reply to %1' : Title for a reply preview to know who said what.
+
+
+
Cli
diff --git a/linphone-app/assets/languages/ja.ts b/linphone-app/assets/languages/ja.ts
index 4879d776f..b94c01e8b 100644
--- a/linphone-app/assets/languages/ja.ts
+++ b/linphone-app/assets/languages/ja.ts
@@ -532,6 +532,16 @@
'Hide delivery status' : Item menu that lead to IMDN of a message
+
+ menuForward
+ 'Forward' : Forward a message from menu
+
+
+
+ menuReply
+ 'Reply' : Reply to a message from menu
+
+
ChatNoticeModel
@@ -560,6 +570,22 @@
+
+ ChatReplyMessage
+
+ headerReply
+ 'Reply' : Header on a message that contains a reply.
+
+
+
+
+ ChatReplyPreview
+
+ titleReply
+ 'Reply to %1' : Title for a reply preview to know who said what.
+
+
+
Cli
diff --git a/linphone-app/assets/languages/lt.ts b/linphone-app/assets/languages/lt.ts
index e0b6f91d0..501bf3120 100644
--- a/linphone-app/assets/languages/lt.ts
+++ b/linphone-app/assets/languages/lt.ts
@@ -534,6 +534,16 @@ Nesukonfigūruotas serverio url.
'Hide delivery status' : Item menu that lead to IMDN of a message
+
+ menuForward
+ 'Forward' : Forward a message from menu
+
+
+
+ menuReply
+ 'Reply' : Reply to a message from menu
+
+
ChatNoticeModel
@@ -570,6 +580,22 @@ Nesukonfigūruotas serverio url.
+
+ ChatReplyMessage
+
+ headerReply
+ 'Reply' : Header on a message that contains a reply.
+
+
+
+
+ ChatReplyPreview
+
+ titleReply
+ 'Reply to %1' : Title for a reply preview to know who said what.
+
+
+
Cli
diff --git a/linphone-app/assets/languages/pt_BR.ts b/linphone-app/assets/languages/pt_BR.ts
index b5be19ad5..55de11580 100644
--- a/linphone-app/assets/languages/pt_BR.ts
+++ b/linphone-app/assets/languages/pt_BR.ts
@@ -533,6 +533,16 @@ URL do servidor não configurado.
'Hide delivery status' : Item menu that lead to IMDN of a message
Ocultar status de entrega
+
+ menuForward
+ 'Forward' : Forward a message from menu
+
+
+
+ menuReply
+ 'Reply' : Reply to a message from menu
+
+
ChatNoticeModel
@@ -565,6 +575,22 @@ URL do servidor não configurado.
+
+ ChatReplyMessage
+
+ headerReply
+ 'Reply' : Header on a message that contains a reply.
+
+
+
+
+ ChatReplyPreview
+
+ titleReply
+ 'Reply to %1' : Title for a reply preview to know who said what.
+
+
+
Cli
diff --git a/linphone-app/assets/languages/ru.ts b/linphone-app/assets/languages/ru.ts
index 94cbb7e3b..3c220282b 100644
--- a/linphone-app/assets/languages/ru.ts
+++ b/linphone-app/assets/languages/ru.ts
@@ -534,6 +534,16 @@
'Hide delivery status' : Item menu that lead to IMDN of a message
+
+ menuForward
+ 'Forward' : Forward a message from menu
+
+
+
+ menuReply
+ 'Reply' : Reply to a message from menu
+
+
ChatNoticeModel
@@ -570,6 +580,22 @@
+
+ ChatReplyMessage
+
+ headerReply
+ 'Reply' : Header on a message that contains a reply.
+
+
+
+
+ ChatReplyPreview
+
+ titleReply
+ 'Reply to %1' : Title for a reply preview to know who said what.
+
+
+
Cli
diff --git a/linphone-app/assets/languages/sv.ts b/linphone-app/assets/languages/sv.ts
index 3a9aed662..99861de06 100644
--- a/linphone-app/assets/languages/sv.ts
+++ b/linphone-app/assets/languages/sv.ts
@@ -533,6 +533,16 @@ Serverwebbadressen är inte konfigurerad.
'Hide delivery status' : Item menu that lead to IMDN of a message
+
+ menuForward
+ 'Forward' : Forward a message from menu
+
+
+
+ menuReply
+ 'Reply' : Reply to a message from menu
+
+
ChatNoticeModel
@@ -565,6 +575,22 @@ Serverwebbadressen är inte konfigurerad.
+
+ ChatReplyMessage
+
+ headerReply
+ 'Reply' : Header on a message that contains a reply.
+
+
+
+
+ ChatReplyPreview
+
+ titleReply
+ 'Reply to %1' : Title for a reply preview to know who said what.
+
+
+
Cli
diff --git a/linphone-app/assets/languages/tr.ts b/linphone-app/assets/languages/tr.ts
index 55979490d..687cf8285 100644
--- a/linphone-app/assets/languages/tr.ts
+++ b/linphone-app/assets/languages/tr.ts
@@ -532,6 +532,16 @@ Sunucu url'si yapılandırılmadı.
'Hide delivery status' : Item menu that lead to IMDN of a message
+
+ menuForward
+ 'Forward' : Forward a message from menu
+
+
+
+ menuReply
+ 'Reply' : Reply to a message from menu
+
+
ChatNoticeModel
@@ -560,6 +570,22 @@ Sunucu url'si yapılandırılmadı.
+
+ ChatReplyMessage
+
+ headerReply
+ 'Reply' : Header on a message that contains a reply.
+
+
+
+
+ ChatReplyPreview
+
+ titleReply
+ 'Reply to %1' : Title for a reply preview to know who said what.
+
+
+
Cli
diff --git a/linphone-app/assets/languages/uk.ts b/linphone-app/assets/languages/uk.ts
index f12ea353b..6039d55b9 100644
--- a/linphone-app/assets/languages/uk.ts
+++ b/linphone-app/assets/languages/uk.ts
@@ -534,6 +534,16 @@
'Hide delivery status' : Item menu that lead to IMDN of a message
+
+ menuForward
+ 'Forward' : Forward a message from menu
+
+
+
+ menuReply
+ 'Reply' : Reply to a message from menu
+
+
ChatNoticeModel
@@ -570,6 +580,22 @@
+
+ ChatReplyMessage
+
+ headerReply
+ 'Reply' : Header on a message that contains a reply.
+
+
+
+
+ ChatReplyPreview
+
+ titleReply
+ 'Reply to %1' : Title for a reply preview to know who said what.
+
+
+
Cli
diff --git a/linphone-app/assets/languages/zh_CN.ts b/linphone-app/assets/languages/zh_CN.ts
index cd78ba20c..b5cbca736 100644
--- a/linphone-app/assets/languages/zh_CN.ts
+++ b/linphone-app/assets/languages/zh_CN.ts
@@ -532,6 +532,16 @@
'Hide delivery status' : Item menu that lead to IMDN of a message
隐藏发送状态
+
+ menuForward
+ 'Forward' : Forward a message from menu
+
+
+
+ menuReply
+ 'Reply' : Reply to a message from menu
+
+
ChatNoticeModel
@@ -560,6 +570,22 @@
+
+ ChatReplyMessage
+
+ headerReply
+ 'Reply' : Header on a message that contains a reply.
+
+
+
+
+ ChatReplyPreview
+
+ titleReply
+ 'Reply to %1' : Title for a reply preview to know who said what.
+
+
+
Cli
diff --git a/linphone-app/resources.qrc b/linphone-app/resources.qrc
index 8a20f82ba..91269be15 100644
--- a/linphone-app/resources.qrc
+++ b/linphone-app/resources.qrc
@@ -82,6 +82,8 @@
assets/images/led_red.svg
assets/images/led_white.svg
assets/images/menu_copy_text_custom.svg
+ assets/images/menu_reply_custom.svg
+ assets/images/menu_forward_custom.svg
assets/images/menu_imdn_info_custom.svg
assets/images/menu_vdots_custom.svg
assets/images/menu_info_custom.svg
@@ -134,7 +136,7 @@
assets/images/tooltip_arrow_right_custom.svg
assets/images/tooltip_arrow_top_custom.svg
assets/images/transfer_custom.svg
- assets/images/update_sign.svg
+ assets/images/update_sign.svg
assets/images/video_call_accept_custom.svg
assets/images/video_call_custom.svg
assets/images/warning.svg
@@ -268,6 +270,9 @@
ui/modules/Linphone/Chat/Chat.qml
ui/modules/Linphone/Chat/ChatDeliveries.qml
ui/modules/Linphone/Chat/ChatMenu.qml
+ ui/modules/Linphone/Chat/ChatMessagePreview.qml
+ ui/modules/Linphone/Chat/ChatReplyMessage.qml
+ ui/modules/Linphone/Chat/ChatReplyPreview.qml
ui/modules/Linphone/Chat/Event.qml
ui/modules/Linphone/Chat/FileMessage.qml
ui/modules/Linphone/Chat/IncomingMessage.qml
@@ -307,6 +312,7 @@
ui/modules/Linphone/Styles/Calls/CallStatisticsStyle.qml
ui/modules/Linphone/Styles/Calls/ConferenceControlsStyle.qml
ui/modules/Linphone/Styles/Chat/ChatStyle.qml
+ ui/modules/Linphone/Styles/Chat/ChatReplyMessageStyle.qml
ui/modules/Linphone/Styles/Codecs/CodecsViewerStyle.qml
ui/modules/Linphone/Styles/Contact/AvatarStyle.qml
ui/modules/Linphone/Styles/Contact/ContactDescriptionStyle.qml
diff --git a/linphone-app/src/components/chat-events/ChatMessageModel.cpp b/linphone-app/src/components/chat-events/ChatMessageModel.cpp
index 3661d9448..237896c7f 100644
--- a/linphone-app/src/components/chat-events/ChatMessageModel.cpp
+++ b/linphone-app/src/components/chat-events/ChatMessageModel.cpp
@@ -82,7 +82,6 @@ QString ContentModel::getThumbnail() const{
return mThumbnail;
}
-
void ContentModel::setFileOffset(quint64 fileOffset){
if( mFileOffset != fileOffset) {
mFileOffset = fileOffset;
@@ -302,6 +301,12 @@ ChatMessageModel::ChatMessageModel ( std::shared_ptr chat
mWasDownloaded = false;
mChatMessage->addListener(mChatMessageListener);
mTimestamp = QDateTime::fromMSecsSinceEpoch(chatMessage->getTime() * 1000);
+ if( mChatMessage->isReply()){
+ auto replyMessage = mChatMessage->getReplyMessage();
+ if( replyMessage)// Reply message could be inexistant (for example : when locally deleted)
+ mReplyChatMessageModel = create(replyMessage, parent);
+ }
+
connect(this, &ChatMessageModel::remove, dynamic_cast(parent), &ChatRoomModel::removeEntry);
std::list> contents = chatMessage->getContents();
@@ -365,6 +370,13 @@ QString ChatMessageModel::getFromDisplayName() const{
return Utils::getDisplayName(mChatMessage->getFromAddress());
}
+QString ChatMessageModel::getFromDisplayNameReplyMessage() const{
+ if( isReply())
+ return Utils::getDisplayName(mChatMessage->getReplyMessageSenderAddress());
+ else
+ return "";
+}
+
QString ChatMessageModel::getFromSipAddress() const{
return Utils::cleanSipAddress(Utils::coreStringToAppString(mChatMessage->getFromAddress()->asStringUriOnly()));
}
@@ -424,6 +436,13 @@ std::shared_ptr ChatMessageModel::getParticipantI
return mParticipantImdnStateListModel;
}
+bool ChatMessageModel::isReply() const{
+ return mChatMessage->isReply();
+}
+
+ChatMessageModel * ChatMessageModel::getReplyChatMessageModel() const{
+ return mReplyChatMessageModel.get();
+}
//-----------------------------------------------------------------------------------------------------------------------
diff --git a/linphone-app/src/components/chat-events/ChatMessageModel.hpp b/linphone-app/src/components/chat-events/ChatMessageModel.hpp
index 66d07056a..c31741f2e 100644
--- a/linphone-app/src/components/chat-events/ChatMessageModel.hpp
+++ b/linphone-app/src/components/chat-events/ChatMessageModel.hpp
@@ -60,6 +60,7 @@ public:
Q_PROPERTY(QString thumbnail READ getThumbnail WRITE setThumbnail NOTIFY thumbnailChanged)
Q_PROPERTY(bool wasDownloaded MEMBER mWasDownloaded WRITE setWasDownloaded NOTIFY wasDownloadedChanged)
+
std::shared_ptr getContent()const;
quint64 getFileSize() const;
@@ -135,6 +136,7 @@ public:
Q_PROPERTY(QString fromDisplayName READ getFromDisplayName CONSTANT)
+ Q_PROPERTY(QString fromDisplayNameReplyMessage READ getFromDisplayNameReplyMessage CONSTANT)
Q_PROPERTY(QString fromSipAddress READ getFromSipAddress CONSTANT)
Q_PROPERTY(QString toDisplayName READ getToDisplayName CONSTANT)
Q_PROPERTY(QString toSipAddress READ getToSipAddress CONSTANT)
@@ -155,6 +157,9 @@ public:
Q_PROPERTY(ContentModel * fileContentModel READ getFileContentModel NOTIFY fileContentChanged)
//Q_PROPERTY(QList contents READ getContents CONSTANT)
+ Q_PROPERTY(bool isReply READ isReply CONSTANT)
+ Q_PROPERTY(ChatMessageModel* replyChatMessageModel READ getReplyChatMessageModel CONSTANT)
+
std::shared_ptr getChatMessage();
std::shared_ptr getContentModel(std::shared_ptr content);
Q_INVOKABLE ContentModel * getContent(int i);
@@ -162,6 +167,7 @@ public:
//----------------------------------------------------------------------------
QString getFromDisplayName() const;
+ QString getFromDisplayNameReplyMessage() const;
QString getFromSipAddress() const;
QString getToDisplayName() const;
QString getToSipAddress() const;
@@ -176,6 +182,9 @@ public:
Q_INVOKABLE ParticipantImdnStateProxyModel * getProxyImdnStates();
std::shared_ptr getParticipantImdnStates() const;
+ bool isReply() const;
+ ChatMessageModel * getReplyChatMessageModel() const;
+
//----------------------------------------------------------------------------
void setWasDownloaded(bool wasDownloaded);
@@ -219,6 +228,8 @@ private:
std::shared_ptr mChatMessage;
std::shared_ptr mParticipantImdnStateListModel;
std::shared_ptr mChatMessageListener;
+
+ std::shared_ptr mReplyChatMessageModel;
};
Q_DECLARE_METATYPE(ChatMessageModel*)
Q_DECLARE_METATYPE(std::shared_ptr)
diff --git a/linphone-app/src/components/chat-room/ChatRoomModel.cpp b/linphone-app/src/components/chat-room/ChatRoomModel.cpp
index 823dfd036..26b657a6d 100644
--- a/linphone-app/src/components/chat-room/ChatRoomModel.cpp
+++ b/linphone-app/src/components/chat-room/ChatRoomModel.cpp
@@ -187,7 +187,7 @@ std::shared_ptr ChatRoomModel::create(std::shared_ptr chatRoom, QObject * parent) : QAbstractListModel(parent){
App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE
CoreManager *coreManager = CoreManager::getInstance();
-
+ mReply = nullptr;
mCoreHandlers = coreManager->getHandlers();
mChatRoom = chatRoom;
@@ -592,6 +592,14 @@ void ChatRoomModel::setEphemeralLifetime(long lifetime){
}
}
+void ChatRoomModel::setReply(ChatMessageModel * model){
+ if(mReply)
+ clearReply();
+ mReply = model->getChatMessage();
+}
+void ChatRoomModel::clearReply(){
+ mReply = nullptr;
+}
//------------------------------------------------------------------------------------------------
void ChatRoomModel::deleteChatRoom(){
@@ -630,9 +638,15 @@ void ChatRoomModel::updateParticipants(const QVariantList& participants){
// -----------------------------------------------------------------------------
void ChatRoomModel::sendMessage (const QString &message) {
- shared_ptr _message = mChatRoom->createMessageFromUtf8(message.toUtf8().toStdString());
- _message->send();
+ shared_ptr _message;
+ if(mReply){
+ _message = mChatRoom->createReplyMessage(mReply);
+ _message->addUtf8TextContent(message.toUtf8().toStdString());
+ }else{
+ _message= mChatRoom->createMessageFromUtf8(message.toUtf8().toStdString());
+ }
+ _message->send();
emit messageSent(_message);
}
diff --git a/linphone-app/src/components/chat-room/ChatRoomModel.hpp b/linphone-app/src/components/chat-room/ChatRoomModel.hpp
index c238eea79..c94ebe705 100644
--- a/linphone-app/src/components/chat-room/ChatRoomModel.hpp
+++ b/linphone-app/src/components/chat-room/ChatRoomModel.hpp
@@ -35,6 +35,7 @@ class ParticipantListModel;
class ChatEvent;
class ContactModel;
class ChatRoomModel;
+class ChatMessageModel;
class ChatRoomModelListener : public QObject, public linphone::ChatRoomListener {
Q_OBJECT
@@ -207,6 +208,9 @@ public:
void addMissedCallsCount(std::shared_ptr call);
void setEphemeralEnabled(bool enabled);
void setEphemeralLifetime(long lifetime);
+
+ void setReply(ChatMessageModel * model);
+ void clearReply();
// Tools
@@ -336,6 +340,8 @@ private:
std::shared_ptr mChatRoom;
std::shared_ptr mChatRoomModelListener;
+ std::shared_ptr mReply;
+
std::weak_ptr mSelf;
};
diff --git a/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp b/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp
index b6198d4db..532b1c672 100644
--- a/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp
+++ b/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp
@@ -120,6 +120,8 @@ CREATE_PARENT_MODEL_FUNCTION(removeAllEntries)
CREATE_PARENT_MODEL_FUNCTION_WITH_PARAM(sendFileMessage, const QString &)
CREATE_PARENT_MODEL_FUNCTION_WITH_PARAM(sendMessage, const QString &)
+CREATE_PARENT_MODEL_FUNCTION_WITH_PARAM(setReply, ChatMessageModel*)
+CREATE_PARENT_MODEL_FUNCTION(clearReply)
CREATE_PARENT_MODEL_FUNCTION_WITH_ID(removeRow)
diff --git a/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp b/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp
index 5dd0faa01..3a003faea 100644
--- a/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp
+++ b/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp
@@ -70,6 +70,9 @@ public:
Q_INVOKABLE void setFilterText(const QString& text);
+ Q_INVOKABLE void setReply(ChatMessageModel* model);
+ Q_INVOKABLE void clearReply();
+
signals:
void peerAddressChanged (const QString &peerAddress);
void localAddressChanged (const QString &localAddress);
diff --git a/linphone-app/ui/modules/Common/Form/DroppableTextArea.qml b/linphone-app/ui/modules/Common/Form/DroppableTextArea.qml
index 5c98e449b..fb0d13a81 100644
--- a/linphone-app/ui/modules/Common/Form/DroppableTextArea.qml
+++ b/linphone-app/ui/modules/Common/Form/DroppableTextArea.qml
@@ -23,6 +23,9 @@ Item {
property string dropDisabledReason
property bool isEphemeral : false
+ property int textLeftMargin: (fileChooserButton.visible? fileChooserButton.totalWidth + DroppableTextAreaStyle.fileChooserButton.margins: 0)
+ property int textRightMargin: sendButton.visible ? sendButton.totalWidth + DroppableTextAreaStyle.fileChooserButton.margins : 0
+
// ---------------------------------------------------------------------------
signal dropped (var files)
@@ -55,6 +58,7 @@ Item {
// Handle click to select files.
ActionButton {
id: fileChooserButton
+ property int totalWidth: DroppableTextAreaStyle.fileChooserButton.margins + width
Layout.leftMargin: DroppableTextAreaStyle.fileChooserButton.margins
Layout.alignment: Qt.AlignVCenter
@@ -189,6 +193,7 @@ Item {
// Handle click to select files.
ActionButton {
id: sendButton
+ property int totalWidth: Layout.rightMargin + Layout.leftMargin + width
Layout.rightMargin: DroppableTextAreaStyle.fileChooserButton.margins+15
Layout.leftMargin: 10
Layout.alignment: Qt.AlignVCenter
diff --git a/linphone-app/ui/modules/Common/Styles/Menus/MenuItemStyle.qml b/linphone-app/ui/modules/Common/Styles/Menus/MenuItemStyle.qml
index 531eac7b7..d9734b636 100644
--- a/linphone-app/ui/modules/Common/Styles/Menus/MenuItemStyle.qml
+++ b/linphone-app/ui/modules/Common/Styles/Menus/MenuItemStyle.qml
@@ -18,6 +18,14 @@ QtObject {
property int iconSize: 30
property string icon : 'menu_copy_text_custom'
}
+ property QtObject reply: QtObject {
+ property int iconSize: 30
+ property string icon : 'menu_reply_custom'
+ }
+ property QtObject forward: QtObject {
+ property int iconSize: 30
+ property string icon : 'menu_forward_custom'
+ }
property QtObject imdn: QtObject {
property int iconSize: 30
property string icon : 'menu_imdn_info_custom'
diff --git a/linphone-app/ui/modules/Linphone/Chat/Chat.qml b/linphone-app/ui/modules/Linphone/Chat/Chat.qml
index 7e9ef14a5..c4c9fc1e8 100644
--- a/linphone-app/ui/modules/Linphone/Chat/Chat.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/Chat.qml
@@ -5,8 +5,11 @@ import QtQuick.Layouts 1.3
import Common 1.0
import Linphone 1.0
import Linphone.Styles 1.0
+import Utils 1.0
import UtilsCpp 1.0
+import Units 1.0
+
import 'Chat.js' as Logic
// =============================================================================
@@ -20,6 +23,8 @@ Rectangle {
property string noticeBannerText : '' // When set, show a banner with text and hide after some time
onNoticeBannerTextChanged: if(noticeBannerText!='') messageBlock.state = "showed"
+ property alias replyChatMessageModel: chatMessagePreview.replyChatMessageModel
+
// ---------------------------------------------------------------------------
signal messageToSend (string text)
@@ -259,31 +264,38 @@ Rectangle {
source: Logic.getComponentFromEntry($chatEntry)
}
Connections{
- target: loader.item
- ignoreUnknownSignals: true
- //: "Copied to clipboard" : when a user copy a text from the menu, this message show up.
- onCopyAllDone: container.noticeBannerText = qsTr("allTextCopied")
- //: "Selection copied to clipboard" : when a user copy a text from the menu, this message show up.
- onCopySelectionDone: container.noticeBannerText = qsTr("selectedTextCopied")
+ target: loader.item
+ ignoreUnknownSignals: true
+ //: "Copied to clipboard" : when a user copy a text from the menu, this message show up.
+ onCopyAllDone: container.noticeBannerText = qsTr("allTextCopied")
+ //: "Selection copied to clipboard" : when a user copy a text from the menu, this message show up.
+ onCopySelectionDone: container.noticeBannerText = qsTr("selectedTextCopied")
+ onReplyClicked: {
+ proxyModel.setReply($chatEntry)
+ container.replyChatMessageModel = $chatEntry
}
+ }
}
}
}
}
footer: Item{
- Text {
- property var composers : container.proxyModel.composers
- color: ChatStyle.composingText.color
- font.pointSize: ChatStyle.composingText.pointSize
- height: visible ? undefined : 0
- leftPadding: ChatStyle.composingText.leftPadding
- visible: composers.length > 0 && (!proxyModel.chatRoomModel.haveEncryption && SettingsModel.standardChatEnabled || proxyModel.chatRoomModel.haveEncryption && SettingsModel.secureChatEnabled)
- wrapMode: Text.Wrap
- //: '%1 is typing...' indicate that someone is composing in chat
- text:(composers.length==0?'': qsTr('chatTyping','',composers.length).arg(container.proxyModel.getDisplayNameComposers()))
- }
- }
-
+ Text {
+ property var composers : container.proxyModel.composers
+ color: ChatStyle.composingText.color
+ font.pointSize: ChatStyle.composingText.pointSize
+ height: visible ? undefined : 0
+ leftPadding: ChatStyle.composingText.leftPadding
+ visible: composers.length > 0 && (!proxyModel.chatRoomModel.haveEncryption && SettingsModel.standardChatEnabled || proxyModel.chatRoomModel.haveEncryption && SettingsModel.secureChatEnabled)
+ wrapMode: Text.Wrap
+ //: '%1 is typing...' indicate that someone is composing in chat
+ text:(composers.length==0?'': qsTr('chatTyping','',composers.length).arg(container.proxyModel.getDisplayNameComposers()))
+ }
+ }
+
+ ChatMessagePreview{
+ id: chatMessagePreview
+ }
Rectangle{
id: messageBlock
height: 32
@@ -315,30 +327,30 @@ Rectangle {
Layout.fillWidth: true
text: container.noticeBannerText
font {
- pointSize: ChatStyle.messageBanner.pointSize
- }
+ pointSize: ChatStyle.messageBanner.pointSize
+ }
color: ChatStyle.messageBanner.textColor
}
}
states: [
- State {
- name: "hidden"
- PropertyChanges { target: messageBlock; opacity: 0 }
- },
- State {
- name: "showed"
- PropertyChanges { target: messageBlock; opacity: 1 }
- }
- ]
- transitions: [
- Transition {
- from: "*"; to: "showed"
- SequentialAnimation{
+ State {
+ name: "hidden"
+ PropertyChanges { target: messageBlock; opacity: 0 }
+ },
+ State {
+ name: "showed"
+ PropertyChanges { target: messageBlock; opacity: 1 }
+ }
+ ]
+ transitions: [
+ Transition {
+ from: "*"; to: "showed"
+ SequentialAnimation{
NumberAnimation{ properties: "opacity"; easing.type: Easing.OutBounce; duration: 500 }
- ScriptAction{ script: hideNoticeBanner.start()}
+ ScriptAction{ script: hideNoticeBanner.start()}
}
- },
- Transition {
+ },
+ Transition {
SequentialAnimation{
NumberAnimation{ properties: "opacity"; duration: 1000 }
ScriptAction{ script: container.noticeBannerText = '' }
@@ -360,7 +372,7 @@ Rectangle {
borderColor: ChatStyle.sendArea.border.color
topWidth: ChatStyle.sendArea.border.width
visible: proxyModel.chatRoomModel && !proxyModel.chatRoomModel.hasBeenLeft && (!proxyModel.chatRoomModel.haveEncryption && SettingsModel.standardChatEnabled || proxyModel.chatRoomModel.haveEncryption && SettingsModel.secureChatEnabled)
-
+
DroppableTextArea {
id: textArea
@@ -385,9 +397,10 @@ Rectangle {
onValidText: {
textArea.text = ''
chat.bindToEnd = true
- if(proxyModel.chatRoomModel)
+ if(proxyModel.chatRoomModel) {
proxyModel.sendMessage(text)
- else{
+
+ }else{
console.log("Peer : " +proxyModel.peerAddress+ "/"+chat.model.peerAddress)
proxyModel.chatRoomModel = CallsListModel.createChat(proxyModel.peerAddress)
proxyModel.sendMessage(text)
diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatMenu.qml b/linphone-app/ui/modules/Linphone/Chat/ChatMenu.qml
index 7f136e185..a85cebd6b 100644
--- a/linphone-app/ui/modules/Linphone/Chat/ChatMenu.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/ChatMenu.qml
@@ -28,6 +28,8 @@ Item {
signal removeEntryRequested()
signal copyAllDone()
signal copySelectionDone()
+ signal replyClicked()
+ signal forwardClicked()
function open(){
messageMenu.popup()
@@ -68,6 +70,27 @@ Item {
onTriggered: TextToSpeech.say(container.content)
visible: content != ''
}
+ MenuItem {
+ //: 'Forward' : Forward a message from menu
+ text: qsTr('menuForward')
+ iconMenu: MenuItemStyle.forward.icon
+ iconSizeMenu: MenuItemStyle.forward.iconSize
+ iconLayoutDirection: Qt.RightToLeft
+ menuItemStyle : MenuItemStyle.aux
+ onTriggered: container.forwardClicked()
+ visible: content != ''
+ }
+ MenuItem {
+ //: 'Reply' : Reply to a message from menu
+ text: qsTr('menuReply')
+ iconMenu: MenuItemStyle.reply.icon
+ iconSizeMenu: MenuItemStyle.reply.iconSize
+ iconLayoutDirection: Qt.RightToLeft
+ menuItemStyle : MenuItemStyle.aux
+ onTriggered: container.replyClicked()
+ visible: content != ''
+ }
+
MenuItem {
//: 'Hide delivery status' : Item menu that lead to IMDN of a message
text: (deliveryVisible ? qsTr('menuHideDeliveryStatus')
@@ -97,8 +120,6 @@ Item {
// Handle hovered link.
MouseArea {
anchors.fill: parent
- //height: messageMenu.height
- //width: messageMenu.width
acceptedButtons: Qt.RightButton
propagateComposedEvents:true
diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatMessagePreview.qml b/linphone-app/ui/modules/Linphone/Chat/ChatMessagePreview.qml
new file mode 100644
index 000000000..b7a15aa38
--- /dev/null
+++ b/linphone-app/ui/modules/Linphone/Chat/ChatMessagePreview.qml
@@ -0,0 +1,28 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.2
+import QtQuick.Layouts 1.3
+
+import Common 1.0
+import Linphone 1.0
+import Linphone.Styles 1.0
+import Utils 1.0
+import UtilsCpp 1.0
+
+import Units 1.0
+
+import 'Chat.js' as Logic
+
+// =============================================================================
+ColumnLayout{
+ property alias replyChatMessageModel : replyPreview.replyChatMessageModel
+ property int maxHeight: parent.height
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ height: replyPreview.height
+
+ ChatReplyPreview{
+ id: replyPreview
+ Layout.fillWidth: true
+ }
+}
\ No newline at end of file
diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatReplyMessage.qml b/linphone-app/ui/modules/Linphone/Chat/ChatReplyMessage.qml
new file mode 100644
index 000000000..688e15a9d
--- /dev/null
+++ b/linphone-app/ui/modules/Linphone/Chat/ChatReplyMessage.qml
@@ -0,0 +1,126 @@
+import QtQuick 2.7
+import QtQuick.Layouts 1.3
+
+import Clipboard 1.0
+import Common 1.0
+import Linphone 1.0
+
+import Common.Styles 1.0
+import Linphone.Styles 1.0
+import TextToSpeech 1.0
+import Utils 1.0
+import Units 1.0
+import UtilsCpp 1.0
+import LinphoneEnums 1.0
+
+import ColorsList 1.0
+
+import 'Message.js' as Logic
+
+// =============================================================================
+
+Item {
+ id: mainItem
+ property ChatMessageModel chatMessageModel
+ property ChatMessageModel mainChatMessageModel
+ property int maxWidth : parent.width
+ property int contentWidth: Math.max(usernameReplied.implicitWidth + replyMessage.implicitWidth , headerArea.width) + 7 + ChatReplyMessageStyle.padding * 2
+ property int contentHeight: headerArea.height + replyArea.height
+ property font customFont : SettingsModel.textMessageFont
+
+ width: maxWidth > contentWidth ? contentWidth : maxWidth
+
+ onMainChatMessageModelChanged: if( mainChatMessageModel.replyChatMessageModel) chatMessageModel = mainChatMessageModel.replyChatMessageModel
+
+ ColumnLayout{
+ anchors.fill: parent
+ spacing: 5
+ Row{
+ id: headerArea
+ Layout.preferredHeight: icon.height
+ Layout.topMargin: 5
+ Icon{
+ id: icon
+ icon: ChatReplyMessageStyle.header.replyIcon.icon
+ iconSize: ChatReplyMessageStyle.header.replyIcon.iconSize
+ height: iconSize
+ overwriteColor: ChatReplyMessageStyle.header.color
+ }
+ Text{
+ height: icon.height
+ verticalAlignment: Qt.AlignVCenter
+ //: 'Reply' : Header on a message that contains a reply.
+ text: qsTr('headerReply')
+ + (chatMessageModel || !mainChatMessageModel? '' : ' - ' + mainChatMessageModel.fromDisplayNameReplyMessage)
+ font.family: mainItem.customFont.family
+ font.pointSize: Units.dp * (mainItem.customFont.pointSize + ChatReplyMessageStyle.header.pointSizeOffset)
+ color: ChatReplyMessageStyle.header.color
+ }
+ }
+ Rectangle{
+ id: replyArea
+ Layout.fillWidth: true
+ Layout.preferredHeight: (chatMessageModel ? replyMessage.implicitHeight + usernameReplied.implicitHeight + ChatStyle.entry.message.padding : 0)
+ Layout.bottomMargin: ChatStyle.entry.message.padding
+ Layout.leftMargin: 10
+ Layout.rightMargin: 10
+ Rectangle{
+ anchors.left: parent.left
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ width: 7
+ color: chatMessageModel && chatMessageModel.isOutgoing ? ChatReplyMessageStyle.replyArea.outgoingMarkColor : ChatReplyMessageStyle.replyArea.incomingMarkColor
+ }
+
+ radius: 5
+ color: ChatReplyMessageStyle.replyArea.backgroundColor
+ visible: chatMessageModel != undefined
+ Text{
+ id: usernameReplied
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.topMargin: 3
+
+
+ leftPadding: 2 * ChatStyle.entry.message.padding
+
+ text: mainChatMessageModel && mainChatMessageModel.fromDisplayNameReplyMessage
+ font.family: mainItem.customFont.family
+ font.pointSize: Units.dp * (mainItem.customFont.pointSize + ChatReplyMessageStyle.replyArea.usernamePointSizeOffset)
+ font.weight: Font.Bold
+
+ color: ChatReplyMessageStyle.replyArea.foregroundColor
+ }
+ TextEdit {
+ id: replyMessage
+ property string lastTextSelected : ''
+ property font customFont : SettingsModel.textMessageFont
+
+ anchors.top: usernameReplied.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.topMargin: 3
+
+ clip: true
+ leftPadding: 2*ChatStyle.entry.message.padding
+ rightPadding: ChatStyle.entry.message.padding
+ bottomPadding: ChatStyle.entry.message.padding
+ readOnly: true
+ selectByMouse: true
+ font.family: customFont.family
+ font.pointSize: Units.dp * (customFont.pointSize + ChatReplyMessageStyle.replyArea.pointSizeOffset)
+ font.weight: Font.Light
+ color: ChatReplyMessageStyle.replyArea.foregroundColor
+ text: (visible ? Utils.encodeTextToQmlRichFormat(chatMessageModel.content, {
+ imagesHeight: ChatStyle.entry.message.images.height,
+ imagesWidth: ChatStyle.entry.message.images.width
+ })
+ : '')
+
+ textFormat: Text.RichText // To supports links and imgs.
+ wrapMode: TextEdit.Wrap
+ }
+ }
+ }
+}
diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatReplyPreview.qml b/linphone-app/ui/modules/Linphone/Chat/ChatReplyPreview.qml
new file mode 100644
index 000000000..01df0ddcd
--- /dev/null
+++ b/linphone-app/ui/modules/Linphone/Chat/ChatReplyPreview.qml
@@ -0,0 +1,139 @@
+import QtQuick 2.7
+import QtQuick.Controls 2.2
+import QtQuick.Layouts 1.3
+
+import Common 1.0
+import Linphone 1.0
+import Linphone.Styles 1.0
+import Utils 1.0
+import UtilsCpp 1.0
+
+import Units 1.0
+
+import 'Chat.js' as Logic
+
+// =============================================================================
+
+Rectangle{
+ id: replyPreviewBlock
+ property ChatMessageModel replyChatMessageModel
+ onReplyChatMessageModelChanged: if(replyChatMessageModel) replyPreviewBlock.state = "showed"
+
+ Layout.preferredHeight: Math.min(replayPreviewText.implicitHeight + replyPreviewHeaderArea.implicitHeight + 10, parent.maxHeight)
+
+ property int leftMargin: textArea.textLeftMargin
+ property int rightMargin: textArea.textRightMargin
+
+ color: ChatStyle.replyPreview.backgroundColor
+ radius: 10
+ state: "hidden"
+ visible: container.replyChatMessageModel
+// Remove bottom corners
+ clip: false
+ Rectangle{
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ height: parent.radius
+ color: parent.color
+ }
+//-------------------------
+ ColumnLayout{
+ anchors.fill: parent
+ anchors.leftMargin: replyPreviewBlock.leftMargin
+ anchors.rightMargin: replyPreviewBlock.rightMargin
+ spacing: 0
+ RowLayout{
+ id: replyPreviewHeaderArea
+ Layout.fillWidth: true
+ Layout.preferredHeight: replyPreviewTitleText.implicitHeight
+ Layout.topMargin: 10
+ spacing: 5
+ Icon{
+ icon: ChatStyle.replyPreview.icon
+ overwriteColor: ChatStyle.replyPreview.iconColor
+ iconSize: 20
+ }
+ Text{
+ id: replyPreviewTitleText
+ Layout.fillWidth: true
+ Layout.preferredHeight: implicitHeight
+ //: 'Reply to %1' : Title for a reply preview to know who said what.
+ text: container.replyChatMessageModel ? qsTr('titleReply').arg(container.replyChatMessageModel.fromDisplayName) : ''
+ font.pointSize: ChatStyle.replyPreview.headerPointSize
+ font.weight: Font.Bold
+ color: ChatStyle.replyPreview.headerTextColor
+ }
+ }
+ Flickable {
+ id: replayPreviewTextArea
+ ScrollBar.vertical: ForceScrollBar {visible: replayPreviewTextArea.height < replayPreviewText.implicitHeight}
+ boundsBehavior: Flickable.StopAtBounds
+ clip: true
+ contentHeight: replayPreviewText.implicitHeight
+ contentWidth: width - ScrollBar.vertical.width
+ flickableDirection: Flickable.VerticalFlick
+
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+
+ TextEdit {
+ id: replayPreviewText
+ property font customFont : SettingsModel.textMessageFont
+
+ anchors.left: parent.left
+ anchors.right: parent.right
+ clip: true
+ padding: ChatStyle.entry.message.padding
+ readOnly: true
+ selectByMouse: true
+ font.family: customFont.family
+ font.pointSize: Units.dp * (customFont.pointSize - 2)
+ text: replyChatMessageModel ? Utils.encodeTextToQmlRichFormat(replyChatMessageModel.content, {
+ imagesHeight: ChatStyle.entry.message.images.height,
+ imagesWidth: ChatStyle.entry.message.images.width
+ })
+ : ''
+ textFormat: Text.RichText // To supports links and imgs.
+ wrapMode: TextEdit.Wrap
+
+ onLinkActivated: Qt.openUrlExternally(link)
+ }
+ }
+ }
+ ActionButton{
+ anchors.right:parent.right
+ anchors.rightMargin: 14
+ anchors.verticalCenter: parent.verticalCenter
+ height: ChatStyle.replyPreview.closeButton.iconSize
+ isCustom: true
+ backgroundRadius: 90
+ colorSet: ChatStyle.replyPreview.closeButton
+
+ onClicked: parent.state = 'hidden'
+ }
+ states: [
+ State {
+ name: "hidden"
+ PropertyChanges { target: replyPreviewBlock; opacity: 0 }
+ },
+ State {
+ name: "showed"
+ PropertyChanges { target: replyPreviewBlock; opacity: 1 }
+ }
+ ]
+ transitions: [
+ Transition {
+ from: "*"; to: "showed"
+ SequentialAnimation{
+ NumberAnimation{ properties: "opacity"; easing.type: Easing.OutBounce; duration: 500 }
+ }
+ },
+ Transition {
+ SequentialAnimation{
+ NumberAnimation{ properties: "opacity"; duration: 250 }
+ ScriptAction{ script: container.replyChatMessageModel = null }
+ }
+ }
+ ]
+}
\ No newline at end of file
diff --git a/linphone-app/ui/modules/Linphone/Chat/IncomingMessage.qml b/linphone-app/ui/modules/Linphone/Chat/IncomingMessage.qml
index 2be7dc21f..da6175024 100644
--- a/linphone-app/ui/modules/Linphone/Chat/IncomingMessage.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/IncomingMessage.qml
@@ -13,6 +13,8 @@ RowLayout {
signal copyAllDone()
signal copySelectionDone()
+ signal replyClicked()
+ signal forwardClicked()
implicitHeight: message.height
spacing: 0
@@ -61,6 +63,8 @@ RowLayout {
onCopyAllDone: parent.copyAllDone()
onCopySelectionDone: parent.copySelectionDone()
+ onReplyClicked: parent.replyClicked()
+ onForwardClicked: parent.forwardClicked()
Layout.fillWidth: true
diff --git a/linphone-app/ui/modules/Linphone/Chat/Message.qml b/linphone-app/ui/modules/Linphone/Chat/Message.qml
index e850e5d05..af0a0f0f8 100644
--- a/linphone-app/ui/modules/Linphone/Chat/Message.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/Message.qml
@@ -34,26 +34,28 @@ Item {
signal copyAllDone()
signal copySelectionDone()
+ signal replyClicked()
+ signal forwardClicked()
// ---------------------------------------------------------------------------
- implicitHeight: message.contentHeight
+ implicitHeight: message.contentHeight +
+ + (replyMessage.visible ? replyMessage.contentHeight + 5 : 0)
+ (ephemeralTimerRow.visible? message.padding * 4 : message.padding * 2)
+ (deliveryLayout.visible? deliveryLayout.height : 0)
Rectangle {
id: rectangle
-
+ property int maxWidth: parent.width
+ property int dataWidth: Math.max(message.implicitWidth + 2*ChatStyle.entry.message.padding + 10, replyMessage.contentWidth)
height: parent.height - (deliveryLayout.visible? deliveryLayout.height : 0)
radius: ChatStyle.entry.message.radius
width: (
- ephemeralTimerRow.visible && message.contentWidth < ephemeralTimerRow.width
+ ephemeralTimerRow.visible && dataWidth < ephemeralTimerRow.width
? ephemeralTimerRow.width
- : message.contentWidth < parent.width
- ? message.contentWidth
- : parent.width
- ) + message.padding * 2
+ : Math.min(dataWidth, maxWidth)
+ )
Row{
id:ephemeralTimerRow
anchors.right:parent.right
@@ -78,64 +80,73 @@ Item {
overwriteColor: ChatStyle.ephemeralTimer.timerColor
iconSize: ChatStyle.ephemeralTimer.iconSize
}
- }
- }
-
-
+ }
// ---------------------------------------------------------------------------
// Message.
// ---------------------------------------------------------------------------
-
- TextEdit {
- id: message
- property string lastTextSelected : ''
- property font customFont : SettingsModel.textMessageFont
-
- anchors {
- left: container.left
- right: container.right
- }
-
- clip: true
- padding: ChatStyle.entry.message.padding
- readOnly: true
- selectByMouse: true
- font.family: customFont.family
- font.pointSize: Units.dp * customFont.pointSize
- text: Utils.encodeTextToQmlRichFormat($chatEntry.content, {
- imagesHeight: ChatStyle.entry.message.images.height,
- imagesWidth: ChatStyle.entry.message.images.width
- })
-
- // See http://doc.qt.io/qt-5/qml-qtquick-text.html#textFormat-prop
- // and http://doc.qt.io/qt-5/richtext-html-subset.html
- textFormat: Text.RichText // To supports links and imgs.
- wrapMode: TextEdit.Wrap
-
- onCursorRectangleChanged: Logic.ensureVisible(cursorRectangle)
- onLinkActivated: Qt.openUrlExternally(link)
- onSelectedTextChanged:if(selectedText != '') lastTextSelected = selectedText
- onActiveFocusChanged: {
- if(activeFocus)
- lastTextSelected = ''
- deselect()
- }
-
- ChatMenu{
- id:chatMenu
- height: parent.height
- width: rectangle.width
-
- lastTextSelected: message.lastTextSelected
- content: $chatEntry.content
- deliveryCount: deliveryLayout.model.count
- onDeliveryStatusClicked: deliveryLayout.visible = !deliveryLayout.visible
- onRemoveEntryRequested: removeEntry()
- deliveryVisible: deliveryLayout.visible
-
- onCopyAllDone: container.copyAllDone()
- onCopySelectionDone: container.copySelectionDone()
+ Column{
+ anchors.left: parent.left
+ anchors.right: parent.right
+ spacing: 5
+ ChatReplyMessage{
+ id: replyMessage
+ mainChatMessageModel: $chatEntry
+ visible: $chatEntry.isReply
+ maxWidth: container.width
+ height: contentHeight
+ }
+ TextEdit {
+ id: message
+ property string lastTextSelected : ''
+ property font customFont : SettingsModel.textMessageFont
+
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ clip: true
+ padding: ChatStyle.entry.message.padding
+ readOnly: true
+ selectByMouse: true
+ font.family: customFont.family
+ font.pointSize: Units.dp * customFont.pointSize
+ text: Utils.encodeTextToQmlRichFormat($chatEntry.content, {
+ imagesHeight: ChatStyle.entry.message.images.height,
+ imagesWidth: ChatStyle.entry.message.images.width
+ })
+
+ // See http://doc.qt.io/qt-5/qml-qtquick-text.html#textFormat-prop
+ // and http://doc.qt.io/qt-5/richtext-html-subset.html
+ textFormat: Text.RichText // To supports links and imgs.
+ wrapMode: TextEdit.Wrap
+
+ onCursorRectangleChanged: Logic.ensureVisible(cursorRectangle)
+ onLinkActivated: Qt.openUrlExternally(link)
+ onSelectedTextChanged:if(selectedText != '') lastTextSelected = selectedText
+ onActiveFocusChanged: {
+ if(activeFocus)
+ lastTextSelected = ''
+ deselect()
+ }
+
+ ChatMenu{
+ id:chatMenu
+ height: parent.height
+ width: rectangle.width
+
+ lastTextSelected: message.lastTextSelected
+ content: $chatEntry.content
+ deliveryCount: deliveryLayout.model.count
+ onDeliveryStatusClicked: deliveryLayout.visible = !deliveryLayout.visible
+ onRemoveEntryRequested: removeEntry()
+ deliveryVisible: deliveryLayout.visible
+
+ onCopyAllDone: container.copyAllDone()
+ onCopySelectionDone: container.copySelectionDone()
+ onReplyClicked: container.replyClicked()
+ onForwardClicked: container.forwardClicked()
+ }
+ }
}
}
diff --git a/linphone-app/ui/modules/Linphone/Chat/OutgoingMessage.qml b/linphone-app/ui/modules/Linphone/Chat/OutgoingMessage.qml
index 5b37d6909..8ff3e7ed0 100644
--- a/linphone-app/ui/modules/Linphone/Chat/OutgoingMessage.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/OutgoingMessage.qml
@@ -16,12 +16,16 @@ Item {
signal copyAllDone()
signal copySelectionDone()
+ signal replyClicked()
+ signal forwardClicked()
Message {
id: message
onCopyAllDone: parent.copyAllDone()
onCopySelectionDone: parent.copySelectionDone()
+ onReplyClicked: parent.replyClicked()
+ onForwardClicked: parent.forwardClicked()
anchors {
left: parent.left
diff --git a/linphone-app/ui/modules/Linphone/Styles/Chat/ChatReplyMessageStyle.qml b/linphone-app/ui/modules/Linphone/Styles/Chat/ChatReplyMessageStyle.qml
new file mode 100644
index 000000000..5a5b64bb5
--- /dev/null
+++ b/linphone-app/ui/modules/Linphone/Styles/Chat/ChatReplyMessageStyle.qml
@@ -0,0 +1,31 @@
+pragma Singleton
+import QtQml 2.2
+
+import Units 1.0
+import ColorsList 1.0
+
+// =============================================================================
+
+QtObject {
+ property string sectionName : 'ChatReplyMessage'
+ property color color: ColorsList.add(sectionName, 'q').color
+ property QtObject header: QtObject{
+ property color color: ColorsList.add(sectionName+'_header', 'h').color
+ property int pointSizeOffset: -3
+ property QtObject replyIcon: QtObject{
+ property string icon : 'menu_reply_custom'
+ property int iconSize: 22
+ }
+ }
+ property QtObject replyArea: QtObject{
+ property color outgoingMarkColor: ColorsList.add(sectionName+'_reply_outgoing_mark', 'm').color
+ property color incomingMarkColor: ColorsList.add(sectionName+'_reply_incoming_mark', 'r').color
+ property color backgroundColor: ColorsList.add(sectionName+'_reply_bg', 'q').color
+ property color foregroundColor: ColorsList.add(sectionName+'_reply_fg', 'h').color
+ property int usernamePointSizeOffset: -2
+ property int pointSizeOffset: -2
+ }
+
+ property int padding: 8
+
+}
diff --git a/linphone-app/ui/modules/Linphone/Styles/Chat/ChatStyle.qml b/linphone-app/ui/modules/Linphone/Styles/Chat/ChatStyle.qml
index 96f3958b2..c0a53d115 100644
--- a/linphone-app/ui/modules/Linphone/Styles/Chat/ChatStyle.qml
+++ b/linphone-app/ui/modules/Linphone/Styles/Chat/ChatStyle.qml
@@ -41,7 +41,28 @@ QtObject {
property int leftPadding: 20
property int pointSize: Units.dp * 9
}
-
+ property QtObject replyPreview: QtObject {
+ id: replyPreviewObject
+ property string name: 'replyPreview'
+ property string icon: 'menu_reply_custom'
+ property color backgroundColor: ColorsList.add(sectionName+'_'+name+'_bg', 'e').color
+ property color headerTextColor: ColorsList.add(sectionName+'_'+name+'_header_fg', 'i').color
+ property color iconColor: ColorsList.add(sectionName+'_'+name+'_header_fg', 'i').color
+ property color textColor: ColorsList.add(sectionName+'_'+name+'_fg', 'd').color
+ property int pointSize: Units.dp * 9
+ property int headerPointSize: Units.dp * 9
+ property QtObject closeButton: QtObject{
+ property int iconSize: 30
+ property string name : 'close'
+ property string icon : 'close_custom'
+ property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+replyPreviewObject.name+'_'+name+'_b_n', icon, 'l_n_b_bg').color
+ property color backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+replyPreviewObject.name+'_'+name+'_b_h', icon, 'l_h_b_bg').color
+ property color backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+replyPreviewObject.name+'_'+name+'_b_p', icon, 'l_p_b_bg').color
+ property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+replyPreviewObject.name+'_'+name+'_f_n', icon, 'l_n_b_fg').color
+ property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+replyPreviewObject.name+'_'+name+'_f_h', icon, 'l_h_b_fg').color
+ property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+replyPreviewObject.name+'_'+name+'_f_p', icon, 'l_p_b_fg').color
+ }
+ }
property QtObject messageBanner: QtObject {
property color color: ColorsList.add(sectionName+'_message_banner', '', 'Background of message banner', '#9ecd1d').color
property color textColor: ColorsList.add(sectionName+'_message_banner_text', 'q', 'Text of message banner').color
diff --git a/linphone-app/ui/modules/Linphone/Styles/qmldir b/linphone-app/ui/modules/Linphone/Styles/qmldir
index 2eccc00c5..2a2445dc4 100644
--- a/linphone-app/ui/modules/Linphone/Styles/qmldir
+++ b/linphone-app/ui/modules/Linphone/Styles/qmldir
@@ -10,6 +10,7 @@ singleton CardBlockStyle 1.0 Blocks/CardBlockStyle.qml
singleton RequestBlockStyle 1.0 Blocks/RequestBlockStyle.qml
singleton ChatStyle 1.0 Chat/ChatStyle.qml
+singleton ChatReplyMessageStyle 1.0 Chat/ChatReplyMessageStyle.qml
singleton CallControlsStyle 1.0 Calls/CallControlsStyle.qml
singleton CallsStyle 1.0 Calls/CallsStyle.qml
diff --git a/linphone-app/ui/modules/Linphone/qmldir b/linphone-app/ui/modules/Linphone/qmldir
index 096c3b498..5eae08a7e 100644
--- a/linphone-app/ui/modules/Linphone/qmldir
+++ b/linphone-app/ui/modules/Linphone/qmldir
@@ -15,6 +15,9 @@ Calls 1.0 Calls/Calls.qml
CallStatistics 1.0 Calls/CallStatistics.qml
Chat 1.0 Chat/Chat.qml
+ChatMessagePreview 1.0 Chat/ChatMessagePreview.qml
+ChatReplyMessage 1.0 Chat/ChatReplyMessage.qml
+ChatReplyPreview 1.0 Chat/ChatReplyPreview.qml
History 1.0 History/History.qml
diff --git a/linphone-sdk b/linphone-sdk
index 6f1485a2d..ec7245a7a 160000
--- a/linphone-sdk
+++ b/linphone-sdk
@@ -1 +1 @@
-Subproject commit 6f1485a2de0507a51087c81d6f457df8e6a496cd
+Subproject commit ec7245a7a8a64d6f8e7f077e48e046907f524399