diff --git a/include/ImageItem.h b/include/ImageItem.h
index 5953c6e5..20e0772d 100644
--- a/include/ImageItem.h
+++ b/include/ImageItem.h
@@ -26,47 +26,52 @@
#include "MatrixClient.h"
namespace events = matrix::events;
-namespace msgs = matrix::events::messages;
+namespace msgs = matrix::events::messages;
class ImageItem : public QWidget
{
- Q_OBJECT
+ Q_OBJECT
public:
- ImageItem(QSharedPointer<MatrixClient> client,
- const events::MessageEvent<msgs::Image> &event,
- QWidget *parent = nullptr);
+ ImageItem(QSharedPointer<MatrixClient> client,
+ const events::MessageEvent<msgs::Image> &event,
+ QWidget *parent = nullptr);
- void setImage(const QPixmap &image);
+ ImageItem(QSharedPointer<MatrixClient> client,
+ const QString &url,
+ const QString &filename,
+ QWidget *parent = nullptr);
- QSize sizeHint() const override;
+ void setImage(const QPixmap &image);
+
+ QSize sizeHint() const override;
protected:
- void paintEvent(QPaintEvent *event) override;
- void mousePressEvent(QMouseEvent *event) override;
- void resizeEvent(QResizeEvent *event) override;
+ void paintEvent(QPaintEvent *event) override;
+ void mousePressEvent(QMouseEvent *event) override;
+ void resizeEvent(QResizeEvent *event) override;
private slots:
- void imageDownloaded(const QString &event_id, const QPixmap &img);
+ void imageDownloaded(const QString &event_id, const QPixmap &img);
private:
- void scaleImage();
- void openUrl();
+ void scaleImage();
+ void openUrl();
- int max_width_ = 500;
- int max_height_ = 300;
+ int max_width_ = 500;
+ int max_height_ = 300;
- int width_;
- int height_;
+ int width_;
+ int height_;
- QPixmap scaled_image_;
- QPixmap image_;
+ QPixmap scaled_image_;
+ QPixmap image_;
- QUrl url_;
- QString text_;
+ QUrl url_;
+ QString text_;
- int bottom_height_ = 30;
+ int bottom_height_ = 30;
- events::MessageEvent<msgs::Image> event_;
+ events::MessageEvent<msgs::Image> event_;
- QSharedPointer<MatrixClient> client_;
+ QSharedPointer<MatrixClient> client_;
};
diff --git a/include/LoginPage.h b/include/LoginPage.h
index ef0a6e9e..5caa3f1e 100644
--- a/include/LoginPage.h
+++ b/include/LoginPage.h
@@ -23,8 +23,8 @@
#include <QVBoxLayout>
#include <QWidget>
-#include "CircularProgress.h"
#include "FlatButton.h"
+#include "LoadingIndicator.h"
#include "MatrixClient.h"
#include "OverlayModal.h"
#include "RaisedButton.h"
@@ -32,68 +32,68 @@
class LoginPage : public QWidget
{
- Q_OBJECT
+ Q_OBJECT
public:
- LoginPage(QSharedPointer<MatrixClient> client, QWidget *parent = 0);
- ~LoginPage();
+ LoginPage(QSharedPointer<MatrixClient> client, QWidget *parent = 0);
+ ~LoginPage();
- void reset();
+ void reset();
signals:
- void backButtonClicked();
+ void backButtonClicked();
private slots:
- // Callback for the back button.
- void onBackButtonClicked();
+ // Callback for the back button.
+ void onBackButtonClicked();
- // Callback for the login button.
- void onLoginButtonClicked();
+ // Callback for the login button.
+ void onLoginButtonClicked();
- // Callback for probing the server found in the mxid
- void onMatrixIdEntered();
+ // Callback for probing the server found in the mxid
+ void onMatrixIdEntered();
- // Callback for probing the manually entered server
- void onServerAddressEntered();
+ // Callback for probing the manually entered server
+ void onServerAddressEntered();
- // Displays errors produced during the login.
- void loginError(QString error_message);
+ // Displays errors produced during the login.
+ void loginError(QString error_message);
- // Callback for errors produced during server probing
- void versionError(QString error_message);
+ // Callback for errors produced during server probing
+ void versionError(QString error_message);
- // Callback for successful server probing
- void versionSuccess();
+ // Callback for successful server probing
+ void versionSuccess();
private:
- bool isMatrixIdValid();
+ bool isMatrixIdValid();
- QVBoxLayout *top_layout_;
+ QVBoxLayout *top_layout_;
- QHBoxLayout *top_bar_layout_;
- QHBoxLayout *logo_layout_;
- QHBoxLayout *button_layout_;
+ QHBoxLayout *top_bar_layout_;
+ QHBoxLayout *logo_layout_;
+ QHBoxLayout *button_layout_;
- QLabel *logo_;
- QLabel *error_label_;
+ QLabel *logo_;
+ QLabel *error_label_;
- QHBoxLayout *serverLayout_;
- QHBoxLayout *matrixidLayout_;
- CircularProgress *spinner_;
- QLabel *errorIcon_;
- QString inferredServerAddress_;
+ QHBoxLayout *serverLayout_;
+ QHBoxLayout *matrixidLayout_;
+ LoadingIndicator *spinner_;
+ QLabel *errorIcon_;
+ QString inferredServerAddress_;
- FlatButton *back_button_;
- RaisedButton *login_button_;
+ FlatButton *back_button_;
+ RaisedButton *login_button_;
- QWidget *form_widget_;
- QHBoxLayout *form_wrapper_;
- QVBoxLayout *form_layout_;
+ QWidget *form_widget_;
+ QHBoxLayout *form_wrapper_;
+ QVBoxLayout *form_layout_;
- TextField *matrixid_input_;
- TextField *password_input_;
- TextField *serverInput_;
+ TextField *matrixid_input_;
+ TextField *password_input_;
+ TextField *serverInput_;
- // Matrix client API provider.
- QSharedPointer<MatrixClient> client_;
+ // Matrix client API provider.
+ QSharedPointer<MatrixClient> client_;
};
diff --git a/include/MainWindow.h b/include/MainWindow.h
index a8a86719..de535d35 100644
--- a/include/MainWindow.h
+++ b/include/MainWindow.h
@@ -21,7 +21,7 @@
#include <QSharedPointer>
#include "ChatPage.h"
-#include "CircularProgress.h"
+#include "LoadingIndicator.h"
#include "LoginPage.h"
#include "MatrixClient.h"
#include "OverlayModal.h"
@@ -32,64 +32,64 @@
class MainWindow : public QMainWindow
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit MainWindow(QWidget *parent = 0);
- ~MainWindow();
+ explicit MainWindow(QWidget *parent = 0);
+ ~MainWindow();
- static MainWindow *instance();
- void saveCurrentWindowSize();
+ static MainWindow *instance();
+ void saveCurrentWindowSize();
protected:
- void closeEvent(QCloseEvent *event);
+ void closeEvent(QCloseEvent *event);
private slots:
- // Handle interaction with the tray icon.
- void iconActivated(QSystemTrayIcon::ActivationReason reason);
+ // Handle interaction with the tray icon.
+ void iconActivated(QSystemTrayIcon::ActivationReason reason);
- // Show the welcome page in the main window.
- void showWelcomePage();
+ // Show the welcome page in the main window.
+ void showWelcomePage();
- // Show the login page in the main window.
- void showLoginPage();
+ // Show the login page in the main window.
+ void showLoginPage();
- // Show the register page in the main window.
- void showRegisterPage();
+ // Show the register page in the main window.
+ void showRegisterPage();
- // Show the chat page and start communicating with the given access token.
- void showChatPage(QString user_id, QString home_server, QString token);
+ // Show the chat page and start communicating with the given access token.
+ void showChatPage(QString user_id, QString home_server, QString token);
- void removeOverlayProgressBar();
+ void removeOverlayProgressBar();
private:
- bool hasActiveUser();
- void restoreWindowSize();
+ bool hasActiveUser();
+ void restoreWindowSize();
- static MainWindow *instance_;
+ static MainWindow *instance_;
- // The initial welcome screen.
- WelcomePage *welcome_page_;
+ // The initial welcome screen.
+ WelcomePage *welcome_page_;
- // The login screen.
- LoginPage *login_page_;
+ // The login screen.
+ LoginPage *login_page_;
- // The register page.
- RegisterPage *register_page_;
+ // The register page.
+ RegisterPage *register_page_;
- // A stacked widget that handles the transitions between widgets.
- SlidingStackWidget *sliding_stack_;
+ // A stacked widget that handles the transitions between widgets.
+ SlidingStackWidget *sliding_stack_;
- // The main chat area.
- ChatPage *chat_page_;
+ // The main chat area.
+ ChatPage *chat_page_;
- // Used to hide undefined states between page transitions.
- OverlayModal *progress_modal_;
- CircularProgress *spinner_;
+ // Used to hide undefined states between page transitions.
+ OverlayModal *progress_modal_;
+ LoadingIndicator *spinner_;
- // Matrix Client API provider.
- QSharedPointer<MatrixClient> client_;
+ // Matrix Client API provider.
+ QSharedPointer<MatrixClient> client_;
- // Tray icon that shows the unread message count.
- TrayIcon *trayIcon_;
+ // Tray icon that shows the unread message count.
+ TrayIcon *trayIcon_;
};
diff --git a/include/MatrixClient.h b/include/MatrixClient.h
index 58b24f9b..8d6c60a7 100644
--- a/include/MatrixClient.h
+++ b/include/MatrixClient.h
@@ -39,7 +39,8 @@ public:
void sync() noexcept;
void sendRoomMessage(matrix::events::MessageEventType ty,
const QString &roomid,
- const QString &msg) noexcept;
+ const QString &msg,
+ const QString &url = "") noexcept;
void login(const QString &username, const QString &password) noexcept;
void registerUser(const QString &username,
const QString &password,
@@ -50,6 +51,7 @@ public:
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;
+ void uploadImage(const QString &roomid, const QString &filename);
inline QUrl getHomeServer();
inline int transactionId();
@@ -77,6 +79,7 @@ signals:
const QString &homeserver,
const QString &token);
void versionSuccess();
+ void imageUploaded(const QString &roomid, const QString &filename, const QString &url);
void roomAvatarRetrieved(const QString &roomid, const QPixmap &img);
void userAvatarRetrieved(const QString &userId, const QImage &img);
@@ -102,6 +105,7 @@ private:
GetProfile,
Image,
InitialSync,
+ ImageUpload,
Login,
Logout,
Messages,
@@ -118,6 +122,7 @@ private:
void onGetOwnProfileResponse(QNetworkReply *reply);
void onImageResponse(QNetworkReply *reply);
void onInitialSyncResponse(QNetworkReply *reply);
+ void onImageUploadResponse(QNetworkReply *reply);
void onLoginResponse(QNetworkReply *reply);
void onLogoutResponse(QNetworkReply *reply);
void onMessagesResponse(QNetworkReply *reply);
@@ -129,7 +134,10 @@ private:
void onVersionsResponse(QNetworkReply *reply);
// Client API prefix.
- QString api_url_;
+ QString clientApiUrl_;
+
+ // Media API prefix.
+ QString mediaApiUrl_;
// The Matrix server used for communication.
QUrl server_;
diff --git a/include/TextInputWidget.h b/include/TextInputWidget.h
index 73c2a603..732f4f61 100644
--- a/include/TextInputWidget.h
+++ b/include/TextInputWidget.h
@@ -24,6 +24,10 @@
#include "EmojiPickButton.h"
#include "FlatButton.h"
+#include "Image.h"
+#include "LoadingIndicator.h"
+
+namespace msgs = matrix::events::messages;
static const QString EMOTE_COMMAND("/me ");
@@ -48,6 +52,8 @@ public:
public slots:
void onSendButtonClicked();
+ void openFileSelection();
+ void hideUploadSpinner();
inline void focusLineEdit();
private slots:
@@ -56,16 +62,20 @@ private slots:
signals:
void sendTextMessage(QString msg);
void sendEmoteMessage(QString msg);
+ void uploadImage(QString filename);
private:
+ void showUploadSpinner();
QString parseEmoteCommand(const QString &cmd);
- QHBoxLayout *top_layout_;
+ QHBoxLayout *topLayout_;
FilteredTextEdit *input_;
- FlatButton *send_file_button_;
- FlatButton *send_message_button_;
- EmojiPickButton *emoji_button_;
+ LoadingIndicator *spinner_;
+
+ FlatButton *sendFileBtn_;
+ FlatButton *sendMessageBtn_;
+ EmojiPickButton *emojiBtn_;
};
inline void
diff --git a/include/TimelineItem.h b/include/TimelineItem.h
index edc15dab..0a0538f9 100644
--- a/include/TimelineItem.h
+++ b/include/TimelineItem.h
@@ -50,11 +50,14 @@ public:
QWidget *parent = 0);
// For local messages.
+ // m.text & m.emote
TimelineItem(events::MessageEventType ty,
const QString &userid,
QString body,
bool withSender,
QWidget *parent = 0);
+ // m.image
+ TimelineItem(ImageItem *item, const QString &userid, bool withSender, QWidget *parent = 0);
TimelineItem(ImageItem *img,
const events::MessageEvent<msgs::Image> &e,
diff --git a/include/TimelineView.h b/include/TimelineView.h
index 3ecf8ba7..61283fa2 100644
--- a/include/TimelineView.h
+++ b/include/TimelineView.h
@@ -85,6 +85,7 @@ public:
// Add new events at the end of the timeline.
int addEvents(const Timeline &timeline);
void addUserMessage(matrix::events::MessageEventType ty, const QString &msg, int txn_id);
+ void addUserMessage(const QString &url, const QString &filename, int txn_id);
void updatePendingMessage(int txn_id, QString event_id);
void scrollDown();
@@ -108,11 +109,11 @@ private:
// Used to determine whether or not we should prefix a message with the sender's name.
bool isSenderRendered(const QString &user_id, TimelineDirection direction);
- template<class T>
- bool isPendingMessage(const events::MessageEvent<T> &e, const QString &userid);
-
- template<class T>
- void removePendingMessage(const events::MessageEvent<T> &e);
+ bool isPendingMessage(const QString &eventid,
+ const QString &body,
+ const QString &sender,
+ const QString &userid);
+ void removePendingMessage(const QString &eventid, const QString &body);
inline bool isDuplicate(const QString &event_id);
@@ -159,32 +160,3 @@ 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;
- }
- }
-}
diff --git a/include/TimelineViewManager.h b/include/TimelineViewManager.h
index d3ca198e..14f47928 100644
--- a/include/TimelineViewManager.h
+++ b/include/TimelineViewManager.h
@@ -56,6 +56,7 @@ public slots:
void setHistoryView(const QString &room_id);
void sendTextMessage(const QString &msg);
void sendEmoteMessage(const QString &msg);
+ void sendImageMessage(const QString &roomid, const QString &filename, const QString &url);
private slots:
void messageSent(const QString &eventid, const QString &roomid, int txnid);
diff --git a/include/ui/CircularProgress.h b/include/ui/CircularProgress.h
deleted file mode 100644
index 5ed8994d..00000000
--- a/include/ui/CircularProgress.h
+++ /dev/null
@@ -1,120 +0,0 @@
-#pragma once
-
-#include <QObject>
-#include <QProgressBar>
-
-#include "Theme.h"
-
-class CircularProgressDelegate;
-
-class CircularProgress : public QProgressBar
-{
- Q_OBJECT
-
- Q_PROPERTY(qreal lineWidth WRITE setLineWidth READ lineWidth)
- Q_PROPERTY(qreal size WRITE setSize READ size)
- Q_PROPERTY(QColor color WRITE setColor READ color)
-
-public:
- explicit CircularProgress(QWidget *parent = nullptr);
- ~CircularProgress();
-
- void setProgressType(ui::ProgressType type);
- void setLineWidth(qreal width);
- void setSize(int size);
- void setColor(const QColor &color);
-
- ui::ProgressType progressType() const;
- qreal lineWidth() const;
- int size() const;
- QColor color() const;
-
- QSize sizeHint() const override;
-
-protected:
- void paintEvent(QPaintEvent *event) override;
-
-private:
- CircularProgressDelegate *delegate_;
-
- ui::ProgressType progress_type_;
-
- QColor color_;
-
- // Circle width.
- qreal width_;
-
- // Circle radius.
- int size_;
-
- // Animation duration.
- int duration_;
-};
-
-class CircularProgressDelegate : public QObject
-{
- Q_OBJECT
-
- Q_PROPERTY(qreal dashOffset WRITE setDashOffset READ dashOffset)
- Q_PROPERTY(qreal dashLength WRITE setDashLength READ dashLength)
- Q_PROPERTY(int angle WRITE setAngle READ angle)
-
-public:
- explicit CircularProgressDelegate(CircularProgress *parent);
- ~CircularProgressDelegate();
-
- inline void setDashOffset(qreal offset);
- inline void setDashLength(qreal length);
- inline void setAngle(int angle);
-
- inline qreal dashOffset() const;
- inline qreal dashLength() const;
- inline int angle() const;
-
-private:
- CircularProgress *const progress_;
-
- qreal dash_offset_;
- qreal dash_length_;
-
- int angle_;
-};
-
-inline void
-CircularProgressDelegate::setDashOffset(qreal offset)
-{
- dash_offset_ = offset;
- progress_->update();
-}
-
-inline void
-CircularProgressDelegate::setDashLength(qreal length)
-{
- dash_length_ = length;
- progress_->update();
-}
-
-inline void
-CircularProgressDelegate::setAngle(int angle)
-{
- angle_ = angle;
- progress_->update();
-}
-
-inline qreal
-CircularProgressDelegate::dashOffset() const
-{
- return dash_offset_;
-}
-
-inline qreal
-CircularProgressDelegate::dashLength() const
-{
- return dash_length_;
-}
-
-inline int
-CircularProgressDelegate::angle() const
-{
- return angle_;
-}
diff --git a/include/ui/LoadingIndicator.h b/include/ui/LoadingIndicator.h
new file mode 100644
index 00000000..2641955a
--- /dev/null
+++ b/include/ui/LoadingIndicator.h
@@ -0,0 +1,49 @@
+#pragma once
+
+#include <QColor>
+#include <QPaintEvent>
+#include <QPainter>
+#include <QTimer>
+#include <QWidget>
+
+class LoadingIndicator : public QWidget
+{
+ Q_OBJECT
+
+public:
+ LoadingIndicator(QWidget *parent = 0);
+ virtual ~LoadingIndicator();
+
+ void paintEvent(QPaintEvent *e);
+
+ void start();
+ void stop();
+
+ QColor color()
+ {
+ return color_;
+ }
+ void setColor(QColor color)
+ {
+ color_ = color;
+ }
+
+ int interval()
+ {
+ return interval_;
+ }
+ void setInterval(int interval)
+ {
+ interval_ = interval;
+ }
+
+private slots:
+ void onTimeout();
+
+private:
+ int interval_;
+ int angle_;
+
+ QColor color_;
+ QTimer *timer_;
+};
|