Skip to content
Snippets Groups Projects
RoomList.cc 3.34 KiB
Newer Older
  • Learn to ignore specific revisions
  • Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    /*
     * nheko Copyright (C) 2017  Konstantinos Sideris <siderisk@auth.gr>
     *
     * This program 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.
     *
     * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
     */
    
    #include "ui_RoomList.h"
    
    #include <QDebug>
    #include <QJsonArray>
    #include <QLabel>
    
    #include <QRegularExpression>
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    
    #include "RoomInfoListItem.h"
    #include "RoomList.h"
    #include "Sync.h"
    
    RoomList::RoomList(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::RoomList)
    {
    	ui->setupUi(this);
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    	ui->scrollVerticalLayout->addStretch(1);
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    }
    
    RoomList::~RoomList()
    {
    	delete ui;
    }
    
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    void RoomList::clear()
    {
    	for (const auto &room : rooms_)
    		room->deleteLater();
    
    	rooms_.clear();
    }
    
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    RoomInfo RoomList::extractRoomInfo(const State &room_state)
    {
    	RoomInfo info;
    
    	auto events = room_state.events();
    
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    	for (const auto &event : events) {
    		if (event.type() == "m.room.name") {
    			info.setName(event.content().value("name").toString());
    		} else if (event.type() == "m.room.topic") {
    			info.setTopic(event.content().value("topic").toString());
    		} else if (event.type() == "m.room.avatar") {
    			info.setAvatarUrl(QUrl(event.content().value("url").toString()));
    		} else if (event.type() == "m.room.canonical_alias") {
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    			if (info.name().isEmpty())
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    				info.setName(event.content().value("alias").toString());
    
    	// Sanitize info for print.
    	info.setTopic(info.topic().replace(QRegularExpression("[\\s\\n\\r]+"), " "));
    	info.setName(info.name().replace(QRegularExpression("[\\s\\n\\r]+"), " "));
    
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    	return info;
    }
    
    void RoomList::setInitialRooms(const Rooms &rooms)
    {
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    	rooms_.clear();
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    
    	for (auto it = rooms.join().constBegin(); it != rooms.join().constEnd(); it++) {
    		RoomInfo info = RoomList::extractRoomInfo(it.value().state());
    		info.setId(it.key());
    
    		if (info.name().isEmpty())
    			continue;
    
    		if (!info.avatarUrl().isEmpty())
    			emit fetchRoomAvatar(info.id(), info.avatarUrl());
    
    		RoomInfoListItem *room_item = new RoomInfoListItem(info, ui->scrollArea);
    		connect(room_item,
    			SIGNAL(clicked(const RoomInfo &)),
    			this,
    			SLOT(highlightSelectedRoom(const RoomInfo &)));
    
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    		rooms_.insert(it.key(), room_item);
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    		int pos = ui->scrollVerticalLayout->count() - 1;
    		ui->scrollVerticalLayout->insertWidget(pos, room_item);
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    	}
    
    	// TODO: Move this into its own function.
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    	auto first_room = rooms_.first();
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    	first_room->setPressedState(true);
    	emit roomChanged(first_room->info());
    }
    
    void RoomList::highlightSelectedRoom(const RoomInfo &info)
    {
    	emit roomChanged(info);
    
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    	for (auto it = rooms_.constBegin(); it != rooms_.constEnd(); it++) {
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    		if (it.key() != info.id())
    			it.value()->setPressedState(false);
    	}
    }
    
    void RoomList::updateRoomAvatar(const QString &roomid, const QImage &avatar_image)
    {
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    	if (!rooms_.contains(roomid)) {
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    		qDebug() << "Avatar update on non existent room" << roomid;
    		return;
    	}
    
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    	auto list_item = rooms_.value(roomid);
    
    Konstantinos Sideris's avatar
    Konstantinos Sideris committed
    	list_item->setAvatar(avatar_image);
    }