summary refs log tree commit diff
path: root/include/timeline/TimelineView.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/timeline/TimelineView.h')
-rw-r--r--include/timeline/TimelineView.h121
1 files changed, 86 insertions, 35 deletions
diff --git a/include/timeline/TimelineView.h b/include/timeline/TimelineView.h

index e6e35ccb..a86c0286 100644 --- a/include/timeline/TimelineView.h +++ b/include/timeline/TimelineView.h
@@ -18,7 +18,6 @@ #pragma once #include <QApplication> -#include <QDebug> #include <QLayout> #include <QList> #include <QQueue> @@ -34,6 +33,19 @@ #include "ScrollBar.h" #include "TimelineItem.h" +class StateKeeper +{ +public: + StateKeeper(std::function<void()> &&fn) + : fn_(std::move(fn)) + {} + + ~StateKeeper() { fn_(); } + +private: + std::function<void()> fn_; +}; + class FloatingButton; struct DescInfo; @@ -42,33 +54,44 @@ struct DescInfo; struct PendingMessage { mtx::events::MessageType ty; - int txn_id; + std::string txn_id; QString body; QString filename; QString mime; uint64_t media_size; QString event_id; TimelineItem *widget; - - PendingMessage(mtx::events::MessageType ty, - int txn_id, - QString body, - QString filename, - QString mime, - uint64_t media_size, - QString event_id, - TimelineItem *widget) - : ty(ty) - , txn_id(txn_id) - , body(body) - , filename(filename) - , mime(mime) - , media_size(media_size) - , event_id(event_id) - , widget(widget) - {} + bool is_encrypted = false; }; +template<class MessageT> +MessageT +toRoomMessage(const PendingMessage &) = delete; + +template<> +mtx::events::msg::Audio +toRoomMessage<mtx::events::msg::Audio>(const PendingMessage &m); + +template<> +mtx::events::msg::Emote +toRoomMessage<mtx::events::msg::Emote>(const PendingMessage &m); + +template<> +mtx::events::msg::File +toRoomMessage<mtx::events::msg::File>(const PendingMessage &); + +template<> +mtx::events::msg::Image +toRoomMessage<mtx::events::msg::Image>(const PendingMessage &m); + +template<> +mtx::events::msg::Text +toRoomMessage<mtx::events::msg::Text>(const PendingMessage &); + +template<> +mtx::events::msg::Video +toRoomMessage<mtx::events::msg::Video>(const PendingMessage &m); + // In which place new TimelineItems should be inserted. enum class TimelineDirection { @@ -129,7 +152,7 @@ public: const QString &filename, const QString &mime, uint64_t size); - void updatePendingMessage(int txn_id, QString event_id); + void updatePendingMessage(const std::string &txn_id, const QString &event_id); void scrollDown(); QLabel *createDateSeparator(QDateTime datetime); @@ -142,18 +165,21 @@ public slots: void fetchHistory(); // Add old events at the top of the timeline. - void addBackwardsEvents(const QString &room_id, const mtx::responses::Messages &msgs); + void addBackwardsEvents(const mtx::responses::Messages &msgs); // Whether or not the initial batch has been loaded. bool hasLoaded() { return scroll_layout_->count() > 1 || isTimelineFinished; } - void handleFailedMessage(int txnid); + void handleFailedMessage(const std::string &txn_id); private slots: void sendNextPendingMessage(); signals: void updateLastTimelineMessage(const QString &user, const DescInfo &info); + void messagesRetrieved(const mtx::responses::Messages &res); + void messageFailed(const std::string &txn_id); + void messageSent(const std::string &txn_id, const QString &event_id); protected: void paintEvent(QPaintEvent *event) override; @@ -165,6 +191,25 @@ private: QWidget *relativeWidget(TimelineItem *item, int dt) const; + TimelineEvent parseEncryptedEvent( + const mtx::events::EncryptedEvent<mtx::events::msg::Encrypted> &e); + + void handleClaimedKeys(std::shared_ptr<StateKeeper> keeper, + const std::string &room_key, + const DevicePublicKeys &pks, + const std::string &user_id, + const std::string &device_id, + const mtx::responses::ClaimKeys &res, + mtx::http::RequestErr err); + + //! Callback for all message sending. + void sendRoomMessageHandler(const std::string &txn_id, + const mtx::responses::EventId &res, + mtx::http::RequestErr err); + void prepareEncryptedMessage(const PendingMessage &msg); + + //! Call the /messages endpoint to fill the timeline. + void getMessages(); //! HACK: Fixing layout flickering when adding to the bottom //! of the timeline. void pushTimelineItem(TimelineItem *item) @@ -230,8 +275,10 @@ private: uint64_t origin_server_ts, TimelineDirection direction); - bool isPendingMessage(const QString &txnid, const QString &sender, const QString &userid); - void removePendingMessage(const QString &txnid); + bool isPendingMessage(const std::string &txn_id, + const QString &sender, + const QString &userid); + void removePendingMessage(const std::string &txn_id); bool isDuplicate(const QString &event_id) { return eventIds_.contains(event_id); } @@ -315,14 +362,18 @@ TimelineView::addUserMessage(const QString &url, lastMessageDirection_ = TimelineDirection::Bottom; - QApplication::processEvents(); - // Keep track of the sender and the timestamp of the current message. saveLastMessageInfo(local_user_, QDateTime::currentDateTime()); - int txn_id = http::client()->incrementTransactionId(); + PendingMessage message; + message.ty = MsgType; + message.txn_id = http::v2::client()->generate_txn_id(); + message.body = url; + message.filename = trimmed; + message.mime = mime; + message.media_size = size; + message.widget = view_item; - PendingMessage message(MsgType, txn_id, url, trimmed, mime, size, "", view_item); handleNewUserMessage(message); } @@ -351,10 +402,10 @@ TimelineView::processMessageEvent(const Event &event, TimelineDirection directio const auto event_id = QString::fromStdString(event.event_id); const auto sender = QString::fromStdString(event.sender); - const QString txnid = QString::fromStdString(event.unsigned_data.transaction_id); - if ((!txnid.isEmpty() && isPendingMessage(txnid, sender, local_user_)) || + const auto txn_id = event.unsigned_data.transaction_id; + if ((!txn_id.empty() && isPendingMessage(txn_id, sender, local_user_)) || isDuplicate(event_id)) { - removePendingMessage(txnid); + removePendingMessage(txn_id); return nullptr; } @@ -376,10 +427,10 @@ TimelineView::processMessageEvent(const Event &event, TimelineDirection directio const auto event_id = QString::fromStdString(event.event_id); const auto sender = QString::fromStdString(event.sender); - const QString txnid = QString::fromStdString(event.unsigned_data.transaction_id); - if ((!txnid.isEmpty() && isPendingMessage(txnid, sender, local_user_)) || + const auto txn_id = event.unsigned_data.transaction_id; + if ((!txn_id.empty() && isPendingMessage(txn_id, sender, local_user_)) || isDuplicate(event_id)) { - removePendingMessage(txnid); + removePendingMessage(txn_id); return nullptr; }