parent
a44a4f36af
commit
b5ae84c3c3
11 changed files with 747 additions and 686 deletions
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <QtNetwork/QNetworkAccessManager>
|
||||
|
||||
#include "MessageEvent.h"
|
||||
#include "Profile.h"
|
||||
#include "RoomMessages.h"
|
||||
#include "Sync.h"
|
||||
|
|
@ -29,145 +30,152 @@
|
|||
*/
|
||||
class MatrixClient : public QNetworkAccessManager
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
MatrixClient(QString server, QObject *parent = 0);
|
||||
MatrixClient(QString server, QObject *parent = 0);
|
||||
|
||||
// Client API.
|
||||
void initialSync() noexcept;
|
||||
void sync() noexcept;
|
||||
void sendTextMessage(const QString &roomid, const QString &msg) noexcept;
|
||||
void login(const QString &username, const QString &password) noexcept;
|
||||
void registerUser(const QString &username, const QString &password, const QString &server) noexcept;
|
||||
void versions() noexcept;
|
||||
void fetchRoomAvatar(const QString &roomid, const QUrl &avatar_url);
|
||||
void fetchUserAvatar(const QString &userId, const QUrl &avatarUrl);
|
||||
void fetchOwnAvatar(const QUrl &avatar_url);
|
||||
void downloadImage(const QString &event_id, const QUrl &url);
|
||||
void messages(const QString &room_id, const QString &from_token, int limit = 20) noexcept;
|
||||
// Client API.
|
||||
void initialSync() noexcept;
|
||||
void sync() noexcept;
|
||||
void sendRoomMessage(matrix::events::MessageEventType ty,
|
||||
const QString &roomid,
|
||||
const QString &msg) noexcept;
|
||||
void login(const QString &username, const QString &password) noexcept;
|
||||
void registerUser(const QString &username,
|
||||
const QString &password,
|
||||
const QString &server) noexcept;
|
||||
void versions() noexcept;
|
||||
void fetchRoomAvatar(const QString &roomid, const QUrl &avatar_url);
|
||||
void fetchUserAvatar(const QString &userId, const QUrl &avatarUrl);
|
||||
void fetchOwnAvatar(const QUrl &avatar_url);
|
||||
void downloadImage(const QString &event_id, const QUrl &url);
|
||||
void messages(const QString &room_id, const QString &from_token, int limit = 20) noexcept;
|
||||
|
||||
inline QUrl getHomeServer();
|
||||
inline int transactionId();
|
||||
inline void incrementTransactionId();
|
||||
inline QUrl getHomeServer();
|
||||
inline int transactionId();
|
||||
inline void incrementTransactionId();
|
||||
|
||||
void reset() noexcept;
|
||||
void reset() noexcept;
|
||||
|
||||
public slots:
|
||||
void getOwnProfile() noexcept;
|
||||
void logout() noexcept;
|
||||
void getOwnProfile() noexcept;
|
||||
void logout() noexcept;
|
||||
|
||||
inline void setServer(const QString &server);
|
||||
inline void setAccessToken(const QString &token);
|
||||
inline void setNextBatchToken(const QString &next_batch);
|
||||
inline void setServer(const QString &server);
|
||||
inline void setAccessToken(const QString &token);
|
||||
inline void setNextBatchToken(const QString &next_batch);
|
||||
|
||||
signals:
|
||||
void loginError(const QString &error);
|
||||
void registerError(const QString &error);
|
||||
void versionError(const QString &error);
|
||||
void loginError(const QString &error);
|
||||
void registerError(const QString &error);
|
||||
void versionError(const QString &error);
|
||||
|
||||
void loggedOut();
|
||||
void loggedOut();
|
||||
|
||||
void loginSuccess(const QString &userid, const QString &homeserver, const QString &token);
|
||||
void registerSuccess(const QString &userid, const QString &homeserver, const QString &token);
|
||||
void versionSuccess();
|
||||
void loginSuccess(const QString &userid, const QString &homeserver, const QString &token);
|
||||
void registerSuccess(const QString &userid,
|
||||
const QString &homeserver,
|
||||
const QString &token);
|
||||
void versionSuccess();
|
||||
|
||||
void roomAvatarRetrieved(const QString &roomid, const QPixmap &img);
|
||||
void userAvatarRetrieved(const QString &userId, const QImage &img);
|
||||
void ownAvatarRetrieved(const QPixmap &img);
|
||||
void imageDownloaded(const QString &event_id, const QPixmap &img);
|
||||
void roomAvatarRetrieved(const QString &roomid, const QPixmap &img);
|
||||
void userAvatarRetrieved(const QString &userId, const QImage &img);
|
||||
void ownAvatarRetrieved(const QPixmap &img);
|
||||
void imageDownloaded(const QString &event_id, const QPixmap &img);
|
||||
|
||||
// Returned profile data for the user's account.
|
||||
void getOwnProfileResponse(const QUrl &avatar_url, const QString &display_name);
|
||||
void initialSyncCompleted(const SyncResponse &response);
|
||||
void syncCompleted(const SyncResponse &response);
|
||||
void syncFailed(const QString &msg);
|
||||
void messageSent(const QString &event_id, const QString &roomid, const int txn_id);
|
||||
void messagesRetrieved(const QString &room_id, const RoomMessages &msgs);
|
||||
// Returned profile data for the user's account.
|
||||
void getOwnProfileResponse(const QUrl &avatar_url, const QString &display_name);
|
||||
void initialSyncCompleted(const SyncResponse &response);
|
||||
void syncCompleted(const SyncResponse &response);
|
||||
void syncFailed(const QString &msg);
|
||||
void messageSent(const QString &event_id, const QString &roomid, const int txn_id);
|
||||
void emoteSent(const QString &event_id, const QString &roomid, const int txn_id);
|
||||
void messagesRetrieved(const QString &room_id, const RoomMessages &msgs);
|
||||
|
||||
private slots:
|
||||
void onResponse(QNetworkReply *reply);
|
||||
void onResponse(QNetworkReply *reply);
|
||||
|
||||
private:
|
||||
enum class Endpoint {
|
||||
GetOwnAvatar,
|
||||
GetOwnProfile,
|
||||
GetProfile,
|
||||
Image,
|
||||
InitialSync,
|
||||
Login,
|
||||
Logout,
|
||||
Messages,
|
||||
Register,
|
||||
RoomAvatar,
|
||||
UserAvatar,
|
||||
SendTextMessage,
|
||||
Sync,
|
||||
Versions,
|
||||
};
|
||||
enum class Endpoint {
|
||||
GetOwnAvatar,
|
||||
GetOwnProfile,
|
||||
GetProfile,
|
||||
Image,
|
||||
InitialSync,
|
||||
Login,
|
||||
Logout,
|
||||
Messages,
|
||||
Register,
|
||||
RoomAvatar,
|
||||
SendRoomMessage,
|
||||
Sync,
|
||||
UserAvatar,
|
||||
Versions,
|
||||
};
|
||||
|
||||
// Response handlers.
|
||||
void onLoginResponse(QNetworkReply *reply);
|
||||
void onLogoutResponse(QNetworkReply *reply);
|
||||
void onRegisterResponse(QNetworkReply *reply);
|
||||
void onVersionsResponse(QNetworkReply *reply);
|
||||
void onGetOwnProfileResponse(QNetworkReply *reply);
|
||||
void onGetOwnAvatarResponse(QNetworkReply *reply);
|
||||
void onSendTextMessageResponse(QNetworkReply *reply);
|
||||
void onInitialSyncResponse(QNetworkReply *reply);
|
||||
void onSyncResponse(QNetworkReply *reply);
|
||||
void onRoomAvatarResponse(QNetworkReply *reply);
|
||||
void onUserAvatarResponse(QNetworkReply *reply);
|
||||
void onImageResponse(QNetworkReply *reply);
|
||||
void onMessagesResponse(QNetworkReply *reply);
|
||||
// Response handlers.
|
||||
void onGetOwnAvatarResponse(QNetworkReply *reply);
|
||||
void onGetOwnProfileResponse(QNetworkReply *reply);
|
||||
void onImageResponse(QNetworkReply *reply);
|
||||
void onInitialSyncResponse(QNetworkReply *reply);
|
||||
void onLoginResponse(QNetworkReply *reply);
|
||||
void onLogoutResponse(QNetworkReply *reply);
|
||||
void onMessagesResponse(QNetworkReply *reply);
|
||||
void onRegisterResponse(QNetworkReply *reply);
|
||||
void onRoomAvatarResponse(QNetworkReply *reply);
|
||||
void onSendRoomMessage(QNetworkReply *reply);
|
||||
void onSyncResponse(QNetworkReply *reply);
|
||||
void onUserAvatarResponse(QNetworkReply *reply);
|
||||
void onVersionsResponse(QNetworkReply *reply);
|
||||
|
||||
// Client API prefix.
|
||||
QString api_url_;
|
||||
// Client API prefix.
|
||||
QString api_url_;
|
||||
|
||||
// The Matrix server used for communication.
|
||||
QUrl server_;
|
||||
// The Matrix server used for communication.
|
||||
QUrl server_;
|
||||
|
||||
// The access token used for authentication.
|
||||
QString token_;
|
||||
// The access token used for authentication.
|
||||
QString token_;
|
||||
|
||||
// Increasing transaction ID.
|
||||
int txn_id_;
|
||||
// Increasing transaction ID.
|
||||
int txn_id_;
|
||||
|
||||
// Token to be used for the next sync.
|
||||
QString next_batch_;
|
||||
// Token to be used for the next sync.
|
||||
QString next_batch_;
|
||||
};
|
||||
|
||||
inline QUrl
|
||||
MatrixClient::getHomeServer()
|
||||
{
|
||||
return server_;
|
||||
return server_;
|
||||
}
|
||||
|
||||
inline int
|
||||
MatrixClient::transactionId()
|
||||
{
|
||||
return txn_id_;
|
||||
return txn_id_;
|
||||
}
|
||||
|
||||
inline void
|
||||
MatrixClient::setServer(const QString &server)
|
||||
{
|
||||
server_ = QUrl(QString("https://%1").arg(server));
|
||||
server_ = QUrl(QString("https://%1").arg(server));
|
||||
}
|
||||
|
||||
inline void
|
||||
MatrixClient::setAccessToken(const QString &token)
|
||||
{
|
||||
token_ = token;
|
||||
token_ = token;
|
||||
}
|
||||
|
||||
inline void
|
||||
MatrixClient::setNextBatchToken(const QString &next_batch)
|
||||
{
|
||||
next_batch_ = next_batch;
|
||||
next_batch_ = next_batch;
|
||||
}
|
||||
|
||||
inline void
|
||||
MatrixClient::incrementTransactionId()
|
||||
{
|
||||
txn_id_ += 1;
|
||||
txn_id_ += 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,49 +25,51 @@
|
|||
#include "EmojiPickButton.h"
|
||||
#include "FlatButton.h"
|
||||
|
||||
static const QString EMOTE_COMMAND("/me ");
|
||||
|
||||
class FilteredTextEdit : public QTextEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FilteredTextEdit(QWidget *parent = nullptr);
|
||||
void keyPressEvent(QKeyEvent *event);
|
||||
explicit FilteredTextEdit(QWidget *parent = nullptr);
|
||||
void keyPressEvent(QKeyEvent *event);
|
||||
|
||||
signals:
|
||||
void enterPressed();
|
||||
void enterPressed();
|
||||
};
|
||||
|
||||
class TextInputWidget : public QWidget
|
||||
class TextInputWidget : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TextInputWidget(QWidget *parent = 0);
|
||||
~TextInputWidget();
|
||||
TextInputWidget(QWidget *parent = 0);
|
||||
~TextInputWidget();
|
||||
|
||||
public slots:
|
||||
void onSendButtonClicked();
|
||||
inline void focusLineEdit();
|
||||
void onSendButtonClicked();
|
||||
inline void focusLineEdit();
|
||||
|
||||
private slots:
|
||||
void addSelectedEmoji(const QString &emoji);
|
||||
void addSelectedEmoji(const QString &emoji);
|
||||
|
||||
signals:
|
||||
void sendTextMessage(QString msg);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
void sendTextMessage(QString msg);
|
||||
void sendEmoteMessage(QString msg);
|
||||
|
||||
private:
|
||||
QHBoxLayout *top_layout_;
|
||||
FilteredTextEdit *input_;
|
||||
QString parseEmoteCommand(const QString &cmd);
|
||||
|
||||
FlatButton *send_file_button_;
|
||||
FlatButton *send_message_button_;
|
||||
EmojiPickButton *emoji_button_;
|
||||
QHBoxLayout *top_layout_;
|
||||
FilteredTextEdit *input_;
|
||||
|
||||
FlatButton *send_file_button_;
|
||||
FlatButton *send_message_button_;
|
||||
EmojiPickButton *emoji_button_;
|
||||
};
|
||||
|
||||
inline void
|
||||
TextInputWidget::focusLineEdit()
|
||||
{
|
||||
input_->setFocus();
|
||||
input_->setFocus();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,8 +50,11 @@ public:
|
|||
QWidget *parent = 0);
|
||||
|
||||
// For local messages.
|
||||
TimelineItem(const QString &userid, QString body, QWidget *parent = 0);
|
||||
TimelineItem(QString body, QWidget *parent = 0);
|
||||
TimelineItem(events::MessageEventType ty,
|
||||
const QString &userid,
|
||||
QString body,
|
||||
bool withSender,
|
||||
QWidget *parent = 0);
|
||||
|
||||
TimelineItem(ImageItem *img,
|
||||
const events::MessageEvent<msgs::Image> &e,
|
||||
|
|
|
|||
|
|
@ -27,8 +27,9 @@
|
|||
#include "Sync.h"
|
||||
#include "TimelineItem.h"
|
||||
|
||||
#include "Image.h"
|
||||
#include "Emote.h"
|
||||
#include "Image.h"
|
||||
#include "MessageEvent.h"
|
||||
#include "Notice.h"
|
||||
#include "RoomInfoListItem.h"
|
||||
#include "Text.h"
|
||||
|
|
@ -83,7 +84,7 @@ public:
|
|||
|
||||
// Add new events at the end of the timeline.
|
||||
int addEvents(const Timeline &timeline);
|
||||
void addUserTextMessage(const QString &msg, int txn_id);
|
||||
void addUserMessage(matrix::events::MessageEventType ty, const QString &msg, int txn_id);
|
||||
void updatePendingMessage(int txn_id, QString event_id);
|
||||
void scrollDown();
|
||||
|
||||
|
|
@ -100,14 +101,19 @@ signals:
|
|||
|
||||
private:
|
||||
void init();
|
||||
void removePendingMessage(const events::MessageEvent<msgs::Text> &e);
|
||||
void addTimelineItem(TimelineItem *item, TimelineDirection direction);
|
||||
void updateLastSender(const QString &user_id, TimelineDirection direction);
|
||||
void notifyForLastEvent();
|
||||
|
||||
// Used to determine whether or not we should prefix a message with the sender's name.
|
||||
bool isSenderRendered(const QString &user_id, TimelineDirection direction);
|
||||
bool isPendingMessage(const events::MessageEvent<msgs::Text> &e, const QString &userid);
|
||||
|
||||
template<class T>
|
||||
bool isPendingMessage(const events::MessageEvent<T> &e, const QString &userid);
|
||||
|
||||
template<class T>
|
||||
void removePendingMessage(const events::MessageEvent<T> &e);
|
||||
|
||||
inline bool isDuplicate(const QString &event_id);
|
||||
|
||||
// Return nullptr if the event couldn't be parsed.
|
||||
|
|
@ -153,3 +159,32 @@ TimelineView::isDuplicate(const QString &event_id)
|
|||
{
|
||||
return eventIds_.contains(event_id);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool
|
||||
TimelineView::isPendingMessage(const events::MessageEvent<T> &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;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
TimelineView::removePendingMessage(const events::MessageEvent<T> &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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include <QWidget>
|
||||
|
||||
#include "MatrixClient.h"
|
||||
#include "MessageEvent.h"
|
||||
#include "RoomInfoListItem.h"
|
||||
#include "Sync.h"
|
||||
#include "TimelineView.h"
|
||||
|
|
@ -54,6 +55,7 @@ signals:
|
|||
public slots:
|
||||
void setHistoryView(const QString &room_id);
|
||||
void sendTextMessage(const QString &msg);
|
||||
void sendEmoteMessage(const QString &msg);
|
||||
|
||||
private slots:
|
||||
void messageSent(const QString &eventid, const QString &roomid, int txnid);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue