Smoother chat loading and simplify async loaders algo.

Display a busy indicator at conversation init and display content bubble only when loader is load (to avoid empty lines with header).
This commit is contained in:
Julien Wadel 2023-06-07 17:02:45 +02:00
parent 7001386fb6
commit 513476706a
3 changed files with 37 additions and 17 deletions

View file

@ -199,7 +199,7 @@ public:
bool mDeleteChatRoom = false; // Use as workaround because of core->deleteChatRoom() that call destructor without takking account of count ref : call it in ChatRoomModel destructor
int mLastEntriesStep = 50; // Retrieve a part of the history to avoid too much processing
int mFirstLastEntriesStep = 10; // Retrieve a part of the history to avoid too much processing at the init
int mFirstLastEntriesStep = 20; // Retrieve a part of the history to avoid too much processing at the init
bool mMarkAsReadEnabled = true;
bool mEntriesLoading = false;

View file

@ -30,10 +30,6 @@
function initView () {
chat.bindToEnd = true
if(chat.atYBeginning && !chat.loadingEntries){//Check if we are at beginning
chat.displaying = true
container.proxyModel.loadMoreEntriesAsync()
}
chat.positionViewAtEnd()
}

View file

@ -67,8 +67,10 @@ Rectangle {
// Load optimizations
property int remainingLoadersCount: 0
property int syncLoaderBatch: 50 // batch of simultaneous loaders on synchronous mode
property int syncLoaderBatch: 20 // batch of simultaneous loaders on synchronous mode
//------------------------------------
signal refreshContents()
onLoadingEntriesChanged: {
if( loadingEntries && !displaying)
@ -84,6 +86,13 @@ Rectangle {
running: false
onTriggered: if(container.proxyModel.chatRoomModel) container.proxyModel.chatRoomModel.resetMessageCount()
}
Timer{
id: refreshContentsTimer
interval: 200
repeat: true
running: false
onTriggered: chat.refreshContents()
}
Layout.fillHeight: true
Layout.fillWidth: true
@ -93,11 +102,15 @@ Rectangle {
onIsMovingChanged:{
if(!chat.isMoving && chat.atYBeginning && !chat.loadingEntries){// Moving has stopped. Check if we are at beginning
chat.displaying = true
container.proxyModel.loadMoreEntriesAsync()
console.log("Trying to load more entries")
Qt.callLater(container.proxyModel.loadMoreEntriesAsync())
}
}
// -----------------------------------------------------------------------
Component.onCompleted: Logic.initView()
Component.onCompleted: {
Logic.initView()
refreshContentsTimer.start()
}
onMovementStarted: {Logic.handleMovementStarted(); chat.isMoving = true}
onMovementEnded: {Logic.handleMovementEnded(); chat.isMoving = false}
@ -156,6 +169,7 @@ Rectangle {
width: chat.contentWidth // Fill all space
clip: false
visible: loader.status == Loader.Ready
// ---------------------------------------------------------------------
MouseArea {
id: mouseArea
@ -228,23 +242,33 @@ Rectangle {
height: (item !== null && typeof(item)!== 'undefined')? item.height: 0
Layout.fillWidth: true
source: Logic.getComponentFromEntry(entry.chatEntry)
property int loaderIndex: 0 // index of loader from remaining loaders
property int remainingIndex : loaderIndex % ((chat.remainingLoadersCount) / chat.syncLoaderBatch) != 0 // Check loader index to remaining loader.
onRemainingIndexChanged: if( remainingIndex == 0 && asynchronous) asynchronous = false
asynchronous: true
z:1
asynchronous: true
property int loaderIndex: 0
function updateSync(){
if( asynchronous && loaderIndex > 0 && chat.remainingLoadersCount - loaderIndex - chat.syncLoaderBatch <= 0 ) asynchronous = false// Sync load the end
}
function stopLoading(){
chatConnections.enabled = false // No more update is needed : ignore signals.
--chat.remainingLoadersCount // Loader is ready: remove one from remaining count.
}
onStatusChanged: if( status == Loader.Ready) {
loader.item.isTopGrouped = entry.isTopGrouped
loader.item.isBottomGrouped = entry.isBottomGrouped
remainingIndex = -1 // overwrite to remove signal changed. That way, there is no more binding loops.
--chat.remainingLoadersCount // Loader is ready: remove one from remaining count.
stopLoading();
}else if( status == Loader.Error) {
stopLoading();
}
Component.onCompleted: {
loaderIndex = ++chat.remainingLoadersCount // on new Loader : one more remaining
}
Component.onDestruction: if( status != Loader.Ready) --chat.remainingLoadersCount // Remove remaining count if not loaded
Component.onDestruction: if( status != Loader.Ready && status != Loader.Error) {stopLoading();} // Remove remaining count if not loaded
Connections{
id: chatConnections
target: chat
onRefreshContents:loader.updateSync()
}
}
Connections{