fix scroll tu first unread index

This commit is contained in:
Gaelle Braud 2025-05-15 11:35:52 +02:00
parent f3a1b5de62
commit 5808368b9a
11 changed files with 73 additions and 23 deletions

View file

@ -81,11 +81,13 @@ ChatCore::ChatCore(const std::shared_ptr<linphone::ChatRoom> &chatRoom) : QObjec
for (auto &eventLog : history) {
if (eventLog->getChatMessage()) lHistory.push_back(eventLog->getChatMessage());
}
QList<QSharedPointer<ChatMessageCore>> messageList;
for (auto &message : lHistory) {
if (!message) continue;
auto chatMessage = ChatMessageCore::create(message);
mChatMessageList.append(chatMessage);
messageList.append(chatMessage);
}
resetChatMessageList(messageList);
mIdentifier = Utils::coreStringToAppString(chatRoom->getIdentifier());
connect(this, &ChatCore::messageListChanged, this, &ChatCore::lUpdateLastMessage);
connect(this, &ChatCore::messagesInserted, this, &ChatCore::lUpdateLastMessage);
@ -108,8 +110,8 @@ void ChatCore::setSelf(QSharedPointer<ChatCore> me) {
clearMessagesList();
//: Deleted
Utils::showInformationPopup(tr("info_toast_deleted_title"),
//: Message history has been deleted
tr("info_toast_deleted_message_history"), true);
//: Message history has been deleted
tr("info_toast_deleted_message_history"), true);
});
});
mChatModelConnection->makeConnectToCore(&ChatCore::lUpdateUnreadCount, [this]() {

View file

@ -55,6 +55,7 @@ ChatMessageCore::ChatMessageCore(const std::shared_ptr<linphone::ChatMessage> &c
!chatroom->hasCapability((int)linphone::ChatRoom::Capabilities::OneToOne);
mIsRead = chatmessage->isRead();
mMessageState = LinphoneEnums::fromLinphone(chatmessage->getState());
mMessageId = Utils::coreStringToAppString(chatmessage->getMessageId());
}
ChatMessageCore::~ChatMessageCore() {
@ -68,8 +69,8 @@ void ChatMessageCore::setSelf(QSharedPointer<ChatMessageCore> me) {
mChatMessageModelConnection->makeConnectToModel(&ChatMessageModel::messageDeleted, [this]() {
//: Deleted
Utils::showInformationPopup(tr("info_toast_deleted_title"),
//: The message has been deleted
tr("info_toast_deleted_message"), true);
//: The message has been deleted
tr("info_toast_deleted_message"), true);
emit deleted();
});
mChatMessageModelConnection->makeConnectToCore(&ChatMessageCore::lMarkAsRead, [this] {
@ -128,6 +129,9 @@ QString ChatMessageCore::getToAddress() const {
return mToAddress;
}
QString ChatMessageCore::getMessageId() const {
return mMessageId;
}
bool ChatMessageCore::isRemoteMessage() const {
return mIsRemoteMessage;
}

View file

@ -63,6 +63,7 @@ public:
QString getFromAddress() const;
QString getFromName() const;
QString getToAddress() const;
QString getMessageId() const;
bool isRemoteMessage() const;
bool isFromChatGroup() const;
@ -94,6 +95,7 @@ private:
QString mToAddress;
QString mFromName;
QString mPeerName;
QString mMessageId;
QDateTime mTimestamp;
bool mIsRemoteMessage = false;
bool mIsFromChatGroup = false;

View file

@ -48,7 +48,6 @@ ChatMessageList::createChatMessageCore(const std::shared_ptr<linphone::ChatMessa
ChatMessageList::ChatMessageList(QObject *parent) : ListProxy(parent) {
mustBeInMainThread(getClassName());
App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
connect(this, &ChatMessageList::chatChanged, this, &ChatMessageList::lUpdate);
}
ChatMessageList::~ChatMessageList() {
@ -73,11 +72,22 @@ void ChatMessageList::setChatCore(QSharedPointer<ChatCore> core) {
if (mChatCore)
connect(mChatCore.get(), &ChatCore::messagesInserted, this,
[this](QList<QSharedPointer<ChatMessageCore>> list) {
auto chatList = getSharedList<ChatMessageCore>();
for (auto &message : list) {
add(message);
auto it = std::find_if(chatList.begin(), chatList.end(),
[message](const QSharedPointer<ChatMessageCore> item) {
return item->getMessageId() == message->getMessageId();
});
if (it == chatList.end()) {
add(message);
int index;
get(message.get(), &index);
emit messageInserted(index, new ChatMessageGui(message));
}
}
});
emit chatChanged();
lUpdate();
}
}
@ -86,6 +96,13 @@ void ChatMessageList::setChatGui(ChatGui *chat) {
setChatCore(chatCore);
}
int ChatMessageList::findFirstUnreadIndex() {
auto chatList = getSharedList<ChatMessageCore>();
auto it = std::find_if(chatList.begin(), chatList.end(),
[](const QSharedPointer<ChatMessageCore> item) { return !item->isRead(); });
return it == chatList.end() ? -1 : std::distance(chatList.begin(), it);
}
void ChatMessageList::setSelf(QSharedPointer<ChatMessageList> me) {
mModelConnection = SafeConnection<ChatMessageList, CoreModel>::create(me, CoreModel::getInstance());

View file

@ -42,9 +42,11 @@ public:
~ChatMessageList();
QSharedPointer<ChatCore> getChatCore() const;
ChatGui* getChat() const;
ChatGui *getChat() const;
void setChatCore(QSharedPointer<ChatCore> core);
void setChatGui(ChatGui* chat);
void setChatGui(ChatGui *chat);
int findFirstUnreadIndex();
void setSelf(QSharedPointer<ChatMessageList> me);
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
@ -52,6 +54,7 @@ signals:
void lUpdate();
void filterChanged(QString filter);
void chatChanged();
void messageInserted(int index, ChatMessageGui *message);
private:
QString mFilter;

View file

@ -41,6 +41,16 @@ void ChatMessageProxy::setSourceModel(QAbstractItemModel *model) {
auto newChatMessageList = dynamic_cast<ChatMessageList *>(model);
if (newChatMessageList) {
connect(newChatMessageList, &ChatMessageList::chatChanged, this, &ChatMessageProxy::chatChanged);
connect(newChatMessageList, &ChatMessageList::messageInserted, this,
[this, newChatMessageList](int index, ChatMessageGui *message) {
if (index != -1) {
index = dynamic_cast<SortFilterList *>(sourceModel())
->mapFromSource(newChatMessageList->index(index, 0))
.row();
if (mMaxDisplayItems <= index) setMaxDisplayItems(index + mDisplayItemsStep);
}
emit messageInserted(index, message);
});
}
setSourceModels(new SortFilterList(model));
sort(0);
@ -68,14 +78,20 @@ ChatMessageGui *ChatMessageProxy::getChatMessageAtIndex(int i) {
}
int ChatMessageProxy::findFirstUnreadIndex() {
int n = getCount();
for (int i = 0; i < n; ++i) {
auto chat = getItemAt<SortFilterList, ChatMessageList, ChatMessageCore>(i);
if (chat && !chat->isRead()) {
return i;
auto chatMessageList = getListModel<ChatMessageList>();
if (chatMessageList) {
auto listIndex = chatMessageList->findFirstUnreadIndex();
if (listIndex != -1) {
listIndex = dynamic_cast<SortFilterList *>(sourceModel())
->mapFromSource(chatMessageList->index(listIndex, 0))
.row();
if (mMaxDisplayItems <= listIndex) setMaxDisplayItems(listIndex + mDisplayItemsStep);
return listIndex;
} else {
return std::max(0, getCount() - 1);
}
}
return std::max(0, n - 1);
return std::max(0, getCount() - 1);
}
bool ChatMessageProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {

View file

@ -49,6 +49,7 @@ public:
signals:
void chatChanged();
void messageInserted(int index, ChatMessageGui *message);
protected:
QSharedPointer<ChatMessageList> mList;

View file

@ -56,6 +56,10 @@ QString ChatMessageModel::getToAddress() const {
return Utils::coreStringToAppString(mMonitor->getToAddress()->asStringUriOnly());
}
QString ChatMessageModel::getMessageId() const {
return Utils::coreStringToAppString(mMonitor->getMessageId());
}
QDateTime ChatMessageModel::getTimestamp() const {
return QDateTime::fromSecsSinceEpoch(mMonitor->getTime());
}

View file

@ -43,6 +43,7 @@ public:
QString getPeerAddress() const;
QString getFromAddress() const;
QString getToAddress() const;
QString getMessageId() const;
bool isRead() const;
void markAsRead();

View file

@ -10,15 +10,9 @@ import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
ListView {
id: mainItem
spacing: Math.round(4 * DefaultStyle.dp)
property ChatGui chat
property color backgroundColor
spacing: Math.round(4 * DefaultStyle.dp)
onChatChanged: {
var index = chatMessageProxy.findFirstUnreadIndex()
positionViewAtIndex(index, ListView.End)
}
Component.onCompleted: {
var index = chatMessageProxy.findFirstUnreadIndex()
@ -56,6 +50,12 @@ ListView {
model: ChatMessageProxy {
id: chatMessageProxy
chatGui: mainItem.chat
// scroll when in view and message inserted
onMessageInserted: (index, gui) => {
if (!mainItem.visible) return
mainItem.positionViewAtIndex(index, ListView.End)
if (!gui.core.isRead) gui.core.lMarkAsRead()
}
}
header: Item {
@ -65,7 +65,6 @@ ListView {
delegate: ChatMessage {
chatMessage: modelData
property real maxWidth: Math.round(mainItem.width * (3/4))
// height: childrenRect.height
onVisibleChanged: if (!modelData.core.isRead) modelData.core.lMarkAsRead()
width: mainItem.width
property var previousIndex: index - 1

View file

@ -157,6 +157,7 @@ RowLayout {
MouseArea {
anchors.fill: parent
onPressed: sendingTextArea.forceActiveFocus()
cursorShape: Qt.IBeamCursor
}
}
contentItem: RowLayout {