mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-04-17 20:08:28 +00:00
scroll to original message on click on reply message #LINQT-2390
This commit is contained in:
parent
ca0bf41ee7
commit
92f4a92f86
9 changed files with 122 additions and 16 deletions
|
|
@ -194,6 +194,7 @@ ChatMessageCore::ChatMessageCore(const std::shared_ptr<linphone::ChatMessage> &c
|
|||
|
||||
mIsForward = chatmessage->isForward();
|
||||
mIsReply = chatmessage->isReply();
|
||||
mReplyMessageId = Utils::coreStringToAppString(chatmessage->getReplyMessageId());
|
||||
if (mIsReply) {
|
||||
auto replymessage = chatmessage->getReplyMessage();
|
||||
if (replymessage) {
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ class ChatMessageCore : public QObject, public AbstractObject {
|
|||
Q_PROPERTY(bool isForward MEMBER mIsForward CONSTANT)
|
||||
Q_PROPERTY(bool isReply MEMBER mIsReply CONSTANT)
|
||||
Q_PROPERTY(QString replyText MEMBER mReplyText CONSTANT)
|
||||
Q_PROPERTY(QString replyMessageId MEMBER mReplyMessageId CONSTANT)
|
||||
Q_PROPERTY(QString repliedToName MEMBER mRepliedToName CONSTANT)
|
||||
Q_PROPERTY(bool hasFileContent MEMBER mHasFileContent CONSTANT)
|
||||
Q_PROPERTY(bool isVoiceRecording MEMBER mIsVoiceRecording CONSTANT)
|
||||
|
|
@ -220,6 +221,7 @@ private:
|
|||
bool mIsForward = false;
|
||||
bool mIsReply = false;
|
||||
QString mReplyText;
|
||||
QString mReplyMessageId;
|
||||
QString mRepliedToName;
|
||||
bool mHasFileContent = false;
|
||||
bool mIsCalendarInvite = false;
|
||||
|
|
|
|||
|
|
@ -201,7 +201,10 @@ void EventLogList::loadMessagesUpTo(std::shared_ptr<linphone::EventLog> event) {
|
|||
: nullptr;
|
||||
auto chatModel = mChatCore->getModel();
|
||||
assert(chatModel);
|
||||
if (!chatModel) return;
|
||||
if (!chatModel) {
|
||||
emit messagesLoadedUpTo(nullptr);
|
||||
return;
|
||||
}
|
||||
int filters = static_cast<int>(linphone::ChatRoom::HistoryFilter::ChatMessage) |
|
||||
static_cast<int>(linphone::ChatRoom::HistoryFilter::InfoNoDevice);
|
||||
auto beforeEvents = chatModel->getHistoryRangeNear(mItemsToLoadBeforeSearchResult, 0, event, filters);
|
||||
|
|
@ -273,19 +276,24 @@ void EventLogList::findChatMessageWithFilter(QString filter, int startIndex, boo
|
|||
mLastFoundResult = *it;
|
||||
mCoreModelConnection->invokeToCore([this, index] { emit messageWithFilterFound(index); });
|
||||
} else {
|
||||
connect(this, &EventLogList::messagesLoadedUpTo, this,
|
||||
[this](std::shared_ptr<linphone::EventLog> event) {
|
||||
auto eventList = getSharedList<EventLogCore>();
|
||||
auto it = std::find_if(eventList.begin(), eventList.end(),
|
||||
[event](const QSharedPointer<EventLogCore> item) {
|
||||
return item->getModel()->getEventLog() == event;
|
||||
});
|
||||
int index = it != eventList.end() ? std::distance(eventList.begin(), it) : -1;
|
||||
if (mLastFoundResult && mLastFoundResult == *it) index = -1;
|
||||
mLastFoundResult = *it;
|
||||
mCoreModelConnection->invokeToCore(
|
||||
[this, index] { emit messageWithFilterFound(index); });
|
||||
});
|
||||
connect(
|
||||
this, &EventLogList::messagesLoadedUpTo, this,
|
||||
[this](std::shared_ptr<linphone::EventLog> event) {
|
||||
if (event == nullptr) emit messageWithFilterFound(-1);
|
||||
else {
|
||||
auto eventList = getSharedList<EventLogCore>();
|
||||
auto it = std::find_if(eventList.begin(), eventList.end(),
|
||||
[event](const QSharedPointer<EventLogCore> item) {
|
||||
return item->getModel()->getEventLog() == event;
|
||||
});
|
||||
int index = it != eventList.end() ? std::distance(eventList.begin(), it) : -1;
|
||||
if (mLastFoundResult && mLastFoundResult == *it) index = -1;
|
||||
mLastFoundResult = *it;
|
||||
mCoreModelConnection->invokeToCore(
|
||||
[this, index] { emit messageWithFilterFound(index); });
|
||||
}
|
||||
},
|
||||
Qt::SingleShotConnection);
|
||||
loadMessagesUpTo(eventLog);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -296,6 +304,55 @@ void EventLogList::findChatMessageWithFilter(QString filter, int startIndex, boo
|
|||
}
|
||||
}
|
||||
|
||||
void EventLogList::findChatMessageById(const QString &messageId) {
|
||||
lInfo() << log().arg("Try to find message by id :");
|
||||
auto eventList = getSharedList<EventLogCore>();
|
||||
auto it = std::find_if(eventList.begin(), eventList.end(), [messageId](const QSharedPointer<EventLogCore> item) {
|
||||
auto messageCore = item->getChatMessageCore();
|
||||
if (!messageCore) return false;
|
||||
return messageCore->getMessageId() == messageId;
|
||||
});
|
||||
if (it != eventList.end()) {
|
||||
int index = std::distance(eventList.begin(), it);
|
||||
if (index != -1) emit foundMessagById(index);
|
||||
} else {
|
||||
lInfo() << log().arg("Not found in displayed messages, search in entire history");
|
||||
auto chatModel = mChatCore->getModel();
|
||||
mCoreModelConnection->invokeToModel([this, chatModel, messageId] {
|
||||
auto history = chatModel->getHistory();
|
||||
auto it = std::find_if(history.begin(), history.end(),
|
||||
[messageId](const std::shared_ptr<linphone::EventLog> eventLog) {
|
||||
auto chatMessage = eventLog->getChatMessage();
|
||||
if (!chatMessage) return false;
|
||||
return Utils::coreStringToAppString(chatMessage->getMessageId()) == messageId;
|
||||
});
|
||||
// int index = it != history.end() ? std::distance(history.begin(), it) : -1;
|
||||
// if (index != -1) emit foundMessagById(index);
|
||||
if (it != history.end()) {
|
||||
lInfo() << log().arg("Found in entire history, load messages up to it");
|
||||
connect(
|
||||
this, &EventLogList::messagesLoadedUpTo, this,
|
||||
[this](std::shared_ptr<linphone::EventLog> event) {
|
||||
if (event == nullptr) return;
|
||||
auto eventList = getSharedList<EventLogCore>();
|
||||
auto it = std::find_if(eventList.begin(), eventList.end(),
|
||||
[event](const QSharedPointer<EventLogCore> item) {
|
||||
return item->getModel()->getEventLog() == event;
|
||||
});
|
||||
int index = it != eventList.end() ? std::distance(eventList.begin(), it) : -1;
|
||||
lInfo() << log().arg("Index corresponding to chat message id :") << index;
|
||||
mCoreModelConnection->invokeToCore([this, index] { emit foundMessagById(index); });
|
||||
},
|
||||
Qt::SingleShotConnection);
|
||||
loadMessagesUpTo(*it);
|
||||
} else {
|
||||
lInfo() << log().arg("Not found in entire history, event must have been deleted");
|
||||
emit foundMessagById(-1);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void EventLogList::setSelf(QSharedPointer<EventLogList> me) {
|
||||
mCoreModelConnection = SafeConnection<EventLogList, CoreModel>::create(me, CoreModel::getInstance());
|
||||
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ public:
|
|||
void setDisplayItemsStep(int displayItemsStep);
|
||||
|
||||
void findChatMessageWithFilter(QString filter, int startIndex, bool forward = true, bool isFirstResearch = true);
|
||||
void findChatMessageById(const QString &messageId);
|
||||
|
||||
void setSelf(QSharedPointer<EventLogList> me);
|
||||
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
|
@ -71,6 +72,7 @@ signals:
|
|||
void filterChanged(QString filter);
|
||||
void eventInsertedByUser(int index);
|
||||
void messageWithFilterFound(int index);
|
||||
void foundMessagById(int index);
|
||||
void listAboutToBeReset();
|
||||
void chatGuiChanged();
|
||||
void displayItemsStepChanged();
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ void EventLogProxy::setSourceModel(QAbstractItemModel *model) {
|
|||
if (oldEventLogList) {
|
||||
disconnect(oldEventLogList, &EventLogList::displayItemsStepChanged, this, nullptr);
|
||||
disconnect(oldEventLogList, &EventLogList::messageWithFilterFound, this, nullptr);
|
||||
disconnect(oldEventLogList, &EventLogList::foundMessagById, this, nullptr);
|
||||
disconnect(oldEventLogList, &EventLogList::eventInsertedByUser, this, nullptr);
|
||||
}
|
||||
auto newEventLogList = dynamic_cast<EventLogList *>(model);
|
||||
|
|
@ -53,6 +54,19 @@ void EventLogProxy::setSourceModel(QAbstractItemModel *model) {
|
|||
}
|
||||
emit indexWithFilterFound(proxyIndex);
|
||||
});
|
||||
connect(newEventLogList, &EventLogList::foundMessagById, this, [this, newEventLogList](int i) {
|
||||
auto model = dynamic_cast<EventLogList *>(sourceModel());
|
||||
int proxyIndex = mapFromSource(newEventLogList->index(i, 0)).row();
|
||||
if (i != -1) {
|
||||
loadUntil(proxyIndex);
|
||||
lInfo() << "Found index by id, request highlight at index" << proxyIndex;
|
||||
emit foundMessagById(proxyIndex);
|
||||
} else {
|
||||
Utils::showInformationPopup("info_popup_error_title",
|
||||
//: Original message not found. It may have been deleted
|
||||
"info_popup_reply_message_not_found_error");
|
||||
}
|
||||
});
|
||||
connect(newEventLogList, &EventLogList::eventInsertedByUser, this, [this, newEventLogList](int i) {
|
||||
int proxyIndex = mapFromSource(newEventLogList->index(i, 0)).row();
|
||||
emit eventInsertedByUser(proxyIndex);
|
||||
|
|
@ -207,3 +221,10 @@ void EventLogProxy::findIndexCorrespondingToFilter(int startIndex, bool forward,
|
|||
eventLogList->findChatMessageWithFilter(filter, listIndex, forward, isFirstResearch);
|
||||
}
|
||||
}
|
||||
|
||||
void EventLogProxy::findChatMessageById(const QString &messageId) {
|
||||
auto eventLogList = dynamic_cast<EventLogList *>(sourceModel());
|
||||
if (eventLogList) {
|
||||
eventLogList->findChatMessageById(messageId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,10 +77,12 @@ public:
|
|||
Q_INVOKABLE int findFirstUnreadIndex();
|
||||
Q_INVOKABLE void markIndexAsRead(int proxyIndex);
|
||||
Q_INVOKABLE void findIndexCorrespondingToFilter(int startIndex, bool forward = true, bool isFirstResearch = true);
|
||||
Q_INVOKABLE void findChatMessageById(const QString &messageId);
|
||||
|
||||
signals:
|
||||
void eventInsertedByUser(int index);
|
||||
void indexWithFilterFound(int index);
|
||||
void foundMessagById(int index);
|
||||
void chatGuiChanged();
|
||||
void countChanged();
|
||||
void initialDisplayItemsChanged();
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ void ChatMessageContentCore::setSelf(QSharedPointer<ChatMessageContentCore> me)
|
|||
mChatMessageContentModelConnection->invokeToCore([this, error] {
|
||||
//: Error downloading file %1
|
||||
if (error->isEmpty()) *error = tr("download_file_default_error").arg(mName);
|
||||
Utils::showInformationPopup(tr("info_popup_error_titile"), *error, false);
|
||||
Utils::showInformationPopup(tr("info_popup_error_title"), *error, false);
|
||||
delete error;
|
||||
});
|
||||
} else delete error;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ Control.Control {
|
|||
property bool isFromChatGroup: chatMessage? chatMessage.core.isFromChatGroup : false
|
||||
property bool isReply: chatMessage? chatMessage.core.isReply : false
|
||||
property bool isForward: chatMessage? chatMessage.core.isForward : false
|
||||
property string replyText: chatMessage? chatMessage.core.replyText : false
|
||||
property string replyText: chatMessage? chatMessage.core.replyText : ""
|
||||
property string replyMessageId: chatMessage? chatMessage.core.replyMessageId : ""
|
||||
property var msgState: chatMessage ? chatMessage.core.messageState : LinphoneEnums.ChatMessageState.StateIdle
|
||||
hoverEnabled: true
|
||||
property bool linkHovered: false
|
||||
|
|
@ -40,6 +41,7 @@ Control.Control {
|
|||
signal forwardMessageRequested()
|
||||
signal endOfVoiceRecordingReached()
|
||||
signal requestAutoPlayVoiceRecording()
|
||||
signal searchMessageByIdRequested(string id)
|
||||
onRequestAutoPlayVoiceRecording: chatBubbleContent.requestAutoPlayVoiceRecording()
|
||||
|
||||
Timer {
|
||||
|
|
@ -154,6 +156,13 @@ Control.Control {
|
|||
anchors.fill: parent
|
||||
color: DefaultStyle.grey_200
|
||||
radius: Utils.getSizeWithScreenRatio(16)
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
mainItem.searchMessageByIdRequested(mainItem.replyMessageId)
|
||||
}
|
||||
}
|
||||
}
|
||||
contentItem: Text {
|
||||
Layout.fillWidth: true
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ ListView {
|
|||
signal editMessageRequested(ChatMessageGui chatMessage)
|
||||
signal requestHighlight(int indexToHighlight)
|
||||
signal requestAutoPlayVoiceRecording(int indexToPlay)
|
||||
signal searchMessageByIdRequested(string id)
|
||||
currentIndex: -1
|
||||
|
||||
property string filterText
|
||||
|
|
@ -45,6 +46,9 @@ ListView {
|
|||
searchForward = forward
|
||||
eventLogProxy.findIndexCorrespondingToFilter(currentIndex, searchForward, false)
|
||||
}
|
||||
onSearchMessageByIdRequested: (id) => {
|
||||
eventLogProxy.findChatMessageById(id)
|
||||
}
|
||||
|
||||
Button {
|
||||
visible: !mainItem.lastItemVisible
|
||||
|
|
@ -127,6 +131,13 @@ ListView {
|
|||
}
|
||||
}
|
||||
}
|
||||
onFoundMessagById: (index) => {
|
||||
if (index !== -1) {
|
||||
currentIndex = index
|
||||
mainItem.positionViewAtIndex(index, ListView.Center)
|
||||
mainItem.requestHighlight(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer: Item {
|
||||
|
|
@ -327,6 +338,7 @@ ListView {
|
|||
onShowReactionsForMessageRequested: mainItem.showReactionsForMessageRequested(chatMessage)
|
||||
onShowImdnStatusForMessageRequested: mainItem.showImdnStatusForMessageRequested(chatMessage)
|
||||
onReplyToMessageRequested: mainItem.replyToMessageRequested(chatMessage)
|
||||
onSearchMessageByIdRequested: (id) => mainItem.searchMessageByIdRequested(id)
|
||||
onForwardMessageRequested: mainItem.forwardMessageRequested(chatMessage)
|
||||
onEndOfVoiceRecordingReached: {
|
||||
if (nextChatMessage && nextChatMessage.core.isVoiceRecording) mainItem.requestAutoPlayVoiceRecording(index - 1)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue