Files
neochat/src/models/devicesmodel.cpp
2023-08-30 21:10:56 +00:00

173 lines
5.0 KiB
C++

// SPDX-FileCopyrightText: Tobias Fella <tobias.fella@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
#include "devicesmodel.h"
#include "controller.h"
#include "jobs/neochatdeletedevicejob.h"
#include <QDateTime>
#include <QLocale>
#include <KLocalizedString>
#include <Quotient/csapi/device_management.h>
#include <Quotient/connection.h>
#include <Quotient/user.h>
using namespace Quotient;
DevicesModel::DevicesModel(QObject *parent)
: QAbstractListModel(parent)
{
}
void DevicesModel::fetchDevices()
{
if (Controller::instance().activeConnection()) {
auto job = Controller::instance().activeConnection()->callApi<GetDevicesJob>();
connect(job, &BaseJob::success, this, [this, job]() {
beginResetModel();
m_devices = job->devices();
endResetModel();
Q_EMIT countChanged();
});
}
}
QVariant DevicesModel::data(const QModelIndex &index, int role) const
{
if (index.row() < 0 || index.row() >= rowCount(QModelIndex())) {
return {};
}
const auto &device = m_devices[index.row()];
switch (role) {
case Id:
return device.deviceId;
case DisplayName:
return device.displayName;
case LastIp:
return device.lastSeenIp;
case LastTimestamp:
if (device.lastSeenTs) {
return *device.lastSeenTs;
} else {
return false;
}
case TimestampString:
if (device.lastSeenTs) {
return QDateTime::fromMSecsSinceEpoch(*device.lastSeenTs).toString(QLocale().dateTimeFormat(QLocale::ShortFormat));
} else {
return false;
}
case Type:
if (device.deviceId == m_connection->deviceId()) {
return This;
}
if (!m_connection->isKnownE2eeCapableDevice(m_connection->userId(), device.deviceId)) {
return Unencrypted;
}
if (m_connection->isVerifiedDevice(m_connection->userId(), device.deviceId)) {
return Verified;
} else {
return Unverified;
}
}
return {};
}
int DevicesModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return m_devices.size();
}
QHash<int, QByteArray> DevicesModel::roleNames() const
{
return {
{Id, "id"},
{DisplayName, "displayName"},
{LastIp, "lastIp"},
{LastTimestamp, "lastTimestamp"},
{TimestampString, "timestamp"},
{Type, "type"},
};
}
void DevicesModel::logout(const QString &deviceId, const QString &password)
{
int index;
for (index = 0; m_devices[index].deviceId != deviceId; index++)
;
auto job = Controller::instance().activeConnection()->callApi<NeochatDeleteDeviceJob>(m_devices[index].deviceId);
connect(job, &BaseJob::result, this, [this, job, password, index] {
auto onSuccess = [this, index]() {
beginRemoveRows(QModelIndex(), index, index);
m_devices.remove(index);
endRemoveRows();
Q_EMIT countChanged();
};
if (job->error() != BaseJob::Success) {
QJsonObject replyData = job->jsonData();
QJsonObject authData;
authData["session"_ls] = replyData["session"_ls];
authData["password"_ls] = password;
authData["type"_ls] = "m.login.password"_ls;
QJsonObject identifier = {{"type"_ls, "m.id.user"_ls}, {"user"_ls, Controller::instance().activeConnection()->user()->id()}};
authData["identifier"_ls] = identifier;
auto *innerJob = Controller::instance().activeConnection()->callApi<NeochatDeleteDeviceJob>(m_devices[index].deviceId, authData);
connect(innerJob, &BaseJob::success, this, onSuccess);
} else {
onSuccess();
}
});
}
void DevicesModel::setName(const QString &deviceId, const QString &name)
{
int index;
for (index = 0; m_devices[index].deviceId != deviceId; index++);
auto job = Controller::instance().activeConnection()->callApi<UpdateDeviceJob>(m_devices[index].deviceId, name);
QString oldName = m_devices[index].displayName;
beginResetModel();
m_devices[index].displayName = name;
endResetModel();
connect(job, &BaseJob::failure, this, [this, index, oldName]() {
beginResetModel();
m_devices[index].displayName = oldName;
endResetModel();
});
}
Connection *DevicesModel::connection() const
{
return m_connection;
}
void DevicesModel::setConnection(Connection *connection)
{
if (m_connection) {
disconnect(m_connection, nullptr, this, nullptr);
}
m_connection = connection;
Q_EMIT connectionChanged();
fetchDevices();
connect(m_connection, &Connection::sessionVerified, this, [this](const QString &userId, const QString &deviceId) {
Q_UNUSED(deviceId);
if (userId == Controller::instance().activeConnection()->userId()) {
fetchDevices();
}
});
connect(m_connection, &Connection::finishedQueryingKeys, this, [this]() {
fetchDevices();
});
}
#include "moc_devicesmodel.cpp"