Skip to content
Snippets Groups Projects
messagemodel.cpp 8.1 KiB
Newer Older
/********************************************************************************************
 *                                                                                          *
 * Copyright (C) 2017 Armin Felder, Dennis Beier                                            *
 * This file is part of RocketChatMobileEngine <https://git.fairkom.net/chat/fairchat>.     *
 *                                                                                          *
 * RocketChatMobileEngine is free software: you can redistribute it and/or modify           *
 * it under the terms of the GNU General Public License as published by                     *
 * the Free Software Foundation, either version 3 of the License, or                        *
 * (at your option) any later version.                                                      *
 *                                                                                          *
 * RocketChatMobileEngine is distributed in the hope that it will be useful,                *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of                           *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                            *
 * GNU General Public License for more details.                                             *
 *                                                                                          *
 * You should have received a copy of the GNU General Public License                        *
 * along with RocketChatMobileEngine. If not, see <http://www.gnu.org/licenses/>.           *
 *                                                                                          *
 ********************************************************************************************/



Armin Felder's avatar
Armin Felder committed
#include "messagemodel.h"

MessagesModel::MessagesModel()
{

}

QVariant MessagesModel::data( const QModelIndex &index, int role ) const
{
    int row = index.row();

    QSharedPointer<RocketChatMessage> messageAtIndex =  messagesOfCurrentChannel.at( row );

    if ( role == MessageRoles::type ) {
        return messageAtIndex->getMessageType();
    }

    if ( role == MessageRoles::text ) {
        return messageAtIndex->getMessageString();
    }

    if ( role == MessageRoles::linkurl ) {
        if ( !messageAtIndex->getAttachments().empty() ) {
            return messageAtIndex->getAttachments().first()->getUrl();
        } else {
            qWarning() << "linkurl not found";
        }
    }

    if ( role == author ) {
        return messageAtIndex->getAuthor();
    }

    if ( role == authorId ) {
        return messageAtIndex->getAuthorId();
    }

Armin Felder's avatar
Armin Felder committed
    if ( role == date ) {
        return messageAtIndex->getFormattedDate();
    }

    if ( role == time ) {
        return messageAtIndex->getFormattedTime();
    }

    if ( role == ownMessage ) {
        return messageAtIndex->getOwnMessage();
    }

    if ( role == width ) {
        if ( !messageAtIndex->getAttachments().empty() ) {
            return messageAtIndex->getAttachments().first()->getWidth();
        } else {
            qWarning() << "height not found";
        }
    }

    if ( role == height ) {
        if ( !messageAtIndex->getAttachments().empty() ) {
            return messageAtIndex->getAttachments().first()->getHeight();
        } else {
            qWarning() << "height not found";
        }
    }

    if ( role == formattedDate ) {
Armin Felder's avatar
Armin Felder committed
        return messageAtIndex->getFormattedDate();
Armin Felder's avatar
Armin Felder committed

    if ( role == formattedTime ) {
Armin Felder's avatar
Armin Felder committed
        return messageAtIndex->getFormattedTime();
Armin Felder's avatar
Armin Felder committed

    if ( role == messageType ) {
Armin Felder's avatar
Armin Felder committed
        return messageAtIndex->getMessageType();
Armin Felder's avatar
Armin Felder committed

    if ( role == blocked ) {
        return mBlockedUsers.contains( messageAtIndex->getAuthorId() );
    }

    if ( role == id ) {
        return messageAtIndex->getId();
    }

Armin Felder's avatar
Armin Felder committed
    qWarning() << "MessagesModel data not found for row";
    return QVariant();
}

QString MessagesModel::getCurrent() const
{
    return current;
}

void MessagesModel::setCurrent( const QString &value )
{
    QMutexLocker( &this->mutex );
Armin Felder's avatar
Armin Felder committed
    current = value;
    beginResetModel();
Armin Felder's avatar
Armin Felder committed
    if ( mChannelMap.contains( value ) ) {
        messagesOfCurrentChannel = mChannelMap[value]->getMessageRepo()->timestampIndex().values().toVector();
        duplicateCheck.clear();

        for ( auto currentMessage : messagesOfCurrentChannel ) {
            duplicateCheck.insert( currentMessage->getId() );
        }
    } else {
        duplicateCheck.clear();
        messagesOfCurrentChannel.clear();
Armin Felder's avatar
Armin Felder committed
       /* QSharedPointer<RocketChatChannel> dummyChannel (new RocketChatChannel());
        dummyChannel->setRoomId(value);
        addChannel(dummyChannel); */
Armin Felder's avatar
Armin Felder committed
    }
Armin Felder's avatar
Armin Felder committed
    endResetModel();
    emit countChanged();
}

int MessagesModel::rowCount( const QModelIndex &parent ) const
{
    Q_UNUSED( parent );
    qDebug() << "number of messages in model" << messagesOfCurrentChannel.count();

    int count = 0;

    if ( messagesOfCurrentChannel.isEmpty() ) {
        return 0;
    }

    count = messagesOfCurrentChannel.count();

    return count;
}

Armin Felder's avatar
Armin Felder committed
int MessagesModel::getPositionOfMessage(const QString &pId)
{
    int pos = -1;
    for(int i=0; i<messagesOfCurrentChannel.size();i++){
        auto element = messagesOfCurrentChannel.at(i);
        if(element->getId()==pId){
            pos = i;
            break;
        }
    }
    return pos;
}

bool MessagesModel::addChannel( const QSharedPointer<RocketChatChannel> &channel )
Armin Felder's avatar
Armin Felder committed
{
    QString id = channel->getRoomId();

    if ( mChannelMap.contains( id ) ) {
Armin Felder's avatar
Armin Felder committed
        return false;
    }

    mChannelMap.insert( id, channel );
    connect( channel.data(), &RocketChatChannel::messageAdded, this, [ = ]( QString id, qint64 timestamp ) {
        Q_UNUSED( id )
        onNewMessage( channel, timestamp );
    } );
Armin Felder's avatar
Armin Felder committed
    return true;
}

void MessagesModel::addBlockedUser( const QString &pUserId )
{
    beginResetModel();
    mBlockedUsers.insert( pUserId );
    endResetModel();
}

Armin Felder's avatar
Armin Felder committed
QHash<int, QByteArray> MessagesModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    roles[text] = QByteArrayLiteral( "msg" );
    roles[author] = QByteArrayLiteral( "author" );
    roles[authorId] = QByteArrayLiteral( "authorId" );
    roles[linkurl] = QByteArrayLiteral( "linkurl" );
    roles[type] = QByteArrayLiteral( "type" );
    roles[date] = QByteArrayLiteral( "date" );
    roles[time] = QByteArrayLiteral( "time" );
    roles[ownMessage] = QByteArrayLiteral( "ownMessage" );
    roles[height] = QByteArrayLiteral( "height" );
    roles[width ] = QByteArrayLiteral( "width" );
    roles[formattedDate ] = QByteArrayLiteral( "formattedDate" );
    roles[formattedTime] = QByteArrayLiteral( "formattedTime" );
    roles[messageType] = QByteArrayLiteral( "messageType" );
    roles[blocked] = QByteArrayLiteral( "blocked" );
    roles[id] = QByteArrayLiteral( "id" );
Armin Felder's avatar
Armin Felder committed
    return roles;
}

void MessagesModel::onNewMessage( const QSharedPointer<RocketChatChannel> &channel, qint64 timestamp )
Armin Felder's avatar
Armin Felder committed
{
    QMutexLocker( &this->mutex );

    if ( timestamp == 0 ) {
        setCurrent( current );
Armin Felder's avatar
Armin Felder committed
    }
Armin Felder's avatar
Armin Felder committed
    if ( channel->getRoomId() == current ) {
        auto message = channel->getMessageRepo()->timestampIndex()[timestamp];
Armin Felder's avatar
Armin Felder committed
            return;
        }

        int row = messagesOfCurrentChannel.findPosition( message );

Armin Felder's avatar
Armin Felder committed
        if ( !duplicateCheck.contains( message->getId() ) ) {
            beginInsertRows( QModelIndex(), row, row );
            messagesOfCurrentChannel.insert( row, message );
            mInsertCount++;
            endInsertRows();
            duplicateCheck.insert( message->getId() );
        }

        if ( !buffered ) {
            mInsertCount = 0;
            emit countChanged();
        }
    }
}

void MessagesModel::onBeginInsertList( const QString &pChannelId )
Armin Felder's avatar
Armin Felder committed
{
    if ( pChannelId == current ) {
        buffered = true;
        mInsertCount = 0;
    }
}

void MessagesModel::onEndInsertList( const QString &pChannelId )
Armin Felder's avatar
Armin Felder committed
{
    if ( pChannelId == current ) {
        buffered = false;

        if ( mInsertCount ) {
            mInsertCount = 0;
            emit countChanged();
        }
    }
}

void MessagesModel::addChannelSlot( const QSharedPointer<RocketChatChannel> &channel )
Armin Felder's avatar
Armin Felder committed
{
    addChannel( channel );
Armin Felder's avatar
Armin Felder committed
}