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