diff --git a/include/ImageItem.h b/include/ImageItem.h
index e37e04b2..20e0772d 100644
--- a/include/ImageItem.h
+++ b/include/ImageItem.h
@@ -36,6 +36,11 @@ public:
const events::MessageEvent<msgs::Image> &event,
QWidget *parent = nullptr);
+ ImageItem(QSharedPointer<MatrixClient> client,
+ const QString &url,
+ const QString &filename,
+ QWidget *parent = nullptr);
+
void setImage(const QPixmap &image);
QSize sizeHint() const override;
diff --git a/include/LoginPage.h b/include/LoginPage.h
index db852e2c..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"
@@ -79,7 +79,7 @@ private:
QHBoxLayout *serverLayout_;
QHBoxLayout *matrixidLayout_;
- CircularProgress *spinner_;
+ LoadingIndicator *spinner_;
QLabel *errorIcon_;
QString inferredServerAddress_;
diff --git a/include/MainWindow.h b/include/MainWindow.h
index 6f1d6e3e..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"
@@ -85,7 +85,7 @@ private:
// Used to hide undefined states between page transitions.
OverlayModal *progress_modal_;
- CircularProgress *spinner_;
+ LoadingIndicator *spinner_;
// Matrix Client API provider.
QSharedPointer<MatrixClient> client_;
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 291cce1c..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_;
+};
|