@ -12,6 +12,7 @@
# include <QPixmap>
# include <QDateTime>
# include <QFile>
# include <QScrollBar>
# include <QApplication>
# include <QDebug>
# include <vector>
@ -163,6 +164,13 @@ MessageList::MessageList(DbManager* db, QWidget *parent)
if ( ! wasActive & & m_animHoverActive ) AnimTimer : : instance ( ) - > activate ( ) ;
else if ( wasActive & & ! m_animHoverActive ) AnimTimer : : instance ( ) - > deactivate ( ) ;
} ) ;
m_readDebounce = new QTimer ( this ) ;
m_readDebounce - > setSingleShot ( true ) ;
m_readDebounce - > setInterval ( 300 ) ;
connect ( m_readDebounce , & QTimer : : timeout , this , & MessageList : : updateReadPosition ) ;
connect ( m_view - > verticalScrollBar ( ) , & QScrollBar : : valueChanged ,
m_readDebounce , QOverload < > : : of ( & QTimer : : start ) ) ;
}
void MessageList : : loadChannel ( const QString & channelId ) {
@ -175,6 +183,9 @@ void MessageList::loadChannel(const QString& channelId) {
m_model - > clear ( ) ;
m_avatarCache . clear ( ) ;
m_currentChannelId = channelId ;
m_readDebounce - > stop ( ) ;
m_lastReadMsgId = m_db - > getUiStateInt64 (
QStringLiteral ( " ch_%1_last_read " ) . arg ( channelId ) , 0 ) ;
if ( ! m_db | | ! m_db - > isOpen ( ) ) return ;
auto msgs = m_db - > getMessages ( channelId , 100 ) ;
@ -247,18 +258,12 @@ void MessageList::saveChannelState() {
int vpHeight = m_view - > viewport ( ) - > height ( ) ;
QModelIndex topIdx = m_view - > indexAt ( QPoint ( 0 , 0 ) ) ;
QModelIndex bottomIdx = m_view - > indexAt ( QPoint ( 0 , vpHeight - 1 ) ) ;
qint64 lastReadMsgId = 0 ;
qint64 lastPosMsgId = 0 ;
if ( topIdx . isValid ( ) )
lastPosMsgId = topIdx . data ( MsgIdRole ) . toLongLong ( ) ;
if ( bottomIdx . isValid ( ) )
lastReadMsgId = bottomIdx . data ( MsgIdRole ) . toLongLong ( ) ;
else if ( m_model - > rowCount ( ) > 0 )
lastReadMsgId = m_model - > item ( m_model - > rowCount ( ) - 1 ) - > data ( MsgIdRole ) . toLongLong ( ) ;
qint64 lastReadMsgId = m_lastReadMsgId ;
if ( lastReadMsgId = = 0 & & lastPosMsgId = = 0 ) return ;
QByteArray cid = m_currentChannelId . toUtf8 ( ) ;
@ -298,3 +303,44 @@ void MessageList::restoreScrollPosition(const QString& channelId) {
m_view - > scrollToBottom ( ) ;
}
void MessageList : : updateReadPosition ( ) {
if ( m_currentChannelId . isEmpty ( ) | | m_model - > rowCount ( ) = = 0 ) return ;
int vpHeight = m_view - > viewport ( ) - > height ( ) ;
int lastFullyVisibleRow = - 1 ;
qint64 newReadMsgId = m_lastReadMsgId ;
for ( int row = m_model - > rowCount ( ) - 1 ; row > = 0 ; - - row ) {
QModelIndex idx = m_model - > index ( row , 0 ) ;
QRect vr = m_view - > visualRect ( idx ) ;
if ( vr . isValid ( ) & & vr . bottom ( ) < = vpHeight ) {
lastFullyVisibleRow = row ;
break ;
}
}
if ( lastFullyVisibleRow > = 0 ) {
qint64 msgId = m_model - > item ( lastFullyVisibleRow ) - > data ( MsgIdRole ) . toLongLong ( ) ;
if ( msgId > m_lastReadMsgId )
newReadMsgId = msgId ;
}
if ( newReadMsgId > m_lastReadMsgId ) {
m_lastReadMsgId = newReadMsgId ;
QByteArray cid = m_currentChannelId . toUtf8 ( ) ;
QByteArray key = " ch_ " + cid + " _last_read " ;
QByteArray valStr = QByteArray : : number ( m_lastReadMsgId ) ;
size_t klen = key . size ( ) , vlen = valStr . size ( ) ;
size_t total = klen + 1 + vlen + 1 ;
if ( total < = 256 ) {
void * arg = u_malloc ( total ) ;
memcpy ( arg , key . constData ( ) , klen + 1 ) ;
memcpy ( ( char * ) arg + klen + 1 , valStr . constData ( ) , vlen + 1 ) ;
gui_bridge_post_uasync_fn ( chat_core_save_ui_state_trampoline , arg ) ;
}
emit readPositionChanged ( m_currentChannelId , m_lastReadMsgId ) ;
}
}