Commit f55f8044 authored by armin's avatar armin
Browse files

faster insertion of channels into view

parent 5a15fd3b
......@@ -58,8 +58,9 @@ QVariant ChannelModel::data( const QModelIndex &index, int role ) const
if ( message->getMessageType() == QStringLiteral( "file" ) || message->getMessageType() == QStringLiteral( "image" ) || message->getMessageType() == QStringLiteral( "audio" ) ) {
return tr( QByteArrayLiteral( "file upload" ) );
}
auto messageText =message->getMessageString();
messageText = messageText.replace("<img height='20' width='20'","<img height='10' width='10'");
auto messageText = message->getMessageString();
messageText = messageText.replace( "<img height='20' width='20'", "<img height='10' width='10'" );
return messageText;
}
......@@ -147,13 +148,15 @@ bool ChannelModel::addChannel( const QSharedPointer<RocketChatChannel> &channel
connect( channel.data(), &RocketChatChannel::unreadMessagesChanged, this, &ChannelModel::onUnreadMessageChanged, Qt::UniqueConnection );
connect( channel.data(), &RocketChatChannel::dataChanged, this, &ChannelModel::onDataChanged, Qt::UniqueConnection );
connect( channel.data(), &RocketChatChannel::channelDeleted, this, &ChannelModel::onDeleted, Qt::UniqueConnection );
connect(channel.data(), &RocketChatChannel::updatedChanged, this, &ChannelModel::onChannelOrderChanged);
connect( channel.data(), &RocketChatChannel::updatedChanged, this, &ChannelModel::onChannelOrderChanged );
duplicateCheck.insert( channel->getRoomId() );
int pos = channelList.findPosition( channel );
if(pos <0){
if ( pos < 0 ) {
pos = 0;
}
beginInsertRows( QModelIndex(), pos, pos );
channelList.insertSort( channel );
endInsertRows();
......@@ -165,35 +168,38 @@ bool ChannelModel::addChannel( const QSharedPointer<RocketChatChannel> &channel
}
bool ChannelModel::addChannelsSlot(const QVector<QSharedPointer<RocketChatChannel> > &pChannels)
bool ChannelModel::addChannelsSlot( const QVector<QSharedPointer<RocketChatChannel> > &pChannels )
{
// beginResetModel();
int from =-1;
// beginResetModel();
int from = -1;
int to = -1;
for(const auto &channel: pChannels){
if ( !channel.isNull() && channel->getRoomId() != "" && !duplicateCheck.contains( channel->getRoomId() ) ) {
for ( const auto &channel : pChannels ) {
if ( !channel.isNull() && !channel->getRoomId().isEmpty() && !duplicateCheck.contains( channel->getRoomId() ) ) {
//connect( channel.data(), &RocketChatChannel::messageAdded, this, &ChannelModel::onNewerMessage, Qt::UniqueConnection );
connect( channel.data(), &RocketChatChannel::unreadMessagesChanged, this, &ChannelModel::onUnreadMessageChanged, Qt::UniqueConnection );
connect( channel.data(), &RocketChatChannel::dataChanged, this, &ChannelModel::onDataChanged, Qt::UniqueConnection );
connect( channel.data(), &RocketChatChannel::channelDeleted, this, &ChannelModel::onDeleted, Qt::UniqueConnection );
connect(channel.data(), &RocketChatChannel::updatedChanged, this, &ChannelModel::onChannelOrderChanged);
connect( channel.data(), &RocketChatChannel::updatedChanged, this, &ChannelModel::onChannelOrderChanged );
duplicateCheck.insert( channel->getRoomId() );
auto index = channelList.insertSort( channel );
if(from == -1){
if ( from == -1 ) {
from = index;
to = index;
}
if(index<from){
if ( index < from ) {
from = index;
}else if(index>to){
} else if ( index > to ) {
to = index;
}
}
}
beginInsertRows( QModelIndex(), from, to );
endInsertRows();
// endResetModel();
// endResetModel();
return true;
}
......@@ -237,7 +243,7 @@ void ChannelModel::onNewerMessage( const QString &id, qint64 timestamp )
//emit dataChanged(index(pos),index(pos),{lastMessageText});
}
// sortChanged();
// sortChanged();
}
void ChannelModel::onUnreadMessageChanged( const QString &id, int number )
......@@ -308,14 +314,13 @@ void ChannelModel::onDeleted( const QString &pId, bool deleted )
}
void ChannelModel::onChannelOrderChanged(const QString &pId, qint64 pTimestamp)
void ChannelModel::onChannelOrderChanged( const QString &pId, qint64 pTimestamp )
{
static int counter = 0;
counter++;
qDebug() << counter;
beginResetModel();
channelList.reOrder();
endResetModel();
static int counter = 0;
counter++;
qDebug() << counter;
auto changed = channelList.reOrder();
emit dataChanged( createIndex( std::get<0>( changed ), 0 ), createIndex( std::get<1>( changed ), 0 ) );
}
void ChannelModel::addChannelSlot( const QSharedPointer<RocketChatChannel> &channel )
......
......@@ -35,13 +35,9 @@ int SortedVector<T>::insertSort( const QSharedPointer<T> &pointer )
return ( *first ) > ( *second );
} );
row = std::distance(this->begin(), elementSmallerThanNew);
row = std::distance( this->begin(), elementSmallerThanNew );
this->insert( elementSmallerThanNew, pointer );
if(row <0 || row>1000){
qDebug()<<elementSmallerThanNew;
qDebug()<<"error";
}
}
return row;
......@@ -54,7 +50,7 @@ int SortedVector<T>::findInsertPosition( const QSharedPointer<T> &pointer ) cons
return ( *first ) < ( *second );
} );
return elementSmallerThanNew - this->begin();;
return std::distance( this->begin(), elementSmallerThanNew );
}
......@@ -62,14 +58,39 @@ template<typename T>
int SortedVector<T>::findPosition( const QSharedPointer<T> &pointer ) const
{
auto pos = find( this->begin(), this->end(), pointer );
return pos - this->begin();
return std::distance( this->begin(), pos );
}
template<typename T>
void SortedVector<T>::reOrder()
std::tuple<int, int> SortedVector<T>::reOrder()
{
std::vector<QSharedPointer<T>> indices( this->size() );
for ( const auto &elem : *this ) {
indices.push_back( elem );
}
std::sort( this->begin(), this->end(), [ = ]( const QSharedPointer<T> &first, const QSharedPointer<T> &second )->bool{
return ( *first ) > ( *second );
} );
int from = -1;
int to = -1;
for ( int i = 0; i < this->size() - 1; i++ ) {
if ( indices[i] != ( *this )[i] ) {
from = i;
break;
}
}
for ( int i = this->size() - 1; i >= 0; i-- ) {
if ( indices[i] != ( *this )[i] ) {
to = i;
break;
}
}
return std::make_tuple( from, to );
}
......@@ -26,9 +26,8 @@
#include <QSharedPointer>
#include <QMutex>
struct SortedVectorProperties
{
enum class sortOrder{
struct SortedVectorProperties {
enum class sortOrder {
asc,
dsc
};
......@@ -40,14 +39,14 @@ template<typename T> class SortedVector : public QVector<QSharedPointer<T>>
int insertSort( const QSharedPointer<T> & );
int findInsertPosition( const QSharedPointer<T> & ) const;
int findPosition( const QSharedPointer<T> & ) const;
void reOrder();
std::tuple<int, int> reOrder();
bool operator =( const QVector<QSharedPointer<T>> &o )
{
this->clear();
this->append( o );
return true;
}
private:
private:
mutable QMutex mSortMutex;
};
#include "sortedvector.cpp"
......
......@@ -83,7 +83,7 @@ const QString &RocketChatChannel::getName() const
void RocketChatChannel::setName( const QString &value )
{
if ( mName != value ) {
if ( mName != value && !value.isEmpty() ) {
mName = value;
emit dataChanged( mName, "name" );
}
......@@ -167,9 +167,11 @@ QList<QSharedPointer<RocketChatMessage>> RocketChatChannel::addMessages( const Q
}
}
}
if(newMessages.count()){
// emit messageAdded( getRoomId(), 0 );
if ( newMessages.count() ) {
// emit messageAdded( getRoomId(), 0 );
}
return newMessages;
}
......@@ -192,7 +194,8 @@ unsigned int RocketChatChannel::getUnreadMessages() const
void RocketChatChannel::setUnreadMessages( unsigned int value )
{
qDebug() << "set unread to: " << value;
if(mUnreadMessages != value){
if ( mUnreadMessages != value ) {
mUnreadMessages = value;
emit unreadMessagesChanged( mRoomId, value );
}
......@@ -205,7 +208,7 @@ const QString &RocketChatChannel::getType() const
void RocketChatChannel::setType( const QString &pType )
{
if ( mType != pType ) {
if ( mType != pType && !pType.isEmpty() ) {
mType = pType;
emit dataChanged( mRoomId, "type" );
}
......@@ -290,7 +293,7 @@ const QString &RocketChatChannel::getOwnerName() const
void RocketChatChannel::setOwnerName( const QString &pOwner )
{
if ( mOwnerName != pOwner ) {
if ( mOwnerName != pOwner && !pOwner.isEmpty() ) {
mOwnerName = pOwner;
emit dataChanged( mRoomId, "ownerName" );
}
......@@ -303,7 +306,7 @@ const QString &RocketChatChannel::getOwnerId() const
void RocketChatChannel::setOwnerId( const QString &ownerId )
{
if ( mOwnerId != ownerId ) {
if ( mOwnerId != ownerId && !ownerId.isEmpty() ) {
mOwnerId = ownerId;
emit dataChanged( mRoomId, "ownerId" );
}
......@@ -316,7 +319,7 @@ const QString &RocketChatChannel::getUsername() const
void RocketChatChannel::setUsername( const QString &username )
{
if ( mUsername != username ) {
if ( mUsername != username && !username.isEmpty() ) {
mUsername = username;
emit dataChanged( mRoomId, "username" );
}
......@@ -329,7 +332,7 @@ const QSharedPointer<RocketChatUser> &RocketChatChannel::getChatPartner() const
void RocketChatChannel::setChatPartner( const QSharedPointer<RocketChatUser> &chatPartner )
{
if(mChatPartner != chatPartner){
if ( mChatPartner != chatPartner && !chatPartner.isNull() ) {
mChatPartner = chatPartner;
connect( chatPartner.data(), &RocketChatUser::statusChanged, this, [ = ]() {
emit dataChanged( mRoomId, "userStatus" );
......@@ -344,7 +347,7 @@ const QString &RocketChatChannel::getChatPartnerId() const
void RocketChatChannel::setChatPartnerId( const QString &chatPartnerId )
{
if ( mChatPartnerId != chatPartnerId ) {
if ( mChatPartnerId != chatPartnerId && !chatPartnerId.isEmpty() ) {
mChatPartnerId = chatPartnerId;
// emit dataChanged( mRoomId, "username" );
}
......@@ -357,7 +360,7 @@ QSharedPointer<TempFile> RocketChatChannel::getAvatarImg() const
void RocketChatChannel::setAvatarImg( const QSharedPointer<TempFile> &pAvatar )
{
if ( mAvatarImg != pAvatar ) {
if ( mAvatarImg != pAvatar && !pAvatar.isNull() ) {
mAvatarImg = pAvatar;
emit dataChanged( mRoomId, "avatarImg" );
}
......@@ -371,10 +374,11 @@ qint64 RocketChatChannel::getUpdatedAt() const
void RocketChatChannel::setUpdatedAt( const qint64 &updatedAt )
{
//skip signal the first time
if(mUpdatedAt != updatedAt && updatedAt != -1){
if(mUpdatedAt != -1 ){
emit updatedChanged(mRoomId,updatedAt);
if ( mUpdatedAt != updatedAt && updatedAt != -1 ) {
if ( mUpdatedAt != -1 ) {
emit updatedChanged( mRoomId, updatedAt );
}
mUpdatedAt = updatedAt;
}
}
......@@ -386,7 +390,7 @@ qint64 RocketChatChannel::getCreatedAt() const
void RocketChatChannel::setCreatedAt( const qint64 &createdAt )
{
mCreatedAt = createdAt;
mCreatedAt = createdAt;
}
bool RocketChatChannel::getBlocked() const
......@@ -402,34 +406,39 @@ void RocketChatChannel::setBlocked( bool blocked )
}
}
QStringList RocketChatChannel::whiteList(const QList<QString> ids, const qint64 newest,const qint64 oldest)
QStringList RocketChatChannel::whiteList( const QList<QString> ids, const qint64 newest, const qint64 oldest )
{
auto idSet = ids.toSet();
auto currentList = mMessages.getElements().keys().toSet();
auto blacklist = currentList - idSet;
QList<QString> buffer = {};
std::copy_if (blacklist.begin(), blacklist.end(), std::back_inserter(buffer),
[=](const QString id){
std::copy_if( blacklist.begin(), blacklist.end(), std::back_inserter( buffer ),
[ = ]( const QString id ) {
bool keep = true;
if(mMessages.contains(id) && mMessages.get(id)->getRoomId() == getRoomId()){
auto message = mMessages.get(id);
keep = message->inTimeIntervall(newest,oldest);
if ( mMessages.contains( id ) && mMessages.get( id )->getRoomId() == getRoomId() ) {
auto message = mMessages.get( id );
keep = message->inTimeIntervall( newest, oldest );
}
return keep;
}
);
);
blacklist = buffer.toSet();
for(QString id : blacklist){
mMessages.remove(id);
for ( QString id : blacklist ) {
mMessages.remove( id );
}
return blacklist.toList();
}
void RocketChatChannel::deleteMessage(const QString id)
void RocketChatChannel::deleteMessage( const QString id )
{
emit messageDeleted(getRoomId(),id);
if(mMessages.contains(id)){
mMessages.remove(id);
emit messageDeleted( getRoomId(), id );
if ( mMessages.contains( id ) ) {
mMessages.remove( id );
}
......
......@@ -110,141 +110,142 @@ void MessageService::persistMessages( const MessageList &pMessage )
void MessageService::persist()
{
if(mServer){
mPersistanceLayer->transaction();
auto channels = mServer->getChannels();
if ( mServer ) {
mPersistanceLayer->transaction();
auto channels = mServer->getChannels();
for ( const auto &channel : channels->getElements() ) {
if ( channel.isNull() ) {
auto messages = channel->getMessageRepo();
for ( const auto &channel : channels->getElements() ) {
if ( channel.isNull() ) {
auto messages = channel->getMessageRepo();
for ( const auto &message : messages->getElements() ) {
if ( !message.isNull() ) {
persistMessage( message );
for ( const auto &message : messages->getElements() ) {
if ( !message.isNull() ) {
persistMessage( message );
}
}
}
}
}
mPersistanceLayer->askForcommit();
mPersistanceLayer->askForcommit();
}
}
QSharedPointer<RocketChatMessage> MessageService::parseMessage( const QJsonObject &pMessageData,
bool linkify )
{
if(mServer){
ChatMessage message( nullptr );
QString userId = mServer->getUserId();
bool blocked = false;
if ( mServer ) {
ChatMessage message( nullptr );
QString userId = mServer->getUserId();
bool blocked = false;
if ( Q_LIKELY( pMessageData.contains( QStringLiteral( "msg" ) ) ) ) {
//parse message String
QString msgString = pMessageData[QStringLiteral( "msg" )].toString();
if ( Q_LIKELY( pMessageData.contains( QStringLiteral( "msg" ) ) ) ) {
//parse message String
QString msgString = pMessageData[QStringLiteral( "msg" )].toString();
if ( linkify ) {
msgString = Utils::removeUtf8Emojis( msgString );
if ( linkify ) {
msgString = Utils::removeUtf8Emojis( msgString );
msgString = Utils::linkiFy( msgString );
msgString = msgString.replace( QStringLiteral( "\n" ), QStringLiteral( "<br>" ) );
msgString = Utils::escapeHtml(msgString);
msgString = Utils::emojiFy( msgString, mEmojiRepo );
msgString = Utils::linkiFy( msgString );
msgString = msgString.replace( QStringLiteral( "\n" ), QStringLiteral( "<br>" ) );
msgString = Utils::escapeHtml( msgString );
msgString = Utils::emojiFy( msgString, mEmojiRepo );
}
}
QString msgType;
QString author;
QString authorId;
QString msgType;
QString author;
QString authorId;
if ( Q_LIKELY( pMessageData.contains( "t" ) ) ) {
msgType = pMessageData["t"].toString();
}
if ( Q_LIKELY( pMessageData.contains( "t" ) ) ) {
msgType = pMessageData["t"].toString();
}
if ( Q_UNLIKELY( mServer->getUsername() == "apple.store" ) && msgType == "jitsi_call_started" ) {
return nullptr;
}
if ( Q_UNLIKELY( mServer->getUsername() == "apple.store" ) && msgType == "jitsi_call_started" ) {
return nullptr;
}
QJsonObject userObject = pMessageData["u"].toObject();
QJsonObject userObject = pMessageData["u"].toObject();
if ( Q_LIKELY( userObject.contains( QStringLiteral( "username" ) ) ) ) {
author = userObject[QStringLiteral( "username" )].toString();
}
if ( Q_LIKELY( userObject.contains( QStringLiteral( "username" ) ) ) ) {
author = userObject[QStringLiteral( "username" )].toString();
}
// if alias given, us it instead of the username, required for bridges
if ( Q_LIKELY( pMessageData.contains( QStringLiteral( "alias" ) ) ) ) {
author = pMessageData[QStringLiteral( "alias" )].toString();
}
// if alias given, us it instead of the username, required for bridges
if ( Q_LIKELY( pMessageData.contains( QStringLiteral( "alias" ) ) ) ) {
author = pMessageData[QStringLiteral( "alias" )].toString();
}
if ( Q_LIKELY( userObject.contains( "_id" ) ) ) {
authorId = userObject[QStringLiteral( "_id" )].toString();
}
if ( Q_LIKELY( userObject.contains( "_id" ) ) ) {
authorId = userObject[QStringLiteral( "_id" )].toString();
}
bool ownMessage = false;
bool ownMessage = false;
if ( authorId == userId ) {
ownMessage = true;
}
if ( authorId == userId ) {
ownMessage = true;
}
QJsonObject timestampObject = pMessageData[QStringLiteral( "ts" )].toObject();
qint64 timestamp = 0;
QJsonObject timestampObject = pMessageData[QStringLiteral( "ts" )].toObject();
qint64 timestamp = 0;
if ( Q_LIKELY( timestampObject.contains( QStringLiteral( "$date" ) ) ) ) {
timestamp = static_cast<qint64>( timestampObject[QStringLiteral( "$date" )].toDouble() );
}
if ( Q_LIKELY( timestampObject.contains( QStringLiteral( "$date" ) ) ) ) {
timestamp = static_cast<qint64>( timestampObject[QStringLiteral( "$date" )].toDouble() );
}
QDateTime date = QDateTime::fromMSecsSinceEpoch( timestamp );
QDateTime date = QDateTime::fromMSecsSinceEpoch( timestamp );
QString formattedDate = date.toString( QStringLiteral( "dd.MM.yyyy" ) );
QString formattedTime = date.toString( QStringLiteral( "hh:mm" ) );
auto attachments = processAttachments( pMessageData );
message = QSharedPointer<RocketChatMessage>::create( pMessageData );
message->setAttachments( attachments );
message->setOwnMessage( ownMessage );
message->setAuthorId( authorId );
QString formattedDate = date.toString( QStringLiteral( "dd.MM.yyyy" ) );
QString formattedTime = date.toString( QStringLiteral( "hh:mm" ) );
auto attachments = processAttachments( pMessageData );
message = QSharedPointer<RocketChatMessage>::create( pMessageData );
message->setAttachments( attachments );
message->setOwnMessage( ownMessage );
message->setAuthorId( authorId );
if ( !attachments.isEmpty() ) {
auto firstAttachment = attachments.first();
if ( !attachments.isEmpty() ) {
auto firstAttachment = attachments.first();
if ( !firstAttachment.isNull() ) {
if ( firstAttachment->getType() == "replyMessage" ) {
QString messageText = msgString;
messageText.replace( mReplyRegeEx, "" );
msgString = messageText;
} else {
msgString = firstAttachment->getTitle();
if ( !firstAttachment.isNull() ) {
if ( firstAttachment->getType() == "replyMessage" ) {
QString messageText = msgString;
messageText.replace( mReplyRegeEx, "" );
msgString = messageText;
} else {
msgString = firstAttachment->getTitle();
}
}
}
}
//TODO: place RocketChatUserObject inside Message instead...
auto then = [ message ]( QSharedPointer<TempFile> tempfile, bool showInline ) {
message->setAvatarImg( tempfile );
};
auto avatarUrl = "/avatar/" + author + ".jpg";
auto avatarRequest = QSharedPointer<FileRequest>::create( avatarUrl, "temp", then, true );
mFileService->getFileRessource( avatarRequest );
message->setAuthor( author );
message->setFormattedDate( formattedDate );
message->setFormattedTime( formattedTime );
message->setMessageString( msgString );
message->setMessageType( msgType );
if ( mBlockedUsers.contains( author ) ) {
blocked = true;
//TODO: place RocketChatUserObject inside Message instead...
auto then = [ message ]( QSharedPointer<TempFile> tempfile, bool showInline ) {
message->setAvatarImg( tempfile );
};
auto avatarUrl = "/avatar/" + author + ".jpg";
auto avatarRequest = QSharedPointer<FileRequest>::create( avatarUrl, "temp", then, true );
//mFileService->getFileRessource( avatarRequest );
message->setAuthor( author );
message->setFormattedDate( formattedDate );
message->setFormattedTime( formattedTime );
message->setMessageString( msgString );
message->setMessageType( msgType );
if ( mBlockedUsers.contains( author ) ) {
blocked = true;
}
}
}
if ( Q_UNLIKELY( message.isNull() ) ) {
qDebug() << "invalid messag";
}
if ( Q_UNLIKELY( message.isNull() ) ) {
qDebug() << "invalid messag";
}
message->setServer( mServer->getBaseUrl() );
message->setServer( mServer->getBaseUrl() );