diff --git a/linphone-app/resources.qrc b/linphone-app/resources.qrc
index 282f0bab3..94c12a836 100644
--- a/linphone-app/resources.qrc
+++ b/linphone-app/resources.qrc
@@ -346,6 +346,7 @@
ui/modules/Linphone/Chat/ChatFilePreview.qml
ui/modules/Linphone/Chat/ChatForwardMessage.qml
ui/modules/Linphone/Chat/ChatMessagePreview.qml
+ ui/modules/Linphone/Chat/ChatReactions.qml
ui/modules/Linphone/Chat/ChatReactionsDetails.qml
ui/modules/Linphone/Chat/ChatReplyMessage.qml
ui/modules/Linphone/Chat/ChatReplyPreview.qml
diff --git a/linphone-app/src/components/chat-events/ChatMessageModel.cpp b/linphone-app/src/components/chat-events/ChatMessageModel.cpp
index 2348b5740..0efdebc91 100644
--- a/linphone-app/src/components/chat-events/ChatMessageModel.cpp
+++ b/linphone-app/src/components/chat-events/ChatMessageModel.cpp
@@ -262,7 +262,7 @@ void ChatMessageModel::sendChatReaction(const QString& reaction){
return; // TODO : remove return when sending empty emoji will be supported.
}
chatReaction->send();
- mChatReactionListModel->updateChatReaction(chatReaction);
+ emit newMessageReaction(mChatMessage, chatReaction);
}
void ChatMessageModel::deleteEvent(){
@@ -327,7 +327,7 @@ void ChatMessageModel::onMsgStateChanged (const std::shared_ptr & message, const std::shared_ptr & reaction){
- mChatReactionListModel->updateChatReaction(reaction);
+ emit newMessageReaction(message, reaction);
}
void ChatMessageModel::onParticipantImdnStateChanged(const std::shared_ptr & message, const std::shared_ptr & state){
diff --git a/linphone-app/src/components/chat-events/ChatMessageModel.hpp b/linphone-app/src/components/chat-events/ChatMessageModel.hpp
index bf51db599..c246bc03b 100644
--- a/linphone-app/src/components/chat-events/ChatMessageModel.hpp
+++ b/linphone-app/src/components/chat-events/ChatMessageModel.hpp
@@ -146,6 +146,7 @@ signals:
void fileContentChanged();
void remove(ChatMessageModel* model);
+ void newMessageReaction(const std::shared_ptr & message, const std::shared_ptr & reaction);
private:
void connectTo(ChatMessageListener * listener);
diff --git a/linphone-app/src/components/chat-reaction/ChatReactionListModel.cpp b/linphone-app/src/components/chat-reaction/ChatReactionListModel.cpp
index e35d25e0d..a428943a4 100644
--- a/linphone-app/src/components/chat-reaction/ChatReactionListModel.cpp
+++ b/linphone-app/src/components/chat-reaction/ChatReactionListModel.cpp
@@ -27,11 +27,15 @@
// =============================================================================
ChatReactionListModel::ChatReactionListModel (ChatMessageModel * message, QObject* parent) : ProxyAbstractListModel(parent) {
- mParent = message;
setChatMessageModel(message);
}
void ChatReactionListModel::setChatMessageModel(ChatMessageModel * message) {
+ if(mParent)
+ disconnect(message, &ChatMessageModel::newMessageReaction, this, &ChatReactionListModel::onNewMessageReaction);
+ mParent = message;
+ if(mParent)
+ connect(message, &ChatMessageModel::newMessageReaction, this, &ChatReactionListModel::onNewMessageReaction);
if(message){
auto reactions = message->getChatMessage()->getReactions();
mReactions.clear();
@@ -45,6 +49,7 @@ void ChatReactionListModel::setChatMessageModel(ChatMessageModel * message) {
}
}
updateList();
+ emit bodiesChanged();
}
}
@@ -69,41 +74,18 @@ QSharedPointer ChatReactionListModel::add(std::shared_ptrget() == model) {
- removeRow(count, QModelIndex());
- return;
- }
- }*/
+void ChatReactionListModel::remove(ChatReactionModel * model){
}
void ChatReactionListModel::clear(){
resetData();
}
-/*
-QSharedPointer ChatReactionListModel::getChatReactionModel(const std::shared_ptr& reaction){
- for(auto item : mList){
- auto c = item.objectCast();
- if(c->get() == content)
- return c;
- }
- if(content->isFileTransfer() || content->isFile() || content->isFileEncrypted()){
- for(auto item : mList){// Content object can be different for file (like while data transfer)
- auto c = item.objectCast();
- if(c->getContent()->getFilePath() == content->getFilePath())
- return c;
- }
- }
- return nullptr;
-}
-*/
void ChatReactionListModel::updateChatReaction(const std::shared_ptr& reaction) {
QString address = Utils::coreStringToAppString(reaction->getFromAddress()->asStringUriOnly());
auto itReaction = mReactions.find(address);
int oldReactionCount = mReactions.size();
+ auto oldBodies = getBodies();
if( itReaction == mReactions.end()) {// New
auto reactionModel = QSharedPointer::create(reaction);
auto body = reactionModel->getBody();
@@ -127,6 +109,7 @@ void ChatReactionListModel::updateChatReaction(const std::shared_ptr data;
@@ -177,54 +160,19 @@ void ChatReactionListModel::setGroupBy(ChatReactionListModel::GROUP_BY_TYPE mode
}
}
-
-/*
-
-void ContentListModel::updateContent(std::shared_ptr oldContent, std::shared_ptr newContent){
- int row = 0;
- for(auto content = mList.begin() ; content != mList.end() ; ++content, ++row){
- auto contentModel = content->objectCast();
- if( contentModel->getContent() == oldContent){
- mList.replace(row, QSharedPointer::create(newContent, contentModel->getChatMessageModel()));
- emit dataChanged(index(row,0), index(row,0));
- return;
+QStringList ChatReactionListModel::getBodies() const {
+ auto bodies = mBodies.keys();
+ auto reactions = Constants::getReactionsList();
+ std::sort(bodies.begin(), bodies.end(), [&](const QString& a, const QString& b){
+ for(auto reaction : reactions){
+ if( a == reaction) return true;
+ if( b == reaction) return false;
}
- }
+ return a < b;
+ });
+ return bodies;
}
-void ContentListModel::updateContents(ChatMessageModel * messageModel){
- std::list> contents = messageModel->getChatMessage()->getContents() ;
- int count = 0;
- beginResetModel();
- for(auto content : contents){
- if( count >= mList.size()){// New content
- mList.insert(count, QSharedPointer::create(content, messageModel));
- }else if(mList.at(count).objectCast()->getContent() != content){ // This content is not at its place
- int c = count + 1;
- while( c < mList.size() && mList.at(c).objectCast()->getContent() != content)
- ++c;
- if( c < mList.size()){// Found => swap position
-#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
- mList.swap(count, c);
-#else
- mList.swapItemsAt(count, c);
-#endif
- }else{// content is new
- mList.insert(count, QSharedPointer::create(content, messageModel));
- }
- }
- ++count;
- }
- if(count < mList.size())// Remove all old contents
- mList.erase(mList.begin()+count, mList.end());
- endResetModel();
+void ChatReactionListModel::onNewMessageReaction(const std::shared_ptr & message, const std::shared_ptr & reaction){
+ updateChatReaction(reaction);
}
-
-void ContentListModel::updateAllTransferData(){
- emit updateTransferDataRequested();
-}
-
-void ContentListModel::downloaded(){
- for(auto content : mList)
- content.objectCast()->createThumbnail();
-}*/
diff --git a/linphone-app/src/components/chat-reaction/ChatReactionListModel.hpp b/linphone-app/src/components/chat-reaction/ChatReactionListModel.hpp
index e94f28b4d..b83302d9d 100644
--- a/linphone-app/src/components/chat-reaction/ChatReactionListModel.hpp
+++ b/linphone-app/src/components/chat-reaction/ChatReactionListModel.hpp
@@ -52,6 +52,8 @@ public:
ChatReactionListModel::GROUP_BY_TYPE getGroupBy() const;
void setGroupBy(ChatReactionListModel::GROUP_BY_TYPE mode);
+ QStringList getBodies() const;
+
//QSharedPointer getChatReactionModel(const std::shared_ptr& reaction);
bool exists(std::shared_ptr reaction) const;
@@ -61,13 +63,16 @@ public:
void updateChatReaction(ChatMessageModel * messageModel);
void updateList();
+
+ void onNewMessageReaction(const std::shared_ptr & message, const std::shared_ptr & reaction);
signals:
void chatReactionsChanged();
void chatReactionCountChanged();
void groupByChanged();
+ void bodiesChanged();
private:
- ChatMessageModel * mParent;
+ ChatMessageModel * mParent = nullptr;
QMap> mReactions;
QMap>> mBodies;
GROUP_BY_TYPE mGroupBy = EMOJIES;
diff --git a/linphone-app/src/components/chat-reaction/ChatReactionProxyModel.cpp b/linphone-app/src/components/chat-reaction/ChatReactionProxyModel.cpp
index f001f09f7..2263a5aa5 100644
--- a/linphone-app/src/components/chat-reaction/ChatReactionProxyModel.cpp
+++ b/linphone-app/src/components/chat-reaction/ChatReactionProxyModel.cpp
@@ -29,6 +29,7 @@ ChatReactionProxyModel::ChatReactionProxyModel (QObject * parent) : SortFilterPr
mContents = QSharedPointer::create();
connect(mContents.get(), &ChatReactionListModel::chatReactionCountChanged, this, &ChatReactionProxyModel::chatReactionCountChanged);
connect(mContents.get(), &ChatReactionListModel::groupByChanged, this, &ChatReactionProxyModel::groupByChanged);
+ connect(mContents.get(), &ChatReactionListModel::bodiesChanged, this, &ChatReactionProxyModel::bodiesChanged);
setSourceModel(mContents.get());
sort(0);
}
@@ -90,13 +91,13 @@ void ChatReactionProxyModel::setFilter(const QString& filter) {
}
}
-/*
-void ChatReactionProxyModel::setContentListModel(ContentListModel * model){
- setSourceModel(model);
- sort(0);
- emit chatMessageModelChanged();
+QStringList ChatReactionProxyModel::getBodies() const {
+ auto model = qobject_cast(sourceModel());
+ if(model) {
+ return model->getBodies();
+ }else
+ return QStringList();
}
-*/
bool ChatReactionProxyModel::filterAcceptsRow (
int sourceRow,
@@ -122,46 +123,8 @@ bool ChatReactionProxyModel::filterAcceptsRow (
/*
bool ChatReactionProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const {
- const ContentModel *contentA = sourceModel()->data(left).value();
- const ContentModel *contentB = sourceModel()->data(right).value();
- bool aIsForward = contentA->getChatMessageModel() && contentA->getChatMessageModel()->isForward();
- bool aIsReply = contentA->getChatMessageModel() && contentA->getChatMessageModel()->isReply();
- bool aIsVoiceRecording = contentA->isVoiceRecording();
- bool aIsFile = contentA->isFile() || contentA->isFileEncrypted() || contentA->isFileTransfer();
- bool aIsText = contentA->isText() ;
- bool bIsForward = contentB->getChatMessageModel() && contentB->getChatMessageModel()->isForward();
- bool bIsReply = contentB->getChatMessageModel() && contentB->getChatMessageModel()->isReply();
- bool bIsVoiceRecording = contentB->isVoiceRecording();
- bool bIsFile = contentB->isFile() || contentB->isFileEncrypted() || contentB->isFileTransfer();
- bool bIsText = contentB->isText() ;
+ auto a = sourceModel()->data(left).value();
+ auto b = sourceModel()->data(right).value();
- return !bIsForward && (aIsForward
- || !bIsReply && (aIsReply
- || !bIsVoiceRecording && (aIsVoiceRecording
- || !bIsFile && (aIsFile
- || aIsText && !bIsText
- )
- )
- )
- );
}
-*/
-/*
-void ChatReactionProxyModel::remove(ContentModel * model){
- qobject_cast(sourceModel())->remove(model);
-}
-
-void ChatReactionProxyModel::clear(){
- qobject_cast(sourceModel())->clear();
-}
-
-ContentProxyModel::FilterContentType ChatReactionProxyModel::getFilter() const{
- return mFilter;
-}
-void ChatReactionProxyModel::setFilter(const FilterContentType& contentType){
- if(contentType != mFilter){
- mFilter = contentType;
- emit filterChanged();
- invalidate();
- }
-}*/
\ No newline at end of file
+*/
\ No newline at end of file
diff --git a/linphone-app/src/components/chat-reaction/ChatReactionProxyModel.hpp b/linphone-app/src/components/chat-reaction/ChatReactionProxyModel.hpp
index 76e3a001b..5f1509969 100644
--- a/linphone-app/src/components/chat-reaction/ChatReactionProxyModel.hpp
+++ b/linphone-app/src/components/chat-reaction/ChatReactionProxyModel.hpp
@@ -36,19 +36,8 @@ public:
Q_PROPERTY(int reactionCount READ getChatReactionCount NOTIFY chatReactionCountChanged)
Q_PROPERTY(ChatReactionListModel::GROUP_BY_TYPE groupBy READ getGroupBy WRITE setGroupBy NOTIFY groupByChanged)
Q_PROPERTY(QString filter READ getFilter WRITE setFilter NOTIFY filterChanged)
- /*
- Q_PROPERTY(FilterContentType filter READ getFilter WRITE setFilter NOTIFY filterChanged)
+ Q_PROPERTY(QStringList bodies READ getBodies NOTIFY bodiesChanged)
- enum FilterContentType {
- All,
- File,
- Text,
- Voice,
- Conference,
- Unknown
- };
- Q_ENUM(FilterContentType)
- */
ChatMessageModel * getChatMessageModel() const;
void setChatMessageModel(ChatMessageModel * message);
Q_INVOKABLE void setChatMessageModel(ChatMessageModel * message, ChatReactionListModel::GROUP_BY_TYPE groupByMode);
@@ -61,16 +50,15 @@ public:
QString getFilter() const;
void setFilter(const QString& filter);
- //Q_INVOKABLE void setContentListModel(ContentListModel * model);
- //Q_INVOKABLE void addFile(const QString& path);
- //Q_INVOKABLE void remove(ContentModel * model);
- //Q_INVOKABLE void clear();
+
+ QStringList getBodies() const;
signals:
void chatMessageModelChanged();
void chatReactionCountChanged();
void groupByChanged();
void filterChanged();
+ void bodiesChanged();
protected:
diff --git a/linphone-app/src/utils/Constants.cpp b/linphone-app/src/utils/Constants.cpp
index ad905b756..d5fa461d0 100644
--- a/linphone-app/src/utils/Constants.cpp
+++ b/linphone-app/src/utils/Constants.cpp
@@ -26,7 +26,9 @@ constexpr char Constants::DefaultFont[];
constexpr int Constants::DefaultFontPointSize;
constexpr char Constants::DefaultEmojiFont[];
constexpr int Constants::DefaultEmojiFontPointSize;
-
+QStringList Constants::getReactionsList(){
+ return {"❤️", "👍", "😂", "😮", "😢"};
+}
constexpr char Constants::QtDomain[];
constexpr size_t Constants::MaxLogsCollectionSize;
constexpr char Constants::SrcPattern[];
diff --git a/linphone-app/src/utils/Constants.hpp b/linphone-app/src/utils/Constants.hpp
index 9d5e8d5eb..29e86686d 100644
--- a/linphone-app/src/utils/Constants.hpp
+++ b/linphone-app/src/utils/Constants.hpp
@@ -45,6 +45,7 @@ public:
static constexpr char DefaultEmojiFont[] = "Noto Color Emoji";
#endif
static constexpr int DefaultEmojiFontPointSize = 10;
+ static QStringList getReactionsList();
static constexpr size_t MaxLogsCollectionSize = 10485760*5; // 50MB.
@@ -93,6 +94,7 @@ public:
Q_PROPERTY(QString ContactUrl MEMBER ContactUrl CONSTANT)
Q_PROPERTY(QString TranslationUrl MEMBER TranslationUrl CONSTANT)
Q_PROPERTY(int maxMosaicParticipants MEMBER MaxMosaicParticipants CONSTANT)
+ Q_PROPERTY(QStringList reactionsList READ getReactionsList CONSTANT)
// For Webviews
static constexpr char DefaultAssistantRegistrationUrl[] = "https://subscribe.linphone.org/register";
diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatMenu.qml b/linphone-app/ui/modules/Linphone/Chat/ChatMenu.qml
index 81806d136..ab7ab3407 100644
--- a/linphone-app/ui/modules/Linphone/Chat/ChatMenu.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/ChatMenu.qml
@@ -10,6 +10,7 @@ import Linphone.Styles 1.0
import TextToSpeech 1.0
import Utils 1.0
import Units 1.0
+import ConstantsCpp 1.0
import UtilsCpp 1.0
import LinphoneEnums 1.0
@@ -53,7 +54,7 @@ Item {
Layout.fillWidth: true
spacing:0
Repeater{
- model: ['❤️','👍','😂','😮','😢']
+ model: ConstantsCpp.reactionsList
delegate: Text{
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatReactions.qml b/linphone-app/ui/modules/Linphone/Chat/ChatReactions.qml
new file mode 100644
index 000000000..f7934eb33
--- /dev/null
+++ b/linphone-app/ui/modules/Linphone/Chat/ChatReactions.qml
@@ -0,0 +1,72 @@
+import QtQuick 2.7
+import QtQuick.Layouts 1.3
+import QtQml.Models 2.15
+
+import Common 1.0
+import Linphone 1.0
+
+import Units 1.0
+
+// =============================================================================
+
+Rectangle{
+ id: mainItem
+
+ property ChatReactionProxyModel model
+ property var modelData
+
+ signal reactionsClicked()
+
+ height: visible ? reactionList.height +10 : 0
+ width: visible ? reactionLayout.width + 10 : 0
+
+ visible: reactionList.count > 0
+ property font customFont : SettingsModel.textMessageFont
+ property font customEmojiFont : SettingsModel.emojiFont
+
+ RowLayout{
+ id: reactionLayout
+ anchors.centerIn: parent
+ ListView{
+ id: reactionList
+ Layout.preferredWidth: contentItem.childrenRect.width
+ Layout.preferredHeight: reactionMetrics.height
+ TextMetrics{
+ id: reactionMetrics
+ text: '😮'
+ font.family: mainItem.customEmojiFont.family
+ font.pointSize: Units.dp * mainItem.customEmojiFont.pointSize * 2
+ }
+ orientation: ListView.Horizontal
+ model: mainItem.model
+ spacing: 10
+ delegate:
+ Text{
+ width: reactionMetrics.width
+ height: reactionList.height
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ font.family: mainItem.customEmojiFont.family
+ font.pointSize: Units.dp * mainItem.customEmojiFont.pointSize * 2
+ text: $modelData.body || ''
+ }
+ }
+
+ Text{
+ Layout.preferredWidth: contentWidth
+ Layout.preferredHeight: reactionList.height
+ Layout.alignment: Qt.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ font.family: mainItem.customFont.family
+ font.pointSize: Units.dp * mainItem.customFont.pointSize
+ visible: mainItem.model && mainItem.model.count != mainItem.model.reactionCount
+
+ text: mainItem.model && mainItem.model.reactionCount || ''
+ }
+ }
+ MouseArea{
+ anchors.fill: parent
+ onClicked: mainItem.reactionsClicked()
+ }
+}
diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatReactionsDetails.qml b/linphone-app/ui/modules/Linphone/Chat/ChatReactionsDetails.qml
index 38eb7de94..b385dc30e 100644
--- a/linphone-app/ui/modules/Linphone/Chat/ChatReactionsDetails.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/ChatReactionsDetails.qml
@@ -28,9 +28,6 @@ Rectangle{
}
color: ChatReactionsDetailsStyle.backgroundColorModel.color
- onVisibleChanged: if(visible){
- tabBar.currentIndex = 0
- }
MouseArea{
anchors.fill: parent
onClicked: mainItem.visible = false
@@ -45,11 +42,23 @@ Rectangle{
ColumnLayout{
anchors.fill: parent
spacing: 0
- TabBar {
+ Loader{
+ id: loader
Layout.fillWidth: true
- id: tabBar
- TabButton {
- Layout.fillWidth: true
+ active: mainItem.visible
+ function refresh(){
+ active = false
+ active = true
+ }
+ Connections{
+ target: chatReactionsList
+ onChatMessageModelChanged: loader.refresh()
+ onBodiesChanged: loader.refresh()
+ }
+ sourceComponent: TabBar {
+ id: tabBar
+ Component.onCompleted: currentIndex = 0
+ TabButton {
//: "%1
reactions" : count of all chat reactions with a jump line between count and text.
text: UtilsCpp.encodeTextToQmlRichFormat(qsTr('reactionsCount', '', chatReactionsList.reactionCount).arg(chatReactionsList.reactionCount), {noLink:1}).toUpperCase()
// noLink=1 to avoid
convertion
@@ -59,24 +68,20 @@ Rectangle{
stretchContent: false
style: TabButtonStyle.popup
}
- Repeater{
- model: ['❤️','👍','😂','😮','😢']
- delegate: TabButton {
- width: visible ? undefined : 0
- property int reactionCount: 0
- visible: reactionCount > 0
- text: UtilsCpp.encodeTextToQmlRichFormat(modelData + ' '+reactionCount)
- textFont.family: mainItem.textFont.family
- textFont.pointSize: ChatReactionsDetailsStyle.tabBar.pointSize
-
- onIsSelectedChanged: if(isSelected) chatReactionsList.filter = modelData
- displaySelector: true
- stretchContent: false
- style: TabButtonStyle.popup
-
- Connections{
- target: chatReactionsList
- onChatMessageModelChanged: reactionCount = chatReactionsList.getChatReactionCount(modelData)
+ Repeater{
+ model: chatReactionsList.bodies
+ delegate: TabButton {
+ width: visible ? undefined : 0
+ property int reactionCount: chatReactionsList.getChatReactionCount(modelData)
+ visible: reactionCount > 0
+ text: UtilsCpp.encodeTextToQmlRichFormat(modelData + ' '+reactionCount)
+ textFont.family: mainItem.textFont.family
+ textFont.pointSize: ChatReactionsDetailsStyle.tabBar.pointSize
+
+ onIsSelectedChanged: if(isSelected) chatReactionsList.filter = modelData
+ displaySelector: true
+ stretchContent: false
+ style: TabButtonStyle.popup
}
}
}
diff --git a/linphone-app/ui/modules/Linphone/Chat/Message.qml b/linphone-app/ui/modules/Linphone/Chat/Message.qml
index 17209565f..84af04e3e 100644
--- a/linphone-app/ui/modules/Linphone/Chat/Message.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/Message.qml
@@ -42,11 +42,11 @@ Item {
signal conferenceIcsCopied()
signal addContactClicked(string contactAddress)
signal viewContactClicked(string contactAddress)
- signal reactionsClicked(ChatMessageModel message);
+ signal reactionsClicked(ChatMessageModel message)
// ---------------------------------------------------------------------------
property string lastTextSelected
- implicitHeight: (deliveryLayout.visible? deliveryLayout.height : 0) +(ephemeralTimerRow.visible? 16 : 0) + chatContent.height + reactionItem.height-10
+ implicitHeight: (deliveryLayout.visible? deliveryLayout.height : 0) +(ephemeralTimerRow.visible? 16 : 0) + chatContent.height + reactionLoader.height-10
Rectangle {
id: rectangle
property int availableWidth: parent.width
@@ -56,7 +56,7 @@ Item {
anchors.left: !$chatEntry.isOutgoing ? parent.left : undefined
anchors.right: $chatEntry.isOutgoing ? parent.right : undefined
- height: parent.height - (deliveryLayout.visible? deliveryLayout.height : 0) - (reactionItem.height-10)
+ height: parent.height - (deliveryLayout.visible? deliveryLayout.height : 0) - (reactionLoader.height-10)
radius: ChatStyle.entry.message.radius
clip: false
color: colorModel.color
@@ -144,69 +144,25 @@ Item {
chatMessageModel: $chatEntry
}
- Rectangle{
- id: reactionItem
+ Loader{
+ id: reactionLoader
anchors.top: rectangle.bottom
anchors.left: !$chatEntry.isOutgoing ? rectangle.left : undefined
anchors.right: $chatEntry.isOutgoing ? rectangle.right : undefined
anchors.topMargin: -10
anchors.leftMargin: 5
anchors.rightMargin: 5
- height: visible ? reactionList.height +10 : 0
- width: visible ? reactionLayout.width + 10 : 0
- color: rectangle.color
- radius: rectangle.radius
- visible: reactionList.count > 0
- property font customFont : SettingsModel.textMessageFont
- property font customEmojiFont : SettingsModel.emojiFont
-
- RowLayout{
- id: reactionLayout
- anchors.centerIn: parent
- ListView{
- id: reactionList
- Layout.preferredWidth: contentItem.childrenRect.width
- Layout.preferredHeight: reactionMetrics.height
- TextMetrics{
- id: reactionMetrics
- text: '😮'
- font.family: reactionItem.customEmojiFont.family
- font.pointSize: Units.dp * reactionItem.customEmojiFont.pointSize * 2
- }
- orientation: ListView.Horizontal
- model: ChatReactionProxyModel{
- id: chatReactionProxyModel
- chatMessageModel: $chatEntry
- }
- spacing: 10
- delegate:
- Text{
- width: reactionMetrics.width
- height: reactionList.height
- horizontalAlignment: Text.AlignHCenter
- verticalAlignment: Text.AlignVCenter
- font.family: reactionItem.customEmojiFont.family
- font.pointSize: Units.dp * reactionItem.customEmojiFont.pointSize * 2
- text: $modelData.body || ''
- }
- }
-
- Text{
- Layout.preferredWidth: contentWidth
- Layout.preferredHeight: reactionList.height
- Layout.alignment: Qt.AlignVCenter
- horizontalAlignment: Text.AlignHCenter
- verticalAlignment: Text.AlignVCenter
- font.family: reactionItem.customFont.family
- font.pointSize: Units.dp * reactionItem.customFont.pointSize
- visible: chatReactionProxyModel.count != chatReactionProxyModel.reactionCount
-
- text: chatReactionProxyModel.reactionCount
- }
+ ChatReactionProxyModel{
+ id: chatReactionProxyModel
+ chatMessageModel: $chatEntry
}
- MouseArea{
- anchors.fill: parent
- onClicked: container.reactionsClicked($chatEntry)
+ active: chatReactionProxyModel.count > 0
+ asynchronous: true
+ sourceComponent: ChatReactions{
+ color: rectangle.color
+ radius: rectangle.radius
+ model: chatReactionProxyModel
+ onReactionsClicked: container.reactionsClicked($chatEntry)
}
}
diff --git a/linphone-app/ui/modules/Linphone/qmldir b/linphone-app/ui/modules/Linphone/qmldir
index c277080dc..043dc3847 100644
--- a/linphone-app/ui/modules/Linphone/qmldir
+++ b/linphone-app/ui/modules/Linphone/qmldir
@@ -29,6 +29,7 @@ ChatEmojis 1.0 Chat/ChatEmojis.qml
ChatFullContent 1.0 Chat/ChatFullContent.qml
ChatMessagePreview 1.0 Chat/ChatMessagePreview.qml
ChatForwardMessage 1.0 Chat/ChatForwardMessage.qml
+ChatReactions 1.0 Chat/ChatReactions.qml
ChatReactionsDetails 1.0 Chat/ChatReactionsDetails.qml
ChatReplyMessage 1.0 Chat/ChatReplyMessage.qml
ChatReplyPreview 1.0 Chat/ChatReplyPreview.qml