fix chat message research #LINQT-2047

try to fix persistent spinner on chat message state icon

remove medias section from contact page #LINQT-2060 #LINQT-2066
This commit is contained in:
Gaelle Braud 2025-10-13 17:03:46 +02:00
parent 82679ab997
commit 1f97112306
9 changed files with 119 additions and 47 deletions

View file

@ -267,7 +267,6 @@ void ChatMessageCore::setSelf(QSharedPointer<ChatMessageCore> me) {
mChatMessageModelConnection->makeConnectToModel(
&ChatMessageModel::msgStateChanged,
[this](const std::shared_ptr<linphone::ChatMessage> &message, linphone::ChatMessage::State state) {
if (mChatMessageModel->getMonitor() != message) return;
auto imdnStatusList = computeDeliveryStatus(message);
auto msgState = LinphoneEnums::fromLinphone(state);
mChatMessageModelConnection->invokeToCore([this, msgState, imdnStatusList] {

View file

@ -161,7 +161,7 @@ void EventLogList::displayMore() {
auto model = EventLogCore::create(it);
events->push_back(model);
}
mCoreModelConnection->invokeToCore([this, events, newCount] {
mCoreModelConnection->invokeToCore([this, events] {
int currentCount = mList.count();
for (auto it = events->end() - 1; it >= events->begin(); --it) {
connectItem(*it);
@ -171,6 +171,35 @@ void EventLogList::displayMore() {
});
}
void EventLogList::loadMessagesUpTo(std::shared_ptr<linphone::EventLog> event) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
auto oldestEventLoaded = getAt<EventLogCore>(0);
auto linOldest = std::const_pointer_cast<linphone::EventLog>(oldestEventLoaded->getModel()->getEventLog());
auto chatModel = mChatCore->getModel();
assert(chatModel);
if (!chatModel) 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);
auto linphoneLogs = chatModel->getHistoryRangeBetween(event, linOldest, filters);
QList<QSharedPointer<EventLogCore>> *events = new QList<QSharedPointer<EventLogCore>>();
for (auto it : beforeEvents) {
auto model = EventLogCore::create(it);
events->push_back(model);
}
for (auto it : linphoneLogs) {
auto model = EventLogCore::create(it);
events->push_back(model);
}
mCoreModelConnection->invokeToCore([this, events, event] {
for (auto &e : *events) {
connectItem(e);
add(e);
}
emit messagesLoadedUpTo(event);
});
}
int EventLogList::findFirstUnreadIndex() {
auto eventList = getSharedList<EventLogCore>();
auto it = std::find_if(eventList.begin(), eventList.end(), [](const QSharedPointer<EventLogCore> item) {
@ -184,31 +213,47 @@ void EventLogList::findChatMessageWithFilter(QString filter,
bool forward,
bool isFirstResearch) {
if (mChatCore) {
auto modelConnection = mChatCore->getChatModelConnection();
if (isFirstResearch) mLastFoundResult.reset();
auto chatModel = mChatCore->getModel();
auto startEventModel = startEvent ? startEvent->getModel() : nullptr;
modelConnection->invokeToModel(
[this, chatModel, startEventModel, filter, forward, modelConnection, isFirstResearch] {
auto linStartEvent = startEventModel ? startEventModel->getEventLog() : nullptr;
auto eventLog = chatModel->searchMessageByText(filter, linStartEvent, forward);
// If it is the first research and event was not found from the start event, search in the
// entire history
if (!eventLog && isFirstResearch) {
auto firstEvent = getAt<EventLogCore>(0);
auto linFirst = firstEvent ? firstEvent->getModel()->getEventLog() : nullptr;
eventLog = chatModel->searchMessageByText(filter, nullptr, forward);
}
int index = -1;
if (eventLog) {
auto eventList = getSharedList<EventLogCore>();
auto it = std::find_if(eventList.begin(), eventList.end(),
[eventLog](const QSharedPointer<EventLogCore> item) {
return item->getModel()->getEventLog() == eventLog;
});
index = it == eventList.end() ? -1 : std::distance(eventList.begin(), it);
}
modelConnection->invokeToCore([this, index] { emit messageWithFilterFound(index); });
});
mCoreModelConnection->invokeToModel([this, chatModel, startEventModel, filter, forward, isFirstResearch] {
auto linStartEvent = startEventModel ? startEventModel->getEventLog() : nullptr;
auto eventLog = chatModel->searchMessageByText(filter, linStartEvent, forward);
if (!eventLog)
// event not found, search in the entire history
auto eventLog = chatModel->searchMessageByText(filter, nullptr, forward);
int index = -1;
if (eventLog) {
auto eventList = getSharedList<EventLogCore>();
auto it = std::find_if(eventList.begin(), eventList.end(),
[eventLog](const QSharedPointer<EventLogCore> item) {
return item->getModel()->getEventLog() == eventLog;
});
if (it != eventList.end()) {
int index = std::distance(eventList.begin(), it);
if (mLastFoundResult && mLastFoundResult == *it) index = -1;
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); });
});
loadMessagesUpTo(eventLog);
}
} else {
mCoreModelConnection->invokeToCore([this, index] { emit messageWithFilterFound(index); });
}
});
}
}
@ -217,7 +262,6 @@ void EventLogList::setSelf(QSharedPointer<EventLogList> me) {
mCoreModelConnection->makeConnectToCore(&EventLogList::lUpdate, [this]() {
mustBeInMainThread(log().arg(Q_FUNC_INFO));
if (mChatCore) qDebug() << "reset messages model for chat core" << mChatCore << mChatCore->getTitle();
setIsUpdating(true);
beginResetModel();
mList.clear();
@ -234,7 +278,6 @@ void EventLogList::setSelf(QSharedPointer<EventLogList> me) {
}
mCoreModelConnection->invokeToModel([this, chatModel]() {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
qDebug() << "update history till" << mDisplayItemsStep;
auto linphoneLogs = chatModel->getHistoryRange(0, mDisplayItemsStep);
QList<QSharedPointer<EventLogCore>> *events = new QList<QSharedPointer<EventLogCore>>();
for (auto it : linphoneLogs) {
@ -251,9 +294,8 @@ void EventLogList::setSelf(QSharedPointer<EventLogList> me) {
}
for (auto &event : *events) {
connectItem(event);
mList.append(event);
}
for (auto i : *events)
mList << i.template objectCast<QObject>();
endResetModel();
setIsUpdating(false);
});

View file

@ -50,6 +50,10 @@ public:
void setIsUpdating(bool updating);
void loadMessagesUpTo(std::shared_ptr<linphone::EventLog> event);
void setLastFoundResult(const QSharedPointer<EventLogCore> &eventLog);
int findFirstUnreadIndex();
void displayMore();
@ -73,6 +77,7 @@ signals:
void chatGuiChanged();
void isUpdatingChanged();
void displayItemsStepChanged();
void messagesLoadedUpTo(std::shared_ptr<linphone::EventLog> event);
private:
QString mFilter;
@ -81,6 +86,8 @@ private:
QSharedPointer<SafeConnection<EventLogList, CoreModel>> mCoreModelConnection;
bool mIsUpdating = false;
int mDisplayItemsStep = 0;
int mItemsToLoadBeforeSearchResult = 3;
QSharedPointer<EventLogCore> mLastFoundResult;
DECLARE_ABSTRACT_OBJECT
};

View file

@ -48,29 +48,31 @@ void EventLogProxy::setSourceModel(QAbstractItemModel *model) {
connect(newEventLogList, &EventLogList::eventInserted, this,
[this, newEventLogList](int index, EventLogGui *event) {
invalidate();
int proxyIndex = -1;
if (index != -1) {
index = dynamic_cast<SortFilterList *>(sourceModel())
->mapFromSource(newEventLogList->index(index, 0))
.row();
if (mMaxDisplayItems <= index) setMaxDisplayItems(index + mDisplayItemsStep);
proxyIndex = dynamic_cast<SortFilterList *>(sourceModel())
->mapFromSource(newEventLogList->index(index, 0))
.row();
}
loadUntil(index);
emit eventInserted(index, event);
loadUntil(proxyIndex);
emit eventInserted(proxyIndex, event);
});
connect(newEventLogList, &EventLogList::messageWithFilterFound, this, [this, newEventLogList](int index) {
if (index != -1) {
connect(newEventLogList, &EventLogList::messageWithFilterFound, this, [this, newEventLogList](int i) {
connect(this, &EventLogProxy::layoutChanged, newEventLogList, [this, i, newEventLogList] {
disconnect(this, &EventLogProxy::layoutChanged, newEventLogList, nullptr);
auto model = getListModel<EventLogList>();
mLastSearchStart = model->getAt<EventLogCore>(index);
index = dynamic_cast<SortFilterList *>(sourceModel())
->mapFromSource(newEventLogList->index(index, 0))
.row();
loadUntil(index);
}
emit indexWithFilterFound(index);
int proxyIndex =
dynamic_cast<SortFilterList *>(sourceModel())->mapFromSource(newEventLogList->index(i, 0)).row();
if (i != -1) {
loadUntil(proxyIndex);
}
emit indexWithFilterFound(proxyIndex);
});
invalidate();
});
}
setSourceModels(new SortFilterList(model, Qt::DescendingOrder));
sort(0);
sort(0, Qt::DescendingOrder);
}
ChatGui *EventLogProxy::getChatGui() {
@ -144,5 +146,8 @@ bool EventLogProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModel
}
bool EventLogProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const {
auto l = getItemAtSource<EventLogList, EventLogCore>(sourceLeft.row());
auto r = getItemAtSource<EventLogList, EventLogCore>(sourceRight.row());
if (l && r) return l->getTimestamp() <= r->getTimestamp();
return true;
}

View file

@ -68,6 +68,18 @@ std::list<std::shared_ptr<linphone::EventLog>> ChatModel::getHistoryRange(int be
return mMonitor->getHistoryRangeEvents(begin, end);
}
std::list<std::shared_ptr<linphone::EventLog>>
ChatModel::getHistoryRangeBetween(const std::shared_ptr<linphone::EventLog> firstEvent,
const std::shared_ptr<linphone::EventLog> lastEvent,
int filters) {
return mMonitor->getHistoryRangeBetween(firstEvent, lastEvent, filters);
}
std::list<std::shared_ptr<linphone::EventLog>>
ChatModel::getHistoryRangeNear(int before, int after, const std::shared_ptr<linphone::EventLog> event, int filters) {
return mMonitor->getHistoryRangeNear(before, after, event, filters);
}
std::list<std::shared_ptr<linphone::ChatMessage>> ChatModel::getChatMessageHistory() const {
auto history = mMonitor->getHistory(0, (int)linphone::ChatRoom::HistoryFilter::ChatMessage);
std::list<std::shared_ptr<linphone::ChatMessage>> res;

View file

@ -50,6 +50,12 @@ public:
std::list<std::shared_ptr<linphone::Content>> getSharedDocuments() const;
std::list<std::shared_ptr<linphone::EventLog>> getHistory() const;
std::list<std::shared_ptr<linphone::EventLog>> getHistoryRange(int begin, int end);
std::list<std::shared_ptr<linphone::EventLog>>
getHistoryRangeBetween(const std::shared_ptr<linphone::EventLog> firstEvent,
const std::shared_ptr<linphone::EventLog> lastEvent,
int filters);
std::list<std::shared_ptr<linphone::EventLog>>
getHistoryRangeNear(int before, int after, const std::shared_ptr<linphone::EventLog> firstEvent, int filters);
std::list<std::shared_ptr<linphone::ChatMessage>> getChatMessageHistory() const;
int getHistorySizeEvents();
QString getIdentifier() const;

View file

@ -299,6 +299,7 @@ Control.Control {
}
}
EffectImage {
// Imdn status icon
visible: !mainItem.isRemoteMessage
Layout.preferredWidth: visible ? 14 * DefaultStyle.dp : 0
Layout.preferredHeight: visible ? 14 * DefaultStyle.dp : 0

View file

@ -72,7 +72,7 @@ Item {
color: DefaultStyle.main1_200
opacity: 0.5
Image {
anchors.fill: image
anchors.fill: parent
z: parent.z + 1
visible: image.status == Image.Error || image.status == Image.Null || !UtilsCpp.fileExists(mainItem.filePath)
source: AppIcons.fileImage

View file

@ -606,7 +606,7 @@ FriendGui{
}
}
ContactDetailLayout {
visible: !SettingsCpp.disableChatFeature
visible: false//!SettingsCpp.disableChatFeature
//: "Medias"
label: qsTr("contact_details_medias_title")
Layout.fillWidth: true