Skip to content
Snippets Groups Projects
Commit e084543c authored by Nicolas Werner's avatar Nicolas Werner
Browse files

Move visitors out of TimelineModel

parent 768ae9a5
No related branches found
No related tags found
No related merge requests found
......@@ -219,6 +219,7 @@ set(SRC_FILES
src/ChatPage.cpp
src/CommunitiesListItem.cpp
src/CommunitiesList.cpp
src/EventAccessors.cpp
src/InviteeItem.cpp
src/LoginPage.cpp
src/Logging.cpp
......
#include "EventAccessors.h"
#include <type_traits>
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>
using is_detected = typename detail::detector<nonesuch, void, Op, Args...>::value_t;
struct EventMsgType
{
template<class E>
using msgtype_t = decltype(E::msgtype);
template<class T>
mtx::events::MessageType operator()(const mtx::events::Event<T> &e)
{
if constexpr (is_detected<msgtype_t, T>::value)
return mtx::events::getMessageType(e.content.msgtype);
return mtx::events::MessageType::Unknown;
}
};
struct EventRoomName
{
template<class T>
std::string operator()(const T &e)
{
if constexpr (std::is_same_v<mtx::events::StateEvent<mtx::events::state::Name>, T>)
return e.content.name;
return "";
}
};
struct EventRoomTopic
{
template<class T>
std::string operator()(const T &e)
{
if constexpr (std::is_same_v<mtx::events::StateEvent<mtx::events::state::Topic>, T>)
return e.content.topic;
return "";
}
};
struct EventBody
{
template<class C>
using body_t = decltype(C::body);
template<class T>
std::string operator()(const mtx::events::Event<T> &e)
{
if constexpr (is_detected<body_t, T>::value)
return e.content.body;
return "";
}
};
struct EventFormattedBody
{
template<class C>
using formatted_body_t = decltype(C::formatted_body);
template<class T>
std::string operator()(const mtx::events::RoomEvent<T> &e)
{
if constexpr (is_detected<formatted_body_t, T>::value)
return e.content.formatted_body;
return "";
}
};
struct EventFile
{
template<class Content>
using file_t = decltype(Content::file);
template<class T>
std::optional<mtx::crypto::EncryptedFile> operator()(const mtx::events::Event<T> &e)
{
if constexpr (is_detected<file_t, T>::value)
return e.content.file;
return std::nullopt;
}
};
struct EventUrl
{
template<class Content>
using url_t = decltype(Content::url);
template<class T>
std::string operator()(const mtx::events::Event<T> &e)
{
if constexpr (is_detected<url_t, T>::value) {
if (auto file = EventFile{}(e))
return file->url;
return e.content.url;
}
return "";
}
};
struct EventThumbnailUrl
{
template<class Content>
using thumbnail_url_t = decltype(Content::info.thumbnail_url);
template<class T>
std::string operator()(const mtx::events::Event<T> &e)
{
if constexpr (is_detected<thumbnail_url_t, T>::value) {
return e.content.info.thumbnail_url;
}
return "";
}
};
struct EventFilename
{
template<class T>
std::string operator()(const mtx::events::Event<T> &)
{
return "";
}
std::string operator()(const mtx::events::RoomEvent<mtx::events::msg::Audio> &e)
{
// body may be the original filename
return e.content.body;
}
std::string operator()(const mtx::events::RoomEvent<mtx::events::msg::Video> &e)
{
// body may be the original filename
return e.content.body;
}
std::string operator()(const mtx::events::RoomEvent<mtx::events::msg::Image> &e)
{
// body may be the original filename
return e.content.body;
}
std::string operator()(const mtx::events::RoomEvent<mtx::events::msg::File> &e)
{
// body may be the original filename
if (!e.content.filename.empty())
return e.content.filename;
return e.content.body;
}
};
struct EventMimeType
{
template<class Content>
using mimetype_t = decltype(Content::info.mimetype);
template<class T>
std::string operator()(const mtx::events::Event<T> &e)
{
if constexpr (is_detected<mimetype_t, T>::value) {
return e.content.info.mimetype;
}
return "";
}
};
struct EventFilesize
{
template<class Content>
using filesize_t = decltype(Content::info.size);
template<class T>
int64_t operator()(const mtx::events::RoomEvent<T> &e)
{
if constexpr (is_detected<filesize_t, T>::value) {
return e.content.info.size;
}
return 0;
}
};
struct EventInReplyTo
{
template<class Content>
using related_ev_id_t = decltype(Content::relates_to.in_reply_to.event_id);
template<class T>
std::string operator()(const mtx::events::Event<T> &e)
{
if constexpr (is_detected<related_ev_id_t, T>::value) {
return e.content.relates_to.in_reply_to.event_id;
}
return "";
}
};
struct EventMediaHeight
{
template<class Content>
using h_t = decltype(Content::info.h);
template<class T>
uint64_t operator()(const mtx::events::Event<T> &e)
{
if constexpr (is_detected<h_t, T>::value) {
return e.content.info.h;
}
return -1;
}
};
struct EventMediaWidth
{
template<class Content>
using w_t = decltype(Content::info.w);
template<class T>
uint64_t operator()(const mtx::events::Event<T> &e)
{
if constexpr (is_detected<w_t, T>::value) {
return e.content.info.w;
}
return -1;
}
};
template<class T>
double
eventPropHeight(const mtx::events::RoomEvent<T> &e)
{
auto w = eventWidth(e);
if (w == 0)
w = 1;
double prop = eventHeight(e) / (double)w;
return prop > 0 ? prop : 1.;
}
}
std::string
mtx::accessors::event_id(const mtx::events::collections::TimelineEvents &event)
{
return std::visit([](const auto e) { return e.event_id; }, event);
}
std::string
mtx::accessors::room_id(const mtx::events::collections::TimelineEvents &event)
{
return std::visit([](const auto e) { return e.room_id; }, event);
}
std::string
mtx::accessors::sender(const mtx::events::collections::TimelineEvents &event)
{
return std::visit([](const auto e) { return e.sender; }, event);
}
QDateTime
mtx::accessors::origin_server_ts(const mtx::events::collections::TimelineEvents &event)
{
return QDateTime::fromMSecsSinceEpoch(
std::visit([](const auto e) { return e.origin_server_ts; }, event));
}
std::string
mtx::accessors::filename(const mtx::events::collections::TimelineEvents &event)
{
return std::visit(EventFilename{}, event);
}
mtx::events::MessageType
mtx::accessors::msg_type(const mtx::events::collections::TimelineEvents &event)
{
return std::visit(EventMsgType{}, event);
}
std::string
mtx::accessors::room_name(const mtx::events::collections::TimelineEvents &event)
{
return std::visit(EventRoomName{}, event);
}
std::string
mtx::accessors::room_topic(const mtx::events::collections::TimelineEvents &event)
{
return std::visit(EventRoomTopic{}, event);
}
std::string
mtx::accessors::body(const mtx::events::collections::TimelineEvents &event)
{
return std::visit(EventBody{}, event);
}
std::string
mtx::accessors::formatted_body(const mtx::events::collections::TimelineEvents &event)
{
return std::visit(EventFormattedBody{}, event);
}
QString
mtx::accessors::formattedBodyWithFallback(const mtx::events::collections::TimelineEvents &event)
{
auto formatted = formatted_body(event);
if (!formatted.empty())
return QString::fromStdString(formatted);
else
return QString::fromStdString(body(event)).toHtmlEscaped().replace("\n", "<br>");
}
std::optional<mtx::crypto::EncryptedFile>
mtx::accessors::file(const mtx::events::collections::TimelineEvents &event)
{
return std::visit(EventFile{}, event);
}
std::string
mtx::accessors::url(const mtx::events::collections::TimelineEvents &event)
{
return std::visit(EventUrl{}, event);
}
std::string
mtx::accessors::thumbnail_url(const mtx::events::collections::TimelineEvents &event)
{
return std::visit(EventThumbnailUrl{}, event);
}
std::string
mtx::accessors::mimetype(const mtx::events::collections::TimelineEvents &event)
{
return std::visit(EventMimeType{}, event);
}
std::string
mtx::accessors::in_reply_to_event(const mtx::events::collections::TimelineEvents &event)
{
return std::visit(EventInReplyTo{}, event);
}
int64_t
mtx::accessors::filesize(const mtx::events::collections::TimelineEvents &event)
{
return std::visit(EventFilesize{}, event);
}
uint64_t
mtx::accessors::media_height(const mtx::events::collections::TimelineEvents &event)
{
return std::visit(EventMediaHeight{}, event);
}
uint64_t
mtx::accessors::media_width(const mtx::events::collections::TimelineEvents &event)
{
return std::visit(EventMediaWidth{}, event);
}
#pragma once
#include <string>
#include <QDateTime>
#include <QString>
#include <mtx/events/collections.hpp>
namespace mtx::accessors {
std::string
event_id(const mtx::events::collections::TimelineEvents &event);
std::string
room_id(const mtx::events::collections::TimelineEvents &event);
std::string
sender(const mtx::events::collections::TimelineEvents &event);
QDateTime
origin_server_ts(const mtx::events::collections::TimelineEvents &event);
std::string
filename(const mtx::events::collections::TimelineEvents &event);
mtx::events::MessageType
msg_type(const mtx::events::collections::TimelineEvents &event);
std::string
room_name(const mtx::events::collections::TimelineEvents &event);
std::string
room_topic(const mtx::events::collections::TimelineEvents &event);
std::string
body(const mtx::events::collections::TimelineEvents &event);
std::string
formatted_body(const mtx::events::collections::TimelineEvents &event);
QString
formattedBodyWithFallback(const mtx::events::collections::TimelineEvents &event);
std::optional<mtx::crypto::EncryptedFile>
file(const mtx::events::collections::TimelineEvents &event);
std::string
url(const mtx::events::collections::TimelineEvents &event);
std::string
thumbnail_url(const mtx::events::collections::TimelineEvents &event);
std::string
mimetype(const mtx::events::collections::TimelineEvents &event);
std::string
in_reply_to_event(const mtx::events::collections::TimelineEvents &event);
int64_t
filesize(const mtx::events::collections::TimelineEvents &event);
uint64_t
media_height(const mtx::events::collections::TimelineEvents &event);
uint64_t
media_width(const mtx::events::collections::TimelineEvents &event);
}
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment