summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2019-09-18 22:58:25 +0200
committerNicolas Werner <nicolas.werner@hotmail.de>2019-11-23 20:06:14 +0100
commit240b3a566b8f73261bd6c48ae7480800136e3ec2 (patch)
tree5c8c4a6d4434fa5c458dfee293bfcac8d8f8a69b /src
parentImplement basic placeholder and disable unimplemented event types (diff)
downloadnheko-240b3a566b8f73261bd6c48ae7480800136e3ec2.tar.xz
Add send/received indicator
Diffstat (limited to 'src')
-rw-r--r--src/timeline2/TimelineModel.cpp43
-rw-r--r--src/timeline2/TimelineModel.h47
2 files changed, 83 insertions, 7 deletions
diff --git a/src/timeline2/TimelineModel.cpp b/src/timeline2/TimelineModel.cpp

index 7a2edda4..13429c3e 100644 --- a/src/timeline2/TimelineModel.cpp +++ b/src/timeline2/TimelineModel.cpp
@@ -240,6 +240,35 @@ TimelineModel::TimelineModel(QString room_id, QObject *parent) { connect( this, &TimelineModel::oldMessagesRetrieved, this, &TimelineModel::addBackwardsEvents); + connect(this, &TimelineModel::messageFailed, this, [this](QString txn_id) { + pending.remove(txn_id); + failed.insert(txn_id); + int idx = idToIndex(txn_id); + if (idx < 0) { + nhlog::ui()->warn("Failed index out of range"); + return; + } + emit dataChanged(index(idx, 0), index(idx, 0)); + }); + connect(this, &TimelineModel::messageSent, this, [this](QString txn_id, QString event_id) { + int idx = idToIndex(txn_id); + if (idx < 0) { + nhlog::ui()->warn("Sent index out of range"); + return; + } + eventOrder[idx] = event_id; + auto ev = events.value(txn_id); + ev = boost::apply_visitor( + [event_id](const auto &e) -> mtx::events::collections::TimelineEvents { + auto eventCopy = e; + eventCopy.event_id = event_id.toStdString(); + return eventCopy; + }, + ev); + events.remove(txn_id); + events.insert(event_id, ev); + emit dataChanged(index(idx, 0), index(idx, 0)); + }); } QHash<int, QByteArray> @@ -258,6 +287,7 @@ TimelineModel::roleNames() const {Width, "width"}, {ProportionalHeight, "proportionalHeight"}, {Id, "id"}, + {State, "state"}, }; } int @@ -341,6 +371,13 @@ TimelineModel::data(const QModelIndex &index, int role) const [](const auto &e) -> double { return eventPropHeight(e); }, event)); case Id: return id; + case State: + if (failed.contains(id)) + return qml_mtx_events::Failed; + else if (pending.contains(id)) + return qml_mtx_events::Sent; + else + return qml_mtx_events::Received; default: return QVariant(); } @@ -378,8 +415,12 @@ TimelineModel::internalAddEvents( QString id = boost::apply_visitor([](const auto &e) -> QString { return eventId(e); }, e); - if (this->events.contains(id)) + if (this->events.contains(id)) { + this->events.insert(id, e); + int idx = idToIndex(id); + emit dataChanged(index(idx, 0), index(idx, 0)); continue; + } if (auto redaction = boost::get<mtx::events::RedactionEvent<mtx::events::msg::Redaction>>(&e)) { diff --git a/src/timeline2/TimelineModel.h b/src/timeline2/TimelineModel.h
index 17f83323..b651708d 100644 --- a/src/timeline2/TimelineModel.h +++ b/src/timeline2/TimelineModel.h
@@ -6,6 +6,7 @@ #include <QColor> #include <QDate> #include <QHash> +#include <QSet> #include "Logging.h" #include "MatrixClient.h" @@ -68,6 +69,21 @@ enum EventType UnknownMessage, }; Q_ENUM_NS(EventType) + +enum EventState +{ + //! The plaintext message was received by the server. + Received, + //! At least one of the participants has read the message. + Read, + //! The client sent the message. Not yet received. + Sent, + //! When the message is loaded from cache or backfill. + Empty, + //! When the message failed to send + Failed, +}; +Q_ENUM_NS(EventState) } struct DecryptionResult @@ -101,6 +117,7 @@ public: Width, ProportionalHeight, Id, + State, }; QHash<int, QByteArray> roleNames() const override; @@ -137,8 +154,8 @@ private slots: signals: void oldMessagesRetrieved(const mtx::responses::Messages &res); - void messageFailed(const std::string txn_id); - void messageSent(const std::string txn_id, std::string event_id); + void messageFailed(QString txn_id); + void messageSent(QString txn_id, QString event_id); void currentIndexChanged(int index); private: @@ -148,6 +165,7 @@ private: const std::vector<mtx::events::collections::TimelineEvents> &timeline); QHash<QString, mtx::events::collections::TimelineEvents> events; + QSet<QString> pending, failed; std::vector<QString> eventOrder; QString room_id_; @@ -164,20 +182,37 @@ template<class T> void TimelineModel::sendMessage(const T &msg) { - auto txn_id = http::client()->generate_txn_id(); + auto txn_id = http::client()->generate_txn_id(); + mtx::events::RoomEvent<T> msgCopy = {}; + msgCopy.content = msg; + msgCopy.type = mtx::events::EventType::RoomMessage; + msgCopy.event_id = txn_id; + msgCopy.sender = http::client()->user_id().to_string(); + msgCopy.origin_server_ts = QDateTime::currentMSecsSinceEpoch(); + internalAddEvents({msgCopy}); + + QString txn_id_qstr = QString::fromStdString(txn_id); + beginInsertRows(QModelIndex(), + static_cast<int>(this->eventOrder.size()), + static_cast<int>(this->eventOrder.size())); + pending.insert(txn_id_qstr); + this->eventOrder.insert(this->eventOrder.end(), txn_id_qstr); + endInsertRows(); + http::client()->send_room_message<T, mtx::events::EventType::RoomMessage>( room_id_.toStdString(), txn_id, msg, - [this, txn_id](const mtx::responses::EventId &res, mtx::http::RequestErr err) { + [this, txn_id, txn_id_qstr](const mtx::responses::EventId &res, + mtx::http::RequestErr err) { if (err) { const int status_code = static_cast<int>(err->status_code); nhlog::net()->warn("[{}] failed to send message: {} {}", txn_id, err->matrix_error.error, status_code); - emit messageFailed(txn_id); + emit messageFailed(txn_id_qstr); } - emit messageSent(txn_id, res.event_id.to_string()); + emit messageSent(txn_id_qstr, QString::fromStdString(res.event_id.to_string())); }); }