mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 03:00:46 +03:00
Cleanup headers a bit more
This commit is contained in:
parent
488a93575a
commit
7824c77234
20 changed files with 226 additions and 269 deletions
|
@ -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 "")
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) \
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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()) {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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 =
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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{};
|
||||||
|
|
|
@ -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_) {
|
||||||
|
|
|
@ -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());
|
||||||
|
|
137
src/Utils.cpp
137
src/Utils.cpp
|
@ -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));
|
||||||
|
|
145
src/Utils.h
145
src/Utils.h
|
@ -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>
|
||||||
|
|
|
@ -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());
|
||||||
|
}
|
||||||
|
|
|
@ -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());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue