From e084543cc07bb430995aaeaf7fc779bfb4e03106 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 27 Dec 2019 21:49:55 +0100 Subject: Move visitors out of TimelineModel --- src/EventAccessors.cpp | 363 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 363 insertions(+) create mode 100644 src/EventAccessors.cpp (limited to 'src/EventAccessors.cpp') diff --git a/src/EventAccessors.cpp b/src/EventAccessors.cpp new file mode 100644 index 00000000..6264af58 --- /dev/null +++ b/src/EventAccessors.cpp @@ -0,0 +1,363 @@ +#include "EventAccessors.h" + +#include + +namespace { +struct nonesuch +{ + ~nonesuch() = delete; + nonesuch(nonesuch const &) = delete; + void operator=(nonesuch const &) = delete; +}; + +namespace detail { +template class Op, class... Args> +struct detector +{ + using value_t = std::false_type; + using type = Default; +}; + +template class Op, class... Args> +struct detector>, Op, Args...> +{ + using value_t = std::true_type; + using type = Op; +}; + +} // namespace detail + +template class Op, class... Args> +using is_detected = typename detail::detector::value_t; + +struct EventMsgType +{ + template + using msgtype_t = decltype(E::msgtype); + template + mtx::events::MessageType operator()(const mtx::events::Event &e) + { + if constexpr (is_detected::value) + return mtx::events::getMessageType(e.content.msgtype); + return mtx::events::MessageType::Unknown; + } +}; + +struct EventRoomName +{ + template + std::string operator()(const T &e) + { + if constexpr (std::is_same_v, T>) + return e.content.name; + return ""; + } +}; + +struct EventRoomTopic +{ + template + std::string operator()(const T &e) + { + if constexpr (std::is_same_v, T>) + return e.content.topic; + return ""; + } +}; + +struct EventBody +{ + template + using body_t = decltype(C::body); + template + std::string operator()(const mtx::events::Event &e) + { + if constexpr (is_detected::value) + return e.content.body; + return ""; + } +}; + +struct EventFormattedBody +{ + template + using formatted_body_t = decltype(C::formatted_body); + template + std::string operator()(const mtx::events::RoomEvent &e) + { + if constexpr (is_detected::value) + return e.content.formatted_body; + return ""; + } +}; + +struct EventFile +{ + template + using file_t = decltype(Content::file); + template + std::optional operator()(const mtx::events::Event &e) + { + if constexpr (is_detected::value) + return e.content.file; + return std::nullopt; + } +}; + +struct EventUrl +{ + template + using url_t = decltype(Content::url); + template + std::string operator()(const mtx::events::Event &e) + { + if constexpr (is_detected::value) { + if (auto file = EventFile{}(e)) + return file->url; + return e.content.url; + } + return ""; + } +}; + +struct EventThumbnailUrl +{ + template + using thumbnail_url_t = decltype(Content::info.thumbnail_url); + template + std::string operator()(const mtx::events::Event &e) + { + if constexpr (is_detected::value) { + return e.content.info.thumbnail_url; + } + return ""; + } +}; + +struct EventFilename +{ + template + std::string operator()(const mtx::events::Event &) + { + return ""; + } + std::string operator()(const mtx::events::RoomEvent &e) + { + // body may be the original filename + return e.content.body; + } + std::string operator()(const mtx::events::RoomEvent &e) + { + // body may be the original filename + return e.content.body; + } + std::string operator()(const mtx::events::RoomEvent &e) + { + // body may be the original filename + return e.content.body; + } + std::string operator()(const mtx::events::RoomEvent &e) + { + // body may be the original filename + if (!e.content.filename.empty()) + return e.content.filename; + return e.content.body; + } +}; + +struct EventMimeType +{ + template + using mimetype_t = decltype(Content::info.mimetype); + template + std::string operator()(const mtx::events::Event &e) + { + if constexpr (is_detected::value) { + return e.content.info.mimetype; + } + return ""; + } +}; + +struct EventFilesize +{ + template + using filesize_t = decltype(Content::info.size); + template + int64_t operator()(const mtx::events::RoomEvent &e) + { + if constexpr (is_detected::value) { + return e.content.info.size; + } + return 0; + } +}; + +struct EventInReplyTo +{ + template + using related_ev_id_t = decltype(Content::relates_to.in_reply_to.event_id); + template + std::string operator()(const mtx::events::Event &e) + { + if constexpr (is_detected::value) { + return e.content.relates_to.in_reply_to.event_id; + } + return ""; + } +}; + +struct EventMediaHeight +{ + template + using h_t = decltype(Content::info.h); + template + uint64_t operator()(const mtx::events::Event &e) + { + if constexpr (is_detected::value) { + return e.content.info.h; + } + return -1; + } +}; + +struct EventMediaWidth +{ + template + using w_t = decltype(Content::info.w); + template + uint64_t operator()(const mtx::events::Event &e) + { + if constexpr (is_detected::value) { + return e.content.info.w; + } + return -1; + } +}; + +template +double +eventPropHeight(const mtx::events::RoomEvent &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", "
"); +} + +std::optional +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); +} -- cgit 1.5.1 From ec9da9f42a29ef12e266ee1e05aebd17f98a3371 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Sun, 16 Feb 2020 00:20:41 +0100 Subject: Try to fix flickering, if sync return event before send completes --- src/EventAccessors.cpp | 20 ++++++++++++++++++++ src/EventAccessors.h | 2 ++ src/timeline/TimelineModel.cpp | 14 ++++++++++++++ 3 files changed, 36 insertions(+) (limited to 'src/EventAccessors.cpp') diff --git a/src/EventAccessors.cpp b/src/EventAccessors.cpp index 6264af58..20cdb63c 100644 --- a/src/EventAccessors.cpp +++ b/src/EventAccessors.cpp @@ -207,6 +207,20 @@ struct EventInReplyTo } }; +struct EventTransactionId +{ + template + std::string operator()(const mtx::events::RoomEvent &e) + { + return e.unsigned_data.transaction_id; + } + template + std::string operator()(const mtx::events::Event &e) + { + return e.unsigned_data.transaction_id; + } +}; + struct EventMediaHeight { template @@ -344,6 +358,12 @@ mtx::accessors::in_reply_to_event(const mtx::events::collections::TimelineEvents return std::visit(EventInReplyTo{}, event); } +std::string +mtx::accessors::transaction_id(const mtx::events::collections::TimelineEvents &event) +{ + return std::visit(EventTransactionId{}, event); +} + int64_t mtx::accessors::filesize(const mtx::events::collections::TimelineEvents &event) { diff --git a/src/EventAccessors.h b/src/EventAccessors.h index 5c03861d..cf79f68f 100644 --- a/src/EventAccessors.h +++ b/src/EventAccessors.h @@ -50,6 +50,8 @@ std::string mimetype(const mtx::events::collections::TimelineEvents &event); std::string in_reply_to_event(const mtx::events::collections::TimelineEvents &event); +std::string +transaction_id(const mtx::events::collections::TimelineEvents &event); int64_t filesize(const mtx::events::collections::TimelineEvents &event); diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index 104d564b..432cd329 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -538,6 +538,20 @@ TimelineModel::internalAddEvents( continue; } + QString txid = QString::fromStdString(mtx::accessors::transaction_id(e)); + if (this->pending.removeOne(txid)) { + this->events.insert(id, e); + this->events.remove(txid); + int idx = idToIndex(txid); + if (idx < 0) { + nhlog::ui()->warn("Received index out of range"); + continue; + } + eventOrder[idx] = id; + emit dataChanged(index(idx, 0), index(idx, 0)); + continue; + } + if (auto redaction = std::get_if>(&e)) { QString redacts = QString::fromStdString(redaction->redacts); -- cgit 1.5.1