Skip to content
Snippets Groups Projects
channelmodel.cpp 8.54 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 "channelmodel.h"

ChannelModel::ChannelModel()
{
    // connect(&timer,&QTimer::timeout,this,&ChannelModel::sortChanged);
Armin Felder's avatar
Armin Felder committed
}

int ChannelModel::rowCount( const QModelIndex &parent ) const
Armin Felder's avatar
Armin Felder committed
{
    Q_UNUSED( parent )
    int count = channelList.count();
Armin Felder's avatar
Armin Felder committed
}

QVariant ChannelModel::data( const QModelIndex &index, int role ) const
Armin Felder's avatar
Armin Felder committed
{
    int row = index.row();

    if ( channelList.isEmpty() || row > channelList.count() ) {
Armin Felder's avatar
Armin Felder committed
        return QVariant();
    }

    auto currentChannel = channelList.at( row );

    if ( role == name ) {
Armin Felder's avatar
Armin Felder committed
        return currentChannel->getName();
    }
Armin Felder's avatar
Armin Felder committed
        return currentChannel->getRoomId();
    }

    if ( role == lastMessageText ) {
        auto channel = channelList.at( row );
Armin Felder's avatar
Armin Felder committed
        auto message = channel->getYoungestMessage();

        if ( message.isNull() ) {
Armin Felder's avatar
Armin Felder committed
            return "";
        if ( message->getMessageType() == QStringLiteral( "file" ) || message->getMessageType() == QStringLiteral( "image" ) || message->getMessageType() == QStringLiteral( "audio" ) ) {
            return tr( QByteArrayLiteral( "file upload" ) );
Armin Felder's avatar
Armin Felder committed
        return message->getMessageString();
    }

    if ( role == channelType ) {
Armin Felder's avatar
Armin Felder committed
        return currentChannel->getType();
    }

    if ( role == unreadMessages ) {
Armin Felder's avatar
Armin Felder committed
        return currentChannel->getUnreadMessages();
    }

    if ( role == readonly ) {
Armin Felder's avatar
Armin Felder committed
        return currentChannel->getReadOnly() || currentChannel->getArchived() || currentChannel->getBlocked();
    if ( role == ownerId ) {
        return currentChannel->getOwnerName();
    }

    if ( role == ownerId ) {
        return currentChannel->getOwnerId();
    }

    if ( role == archived ) {
Armin Felder's avatar
Armin Felder committed
        return currentChannel->getArchived();
    }
Armin Felder's avatar
Armin Felder committed
    if ( role == blocked ) {
        return currentChannel->getBlocked();
    }
Armin Felder's avatar
Armin Felder committed

    if ( role == username ) {
        return currentChannel->getUsername();
    }

Armin Felder's avatar
Armin Felder committed
    return QVariant();
Armin Felder's avatar
Armin Felder committed
}

bool ChannelModel::addChannel( const QSharedPointer<RocketChatChannel> &channel )
Armin Felder's avatar
Armin Felder committed
{
    if ( !channel.isNull() && channel->getRoomId() != "" && !duplicateCheck.contains( channel->getRoomId() ) ) {
        connect( channel.data(), &RocketChatChannel::messageAdded, this, &ChannelModel::onNewerMessage, Qt::UniqueConnection );
        connect( channel.data(), &RocketChatChannel::unreadMessagesChanged, this, &ChannelModel::onUnreadMessageChanged, Qt::UniqueConnection );
Armin Felder's avatar
Armin Felder committed
        connect( channel.data(), &RocketChatChannel::dataChanged, this, &ChannelModel::onDataChanged, Qt::UniqueConnection );
        connect( channel.data(), &RocketChatChannel::channelDeleted, this, &ChannelModel::onDeleted, Qt::UniqueConnection );
        duplicateCheck.insert( channel->getRoomId() );
        int pos = channelList.findPosition( channel );
        emit beginInsertRows( QModelIndex(), pos, pos );
        channelList.insertSort( channel );
Armin Felder's avatar
Armin Felder committed
        emit endInsertRows();
        sortChanged();
        return true;
Armin Felder's avatar
Armin Felder committed
        return false;
    }
}

QHash<int, QByteArray> ChannelModel::roleNames() const
{
    QHash<int, QByteArray> roles;
    roles[name] = QByteArrayLiteral( "name" );
    roles[roomId] =  QByteArrayLiteral( "roomId" );
    roles[unreadMessages] = QByteArrayLiteral( "unreadMessages" );
    roles[channelType] = QByteArrayLiteral( "type" );
    roles[lastMessageText] = QByteArrayLiteral( "lastMessageText" );
    roles[readonly] = QByteArrayLiteral( "readonly" );
    roles[archived] = QByteArrayLiteral( "archived" );
    roles[blocked] = QByteArrayLiteral( "blocked" );
    roles[deleted] = QByteArrayLiteral( "deleted" );
    roles[ownerId] = QByteArrayLiteral( "ownerId" );
    roles[ownerName] = QByteArrayLiteral( "ownerName" );
Armin Felder's avatar
Armin Felder committed
    roles[username] = QByteArrayLiteral( "username" );
Armin Felder's avatar
Armin Felder committed
    return roles;
}

void ChannelModel::onNewerMessage( const QString &id, qint64 timestamp )
Armin Felder's avatar
Armin Felder committed
{
Armin Felder's avatar
Armin Felder committed
    int pos = 0;
    bool found = false;

    for ( const auto &current : channelList ) {
        if ( current->getRoomId() == id ) {
Armin Felder's avatar
Armin Felder committed
            found = true;
            break;
        }
Armin Felder's avatar
Armin Felder committed
        pos++;
    }
Armin Felder's avatar
Armin Felder committed
        //emit dataChanged(index(pos),index(pos),{lastMessageText});
    }

    sortChanged();
}

void ChannelModel::onUnreadMessageChanged( const QString &id, int number )
Armin Felder's avatar
Armin Felder committed
{
    Q_UNUSED( number )
    qDebug() << "unread signal catched";
Armin Felder's avatar
Armin Felder committed
    int pos = 0;
    bool found = false;
    for ( const auto &current : channelList ) {
        if ( current->getRoomId() == id ) {
Armin Felder's avatar
Armin Felder committed
            found = true;
            break;
        }
Armin Felder's avatar
Armin Felder committed
        pos++;
    }
    if ( found ) {
        qDebug() << "channel found";
        emit dataChanged( index( pos ), index( pos ), {unreadMessages} );
Armin Felder's avatar
Armin Felder committed
        emit unreadMessagesChanged();
    }
}

Armin Felder's avatar
Armin Felder committed
void ChannelModel::onDataChanged( const QString &id, const QString &property )
{
    int pos = 0;
    bool found = false;

    for ( const auto &current : channelList ) {
        if ( current->getRoomId() == id ) {
            found = true;
            break;
        }

        pos++;
    }

    if ( found ) {
        auto roles = roleNames();
        auto roleKeys = roles.keys();

        for ( auto roleKey : roleKeys ) {
            if ( roles[roleKey] == property ) {
                emit dataChanged( index( pos ), index( pos ), {roleKey} );
            }
        }
    }
}

void ChannelModel::onDeleted( const QString &pId, bool deleted )
Armin Felder's avatar
Armin Felder committed
    int idx = -1;
Armin Felder's avatar
Armin Felder committed
    for ( int i = 0; i < channelList.length(); i++ ) {
        if ( channelList.at( i )->getRoomId() == pId ) {
            idx = i;
            break;
Armin Felder's avatar
Armin Felder committed
    if ( idx != -1 ) {
        beginRemoveRows( QModelIndex(), idx, idx );
        channelList.remove( idx );
        endRemoveRows();
void ChannelModel::addChannelSlot( const QSharedPointer<RocketChatChannel> &channel )
Armin Felder's avatar
Armin Felder committed
{
    addChannel( channel );
Armin Felder's avatar
Armin Felder committed
}

QString ChannelModel::getType() const
{
    return type;
}

void ChannelModel::setType( const QString &value )
Armin Felder's avatar
Armin Felder committed
{
    type = value;
}

void ChannelModel::sortChanged()
{

    beginResetModel();
    std::sort( channelList.begin(), channelList.end(), []( QSharedPointer<RocketChatChannel> channel1, QSharedPointer<RocketChatChannel> channel2 ) {
Armin Felder's avatar
Armin Felder committed
        auto youngest1 = channel1->getYoungestMessage();
        auto youngest2 = channel2->getYoungestMessage();

        if ( !youngest1.isNull() && !youngest2.isNull() ) {
Armin Felder's avatar
Armin Felder committed
            auto timestamp1 = youngest1->getTimestamp();
            auto timestamp2 = youngest2->getTimestamp();
            return timestamp2 < timestamp1;
        } else if ( youngest1.isNull() && !youngest2.isNull() ) {
Armin Felder's avatar
Armin Felder committed
            return false;
        } else if ( youngest2.isNull() && !youngest1.isNull() ) {
Armin Felder's avatar
Armin Felder committed
            return true;
Armin Felder's avatar
Armin Felder committed
            return false;
        }
Armin Felder's avatar
Armin Felder committed
    endResetModel();
    emit countChanged();
}
Dennis Beier's avatar
Dennis Beier committed
    beginResetModel();
Dennis Beier's avatar
Dennis Beier committed
    duplicateCheck.clear();
    endResetModel();