summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorKonstantinos Sideris <sideris.konstantin@gmail.com>2017-09-03 11:43:45 +0300
committerKonstantinos Sideris <sideris.konstantin@gmail.com>2017-09-03 11:43:45 +0300
commitb5ae84c3c3ee6ff42bb4ae4fd3a54e858160a1b1 (patch)
treed463295478ac0473383f22343bac251def46d6fe /src
parentAdd read support for m.emote events (#41) (diff)
downloadnheko-b5ae84c3c3ee6ff42bb4ae4fd3a54e858160a1b1.tar.xz
Add write support for m.emote events
closes #41
Diffstat (limited to 'src')
-rw-r--r--src/ChatPage.cc5
-rw-r--r--src/MatrixClient.cc874
-rw-r--r--src/TextInputWidget.cc152
-rw-r--r--src/TimelineItem.cc54
-rw-r--r--src/TimelineView.cc47
-rw-r--r--src/TimelineViewManager.cc21
6 files changed, 582 insertions, 571 deletions
diff --git a/src/ChatPage.cc b/src/ChatPage.cc

index 9bbf58b7..d393a65d 100644 --- a/src/ChatPage.cc +++ b/src/ChatPage.cc
@@ -148,6 +148,11 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent) view_manager_, SLOT(sendTextMessage(const QString &))); + connect(text_input_, + SIGNAL(sendEmoteMessage(const QString &)), + view_manager_, + SLOT(sendEmoteMessage(const QString &))); + connect(client_.data(), SIGNAL(roomAvatarRetrieved(const QString &, const QPixmap &)), this, diff --git a/src/MatrixClient.cc b/src/MatrixClient.cc
index 430bacf9..e42b4184 100644 --- a/src/MatrixClient.cc +++ b/src/MatrixClient.cc
@@ -35,709 +35,733 @@ MatrixClient::MatrixClient(QString server, QObject *parent) : QNetworkAccessManager(parent) { - server_ = "https://" + server; - api_url_ = "/_matrix/client/r0"; - token_ = ""; + server_ = "https://" + server; + api_url_ = "/_matrix/client/r0"; + token_ = ""; - QSettings settings; - txn_id_ = settings.value("client/transaction_id", 1).toInt(); + QSettings settings; + txn_id_ = settings.value("client/transaction_id", 1).toInt(); - connect(this, SIGNAL(finished(QNetworkReply *)), this, SLOT(onResponse(QNetworkReply *))); + connect(this, SIGNAL(finished(QNetworkReply *)), this, SLOT(onResponse(QNetworkReply *))); } void MatrixClient::reset() noexcept { - next_batch_ = ""; - server_ = ""; - token_ = ""; + next_batch_ = ""; + server_ = ""; + token_ = ""; - txn_id_ = 0; + txn_id_ = 0; } void MatrixClient::onVersionsResponse(QNetworkReply *reply) { - reply->deleteLater(); + reply->deleteLater(); - int status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + int status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if (status_code == 404) { - emit versionError("Versions endpoint was not found on the server. Possibly not a Matrix server"); - return; - } + if (status_code == 404) { + emit versionError( + "Versions endpoint was not found on the server. Possibly not a Matrix server"); + return; + } - if (status_code >= 400) { - qWarning() << "API version error: " << reply->errorString(); - emit versionError("An unknown error occured. Please try again."); - return; - } + if (status_code >= 400) { + qWarning() << "API version error: " << reply->errorString(); + emit versionError("An unknown error occured. Please try again."); + return; + } - auto data = reply->readAll(); - auto json = QJsonDocument::fromJson(data); + auto data = reply->readAll(); + auto json = QJsonDocument::fromJson(data); - VersionsResponse response; + VersionsResponse response; - try { - response.deserialize(json); - if (!response.isVersionSupported(0, 2, 0)) - emit versionError("Server does not support required API version."); - else - emit versionSuccess(); - } catch (DeserializationException &e) { - qWarning() << "Malformed JSON response" << e.what(); - emit versionError("Malformed response. Possibly not a Matrix server"); - } + try { + response.deserialize(json); + if (!response.isVersionSupported(0, 2, 0)) + emit versionError("Server does not support required API version."); + else + emit versionSuccess(); + } catch (DeserializationException &e) { + qWarning() << "Malformed JSON response" << e.what(); + emit versionError("Malformed response. Possibly not a Matrix server"); + } } void MatrixClient::onLoginResponse(QNetworkReply *reply) { - reply->deleteLater(); + reply->deleteLater(); - int status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + int status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if (status_code == 403) { - emit loginError(tr("Wrong username or password")); - return; - } + if (status_code == 403) { + emit loginError(tr("Wrong username or password")); + return; + } - if (status_code == 404) { - emit loginError(tr("Login endpoint was not found on the server")); - return; - } + if (status_code == 404) { + emit loginError(tr("Login endpoint was not found on the server")); + return; + } - if (status_code >= 400) { - qWarning() << "Login error: " << reply->errorString(); - emit loginError(tr("An unknown error occured. Please try again.")); - return; - } + if (status_code >= 400) { + qWarning() << "Login error: " << reply->errorString(); + emit loginError(tr("An unknown error occured. Please try again.")); + return; + } - auto data = reply->readAll(); - auto json = QJsonDocument::fromJson(data); + auto data = reply->readAll(); + auto json = QJsonDocument::fromJson(data); - LoginResponse response; + LoginResponse response; - try { - response.deserialize(json); - emit loginSuccess(response.getUserId(), server_.host(), response.getAccessToken()); - } catch (DeserializationException &e) { - qWarning() << "Malformed JSON response" << e.what(); - emit loginError(tr("Malformed response. Possibly not a Matrix server")); - } + try { + response.deserialize(json); + emit loginSuccess(response.getUserId(), server_.host(), response.getAccessToken()); + } catch (DeserializationException &e) { + qWarning() << "Malformed JSON response" << e.what(); + emit loginError(tr("Malformed response. Possibly not a Matrix server")); + } } void MatrixClient::onLogoutResponse(QNetworkReply *reply) { - reply->deleteLater(); + reply->deleteLater(); - int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if (status != 200) { - qWarning() << "Logout error: " << reply->errorString(); - return; - } + if (status != 200) { + qWarning() << "Logout error: " << reply->errorString(); + return; + } - emit loggedOut(); + emit loggedOut(); } void MatrixClient::onRegisterResponse(QNetworkReply *reply) { - reply->deleteLater(); + reply->deleteLater(); - int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - auto data = reply->readAll(); - auto json = QJsonDocument::fromJson(data); + auto data = reply->readAll(); + auto json = QJsonDocument::fromJson(data); - if (status == 0 || status >= 400) { - if (json.isObject() && json.object().contains("error")) - emit registerError(json.object().value("error").toString()); - else - emit registerError(reply->errorString()); + if (status == 0 || status >= 400) { + if (json.isObject() && json.object().contains("error")) + emit registerError(json.object().value("error").toString()); + else + emit registerError(reply->errorString()); - return; - } + return; + } - RegisterResponse response; + RegisterResponse response; - try { - response.deserialize(json); - emit registerSuccess(response.getUserId(), response.getHomeServer(), response.getAccessToken()); - } catch (DeserializationException &e) { - qWarning() << "Register" << e.what(); - emit registerError("Received malformed response."); - } + try { + response.deserialize(json); + emit registerSuccess( + response.getUserId(), response.getHomeServer(), response.getAccessToken()); + } catch (DeserializationException &e) { + qWarning() << "Register" << e.what(); + emit registerError("Received malformed response."); + } } void MatrixClient::onGetOwnProfileResponse(QNetworkReply *reply) { - reply->deleteLater(); + reply->deleteLater(); - int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if (status >= 400) { - qWarning() << reply->errorString(); - return; - } + if (status >= 400) { + qWarning() << reply->errorString(); + return; + } - auto data = reply->readAll(); - auto json = QJsonDocument::fromJson(data); + auto data = reply->readAll(); + auto json = QJsonDocument::fromJson(data); - ProfileResponse response; + ProfileResponse response; - try { - response.deserialize(json); - emit getOwnProfileResponse(response.getAvatarUrl(), response.getDisplayName()); - } catch (DeserializationException &e) { - qWarning() << "Profile:" << e.what(); - } + try { + response.deserialize(json); + emit getOwnProfileResponse(response.getAvatarUrl(), response.getDisplayName()); + } catch (DeserializationException &e) { + qWarning() << "Profile:" << e.what(); + } } void MatrixClient::onInitialSyncResponse(QNetworkReply *reply) { - reply->deleteLater(); + reply->deleteLater(); - int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if (status == 0 || status >= 400) { - qWarning() << reply->errorString(); - return; - } + if (status == 0 || status >= 400) { + qWarning() << reply->errorString(); + return; + } - auto data = reply->readAll(); + auto data = reply->readAll(); - if (data.isEmpty()) - return; + if (data.isEmpty()) + return; - auto json = QJsonDocument::fromJson(data); + auto json = QJsonDocument::fromJson(data); - SyncResponse response; + SyncResponse response; - try { - response.deserialize(json); - } catch (DeserializationException &e) { - qWarning() << "Sync malformed response" << e.what(); - return; - } + try { + response.deserialize(json); + } catch (DeserializationException &e) { + qWarning() << "Sync malformed response" << e.what(); + return; + } - emit initialSyncCompleted(response); + emit initialSyncCompleted(response); } void MatrixClient::onSyncResponse(QNetworkReply *reply) { - reply->deleteLater(); + reply->deleteLater(); - int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if (status == 0 || status >= 400) { - emit syncFailed(reply->errorString()); - return; - } + if (status == 0 || status >= 400) { + emit syncFailed(reply->errorString()); + return; + } - auto data = reply->readAll(); + auto data = reply->readAll(); - if (data.isEmpty()) - return; + if (data.isEmpty()) + return; - auto json = QJsonDocument::fromJson(data); + auto json = QJsonDocument::fromJson(data); - SyncResponse response; + SyncResponse response; - try { - response.deserialize(json); - emit syncCompleted(response); - } catch (DeserializationException &e) { - qWarning() << "Sync malformed response" << e.what(); - } + try { + response.deserialize(json); + emit syncCompleted(response); + } catch (DeserializationException &e) { + qWarning() << "Sync malformed response" << e.what(); + } } void -MatrixClient::onSendTextMessageResponse(QNetworkReply *reply) +MatrixClient::onSendRoomMessage(QNetworkReply *reply) { - reply->deleteLater(); + reply->deleteLater(); - int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if (status == 0 || status >= 400) { - qWarning() << reply->errorString(); - return; - } + if (status == 0 || status >= 400) { + qWarning() << reply->errorString(); + return; + } - auto data = reply->readAll(); + auto data = reply->readAll(); - if (data.isEmpty()) - return; + if (data.isEmpty()) + return; - auto json = QJsonDocument::fromJson(data); + auto json = QJsonDocument::fromJson(data); - if (!json.isObject()) { - qDebug() << "Send message response is not a JSON object"; - return; - } + if (!json.isObject()) { + qDebug() << "Send message response is not a JSON object"; + return; + } - auto object = json.object(); + auto object = json.object(); - if (!object.contains("event_id")) { - qDebug() << "SendTextMessage: missing event_id from response"; - return; - } + if (!object.contains("event_id")) { + qDebug() << "SendTextMessage: missing event_id from response"; + return; + } - emit messageSent(object.value("event_id").toString(), - reply->property("roomid").toString(), - reply->property("txn_id").toInt()); + emit messageSent(object.value("event_id").toString(), + reply->property("roomid").toString(), + reply->property("txn_id").toInt()); } void MatrixClient::onRoomAvatarResponse(QNetworkReply *reply) { - reply->deleteLater(); + reply->deleteLater(); - int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if (status == 0 || status >= 400) { - qWarning() << reply->errorString(); - return; - } + if (status == 0 || status >= 400) { + qWarning() << reply->errorString(); + return; + } - auto img = reply->readAll(); + auto img = reply->readAll(); - if (img.size() == 0) - return; + if (img.size() == 0) + return; - auto roomid = reply->property("roomid").toString(); + auto roomid = reply->property("roomid").toString(); - QPixmap pixmap; - pixmap.loadFromData(img); + QPixmap pixmap; + pixmap.loadFromData(img); - emit roomAvatarRetrieved(roomid, pixmap); + emit roomAvatarRetrieved(roomid, pixmap); } void MatrixClient::onUserAvatarResponse(QNetworkReply *reply) { - reply->deleteLater(); + reply->deleteLater(); - int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if (status == 0 || status >= 400) { - qWarning() << reply->errorString(); - return; - } + if (status == 0 || status >= 400) { + qWarning() << reply->errorString(); + return; + } - auto data = reply->readAll(); + auto data = reply->readAll(); - if (data.size() == 0) - return; + if (data.size() == 0) + return; - auto roomid = reply->property("userid").toString(); + auto roomid = reply->property("userid").toString(); - QImage img; - img.loadFromData(data); + QImage img; + img.loadFromData(data); - emit userAvatarRetrieved(roomid, img); + emit userAvatarRetrieved(roomid, img); } void MatrixClient::onGetOwnAvatarResponse(QNetworkReply *reply) { - reply->deleteLater(); + reply->deleteLater(); - int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if (status == 0 || status >= 400) { - qWarning() << reply->errorString(); - return; - } + if (status == 0 || status >= 400) { + qWarning() << reply->errorString(); + return; + } - auto img = reply->readAll(); + auto img = reply->readAll(); - if (img.size() == 0) - return; + if (img.size() == 0) + return; - QPixmap pixmap; - pixmap.loadFromData(img); + QPixmap pixmap; + pixmap.loadFromData(img); - emit ownAvatarRetrieved(pixmap); + emit ownAvatarRetrieved(pixmap); } void MatrixClient::onImageResponse(QNetworkReply *reply) { - reply->deleteLater(); + reply->deleteLater(); - int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if (status == 0 || status >= 400) { - qWarning() << reply->errorString(); - return; - } + if (status == 0 || status >= 400) { + qWarning() << reply->errorString(); + return; + } - auto img = reply->readAll(); + auto img = reply->readAll(); - if (img.size() == 0) - return; + if (img.size() == 0) + return; - QPixmap pixmap; - pixmap.loadFromData(img); + QPixmap pixmap; + pixmap.loadFromData(img); - auto event_id = reply->property("event_id").toString(); + auto event_id = reply->property("event_id").toString(); - emit imageDownloaded(event_id, pixmap); + emit imageDownloaded(event_id, pixmap); } void MatrixClient::onMessagesResponse(QNetworkReply *reply) { - reply->deleteLater(); + reply->deleteLater(); - int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + int status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - if (status == 0 || status >= 400) { - qWarning() << reply->errorString(); - return; - } + if (status == 0 || status >= 400) { + qWarning() << reply->errorString(); + return; + } - auto data = reply->readAll(); - auto room_id = reply->property("room_id").toString(); + auto data = reply->readAll(); + auto room_id = reply->property("room_id").toString(); - RoomMessages msgs; + RoomMessages msgs; - try { - msgs.deserialize(QJsonDocument::fromJson(data)); - } catch (const DeserializationException &e) { - qWarning() << "Room messages from" << room_id << e.what(); - return; - } + try { + msgs.deserialize(QJsonDocument::fromJson(data)); + } catch (const DeserializationException &e) { + qWarning() << "Room messages from" << room_id << e.what(); + return; + } - emit messagesRetrieved(room_id, msgs); + emit messagesRetrieved(room_id, msgs); } void MatrixClient::onResponse(QNetworkReply *reply) { - switch (static_cast<Endpoint>(reply->property("endpoint").toInt())) { - case Endpoint::Versions: - onVersionsResponse(reply); - break; - case Endpoint::Login: - onLoginResponse(reply); - break; - case Endpoint::Logout: - onLogoutResponse(reply); - break; - case Endpoint::Register: - onRegisterResponse(reply); - break; - case Endpoint::GetOwnProfile: - onGetOwnProfileResponse(reply); - break; - case Endpoint::Image: - onImageResponse(reply); - break; - case Endpoint::InitialSync: - onInitialSyncResponse(reply); - break; - case Endpoint::Sync: - onSyncResponse(reply); - break; - case Endpoint::SendTextMessage: - onSendTextMessageResponse(reply); - break; - case Endpoint::RoomAvatar: - onRoomAvatarResponse(reply); - break; - case Endpoint::UserAvatar: - onUserAvatarResponse(reply); - break; - case Endpoint::GetOwnAvatar: - onGetOwnAvatarResponse(reply); - break; - case Endpoint::Messages: - onMessagesResponse(reply); - break; - default: - break; - } + switch (static_cast<Endpoint>(reply->property("endpoint").toInt())) { + case Endpoint::Versions: + onVersionsResponse(reply); + break; + case Endpoint::Login: + onLoginResponse(reply); + break; + case Endpoint::Logout: + onLogoutResponse(reply); + break; + case Endpoint::Register: + onRegisterResponse(reply); + break; + case Endpoint::GetOwnProfile: + onGetOwnProfileResponse(reply); + break; + case Endpoint::Image: + onImageResponse(reply); + break; + case Endpoint::InitialSync: + onInitialSyncResponse(reply); + break; + case Endpoint::Sync: + onSyncResponse(reply); + break; + case Endpoint::SendRoomMessage: + onSendRoomMessage(reply); + break; + case Endpoint::RoomAvatar: + onRoomAvatarResponse(reply); + break; + case Endpoint::UserAvatar: + onUserAvatarResponse(reply); + break; + case Endpoint::GetOwnAvatar: + onGetOwnAvatarResponse(reply); + break; + case Endpoint::Messages: + onMessagesResponse(reply); + break; + default: + break; + } } void MatrixClient::login(const QString &username, const QString &password) noexcept { - QUrl endpoint(server_); - endpoint.setPath(api_url_ + "/login"); + QUrl endpoint(server_); + endpoint.setPath(api_url_ + "/login"); - QNetworkRequest request(endpoint); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + QNetworkRequest request(endpoint); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - LoginRequest body(username, password); + LoginRequest body(username, password); - QNetworkReply *reply = post(request, body.serialize()); - reply->setProperty("endpoint", static_cast<int>(Endpoint::Login)); + QNetworkReply *reply = post(request, body.serialize()); + reply->setProperty("endpoint", static_cast<int>(Endpoint::Login)); } void MatrixClient::logout() noexcept { - QUrlQuery query; - query.addQueryItem("access_token", token_); + QUrlQuery query; + query.addQueryItem("access_token", token_); - QUrl endpoint(server_); - endpoint.setPath(api_url_ + "/logout"); - endpoint.setQuery(query); + QUrl endpoint(server_); + endpoint.setPath(api_url_ + "/logout"); + endpoint.setQuery(query); - QNetworkRequest request(endpoint); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + QNetworkRequest request(endpoint); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - QJsonObject body{}; - QNetworkReply *reply = post(request, QJsonDocument(body).toJson(QJsonDocument::Compact)); - reply->setProperty("endpoint", static_cast<int>(Endpoint::Logout)); + QJsonObject body{}; + QNetworkReply *reply = post(request, QJsonDocument(body).toJson(QJsonDocument::Compact)); + reply->setProperty("endpoint", static_cast<int>(Endpoint::Logout)); } void MatrixClient::registerUser(const QString &user, const QString &pass, const QString &server) noexcept { - setServer(server); + setServer(server); - QUrlQuery query; - query.addQueryItem("kind", "user"); + QUrlQuery query; + query.addQueryItem("kind", "user"); - QUrl endpoint(server_); - endpoint.setPath(api_url_ + "/register"); - endpoint.setQuery(query); + QUrl endpoint(server_); + endpoint.setPath(api_url_ + "/register"); + endpoint.setQuery(query); - QNetworkRequest request(QString(endpoint.toEncoded())); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + QNetworkRequest request(QString(endpoint.toEncoded())); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - RegisterRequest body(user, pass); + RegisterRequest body(user, pass); - QNetworkReply *reply = post(request, body.serialize()); - reply->setProperty("endpoint", static_cast<int>(Endpoint::Register)); + QNetworkReply *reply = post(request, body.serialize()); + reply->setProperty("endpoint", static_cast<int>(Endpoint::Register)); } void MatrixClient::sync() noexcept { - QJsonObject filter{ { "room", QJsonObject{ { "ephemeral", QJsonObject{ { "limit", 0 } } } } }, - { "presence", QJsonObject{ { "limit", 0 } } } }; + QJsonObject filter{ { "room", + QJsonObject{ { "ephemeral", QJsonObject{ { "limit", 0 } } } } }, + { "presence", QJsonObject{ { "limit", 0 } } } }; - QUrlQuery query; - query.addQueryItem("set_presence", "online"); - query.addQueryItem("filter", QJsonDocument(filter).toJson(QJsonDocument::Compact)); - query.addQueryItem("timeout", "30000"); - query.addQueryItem("access_token", token_); + QUrlQuery query; + query.addQueryItem("set_presence", "online"); + query.addQueryItem("filter", QJsonDocument(filter).toJson(QJsonDocument::Compact)); + query.addQueryItem("timeout", "30000"); + query.addQueryItem("access_token", token_); - if (next_batch_.isEmpty()) { - qDebug() << "Sync requires a valid next_batch token. Initial sync should be performed."; - return; - } + if (next_batch_.isEmpty()) { + qDebug() + << "Sync requires a valid next_batch token. Initial sync should be performed."; + return; + } - query.addQueryItem("since", next_batch_); + query.addQueryItem("since", next_batch_); - QUrl endpoint(server_); - endpoint.setPath(api_url_ + "/sync"); - endpoint.setQuery(query); + QUrl endpoint(server_); + endpoint.setPath(api_url_ + "/sync"); + endpoint.setQuery(query); - QNetworkRequest request(QString(endpoint.toEncoded())); + QNetworkRequest request(QString(endpoint.toEncoded())); - QNetworkReply *reply = get(request); - reply->setProperty("endpoint", static_cast<int>(Endpoint::Sync)); + QNetworkReply *reply = get(request); + reply->setProperty("endpoint", static_cast<int>(Endpoint::Sync)); } void -MatrixClient::sendTextMessage(const QString &roomid, const QString &msg) noexcept +MatrixClient::sendRoomMessage(matrix::events::MessageEventType ty, + const QString &roomid, + const QString &msg) noexcept { - QUrlQuery query; - query.addQueryItem("access_token", token_); + QUrlQuery query; + query.addQueryItem("access_token", token_); - QUrl endpoint(server_); - endpoint.setPath(api_url_ + QString("/rooms/%1/send/m.room.message/%2").arg(roomid).arg(txn_id_)); - endpoint.setQuery(query); + QUrl endpoint(server_); + endpoint.setPath(api_url_ + + QString("/rooms/%1/send/m.room.message/%2").arg(roomid).arg(txn_id_)); + endpoint.setQuery(query); - QJsonObject body{ { "msgtype", "m.text" }, { "body", msg } }; + QString msgType(""); - QNetworkRequest request(QString(endpoint.toEncoded())); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + switch (ty) { + case matrix::events::MessageEventType::Text: + msgType = "m.text"; + break; + case matrix::events::MessageEventType::Emote: + msgType = "m.emote"; + break; + default: + msgType = "m.text"; + break; + } - QNetworkReply *reply = put(request, QJsonDocument(body).toJson(QJsonDocument::Compact)); + QJsonObject body{ { "msgtype", msgType }, { "body", msg } }; - reply->setProperty("endpoint", static_cast<int>(Endpoint::SendTextMessage)); - reply->setProperty("txn_id", txn_id_); - reply->setProperty("roomid", roomid); + QNetworkRequest request(QString(endpoint.toEncoded())); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - incrementTransactionId(); + QNetworkReply *reply = put(request, QJsonDocument(body).toJson(QJsonDocument::Compact)); + reply->setProperty("endpoint", static_cast<int>(Endpoint::SendRoomMessage)); + reply->setProperty("txn_id", txn_id_); + reply->setProperty("roomid", roomid); + + incrementTransactionId(); } void MatrixClient::initialSync() noexcept { - QJsonArray excluded_presence = { - QString("m.presence"), - }; + QJsonArray excluded_presence = { + QString("m.presence"), + }; - QJsonObject filter{ { "room", - QJsonObject{ { "timeline", QJsonObject{ { "limit", 20 } } }, - { "ephemeral", QJsonObject{ { "limit", 0 } } } } }, - { "presence", QJsonObject{ { "not_types", excluded_presence } } } }; + QJsonObject filter{ { "room", + QJsonObject{ { "timeline", QJsonObject{ { "limit", 20 } } }, + { "ephemeral", QJsonObject{ { "limit", 0 } } } } }, + { "presence", QJsonObject{ { "not_types", excluded_presence } } } }; - QUrlQuery query; - query.addQueryItem("full_state", "true"); - query.addQueryItem("set_presence", "online"); - query.addQueryItem("filter", QJsonDocument(filter).toJson(QJsonDocument::Compact)); - query.addQueryItem("access_token", token_); + QUrlQuery query; + query.addQueryItem("full_state", "true"); + query.addQueryItem("set_presence", "online"); + query.addQueryItem("filter", QJsonDocument(filter).toJson(QJsonDocument::Compact)); + query.addQueryItem("access_token", token_); - QUrl endpoint(server_); - endpoint.setPath(api_url_ + "/sync"); - endpoint.setQuery(query); + QUrl endpoint(server_); + endpoint.setPath(api_url_ + "/sync"); + endpoint.setQuery(query); - QNetworkRequest request(QString(endpoint.toEncoded())); + QNetworkRequest request(QString(endpoint.toEncoded())); - QNetworkReply *reply = get(request); - reply->setProperty("endpoint", static_cast<int>(Endpoint::InitialSync)); + QNetworkReply *reply = get(request); + reply->setProperty("endpoint", static_cast<int>(Endpoint::InitialSync)); } void MatrixClient::versions() noexcept { - QUrl endpoint(server_); - endpoint.setPath("/_matrix/client/versions"); + QUrl endpoint(server_); + endpoint.setPath("/_matrix/client/versions"); - QNetworkRequest request(endpoint); + QNetworkRequest request(endpoint); - QNetworkReply *reply = get(request); - reply->setProperty("endpoint", static_cast<int>(Endpoint::Versions)); + QNetworkReply *reply = get(request); + reply->setProperty("endpoint", static_cast<int>(Endpoint::Versions)); } void MatrixClient::getOwnProfile() noexcept { - // FIXME: Remove settings from the matrix client. The class should store the user's matrix ID. - QSettings settings; - auto userid = settings.value("auth/user_id", "").toString(); + // FIXME: Remove settings from the matrix client. The class should store the user's matrix + // ID. + QSettings settings; + auto userid = settings.value("auth/user_id", "").toString(); - QUrlQuery query; - query.addQueryItem("access_token", token_); + QUrlQuery query; + query.addQueryItem("access_token", token_); - QUrl endpoint(server_); - endpoint.setPath(api_url_ + "/profile/" + userid); - endpoint.setQuery(query); + QUrl endpoint(server_); + endpoint.setPath(api_url_ + "/profile/" + userid); + endpoint.setQuery(query); - QNetworkRequest request(QString(endpoint.toEncoded())); + QNetworkRequest request(QString(endpoint.toEncoded())); - QNetworkReply *reply = get(request); - reply->setProperty("endpoint", static_cast<int>(Endpoint::GetOwnProfile)); + QNetworkReply *reply = get(request); + reply->setProperty("endpoint", static_cast<int>(Endpoint::GetOwnProfile)); } void MatrixClient::fetchRoomAvatar(const QString &roomid, const QUrl &avatar_url) { - QList<QString> url_parts = avatar_url.toString().split("mxc://"); + QList<QString> url_parts = avatar_url.toString().split("mxc://"); - if (url_parts.size() != 2) { - qDebug() << "Invalid format for room avatar " << avatar_url.toString(); - return; - } + if (url_parts.size() != 2) { + qDebug() << "Invalid format for room avatar " << avatar_url.toString(); + return; + } - QUrlQuery query; - query.addQueryItem("width", "512"); - query.addQueryItem("height", "512"); - query.addQueryItem("method", "crop"); + QUrlQuery query; + query.addQueryItem("width", "512"); + query.addQueryItem("height", "512"); + query.addQueryItem("method", "crop"); - QString media_url = QString("%1/_matrix/media/r0/thumbnail/%2").arg(getHomeServer().toString(), url_parts[1]); + QString media_url = + QString("%1/_matrix/media/r0/thumbnail/%2").arg(getHomeServer().toString(), url_parts[1]); - QUrl endpoint(media_url); - endpoint.setQuery(query); + QUrl endpoint(media_url); + endpoint.setQuery(query); - QNetworkRequest avatar_request(endpoint); + QNetworkRequest avatar_request(endpoint); - QNetworkReply *reply = get(avatar_request); - reply->setProperty("roomid", roomid); - reply->setProperty("endpoint", static_cast<int>(Endpoint::RoomAvatar)); + QNetworkReply *reply = get(avatar_request); + reply->setProperty("roomid", roomid); + reply->setProperty("endpoint", static_cast<int>(Endpoint::RoomAvatar)); } void MatrixClient::fetchUserAvatar(const QString &userId, const QUrl &avatarUrl) { - QList<QString> url_parts = avatarUrl.toString().split("mxc://"); + QList<QString> url_parts = avatarUrl.toString().split("mxc://"); - if (url_parts.size() != 2) { - qDebug() << "Invalid format for user avatar " << avatarUrl.toString(); - return; - } + if (url_parts.size() != 2) { + qDebug() << "Invalid format for user avatar " << avatarUrl.toString(); + return; + } - QUrlQuery query; - query.addQueryItem("width", "128"); - query.addQueryItem("height", "128"); - query.addQueryItem("method", "crop"); + QUrlQuery query; + query.addQueryItem("width", "128"); + query.addQueryItem("height", "128"); + query.addQueryItem("method", "crop"); - QString media_url = QString("%1/_matrix/media/r0/thumbnail/%2").arg(getHomeServer().toString(), url_parts[1]); + QString media_url = + QString("%1/_matrix/media/r0/thumbnail/%2").arg(getHomeServer().toString(), url_parts[1]); - QUrl endpoint(media_url); - endpoint.setQuery(query); + QUrl endpoint(media_url); + endpoint.setQuery(query); - QNetworkRequest avatar_request(endpoint); + QNetworkRequest avatar_request(endpoint); - QNetworkReply *reply = get(avatar_request); - reply->setProperty("userid", userId); - reply->setProperty("endpoint", static_cast<int>(Endpoint::UserAvatar)); + QNetworkReply *reply = get(avatar_request); + reply->setProperty("userid", userId); + reply->setProperty("endpoint", static_cast<int>(Endpoint::UserAvatar)); } void MatrixClient::downloadImage(const QString &event_id, const QUrl &url) { - QNetworkRequest image_request(url); + QNetworkRequest image_request(url); - QNetworkReply *reply = get(image_request); - reply->setProperty("event_id", event_id); - reply->setProperty("endpoint", static_cast<int>(Endpoint::Image)); + QNetworkReply *reply = get(image_request); + reply->setProperty("event_id", event_id); + reply->setProperty("endpoint", static_cast<int>(Endpoint::Image)); } void MatrixClient::fetchOwnAvatar(const QUrl &avatar_url) { - QList<QString> url_parts = avatar_url.toString().split("mxc://"); + QList<QString> url_parts = avatar_url.toString().split("mxc://"); - if (url_parts.size() != 2) { - qDebug() << "Invalid format for media " << avatar_url.toString(); - return; - } + if (url_parts.size() != 2) { + qDebug() << "Invalid format for media " << avatar_url.toString(); + return; + } - QUrlQuery query; - query.addQueryItem("width", "512"); - query.addQueryItem("height", "512"); - query.addQueryItem("method", "crop"); + QUrlQuery query; + query.addQueryItem("width", "512"); + query.addQueryItem("height", "512"); + query.addQueryItem("method", "crop"); - QString media_url = QString("%1/_matrix/media/r0/thumbnail/%2").arg(getHomeServer().toString(), url_parts[1]); + QString media_url = + QString("%1/_matrix/media/r0/thumbnail/%2").arg(getHomeServer().toString(), url_parts[1]); - QUrl endpoint(media_url); - endpoint.setQuery(query); + QUrl endpoint(media_url); + endpoint.setQuery(query); - QNetworkRequest avatar_request(endpoint); + QNetworkRequest avatar_request(endpoint); - QNetworkReply *reply = get(avatar_request); - reply->setProperty("endpoint", static_cast<int>(Endpoint::GetOwnAvatar)); + QNetworkReply *reply = get(avatar_request); + reply->setProperty("endpoint", static_cast<int>(Endpoint::GetOwnAvatar)); } void MatrixClient::messages(const QString &room_id, const QString &from_token, int limit) noexcept { - QUrlQuery query; - query.addQueryItem("access_token", token_); - query.addQueryItem("from", from_token); - query.addQueryItem("dir", "b"); - query.addQueryItem("limit", QString::number(limit)); + QUrlQuery query; + query.addQueryItem("access_token", token_); + query.addQueryItem("from", from_token); + query.addQueryItem("dir", "b"); + query.addQueryItem("limit", QString::number(limit)); - QUrl endpoint(server_); - endpoint.setPath(api_url_ + QString("/rooms/%1/messages").arg(room_id)); - endpoint.setQuery(query); + QUrl endpoint(server_); + endpoint.setPath(api_url_ + QString("/rooms/%1/messages").arg(room_id)); + endpoint.setQuery(query); - QNetworkRequest request(QString(endpoint.toEncoded())); + QNetworkRequest request(QString(endpoint.toEncoded())); - QNetworkReply *reply = get(request); - reply->setProperty("endpoint", static_cast<int>(Endpoint::Messages)); - reply->setProperty("room_id", room_id); + QNetworkReply *reply = get(request); + reply->setProperty("endpoint", static_cast<int>(Endpoint::Messages)); + reply->setProperty("room_id", room_id); } diff --git a/src/TextInputWidget.cc b/src/TextInputWidget.cc
index 328c99e2..bd74186e 100644 --- a/src/TextInputWidget.cc +++ b/src/TextInputWidget.cc
@@ -26,123 +26,133 @@ FilteredTextEdit::FilteredTextEdit(QWidget *parent) : QTextEdit(parent) { - setAcceptRichText(false); + setAcceptRichText(false); } void FilteredTextEdit::keyPressEvent(QKeyEvent *event) { - if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) - emit enterPressed(); - else - QTextEdit::keyPressEvent(event); + if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) + emit enterPressed(); + else + QTextEdit::keyPressEvent(event); } TextInputWidget::TextInputWidget(QWidget *parent) - : QWidget(parent) + : QFrame(parent) { - setFont(QFont("Emoji One")); + setFont(QFont("Emoji One")); - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - setCursor(Qt::ArrowCursor); - setStyleSheet("background-color: #f8fbfe; height: 45px;"); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + setCursor(Qt::ArrowCursor); + setStyleSheet("background-color: #f8fbfe; height: 45px;"); - top_layout_ = new QHBoxLayout(); - top_layout_->setSpacing(0); - top_layout_->setMargin(0); + top_layout_ = new QHBoxLayout(); + top_layout_->setSpacing(0); + top_layout_->setMargin(0); - send_file_button_ = new FlatButton(this); + send_file_button_ = new FlatButton(this); - QIcon send_file_icon; - send_file_icon.addFile(":/icons/icons/clip-dark.png", QSize(), QIcon::Normal, QIcon::Off); - send_file_button_->setForegroundColor(QColor("#acc7dc")); - send_file_button_->setIcon(send_file_icon); - send_file_button_->setIconSize(QSize(24, 24)); + QIcon send_file_icon; + send_file_icon.addFile(":/icons/icons/clip-dark.png", QSize(), QIcon::Normal, QIcon::Off); + send_file_button_->setForegroundColor(QColor("#acc7dc")); + send_file_button_->setIcon(send_file_icon); + send_file_button_->setIconSize(QSize(24, 24)); - QFont font; - font.setPixelSize(conf::fontSize); + QFont font; + font.setPixelSize(conf::fontSize); - input_ = new FilteredTextEdit(this); - input_->setFixedHeight(45); - input_->setFont(font); - input_->setPlaceholderText(tr("Write a message...")); - input_->setStyleSheet("color: #333333; border-radius: 0; padding-top: 10px;"); + input_ = new FilteredTextEdit(this); + input_->setFixedHeight(45); + input_->setFont(font); + input_->setPlaceholderText(tr("Write a message...")); + input_->setStyleSheet("color: #333333; border-radius: 0; padding-top: 10px;"); - send_message_button_ = new FlatButton(this); - send_message_button_->setForegroundColor(QColor("#acc7dc")); + send_message_button_ = new FlatButton(this); + send_message_button_->setForegroundColor(QColor("#acc7dc")); - QIcon send_message_icon; - send_message_icon.addFile(":/icons/icons/share-dark.png", QSize(), QIcon::Normal, QIcon::Off); - send_message_button_->setIcon(send_message_icon); - send_message_button_->setIconSize(QSize(24, 24)); + QIcon send_message_icon; + send_message_icon.addFile( + ":/icons/icons/share-dark.png", QSize(), QIcon::Normal, QIcon::Off); + send_message_button_->setIcon(send_message_icon); + send_message_button_->setIconSize(QSize(24, 24)); - emoji_button_ = new EmojiPickButton(this); - emoji_button_->setForegroundColor(QColor("#acc7dc")); + emoji_button_ = new EmojiPickButton(this); + emoji_button_->setForegroundColor(QColor("#acc7dc")); - QIcon emoji_icon; - emoji_icon.addFile(":/icons/icons/smile.png", QSize(), QIcon::Normal, QIcon::Off); - emoji_button_->setIcon(emoji_icon); - emoji_button_->setIconSize(QSize(24, 24)); + QIcon emoji_icon; + emoji_icon.addFile(":/icons/icons/smile.png", QSize(), QIcon::Normal, QIcon::Off); + emoji_button_->setIcon(emoji_icon); + emoji_button_->setIconSize(QSize(24, 24)); - top_layout_->addWidget(send_file_button_); - top_layout_->addWidget(input_); - top_layout_->addWidget(emoji_button_); - top_layout_->addWidget(send_message_button_); + top_layout_->addWidget(send_file_button_); + top_layout_->addWidget(input_); + top_layout_->addWidget(emoji_button_); + top_layout_->addWidget(send_message_button_); - setLayout(top_layout_); + setLayout(top_layout_); - connect(send_message_button_, SIGNAL(clicked()), this, SLOT(onSendButtonClicked())); - connect(input_, SIGNAL(enterPressed()), send_message_button_, SIGNAL(clicked())); - connect(emoji_button_, SIGNAL(emojiSelected(const QString &)), this, SLOT(addSelectedEmoji(const QString &))); + connect(send_message_button_, SIGNAL(clicked()), this, SLOT(onSendButtonClicked())); + connect(input_, SIGNAL(enterPressed()), send_message_button_, SIGNAL(clicked())); + connect(emoji_button_, + SIGNAL(emojiSelected(const QString &)), + this, + SLOT(addSelectedEmoji(const QString &))); } void TextInputWidget::addSelectedEmoji(const QString &emoji) { - QTextCursor cursor = input_->textCursor(); + QTextCursor cursor = input_->textCursor(); - QFont emoji_font("Emoji One"); - emoji_font.setPixelSize(conf::emojiSize); + QFont emoji_font("Emoji One"); + emoji_font.setPixelSize(conf::emojiSize); - QFont text_font("Open Sans"); - text_font.setPixelSize(conf::fontSize); + QFont text_font("Open Sans"); + text_font.setPixelSize(conf::fontSize); - QTextCharFormat charfmt; - charfmt.setFont(emoji_font); - input_->setCurrentCharFormat(charfmt); + QTextCharFormat charfmt; + charfmt.setFont(emoji_font); + input_->setCurrentCharFormat(charfmt); - input_->insertPlainText(emoji); - cursor.movePosition(QTextCursor::End); + input_->insertPlainText(emoji); + cursor.movePosition(QTextCursor::End); - charfmt.setFont(text_font); - input_->setCurrentCharFormat(charfmt); + charfmt.setFont(text_font); + input_->setCurrentCharFormat(charfmt); - input_->show(); + input_->show(); } void TextInputWidget::onSendButtonClicked() { - auto msg_text = input_->document()->toPlainText().trimmed(); + auto msgText = input_->document()->toPlainText().trimmed(); - if (msg_text.isEmpty()) - return; + if (msgText.isEmpty()) + return; - emit sendTextMessage(msg_text); + if (msgText.startsWith(EMOTE_COMMAND)) { + auto text = parseEmoteCommand(msgText); - input_->clear(); + if (!text.isEmpty()) + emit sendEmoteMessage(text); + } else { + emit sendTextMessage(msgText); + } + + input_->clear(); } -void -TextInputWidget::paintEvent(QPaintEvent *event) +QString +TextInputWidget::parseEmoteCommand(const QString &cmd) { - Q_UNUSED(event); + auto text = cmd.right(cmd.size() - EMOTE_COMMAND.size()).trimmed(); - QStyleOption option; - option.initFrom(this); + if (!text.isEmpty()) + return text; - QPainter painter(this); - style()->drawPrimitive(QStyle::PE_Widget, &option, &painter, this); + return QString(""); } TextInputWidget::~TextInputWidget() diff --git a/src/TimelineItem.cc b/src/TimelineItem.cc
index 62ebc515..9d24a96c 100644 --- a/src/TimelineItem.cc +++ b/src/TimelineItem.cc
@@ -67,46 +67,42 @@ TimelineItem::init() } /* - * For messages created locally. The avatar and the username are displayed. + * For messages created locally. */ -TimelineItem::TimelineItem(const QString &userid, QString body, QWidget *parent) +TimelineItem::TimelineItem(events::MessageEventType ty, + const QString &userid, + QString body, + bool withSender, + QWidget *parent) : QWidget(parent) { init(); - descriptionMsg_ = { "You: ", userid, body, descriptiveTime(QDateTime::currentDateTime()) }; - body.replace(URL_REGEX, URL_HTML); auto displayName = TimelineViewManager::displayName(userid); + auto timestamp = QDateTime::currentDateTime(); - generateTimestamp(QDateTime::currentDateTime()); - generateBody(displayName, body); - - setupAvatarLayout(displayName); - - mainLayout_->addLayout(headerLayout_); - mainLayout_->addWidget(body_); - - AvatarProvider::resolve(userid, this); -} - -/* - * For messages created locally. Only the text is displayed. - */ -TimelineItem::TimelineItem(QString body, QWidget *parent) - : QWidget(parent) -{ - QSettings settings; - auto userid = settings.value("auth/user_id").toString(); - - init(); - descriptionMsg_ = { "You: ", userid, body, descriptiveTime(QDateTime::currentDateTime()) }; + if (ty == events::MessageEventType::Emote) { + body = QString("* %1 %2").arg(displayName).arg(body); + descriptionMsg_ = { "", userid, body, descriptiveTime(timestamp) }; + } else { + descriptionMsg_ = { + "You: ", userid, body, descriptiveTime(QDateTime::currentDateTime()) + }; + } body.replace(URL_REGEX, URL_HTML); + generateTimestamp(timestamp); - generateTimestamp(QDateTime::currentDateTime()); - generateBody(body); + if (withSender) { + generateBody(displayName, body); + setupAvatarLayout(displayName); + mainLayout_->addLayout(headerLayout_); - setupSimpleLayout(); + AvatarProvider::resolve(userid, this); + } else { + generateBody(body); + setupSimpleLayout(); + } mainLayout_->addWidget(body_); } diff --git a/src/TimelineView.cc b/src/TimelineView.cc
index 4dd63604..518676ac 100644 --- a/src/TimelineView.cc +++ b/src/TimelineView.cc
@@ -289,7 +289,10 @@ TimelineView::parseMessageEvent(const QJsonObject &event, TimelineDirection dire eventIds_[emote.eventId()] = true; - // TODO Check if it's a message waiting for validation + if (isPendingMessage(emote, local_user_)) { + removePendingMessage(emote); + return nullptr; + } auto with_sender = isSenderRendered(emote.sender(), direction); @@ -452,55 +455,19 @@ TimelineView::updatePendingMessage(int txn_id, QString event_id) } } -bool -TimelineView::isPendingMessage(const events::MessageEvent<msgs::Text> &e, - const QString &local_userid) -{ - if (e.sender() != local_userid) - return false; - - for (const auto &msg : pending_msgs_) { - if (msg.event_id == e.eventId() || msg.body == e.content().body()) - return true; - } - - return false; -} - -void -TimelineView::removePendingMessage(const events::MessageEvent<msgs::Text> &e) -{ - for (auto it = pending_msgs_.begin(); it != pending_msgs_.end(); it++) { - int index = std::distance(pending_msgs_.begin(), it); - - if (it->event_id == e.eventId() || it->body == e.content().body()) { - pending_msgs_.removeAt(index); - break; - } - } -} - void -TimelineView::addUserTextMessage(const QString &body, int txn_id) +TimelineView::addUserMessage(matrix::events::MessageEventType ty, const QString &body, int txn_id) { QSettings settings; - auto user_id = settings.value("auth/user_id").toString(); - + auto user_id = settings.value("auth/user_id").toString(); auto with_sender = lastSender_ != user_id; - TimelineItem *view_item; - - if (with_sender) - view_item = new TimelineItem(user_id, body, scroll_widget_); - else - view_item = new TimelineItem(body, scroll_widget_); - + TimelineItem *view_item = new TimelineItem(ty, user_id, body, with_sender, scroll_widget_); scroll_layout_->addWidget(view_item); lastSender_ = user_id; PendingMessage message(txn_id, body, "", view_item); - pending_msgs_.push_back(message); } diff --git a/src/TimelineViewManager.cc b/src/TimelineViewManager.cc
index 3cb61889..0bb56bf9 100644 --- a/src/TimelineViewManager.cc +++ b/src/TimelineViewManager.cc
@@ -32,10 +32,8 @@ TimelineViewManager::TimelineViewManager(QSharedPointer<MatrixClient> client, QW { setStyleSheet("QWidget { background: #f8fbfe; color: #e8e8e8; border: none;}"); - connect(client_.data(), - SIGNAL(messageSent(const QString &, const QString &, int)), - this, - SLOT(messageSent(const QString &, const QString &, int))); + connect( + client_.data(), &MatrixClient::messageSent, this, &TimelineViewManager::messageSent); } TimelineViewManager::~TimelineViewManager() @@ -59,8 +57,19 @@ TimelineViewManager::sendTextMessage(const QString &msg) auto room_id = active_room_; auto view = views_[room_id]; - view->addUserTextMessage(msg, client_->transactionId()); - client_->sendTextMessage(room_id, msg); + view->addUserMessage(matrix::events::MessageEventType::Text, msg, client_->transactionId()); + client_->sendRoomMessage(matrix::events::MessageEventType::Text, room_id, msg); +} + +void +TimelineViewManager::sendEmoteMessage(const QString &msg) +{ + auto room_id = active_room_; + auto view = views_[room_id]; + + view->addUserMessage( + matrix::events::MessageEventType::Emote, msg, client_->transactionId()); + client_->sendRoomMessage(matrix::events::MessageEventType::Emote, room_id, msg); } void