mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-25 12:38:48 +03:00
move detection code to nheko namespace and fix a few other bugs
This commit is contained in:
parent
eb13f7c169
commit
06e12a0a16
6 changed files with 80 additions and 114 deletions
|
@ -11,32 +11,8 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct nonesuch
|
|
||||||
{
|
|
||||||
~nonesuch() = delete;
|
|
||||||
nonesuch(nonesuch const &) = delete;
|
|
||||||
void operator=(nonesuch const &) = delete;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
template<class Default, class AlwaysVoid, template<class...> class Op, class... Args>
|
|
||||||
struct detector
|
|
||||||
{
|
|
||||||
using value_t = std::false_type;
|
|
||||||
using type = Default;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Default, template<class...> class Op, class... Args>
|
|
||||||
struct detector<Default, std::void_t<Op<Args...>>, Op, Args...>
|
|
||||||
{
|
|
||||||
using value_t = std::true_type;
|
|
||||||
using type = Op<Args...>;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template<template<class...> class Op, class... Args>
|
template<template<class...> class Op, class... Args>
|
||||||
using is_detected = typename detail::detector<nonesuch, void, Op, Args...>::value_t;
|
using is_detected = typename nheko::detail::detector<nheko::nonesuch, void, Op, Args...>::value_t;
|
||||||
|
|
||||||
struct IsStateEvent
|
struct IsStateEvent
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,6 +11,32 @@
|
||||||
|
|
||||||
#include <mtx/events/collections.hpp>
|
#include <mtx/events/collections.hpp>
|
||||||
|
|
||||||
|
namespace nheko {
|
||||||
|
struct nonesuch
|
||||||
|
{
|
||||||
|
~nonesuch() = delete;
|
||||||
|
nonesuch(nonesuch const &) = delete;
|
||||||
|
void operator=(nonesuch const &) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template<class Default, class AlwaysVoid, template<class...> class Op, class... Args>
|
||||||
|
struct detector
|
||||||
|
{
|
||||||
|
using value_t = std::false_type;
|
||||||
|
using type = Default;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Default, template<class...> class Op, class... Args>
|
||||||
|
struct detector<Default, std::void_t<Op<Args...>>, Op, Args...>
|
||||||
|
{
|
||||||
|
using value_t = std::true_type;
|
||||||
|
using type = Op<Args...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
}
|
||||||
|
|
||||||
namespace mtx::accessors {
|
namespace mtx::accessors {
|
||||||
std::string
|
std::string
|
||||||
event_id(const mtx::events::collections::TimelineEvents &event);
|
event_id(const mtx::events::collections::TimelineEvents &event);
|
||||||
|
|
|
@ -829,7 +829,7 @@ TimelineModel::forwardMessage(QString eventId, QString roomId)
|
||||||
if (!e)
|
if (!e)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
emit forwardToRoom(e, roomId, cache::isRoomEncrypted(room_id_.toStdString()));
|
emit forwardToRoom(e, roomId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -323,9 +323,7 @@ signals:
|
||||||
void roomNameChanged();
|
void roomNameChanged();
|
||||||
void roomTopicChanged();
|
void roomTopicChanged();
|
||||||
void roomAvatarUrlChanged();
|
void roomAvatarUrlChanged();
|
||||||
void forwardToRoom(mtx::events::collections::TimelineEvents *e,
|
void forwardToRoom(mtx::events::collections::TimelineEvents *e, QString roomId);
|
||||||
QString roomId,
|
|
||||||
bool sentFromEncrypted);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
|
@ -621,68 +621,63 @@ TimelineViewManager::focusTimeline()
|
||||||
|
|
||||||
void
|
void
|
||||||
TimelineViewManager::forwardMessageToRoom(mtx::events::collections::TimelineEvents *e,
|
TimelineViewManager::forwardMessageToRoom(mtx::events::collections::TimelineEvents *e,
|
||||||
QString roomId,
|
QString roomId)
|
||||||
bool sentFromEncrypted)
|
|
||||||
{
|
{
|
||||||
auto elem = *e;
|
auto elem = *e;
|
||||||
auto room = models.find(roomId);
|
auto room = models.find(roomId);
|
||||||
auto messageType = mtx::accessors::msg_type(elem);
|
auto content = mtx::accessors::url(elem);
|
||||||
auto content = mtx::accessors::url(elem);
|
std::optional<mtx::crypto::EncryptedFile> encryptionInfo = mtx::accessors::file(elem);
|
||||||
|
|
||||||
if (sentFromEncrypted) {
|
|
||||||
std::optional<mtx::crypto::EncryptedFile> encryptionInfo =
|
|
||||||
mtx::accessors::file(elem);
|
|
||||||
|
|
||||||
|
if (encryptionInfo) {
|
||||||
http::client()->download(
|
http::client()->download(
|
||||||
content,
|
content,
|
||||||
[this, roomId, e, encryptionInfo](const std::string &res,
|
[this, roomId, e, encryptionInfo](const std::string &res,
|
||||||
const std::string &content_type,
|
const std::string &content_type,
|
||||||
const std::string &originalFilename,
|
const std::string &originalFilename,
|
||||||
mtx::http::RequestErr err) {
|
mtx::http::RequestErr err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(encryptionInfo);
|
auto data = mtx::crypto::to_string(
|
||||||
|
mtx::crypto::decrypt_file(res, encryptionInfo.value()));
|
||||||
|
|
||||||
auto data = mtx::crypto::to_string(
|
http::client()->upload(
|
||||||
mtx::crypto::decrypt_file(res, encryptionInfo.value()));
|
data,
|
||||||
|
content_type,
|
||||||
|
originalFilename,
|
||||||
|
[this, roomId, e](const mtx::responses::ContentURI &res,
|
||||||
|
mtx::http::RequestErr err) mutable {
|
||||||
|
if (err) {
|
||||||
|
nhlog::net()->warn("failed to upload media: {} {} ({})",
|
||||||
|
err->matrix_error.error,
|
||||||
|
to_string(err->matrix_error.errcode),
|
||||||
|
static_cast<int>(err->status_code));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
http::client()->upload(
|
std::visit(
|
||||||
data,
|
[this, roomId, e, url = res.content_uri](auto ev) {
|
||||||
content_type,
|
if constexpr (mtx::events::message_content_to_type<
|
||||||
originalFilename,
|
decltype(ev.content)> ==
|
||||||
[this, roomId, e](const mtx::responses::ContentURI &res,
|
mtx::events::EventType::RoomMessage) {
|
||||||
mtx::http::RequestErr err) mutable {
|
if constexpr (messageWithFileAndUrl(ev)) {
|
||||||
if (err) {
|
ev.content.relations.relations
|
||||||
nhlog::net()->warn("failed to upload media: {} {} ({})",
|
.clear();
|
||||||
err->matrix_error.error,
|
ev.content.file.reset();
|
||||||
to_string(err->matrix_error.errcode),
|
ev.content.url = url;
|
||||||
static_cast<int>(err->status_code));
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::visit(
|
auto room = models.find(roomId);
|
||||||
[this, roomId, e, url = res.content_uri](auto ev) {
|
room.value()->sendMessageEvent(
|
||||||
if constexpr (mtx::events::message_content_to_type<
|
ev.content,
|
||||||
decltype(ev.content)> ==
|
mtx::events::EventType::RoomMessage);
|
||||||
mtx::events::EventType::RoomMessage) {
|
}
|
||||||
if constexpr (messageWithFileAndUrl(ev)) {
|
},
|
||||||
ev.content.relations.relations.clear();
|
*e);
|
||||||
ev.content.file.reset();
|
});
|
||||||
ev.content.url = url;
|
|
||||||
|
|
||||||
auto room = models.find(roomId);
|
return;
|
||||||
room.value()->sendMessageEvent(
|
|
||||||
ev.content,
|
|
||||||
mtx::events::EventType::RoomMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
*e);
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -32,33 +32,6 @@ class UserSettings;
|
||||||
class ChatPage;
|
class ChatPage;
|
||||||
class DeviceVerificationFlow;
|
class DeviceVerificationFlow;
|
||||||
|
|
||||||
struct nonesuch
|
|
||||||
{
|
|
||||||
~nonesuch() = delete;
|
|
||||||
nonesuch(nonesuch const &) = delete;
|
|
||||||
void operator=(nonesuch const &) = delete;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
template<class Default, class AlwaysVoid, template<class...> class Op, class... Args>
|
|
||||||
struct detector
|
|
||||||
{
|
|
||||||
using value_t = std::false_type;
|
|
||||||
using type = Default;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Default, template<class...> class Op, class... Args>
|
|
||||||
struct detector<Default, std::void_t<Op<Args...>>, Op, Args...>
|
|
||||||
{
|
|
||||||
using value_t = std::true_type;
|
|
||||||
using type = Op<Args...>;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template<template<class...> class Op, class... Args>
|
|
||||||
using is_detected = typename detail::detector<nonesuch, void, Op, Args...>::value_t;
|
|
||||||
|
|
||||||
class TimelineViewManager : public QObject
|
class TimelineViewManager : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -175,15 +148,17 @@ public slots:
|
||||||
|
|
||||||
void backToRooms() { emit showRoomList(); }
|
void backToRooms() { emit showRoomList(); }
|
||||||
QObject *completerFor(QString completerName, QString roomId = "");
|
QObject *completerFor(QString completerName, QString roomId = "");
|
||||||
void forwardMessageToRoom(mtx::events::collections::TimelineEvents *e,
|
void forwardMessageToRoom(mtx::events::collections::TimelineEvents *e, QString roomId);
|
||||||
QString roomId,
|
|
||||||
bool sentFromEncrypted);
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void openImageOverlayInternal(QString eventId, QImage img);
|
void openImageOverlayInternal(QString eventId, QImage img);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<class Content>
|
template<template<class...> class Op, class... Args>
|
||||||
|
using is_detected =
|
||||||
|
typename nheko::detail::detector<nheko::nonesuch, void, Op, Args...>::value_t;
|
||||||
|
|
||||||
|
template<class Content>
|
||||||
using f_t = decltype(Content::file);
|
using f_t = decltype(Content::file);
|
||||||
|
|
||||||
template<class Content>
|
template<class Content>
|
||||||
|
@ -192,11 +167,7 @@ private:
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static constexpr bool messageWithFileAndUrl(const mtx::events::Event<T> &e)
|
static constexpr bool messageWithFileAndUrl(const mtx::events::Event<T> &e)
|
||||||
{
|
{
|
||||||
if constexpr (is_detected<f_t, T>::value && is_detected<u_t, T>::value) {
|
return is_detected<f_t, T>::value && is_detected<u_t, T>::value;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in a new issue