Cleanup headers a bit more

This commit is contained in:
Nicolas Werner 2023-10-31 16:38:15 +01:00
parent 488a93575a
commit 7824c77234
No known key found for this signature in database
GPG key ID: C8D75E610773F2D9
20 changed files with 226 additions and 269 deletions

View file

@ -595,7 +595,7 @@ if(USE_BUNDLED_MTXCLIENT)
FetchContent_Declare( FetchContent_Declare(
MatrixClient MatrixClient
GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git
GIT_TAG 9876a75f46cc829beaa630d49dc8c5279a940b0d GIT_TAG f7734a6f26eddc74fb59c4e4bd0be28b632af9fd
) )
set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "") set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "")
set(BUILD_LIB_TESTS OFF CACHE INTERNAL "") set(BUILD_LIB_TESTS OFF CACHE INTERNAL "")

View file

@ -214,7 +214,7 @@ modules:
buildsystem: cmake-ninja buildsystem: cmake-ninja
name: mtxclient name: mtxclient
sources: sources:
- commit: 9876a75f46cc829beaa630d49dc8c5279a940b0d - commit: f7734a6f26eddc74fb59c4e4bd0be28b632af9fd
#tag: v0.9.2 #tag: v0.9.2
type: git type: git
url: https://github.com/Nheko-Reborn/mtxclient.git url: https://github.com/Nheko-Reborn/mtxclient.git

View file

@ -463,14 +463,14 @@ fatalSecretError()
} }
static QString static QString
secretName(std::string name, bool internal) secretName(std::string_view name, bool internal)
{ {
auto settings = UserSettings::instance(); auto settings = UserSettings::instance();
return (internal ? "nheko." : "matrix.") + return (internal ? "nheko." : "matrix.") +
QString( QString(
QCryptographicHash::hash(settings->profile().toUtf8(), QCryptographicHash::Sha256) QCryptographicHash::hash(settings->profile().toUtf8(), QCryptographicHash::Sha256)
.toBase64()) + .toBase64()) +
"." + QString::fromStdString(name); "." + QString::fromUtf8(name);
} }
void void
@ -560,7 +560,7 @@ Cache::loadSecretsFromStore(
} }
std::optional<std::string> std::optional<std::string>
Cache::secret(const std::string &name_, bool internal) Cache::secret(std::string_view name_, bool internal)
{ {
auto name = secretName(name_, internal); auto name = secretName(name_, internal);
@ -580,7 +580,7 @@ Cache::secret(const std::string &name_, bool internal)
} }
void void
Cache::storeSecret(const std::string &name_, const std::string &secret, bool internal) Cache::storeSecret(std::string_view name_, const std::string &secret, bool internal)
{ {
auto name = secretName(name_, internal); auto name = secretName(name_, internal);
@ -592,11 +592,11 @@ Cache::storeSecret(const std::string &name_, const std::string &secret, bool int
auto db_name = "secret." + name.toStdString(); auto db_name = "secret." + name.toStdString();
syncStateDb_.put(txn, db_name, nlohmann::json(encrypted).dump()); syncStateDb_.put(txn, db_name, nlohmann::json(encrypted).dump());
txn.commit(); txn.commit();
emit secretChanged(name_); emit secretChanged(std::string(name_));
} }
void void
Cache::deleteSecret(const std::string &name_, bool internal) Cache::deleteSecret(std::string_view name_, bool internal)
{ {
auto name = secretName(name_, internal); auto name = secretName(name_, internal);
@ -1631,10 +1631,10 @@ Cache::runMigrations()
this->databaseReady_ = false; this->databaseReady_ = false;
loadSecretsFromStore( loadSecretsFromStore(
{ {
{mtx::secret_storage::secrets::cross_signing_master, false}, {std::string(mtx::secret_storage::secrets::cross_signing_master), false},
{mtx::secret_storage::secrets::cross_signing_self_signing, false}, {std::string(mtx::secret_storage::secrets::cross_signing_self_signing), false},
{mtx::secret_storage::secrets::cross_signing_user_signing, false}, {std::string(mtx::secret_storage::secrets::cross_signing_user_signing), false},
{mtx::secret_storage::secrets::megolm_backup_v1, false}, {std::string(mtx::secret_storage::secrets::megolm_backup_v1), false},
}, },
[this, [this,
count = 1](const std::string &name, bool internal, const std::string &value) mutable { count = 1](const std::string &name, bool internal, const std::string &value) mutable {
@ -6147,15 +6147,21 @@ restoreOlmAccount()
} }
void void
storeSecret(const std::string &name, const std::string &secret) storeSecret(std::string_view name, const std::string &secret)
{ {
instance_->storeSecret(name, secret); instance_->storeSecret(name, secret);
} }
std::optional<std::string> std::optional<std::string>
secret(const std::string &name) secret(std::string_view name)
{ {
return instance_->secret(name); return instance_->secret(name);
} }
std::vector<ImagePackInfo>
getImagePacks(const std::string &room_id, std::optional<bool> stickers)
{
return instance_->getImagePacks(room_id, stickers);
}
} // namespace cache } // namespace cache
#define NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(Content) \ #define NHEKO_CACHE_GET_STATE_EVENT_DEFINITION(Content) \

View file

@ -253,7 +253,10 @@ std::string
restoreOlmAccount(); restoreOlmAccount();
void void
storeSecret(const std::string &name, const std::string &secret); storeSecret(std::string_view name, const std::string &secret);
std::optional<std::string> std::optional<std::string>
secret(const std::string &name); secret(std::string_view name);
std::vector<ImagePackInfo>
getImagePacks(const std::string &room_id, std::optional<bool> stickers);
} }

View file

@ -291,9 +291,9 @@ public:
void deleteBackupVersion(); void deleteBackupVersion();
std::optional<OnlineBackupVersion> backupVersion(); std::optional<OnlineBackupVersion> backupVersion();
void storeSecret(const std::string &name, const std::string &secret, bool internal = false); void storeSecret(std::string_view name, const std::string &secret, bool internal = false);
void deleteSecret(const std::string &name, bool internal = false); void deleteSecret(std::string_view name, bool internal = false);
std::optional<std::string> secret(const std::string &name, bool internal = false); std::optional<std::string> secret(std::string_view name, bool internal = false);
std::string pickleSecret(); std::string pickleSecret();

View file

@ -778,7 +778,9 @@ ChatPage::handleSyncResponse(const mtx::responses::Sync &res, const std::string
nhlog::net()->debug("sync completed: {}", res.next_batch); nhlog::net()->debug("sync completed: {}", res.next_batch);
// Ensure that we have enough one-time keys available. // Ensure that we have enough one-time keys available.
ensureOneTimeKeyCount(res.device_one_time_keys_count, res.device_unused_fallback_key_types); std::map<std::string_view, std::uint16_t> counts{res.device_one_time_keys_count.begin(),
res.device_one_time_keys_count.end()};
ensureOneTimeKeyCount(counts, res.device_unused_fallback_key_types);
std::optional<mtx::events::account_data::IgnoredUsers> oldIgnoredUsers; std::optional<mtx::events::account_data::IgnoredUsers> oldIgnoredUsers;
if (auto ignoreEv = std::ranges::find_if( if (auto ignoreEv = std::ranges::find_if(
@ -1194,7 +1196,7 @@ ChatPage::verifyOneTimeKeyCountAfterStartup()
return; return;
} }
std::map<std::string, uint16_t> key_counts; std::map<std::string_view, uint16_t> key_counts;
std::uint64_t count = 0; std::uint64_t count = 0;
if (auto c = res.one_time_key_counts.find(mtx::crypto::SIGNED_CURVE25519); if (auto c = res.one_time_key_counts.find(mtx::crypto::SIGNED_CURVE25519);
c == res.one_time_key_counts.end()) { c == res.one_time_key_counts.end()) {
@ -1215,7 +1217,7 @@ ChatPage::verifyOneTimeKeyCountAfterStartup()
} }
void void
ChatPage::ensureOneTimeKeyCount(const std::map<std::string, uint16_t> &counts, ChatPage::ensureOneTimeKeyCount(const std::map<std::string_view, uint16_t> &counts,
const std::optional<std::vector<std::string>> &unused_fallback_keys) const std::optional<std::vector<std::string>> &unused_fallback_keys)
{ {
if (auto count = counts.find(mtx::crypto::SIGNED_CURVE25519); count != counts.end()) { if (auto count = counts.find(mtx::crypto::SIGNED_CURVE25519); count != counts.end()) {

View file

@ -6,7 +6,6 @@
#include <atomic> #include <atomic>
#include <optional> #include <optional>
#include <variant>
#include <mtx/common.hpp> #include <mtx/common.hpp>
#include <mtx/events.hpp> #include <mtx/events.hpp>
@ -191,7 +190,7 @@ private:
void tryInitialSync(); void tryInitialSync();
void trySync(); void trySync();
void verifyOneTimeKeyCountAfterStartup(); void verifyOneTimeKeyCountAfterStartup();
void ensureOneTimeKeyCount(const std::map<std::string, uint16_t> &counts, void ensureOneTimeKeyCount(const std::map<std::string_view, uint16_t> &counts,
const std::optional<std::vector<std::string>> &fallback_keys); const std::optional<std::vector<std::string>> &fallback_keys);
void removeOldFallbackKey(); void removeOldFallbackKey();
void getProfileInfo(); void getProfileInfo();

View file

@ -4,7 +4,7 @@
#include "CombinedImagePackModel.h" #include "CombinedImagePackModel.h"
#include "Cache_p.h" #include "Cache.h"
#include "CompletionModelRoles.h" #include "CompletionModelRoles.h"
#include "emoji/Provider.h" #include "emoji/Provider.h"
@ -12,7 +12,7 @@ CombinedImagePackModel::CombinedImagePackModel(const std::string &roomId, QObjec
: QAbstractListModel(parent) : QAbstractListModel(parent)
, room_id(roomId) , room_id(roomId)
{ {
auto packs = cache::client()->getImagePacks(room_id, false); auto packs = cache::getImagePacks(room_id, false);
for (const auto &pack : packs) { for (const auto &pack : packs) {
QString packname = QString packname =

View file

@ -10,6 +10,8 @@
#include <cctype> #include <cctype>
#include <type_traits> #include <type_traits>
#include <mtx/events/collections.hpp>
namespace { namespace {
struct IsStateEvent struct IsStateEvent

View file

@ -9,7 +9,13 @@
#include <QDateTime> #include <QDateTime>
#include <QString> #include <QString>
#include <mtx/events/collections.hpp> #include <mtx/common.hpp>
#include <mtx/events.hpp>
namespace mtx::events::collections {
struct TimelineEvents;
struct StateEvents;
}
namespace nheko { namespace nheko {
struct nonesuch struct nonesuch

View file

@ -10,7 +10,6 @@
#include <algorithm> #include <algorithm>
#include "Cache.h" #include "Cache.h"
#include "Cache_p.h"
#include "emoji/Provider.h" #include "emoji/Provider.h"
QString QString
@ -102,7 +101,7 @@ GridImagePackModel::GridImagePackModel(const std::string &roomId, bool stickers,
} }
} }
auto originalPacks = cache::client()->getImagePacks(room_id, stickers); auto originalPacks = cache::getImagePacks(room_id, stickers);
for (auto &pack : originalPacks) { for (auto &pack : originalPacks) {
PackDesc newPack{}; PackDesc newPack{};

View file

@ -6,14 +6,14 @@
#include <QQmlEngine> #include <QQmlEngine>
#include "Cache_p.h" #include "Cache.h"
#include "SingleImagePackModel.h" #include "SingleImagePackModel.h"
ImagePackListModel::ImagePackListModel(const std::string &roomId, QObject *parent) ImagePackListModel::ImagePackListModel(const std::string &roomId, QObject *parent)
: QAbstractListModel(parent) : QAbstractListModel(parent)
, room_id(roomId) , room_id(roomId)
{ {
auto packs_ = cache::client()->getImagePacks(room_id, std::nullopt); auto packs_ = cache::getImagePacks(room_id, std::nullopt);
packs.reserve(packs_.size()); packs.reserve(packs_.size());
for (const auto &pack : packs_) { for (const auto &pack : packs_) {

View file

@ -101,58 +101,6 @@ MainWindow::MainWindow(QWindow *parent)
void void
MainWindow::registerQmlTypes() MainWindow::registerQmlTypes()
{ {
// qmlRegisterUncreatableType<DeviceVerificationFlow>(
// "im.nheko",
// 1,
// 0,
// "DeviceVerificationFlow",
// QStringLiteral("Can't create verification flow from QML!"));
// qmlRegisterUncreatableType<UserProfile>(
// "im.nheko",
// 1,
// 0,
// "UserProfileModel",
// QStringLiteral("UserProfile needs to be instantiated on the C++ side"));
// qmlRegisterUncreatableType<MemberList>(
// "im.nheko",
// 1,
// 0,
// "MemberList",
// QStringLiteral("MemberList needs to be instantiated on the C++ side"));
// qmlRegisterUncreatableType<RoomSettings>(
// "im.nheko",
// 1,
// 0,
// "RoomSettingsModel",
// QStringLiteral("Room Settings needs to be instantiated on the C++ side"));
// qmlRegisterUncreatableType<TimelineModel>(
// "im.nheko", 1, 0, "Room", QStringLiteral("Room needs to be instantiated on the C++ side"));
// qmlRegisterUncreatableType<ImagePackListModel>(
// "im.nheko",
// 1,
// 0,
// "ImagePackListModel",
// QStringLiteral("ImagePackListModel needs to be instantiated on the C++ side"));
// qmlRegisterUncreatableType<SingleImagePackModel>(
// "im.nheko",
// 1,
// 0,
// "SingleImagePackModel",
// QStringLiteral("SingleImagePackModel needs to be instantiated on the C++ side"));
// qmlRegisterUncreatableType<InviteesModel>(
// "im.nheko",
// 1,
// 0,
// "InviteesModel",
// QStringLiteral("InviteesModel needs to be instantiated on the C++ side"));
// qmlRegisterUncreatableMetaObject(emoji::staticMetaObject,
// "im.nheko.EmojiModel",
// 1,
// 0,
// "EmojiCategory",
// QStringLiteral("Error: Only enums"));
imgProvider = new MxcImageProvider(); imgProvider = new MxcImageProvider();
engine()->addImageProvider(QStringLiteral("MxcImage"), imgProvider); engine()->addImageProvider(QStringLiteral("MxcImage"), imgProvider);
engine()->addImageProvider(QStringLiteral("colorimage"), new ColorImageProvider()); engine()->addImageProvider(QStringLiteral("colorimage"), new ColorImageProvider());

View file

@ -40,6 +40,133 @@
#include "MatrixClient.h" #include "MatrixClient.h"
#include "UserSettingsPage.h" #include "UserSettingsPage.h"
//! Match widgets/events with a description message.
namespace {
template<class T>
QString
messageDescription(const QString &username = QString(),
const QString &body = QString(),
const bool isLocal = false)
{
using Audio = mtx::events::RoomEvent<mtx::events::msg::Audio>;
using Emote = mtx::events::RoomEvent<mtx::events::msg::Emote>;
using File = mtx::events::RoomEvent<mtx::events::msg::File>;
using Image = mtx::events::RoomEvent<mtx::events::msg::Image>;
using Notice = mtx::events::RoomEvent<mtx::events::msg::Notice>;
using Sticker = mtx::events::Sticker;
using Text = mtx::events::RoomEvent<mtx::events::msg::Text>;
using Unknown = mtx::events::RoomEvent<mtx::events::msg::Unknown>;
using Video = mtx::events::RoomEvent<mtx::events::msg::Video>;
using ElementEffect = mtx::events::RoomEvent<mtx::events::msg::ElementEffect>;
using CallInvite = mtx::events::RoomEvent<mtx::events::voip::CallInvite>;
using CallAnswer = mtx::events::RoomEvent<mtx::events::voip::CallAnswer>;
using CallHangUp = mtx::events::RoomEvent<mtx::events::voip::CallHangUp>;
using CallReject = mtx::events::RoomEvent<mtx::events::voip::CallReject>;
using Encrypted = mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>;
if (std::is_same<T, Audio>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:",
"You sent an audio clip");
else
return QCoreApplication::translate("message-description sent:", "%1 sent an audio clip")
.arg(username);
} else if (std::is_same<T, Image>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:", "You sent an image");
else
return QCoreApplication::translate("message-description sent:", "%1 sent an image")
.arg(username);
} else if (std::is_same<T, File>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:", "You sent a file");
else
return QCoreApplication::translate("message-description sent:", "%1 sent a file")
.arg(username);
} else if (std::is_same<T, Video>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:", "You sent a video");
else
return QCoreApplication::translate("message-description sent:", "%1 sent a video")
.arg(username);
} else if (std::is_same<T, Sticker>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:", "You sent a sticker");
else
return QCoreApplication::translate("message-description sent:", "%1 sent a sticker")
.arg(username);
} else if (std::is_same<T, Notice>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:",
"You sent a notification");
else
return QCoreApplication::translate("message-description sent:",
"%1 sent a notification")
.arg(username);
} else if (std::is_same<T, Text>::value || std::is_same<T, Unknown>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:", "You: %1").arg(body);
else
return QCoreApplication::translate("message-description sent:", "%1: %2")
.arg(username, body);
} else if (std::is_same<T, ElementEffect>::value) {
if (body.isEmpty()) {
// TODO: what is the best way to handle this?
if (isLocal)
return QCoreApplication::translate("message-description sent:",
"You sent a chat effect");
else
return QCoreApplication::translate("message-description sent:",
"%1 sent a chat effect")
.arg(username);
} else {
if (isLocal)
return QCoreApplication::translate("message-description sent:", "You: %1")
.arg(body);
else
return QCoreApplication::translate("message-description sent:", "%1: %2")
.arg(username, body);
}
} else if (std::is_same<T, Emote>::value) {
return QStringLiteral("* %1 %2").arg(username, body);
} else if (std::is_same<T, Encrypted>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:",
"You sent an encrypted message");
else
return QCoreApplication::translate("message-description sent:",
"%1 sent an encrypted message")
.arg(username);
} else if (std::is_same<T, CallInvite>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:", "You placed a call");
else
return QCoreApplication::translate("message-description sent:", "%1 placed a call")
.arg(username);
} else if (std::is_same<T, CallAnswer>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:", "You answered a call");
else
return QCoreApplication::translate("message-description sent:", "%1 answered a call")
.arg(username);
} else if (std::is_same<T, CallHangUp>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:", "You ended a call");
else
return QCoreApplication::translate("message-description sent:", "%1 ended a call")
.arg(username);
} else if (std::is_same<T, CallReject>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:", "You rejected a call");
else
return QCoreApplication::translate("message-description sent:", "%1 rejected a call")
.arg(username);
} else {
return QCoreApplication::translate("utils", "Unknown Message Type");
}
}
}
template<class T, class Event> template<class T, class Event>
static DescInfo static DescInfo
createDescriptionInfo(const Event &event, const QString &localUser, const QString &displayName) createDescriptionInfo(const Event &event, const QString &localUser, const QString &displayName)
@ -56,7 +183,7 @@ createDescriptionInfo(const Event &event, const QString &localUser, const QStrin
return DescInfo{ return DescInfo{
QString::fromStdString(msg.event_id), QString::fromStdString(msg.event_id),
sender, sender,
utils::messageDescription<T>(username, QString::fromStdString(body), sender == localUser), messageDescription<T>(username, QString::fromStdString(body), sender == localUser),
utils::descriptiveTime(ts), utils::descriptiveTime(ts),
msg.origin_server_ts, msg.origin_server_ts,
ts}; ts};
@ -389,13 +516,9 @@ utils::mxcToHttp(const QUrl &url, const QString &server, int port)
} }
QString QString
utils::humanReadableFingerprint(const std::string &ed25519) utils::humanReadableFingerprint(const std::string &ed25519_)
{
return humanReadableFingerprint(QString::fromStdString(ed25519));
}
QString
utils::humanReadableFingerprint(const QString &ed25519)
{ {
auto ed25519 = QString::fromStdString(ed25519_);
QString fingerprint; QString fingerprint;
for (int i = 0; i < ed25519.length(); i = i + 4) { for (int i = 0; i < ed25519.length(); i = i + 4) {
fingerprint.append(QStringView(ed25519).mid(i, 4)); fingerprint.append(QStringView(ed25519).mid(i, 4));

View file

@ -5,14 +5,14 @@
#pragma once #pragma once
#include <CacheStructs.h> #include <CacheStructs.h>
#include <QCoreApplication>
#include <QDateTime> #include <QDateTime>
#include <QPixmap> #include <QPixmap>
#include <QRegularExpression> #include <mtx/events.hpp>
#include <mtx/events/collections.hpp>
#include <mtx/events/common.hpp>
#include <qmath.h> namespace mtx::events::collections {
struct TimelineEvents;
struct StateEvents;
}
struct DescInfo; struct DescInfo;
@ -85,131 +85,6 @@ firstChar(const QString &input);
QString QString
humanReadableFileSize(uint64_t bytes); humanReadableFileSize(uint64_t bytes);
//! Match widgets/events with a description message.
template<class T>
QString
messageDescription(const QString &username = QString(),
const QString &body = QString(),
const bool isLocal = false)
{
using Audio = mtx::events::RoomEvent<mtx::events::msg::Audio>;
using Emote = mtx::events::RoomEvent<mtx::events::msg::Emote>;
using File = mtx::events::RoomEvent<mtx::events::msg::File>;
using Image = mtx::events::RoomEvent<mtx::events::msg::Image>;
using Notice = mtx::events::RoomEvent<mtx::events::msg::Notice>;
using Sticker = mtx::events::Sticker;
using Text = mtx::events::RoomEvent<mtx::events::msg::Text>;
using Unknown = mtx::events::RoomEvent<mtx::events::msg::Unknown>;
using Video = mtx::events::RoomEvent<mtx::events::msg::Video>;
using ElementEffect = mtx::events::RoomEvent<mtx::events::msg::ElementEffect>;
using CallInvite = mtx::events::RoomEvent<mtx::events::voip::CallInvite>;
using CallAnswer = mtx::events::RoomEvent<mtx::events::voip::CallAnswer>;
using CallHangUp = mtx::events::RoomEvent<mtx::events::voip::CallHangUp>;
using CallReject = mtx::events::RoomEvent<mtx::events::voip::CallReject>;
using Encrypted = mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>;
if (std::is_same<T, Audio>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:",
"You sent an audio clip");
else
return QCoreApplication::translate("message-description sent:", "%1 sent an audio clip")
.arg(username);
} else if (std::is_same<T, Image>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:", "You sent an image");
else
return QCoreApplication::translate("message-description sent:", "%1 sent an image")
.arg(username);
} else if (std::is_same<T, File>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:", "You sent a file");
else
return QCoreApplication::translate("message-description sent:", "%1 sent a file")
.arg(username);
} else if (std::is_same<T, Video>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:", "You sent a video");
else
return QCoreApplication::translate("message-description sent:", "%1 sent a video")
.arg(username);
} else if (std::is_same<T, Sticker>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:", "You sent a sticker");
else
return QCoreApplication::translate("message-description sent:", "%1 sent a sticker")
.arg(username);
} else if (std::is_same<T, Notice>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:",
"You sent a notification");
else
return QCoreApplication::translate("message-description sent:",
"%1 sent a notification")
.arg(username);
} else if (std::is_same<T, Text>::value || std::is_same<T, Unknown>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:", "You: %1").arg(body);
else
return QCoreApplication::translate("message-description sent:", "%1: %2")
.arg(username, body);
} else if (std::is_same<T, ElementEffect>::value) {
if (body.isEmpty()) {
// TODO: what is the best way to handle this?
if (isLocal)
return QCoreApplication::translate("message-description sent:",
"You sent a chat effect");
else
return QCoreApplication::translate("message-description sent:",
"%1 sent a chat effect")
.arg(username);
} else {
if (isLocal)
return QCoreApplication::translate("message-description sent:", "You: %1")
.arg(body);
else
return QCoreApplication::translate("message-description sent:", "%1: %2")
.arg(username, body);
}
} else if (std::is_same<T, Emote>::value) {
return QStringLiteral("* %1 %2").arg(username, body);
} else if (std::is_same<T, Encrypted>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:",
"You sent an encrypted message");
else
return QCoreApplication::translate("message-description sent:",
"%1 sent an encrypted message")
.arg(username);
} else if (std::is_same<T, CallInvite>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:", "You placed a call");
else
return QCoreApplication::translate("message-description sent:", "%1 placed a call")
.arg(username);
} else if (std::is_same<T, CallAnswer>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:", "You answered a call");
else
return QCoreApplication::translate("message-description sent:", "%1 answered a call")
.arg(username);
} else if (std::is_same<T, CallHangUp>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:", "You ended a call");
else
return QCoreApplication::translate("message-description sent:", "%1 ended a call")
.arg(username);
} else if (std::is_same<T, CallReject>::value) {
if (isLocal)
return QCoreApplication::translate("message-description sent:", "You rejected a call");
else
return QCoreApplication::translate("message-description sent:", "%1 rejected a call")
.arg(username);
} else {
return QCoreApplication::translate("utils", "Unknown Message Type");
}
}
//! Scale down an image to fit to the given width & height limitations. //! Scale down an image to fit to the given width & height limitations.
QPixmap QPixmap
scaleDown(uint64_t maxWidth, uint64_t maxHeight, const QPixmap &source); scaleDown(uint64_t maxWidth, uint64_t maxHeight, const QPixmap &source);
@ -227,13 +102,6 @@ erase_if(ContainerT &items, const PredicateT &predicate)
} }
} }
template<class T>
QString
message_body(const mtx::events::collections::TimelineEvents &event)
{
return QString::fromStdString(std::get<T>(event).content.body);
}
//! Calculate the Levenshtein distance between two strings with character skipping. //! Calculate the Levenshtein distance between two strings with character skipping.
int int
levenshtein_distance(const std::string &s1, const std::string &s2); levenshtein_distance(const std::string &s1, const std::string &s2);
@ -249,9 +117,6 @@ mxcToHttp(const QUrl &url, const QString &server, int port);
QString QString
humanReadableFingerprint(const std::string &ed25519); humanReadableFingerprint(const std::string &ed25519);
QString
humanReadableFingerprint(const QString &ed25519);
//! Retrieve the message body taking into account the `formatted_body` field. //! Retrieve the message body taking into account the `formatted_body` field.
//! If the `format` of the message is not supported we fallback to `body`. //! If the `format` of the message is not supported we fallback to `body`.
template<typename RoomMessageT> template<typename RoomMessageT>

View file

@ -944,3 +944,33 @@ DeviceVerificationFlow::InitiateDeviceVerification(QObject *parent_,
return flow; return flow;
} }
template<typename T>
void
DeviceVerificationFlow::send(T msg)
{
if (this->type == DeviceVerificationFlow::Type::ToDevice) {
mtx::requests::ToDeviceMessages<T> body;
msg.transaction_id = this->transaction_id;
for (const auto &d : deviceIds)
body[this->toClient][d.toStdString()] = msg;
http::client()->send_to_device<T>(
http::client()->generate_txn_id(), body, [](mtx::http::RequestErr err) {
if (err)
nhlog::net()->warn("failed to send verification to_device message: {} {}",
err->matrix_error.error,
static_cast<int>(err->status_code));
});
} else if (this->type == DeviceVerificationFlow::Type::RoomMsg && model_) {
if constexpr (!std::is_same_v<T, mtx::events::msg::KeyVerificationRequest>) {
msg.relations.relations.push_back(this->relation);
// Set synthesized to surpress the nheko relation extensions
msg.relations.synthesized = true;
}
(model_)->sendMessageEvent(msg, mtx::events::to_device_content_to_type<T>);
}
nhlog::net()->debug("Sent verification step: {} in state: {}",
mtx::events::to_string(mtx::events::to_device_content_to_type<T>),
state().toStdString());
}

View file

@ -7,13 +7,14 @@
#include <QObject> #include <QObject>
#include <mtx/responses/crypto.hpp> #include <mtx/responses/crypto.hpp>
#include <mtxclient/crypto/client.hpp>
#include "CacheCryptoStructs.h" #include "CacheCryptoStructs.h"
#include "Logging.h" #include "Logging.h"
#include "MatrixClient.h" #include "MatrixClient.h"
#include "timeline/TimelineModel.h"
class QTimer; class QTimer;
class TimelineModel;
using sas_ptr = std::unique_ptr<mtx::crypto::SAS>; using sas_ptr = std::unique_ptr<mtx::crypto::SAS>;
@ -230,32 +231,5 @@ private:
bool keySent = false, macSent = false, acceptSent = false, startSent = false; bool keySent = false, macSent = false, acceptSent = false, startSent = false;
template<typename T> template<typename T>
void send(T msg) void send(T msg);
{
if (this->type == DeviceVerificationFlow::Type::ToDevice) {
mtx::requests::ToDeviceMessages<T> body;
msg.transaction_id = this->transaction_id;
for (const auto &d : deviceIds)
body[this->toClient][d.toStdString()] = msg;
http::client()->send_to_device<T>(
http::client()->generate_txn_id(), body, [](mtx::http::RequestErr err) {
if (err)
nhlog::net()->warn("failed to send verification to_device message: {} {}",
err->matrix_error.error,
static_cast<int>(err->status_code));
});
} else if (this->type == DeviceVerificationFlow::Type::RoomMsg && model_) {
if constexpr (!std::is_same_v<T, mtx::events::msg::KeyVerificationRequest>) {
msg.relations.relations.push_back(this->relation);
// Set synthesized to surpress the nheko relation extensions
msg.relations.synthesized = true;
}
(model_)->sendMessageEvent(msg, mtx::events::to_device_content_to_type<T>);
}
nhlog::net()->debug("Sent verification step: {} in state: {}",
mtx::events::to_string(mtx::events::to_device_content_to_type<T>),
state().toStdString());
}
}; };

View file

@ -1665,10 +1665,10 @@ request_cross_signing_keys()
}); });
}; };
request(mtx::secret_storage::secrets::cross_signing_master); request(std::string(mtx::secret_storage::secrets::cross_signing_master));
request(mtx::secret_storage::secrets::cross_signing_self_signing); request(std::string(mtx::secret_storage::secrets::cross_signing_self_signing));
request(mtx::secret_storage::secrets::cross_signing_user_signing); request(std::string(mtx::secret_storage::secrets::cross_signing_user_signing));
request(mtx::secret_storage::secrets::megolm_backup_v1); request(std::string(mtx::secret_storage::secrets::megolm_backup_v1));
} }
namespace { namespace {
@ -1725,22 +1725,22 @@ download_cross_signing_keys()
if (backup_key && !backup_key->encrypted.empty()) if (backup_key && !backup_key->encrypted.empty())
secrets[backup_key->encrypted.begin()->first] secrets[backup_key->encrypted.begin()->first]
[secrets::megolm_backup_v1] = [std::string(secrets::megolm_backup_v1)] =
backup_key->encrypted.begin()->second; backup_key->encrypted.begin()->second;
if (master_key && !master_key->encrypted.empty()) if (master_key && !master_key->encrypted.empty())
secrets[master_key->encrypted.begin()->first] secrets[master_key->encrypted.begin()->first]
[secrets::cross_signing_master] = [std::string(secrets::cross_signing_master)] =
master_key->encrypted.begin()->second; master_key->encrypted.begin()->second;
if (self_signing_key && !self_signing_key->encrypted.empty()) if (self_signing_key && !self_signing_key->encrypted.empty())
secrets[self_signing_key->encrypted.begin()->first] secrets[self_signing_key->encrypted.begin()->first]
[secrets::cross_signing_self_signing] = [std::string(secrets::cross_signing_self_signing)] =
self_signing_key->encrypted.begin()->second; self_signing_key->encrypted.begin()->second;
if (user_signing_key && !user_signing_key->encrypted.empty()) if (user_signing_key && !user_signing_key->encrypted.empty())
secrets[user_signing_key->encrypted.begin()->first] secrets[user_signing_key->encrypted.begin()->first]
[secrets::cross_signing_user_signing] = [std::string(secrets::cross_signing_user_signing)] =
user_signing_key->encrypted.begin()->second; user_signing_key->encrypted.begin()->second;
for (const auto &[key, secret_] : secrets) for (const auto &[key, secret_] : secrets)

View file

@ -110,7 +110,7 @@ SelfVerificationStatus::setupCrosssigning(bool useSSSS,
http::client()->set_secret_storage_default_key(ssss->keyDescription.name, http::client()->set_secret_storage_default_key(ssss->keyDescription.name,
[](mtx::http::RequestErr) {}); [](mtx::http::RequestErr) {});
auto uploadSecret = [ssss](const std::string &key_name, const std::string &secret) { auto uploadSecret = [ssss](std::string_view key_name, const std::string &secret) {
mtx::secret_storage::Secret s; mtx::secret_storage::Secret s;
s.encrypted[ssss->keyDescription.name] = s.encrypted[ssss->keyDescription.name] =
mtx::crypto::encrypt(secret, ssss->privateKey, key_name); mtx::crypto::encrypt(secret, ssss->privateKey, key_name);

View file

@ -18,7 +18,7 @@
#include <memory> #include <memory>
#include <mtx/common.hpp> #include <mtx/common.hpp>
#include <mtx/responses/messages.hpp> #include <mtx/events/common.hpp>
class TimelineModel; class TimelineModel;
class CombinedImagePackModel; class CombinedImagePackModel;