fix scroll tu first unread index
This commit is contained in:
parent
f3a1b5de62
commit
5808368b9a
11 changed files with 73 additions and 23 deletions
|
|
@ -81,11 +81,13 @@ ChatCore::ChatCore(const std::shared_ptr<linphone::ChatRoom> &chatRoom) : QObjec
|
||||||
for (auto &eventLog : history) {
|
for (auto &eventLog : history) {
|
||||||
if (eventLog->getChatMessage()) lHistory.push_back(eventLog->getChatMessage());
|
if (eventLog->getChatMessage()) lHistory.push_back(eventLog->getChatMessage());
|
||||||
}
|
}
|
||||||
|
QList<QSharedPointer<ChatMessageCore>> messageList;
|
||||||
for (auto &message : lHistory) {
|
for (auto &message : lHistory) {
|
||||||
if (!message) continue;
|
if (!message) continue;
|
||||||
auto chatMessage = ChatMessageCore::create(message);
|
auto chatMessage = ChatMessageCore::create(message);
|
||||||
mChatMessageList.append(chatMessage);
|
messageList.append(chatMessage);
|
||||||
}
|
}
|
||||||
|
resetChatMessageList(messageList);
|
||||||
mIdentifier = Utils::coreStringToAppString(chatRoom->getIdentifier());
|
mIdentifier = Utils::coreStringToAppString(chatRoom->getIdentifier());
|
||||||
connect(this, &ChatCore::messageListChanged, this, &ChatCore::lUpdateLastMessage);
|
connect(this, &ChatCore::messageListChanged, this, &ChatCore::lUpdateLastMessage);
|
||||||
connect(this, &ChatCore::messagesInserted, this, &ChatCore::lUpdateLastMessage);
|
connect(this, &ChatCore::messagesInserted, this, &ChatCore::lUpdateLastMessage);
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ ChatMessageCore::ChatMessageCore(const std::shared_ptr<linphone::ChatMessage> &c
|
||||||
!chatroom->hasCapability((int)linphone::ChatRoom::Capabilities::OneToOne);
|
!chatroom->hasCapability((int)linphone::ChatRoom::Capabilities::OneToOne);
|
||||||
mIsRead = chatmessage->isRead();
|
mIsRead = chatmessage->isRead();
|
||||||
mMessageState = LinphoneEnums::fromLinphone(chatmessage->getState());
|
mMessageState = LinphoneEnums::fromLinphone(chatmessage->getState());
|
||||||
|
mMessageId = Utils::coreStringToAppString(chatmessage->getMessageId());
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatMessageCore::~ChatMessageCore() {
|
ChatMessageCore::~ChatMessageCore() {
|
||||||
|
|
@ -128,6 +129,9 @@ QString ChatMessageCore::getToAddress() const {
|
||||||
return mToAddress;
|
return mToAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString ChatMessageCore::getMessageId() const {
|
||||||
|
return mMessageId;
|
||||||
|
}
|
||||||
bool ChatMessageCore::isRemoteMessage() const {
|
bool ChatMessageCore::isRemoteMessage() const {
|
||||||
return mIsRemoteMessage;
|
return mIsRemoteMessage;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ public:
|
||||||
QString getFromAddress() const;
|
QString getFromAddress() const;
|
||||||
QString getFromName() const;
|
QString getFromName() const;
|
||||||
QString getToAddress() const;
|
QString getToAddress() const;
|
||||||
|
QString getMessageId() const;
|
||||||
|
|
||||||
bool isRemoteMessage() const;
|
bool isRemoteMessage() const;
|
||||||
bool isFromChatGroup() const;
|
bool isFromChatGroup() const;
|
||||||
|
|
@ -94,6 +95,7 @@ private:
|
||||||
QString mToAddress;
|
QString mToAddress;
|
||||||
QString mFromName;
|
QString mFromName;
|
||||||
QString mPeerName;
|
QString mPeerName;
|
||||||
|
QString mMessageId;
|
||||||
QDateTime mTimestamp;
|
QDateTime mTimestamp;
|
||||||
bool mIsRemoteMessage = false;
|
bool mIsRemoteMessage = false;
|
||||||
bool mIsFromChatGroup = false;
|
bool mIsFromChatGroup = false;
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,6 @@ ChatMessageList::createChatMessageCore(const std::shared_ptr<linphone::ChatMessa
|
||||||
ChatMessageList::ChatMessageList(QObject *parent) : ListProxy(parent) {
|
ChatMessageList::ChatMessageList(QObject *parent) : ListProxy(parent) {
|
||||||
mustBeInMainThread(getClassName());
|
mustBeInMainThread(getClassName());
|
||||||
App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||||
connect(this, &ChatMessageList::chatChanged, this, &ChatMessageList::lUpdate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatMessageList::~ChatMessageList() {
|
ChatMessageList::~ChatMessageList() {
|
||||||
|
|
@ -73,11 +72,22 @@ void ChatMessageList::setChatCore(QSharedPointer<ChatCore> core) {
|
||||||
if (mChatCore)
|
if (mChatCore)
|
||||||
connect(mChatCore.get(), &ChatCore::messagesInserted, this,
|
connect(mChatCore.get(), &ChatCore::messagesInserted, this,
|
||||||
[this](QList<QSharedPointer<ChatMessageCore>> list) {
|
[this](QList<QSharedPointer<ChatMessageCore>> list) {
|
||||||
|
auto chatList = getSharedList<ChatMessageCore>();
|
||||||
for (auto &message : list) {
|
for (auto &message : list) {
|
||||||
|
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);
|
add(message);
|
||||||
|
int index;
|
||||||
|
get(message.get(), &index);
|
||||||
|
emit messageInserted(index, new ChatMessageGui(message));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
emit chatChanged();
|
emit chatChanged();
|
||||||
|
lUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -86,6 +96,13 @@ void ChatMessageList::setChatGui(ChatGui *chat) {
|
||||||
setChatCore(chatCore);
|
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) {
|
void ChatMessageList::setSelf(QSharedPointer<ChatMessageList> me) {
|
||||||
mModelConnection = SafeConnection<ChatMessageList, CoreModel>::create(me, CoreModel::getInstance());
|
mModelConnection = SafeConnection<ChatMessageList, CoreModel>::create(me, CoreModel::getInstance());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,11 @@ public:
|
||||||
~ChatMessageList();
|
~ChatMessageList();
|
||||||
|
|
||||||
QSharedPointer<ChatCore> getChatCore() const;
|
QSharedPointer<ChatCore> getChatCore() const;
|
||||||
ChatGui* getChat() const;
|
ChatGui *getChat() const;
|
||||||
void setChatCore(QSharedPointer<ChatCore> core);
|
void setChatCore(QSharedPointer<ChatCore> core);
|
||||||
void setChatGui(ChatGui* chat);
|
void setChatGui(ChatGui *chat);
|
||||||
|
|
||||||
|
int findFirstUnreadIndex();
|
||||||
|
|
||||||
void setSelf(QSharedPointer<ChatMessageList> me);
|
void setSelf(QSharedPointer<ChatMessageList> me);
|
||||||
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
@ -52,6 +54,7 @@ signals:
|
||||||
void lUpdate();
|
void lUpdate();
|
||||||
void filterChanged(QString filter);
|
void filterChanged(QString filter);
|
||||||
void chatChanged();
|
void chatChanged();
|
||||||
|
void messageInserted(int index, ChatMessageGui *message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString mFilter;
|
QString mFilter;
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,16 @@ void ChatMessageProxy::setSourceModel(QAbstractItemModel *model) {
|
||||||
auto newChatMessageList = dynamic_cast<ChatMessageList *>(model);
|
auto newChatMessageList = dynamic_cast<ChatMessageList *>(model);
|
||||||
if (newChatMessageList) {
|
if (newChatMessageList) {
|
||||||
connect(newChatMessageList, &ChatMessageList::chatChanged, this, &ChatMessageProxy::chatChanged);
|
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));
|
setSourceModels(new SortFilterList(model));
|
||||||
sort(0);
|
sort(0);
|
||||||
|
|
@ -68,14 +78,20 @@ ChatMessageGui *ChatMessageProxy::getChatMessageAtIndex(int i) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int ChatMessageProxy::findFirstUnreadIndex() {
|
int ChatMessageProxy::findFirstUnreadIndex() {
|
||||||
int n = getCount();
|
auto chatMessageList = getListModel<ChatMessageList>();
|
||||||
for (int i = 0; i < n; ++i) {
|
if (chatMessageList) {
|
||||||
auto chat = getItemAt<SortFilterList, ChatMessageList, ChatMessageCore>(i);
|
auto listIndex = chatMessageList->findFirstUnreadIndex();
|
||||||
if (chat && !chat->isRead()) {
|
if (listIndex != -1) {
|
||||||
return i;
|
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 {
|
bool ChatMessageProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ public:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void chatChanged();
|
void chatChanged();
|
||||||
|
void messageInserted(int index, ChatMessageGui *message);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QSharedPointer<ChatMessageList> mList;
|
QSharedPointer<ChatMessageList> mList;
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,10 @@ QString ChatMessageModel::getToAddress() const {
|
||||||
return Utils::coreStringToAppString(mMonitor->getToAddress()->asStringUriOnly());
|
return Utils::coreStringToAppString(mMonitor->getToAddress()->asStringUriOnly());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString ChatMessageModel::getMessageId() const {
|
||||||
|
return Utils::coreStringToAppString(mMonitor->getMessageId());
|
||||||
|
}
|
||||||
|
|
||||||
QDateTime ChatMessageModel::getTimestamp() const {
|
QDateTime ChatMessageModel::getTimestamp() const {
|
||||||
return QDateTime::fromSecsSinceEpoch(mMonitor->getTime());
|
return QDateTime::fromSecsSinceEpoch(mMonitor->getTime());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ public:
|
||||||
QString getPeerAddress() const;
|
QString getPeerAddress() const;
|
||||||
QString getFromAddress() const;
|
QString getFromAddress() const;
|
||||||
QString getToAddress() const;
|
QString getToAddress() const;
|
||||||
|
QString getMessageId() const;
|
||||||
|
|
||||||
bool isRead() const;
|
bool isRead() const;
|
||||||
void markAsRead();
|
void markAsRead();
|
||||||
|
|
|
||||||
|
|
@ -10,15 +10,9 @@ import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
id: mainItem
|
id: mainItem
|
||||||
|
spacing: Math.round(4 * DefaultStyle.dp)
|
||||||
property ChatGui chat
|
property ChatGui chat
|
||||||
property color backgroundColor
|
property color backgroundColor
|
||||||
spacing: Math.round(4 * DefaultStyle.dp)
|
|
||||||
|
|
||||||
onChatChanged: {
|
|
||||||
var index = chatMessageProxy.findFirstUnreadIndex()
|
|
||||||
positionViewAtIndex(index, ListView.End)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
var index = chatMessageProxy.findFirstUnreadIndex()
|
var index = chatMessageProxy.findFirstUnreadIndex()
|
||||||
|
|
@ -56,6 +50,12 @@ ListView {
|
||||||
model: ChatMessageProxy {
|
model: ChatMessageProxy {
|
||||||
id: chatMessageProxy
|
id: chatMessageProxy
|
||||||
chatGui: mainItem.chat
|
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 {
|
header: Item {
|
||||||
|
|
@ -65,7 +65,6 @@ ListView {
|
||||||
delegate: ChatMessage {
|
delegate: ChatMessage {
|
||||||
chatMessage: modelData
|
chatMessage: modelData
|
||||||
property real maxWidth: Math.round(mainItem.width * (3/4))
|
property real maxWidth: Math.round(mainItem.width * (3/4))
|
||||||
// height: childrenRect.height
|
|
||||||
onVisibleChanged: if (!modelData.core.isRead) modelData.core.lMarkAsRead()
|
onVisibleChanged: if (!modelData.core.isRead) modelData.core.lMarkAsRead()
|
||||||
width: mainItem.width
|
width: mainItem.width
|
||||||
property var previousIndex: index - 1
|
property var previousIndex: index - 1
|
||||||
|
|
|
||||||
|
|
@ -157,6 +157,7 @@ RowLayout {
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onPressed: sendingTextArea.forceActiveFocus()
|
onPressed: sendingTextArea.forceActiveFocus()
|
||||||
|
cursorShape: Qt.IBeamCursor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
contentItem: RowLayout {
|
contentItem: RowLayout {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue