summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorKonstantinos Sideris <sideris.konstantin@gmail.com>2018-07-20 12:02:35 +0300
committerKonstantinos Sideris <sideris.konstantin@gmail.com>2018-07-20 12:02:35 +0300
commitd7e5171bfabf48e69112190b7096268222979c1c (patch)
tree89e09ff0189dbd87f7f203da0a53a52ccbb7fa2a /src
parentAdd user avatar after the 'encryption is enabled' message (diff)
downloadnheko-d7e5171bfabf48e69112190b7096268222979c1c.tar.xz
Create user profile modal
Diffstat (limited to 'src')
-rw-r--r--src/AvatarProvider.cpp2
-rw-r--r--src/MainWindow.cpp13
-rw-r--r--src/MainWindow.h5
-rw-r--r--src/dialogs/UserProfile.cpp153
-rw-r--r--src/dialogs/UserProfile.h53
-rw-r--r--src/timeline/TimelineItem.cpp17
-rw-r--r--src/timeline/TimelineItem.h5
-rw-r--r--src/ui/OverlayModal.cpp10
-rw-r--r--src/ui/OverlayModal.h5
9 files changed, 251 insertions, 12 deletions
diff --git a/src/AvatarProvider.cpp b/src/AvatarProvider.cpp

index dbfc1945..57b61c75 100644 --- a/src/AvatarProvider.cpp +++ b/src/AvatarProvider.cpp
@@ -50,6 +50,8 @@ resolve(const QString &room_id, const QString &user_id, QObject *receiver, Avata [callback](const QByteArray &data) { callback(QImage::fromData(data)); }); mtx::http::ThumbOpts opts; + opts.width = 256; + opts.height = 256; opts.mxc_url = avatarUrl.toStdString(); http::client()->get_thumbnail( diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
index fdca98c3..35bfba86 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp
@@ -310,6 +310,18 @@ MainWindow::hasActiveUser() } void +MainWindow::openUserProfile(const QString &user_id, const QString &room_id) +{ + userProfileDialog_ = QSharedPointer<dialogs::UserProfile>(new dialogs::UserProfile(this)); + userProfileDialog_->init(user_id, room_id); + + userProfileModal_ = + QSharedPointer<OverlayModal>(new OverlayModal(this, userProfileDialog_.data())); + + userProfileModal_->show(); +} + +void MainWindow::openRoomSettings(const QString &room_id) { const auto roomToSearch = room_id.isEmpty() ? chat_page_->currentRoom() : ""; @@ -382,6 +394,7 @@ MainWindow::showOverlayProgressBar() progressModal_ = QSharedPointer<OverlayModal>(new OverlayModal(this, spinner_.data()), [](OverlayModal *modal) { modal->deleteLater(); }); + progressModal_->setContentAlignment(Qt::AlignCenter); progressModal_->setColor(QColor(30, 30, 30)); progressModal_->setDismissible(false); progressModal_->show(); diff --git a/src/MainWindow.h b/src/MainWindow.h
index 92040191..3d9a94d3 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h
@@ -28,6 +28,7 @@ #include "RegisterPage.h" #include "UserSettingsPage.h" #include "WelcomePage.h" +#include "dialogs/UserProfile.h" class ChatPage; class LoadingIndicator; @@ -71,6 +72,7 @@ public: void openLogoutDialog(std::function<void()> callback); void openRoomSettings(const QString &room_id = ""); void openMemberListDialog(const QString &room_id = ""); + void openUserProfile(const QString &user_id, const QString &room_id); protected: void closeEvent(QCloseEvent *event) override; @@ -171,4 +173,7 @@ private: QSharedPointer<OverlayModal> memberListModal_; //! Member list dialog. QSharedPointer<dialogs::MemberList> memberListDialog_; + + QSharedPointer<OverlayModal> userProfileModal_; + QSharedPointer<dialogs::UserProfile> userProfileDialog_; }; diff --git a/src/dialogs/UserProfile.cpp b/src/dialogs/UserProfile.cpp new file mode 100644
index 00000000..1da293a5 --- /dev/null +++ b/src/dialogs/UserProfile.cpp
@@ -0,0 +1,153 @@ +#include <QHBoxLayout> +#include <QLabel> +#include <QListWidget> +#include <QPaintEvent> +#include <QSettings> +#include <QStyleOption> +#include <QVBoxLayout> + +#include "AvatarProvider.h" +#include "Cache.h" +#include "Utils.h" +#include "dialogs/UserProfile.h" +#include "ui/Avatar.h" +#include "ui/FlatButton.h" + +using namespace dialogs; + +constexpr int BUTTON_SIZE = 36; + +DeviceItem::DeviceItem(QWidget *parent, QString deviceName) + : QWidget(parent) + , name_(deviceName) +{} + +UserProfile::UserProfile(QWidget *parent) + : QWidget(parent) +{ + QIcon banIcon, kickIcon, ignoreIcon, startChatIcon; + + banIcon.addFile(":/icons/icons/ui/do-not-disturb-rounded-sign.png"); + banBtn_ = new FlatButton(this); + banBtn_->setFixedSize(BUTTON_SIZE, BUTTON_SIZE); + banBtn_->setCornerRadius(BUTTON_SIZE / 2); + banBtn_->setIcon(banIcon); + banBtn_->setIconSize(QSize(BUTTON_SIZE / 2, BUTTON_SIZE / 2)); + banBtn_->setToolTip(tr("Ban the user from the room")); + + ignoreIcon.addFile(":/icons/icons/ui/volume-off-indicator.png"); + ignoreBtn_ = new FlatButton(this); + ignoreBtn_->setFixedSize(BUTTON_SIZE, BUTTON_SIZE); + ignoreBtn_->setCornerRadius(BUTTON_SIZE / 2); + ignoreBtn_->setIcon(ignoreIcon); + ignoreBtn_->setIconSize(QSize(BUTTON_SIZE / 2, BUTTON_SIZE / 2)); + ignoreBtn_->setToolTip(tr("Ignore messages from this user")); + + kickIcon.addFile(":/icons/icons/ui/round-remove-button.png"); + kickBtn_ = new FlatButton(this); + kickBtn_->setFixedSize(BUTTON_SIZE, BUTTON_SIZE); + kickBtn_->setCornerRadius(BUTTON_SIZE / 2); + kickBtn_->setIcon(kickIcon); + kickBtn_->setIconSize(QSize(BUTTON_SIZE / 2, BUTTON_SIZE / 2)); + kickBtn_->setToolTip(tr("Kick the user from the room")); + + startChatIcon.addFile(":/icons/icons/ui/black-bubble-speech.png"); + startChat_ = new FlatButton(this); + startChat_->setFixedSize(BUTTON_SIZE, BUTTON_SIZE); + startChat_->setCornerRadius(BUTTON_SIZE / 2); + startChat_->setIcon(startChatIcon); + startChat_->setIconSize(QSize(BUTTON_SIZE / 2, BUTTON_SIZE / 2)); + startChat_->setToolTip(tr("Start a conversation")); + + // Button line + auto btnLayout = new QHBoxLayout; + btnLayout->addWidget(startChat_); + btnLayout->addWidget(ignoreBtn_); + + // TODO: check if the user has enough power level given the room_id + // in which the profile was opened. + btnLayout->addWidget(kickBtn_); + btnLayout->addWidget(banBtn_); + btnLayout->setSpacing(8); + btnLayout->setMargin(0); + + avatar_ = new Avatar(this); + avatar_->setLetter("X"); + avatar_->setSize(148); + + QFont font; + font.setPointSizeF(font.pointSizeF() * 2); + + userIdLabel_ = new QLabel(this); + displayNameLabel_ = new QLabel(this); + displayNameLabel_->setFont(font); + + auto textLayout = new QVBoxLayout; + textLayout->addWidget(displayNameLabel_); + textLayout->addWidget(userIdLabel_); + textLayout->setAlignment(displayNameLabel_, Qt::AlignCenter | Qt::AlignTop); + textLayout->setAlignment(userIdLabel_, Qt::AlignCenter | Qt::AlignTop); + textLayout->setSpacing(4); + textLayout->setMargin(0); + + auto vlayout = new QVBoxLayout{this}; + vlayout->addWidget(avatar_); + vlayout->addLayout(textLayout); + vlayout->addLayout(btnLayout); + + vlayout->setAlignment(avatar_, Qt::AlignCenter | Qt::AlignTop); + vlayout->setAlignment(userIdLabel_, Qt::AlignCenter | Qt::AlignTop); + + setAutoFillBackground(true); + setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); + setWindowModality(Qt::WindowModal); + + setMinimumWidth(340); + setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum); + + vlayout->setSpacing(15); + vlayout->setContentsMargins(20, 40, 20, 20); +} + +void +UserProfile::init(const QString &userId, const QString &roomId) +{ + auto displayName = Cache::displayName(roomId, userId); + + userIdLabel_->setText(userId); + displayNameLabel_->setText(displayName); + avatar_->setLetter(utils::firstChar(displayName)); + + AvatarProvider::resolve( + roomId, userId, this, [this](const QImage &img) { avatar_->setImage(img); }); + + QSettings settings; + auto localUser = settings.value("auth/user_id").toString(); + + if (localUser == userId) { + qDebug() << "the local user should have edit rights on avatar & display name"; + // TODO: click on display name & avatar to change. + } + + try { + bool hasMemberRights = + cache::client()->hasEnoughPowerLevel({mtx::events::EventType::RoomMember}, + roomId.toStdString(), + localUser.toStdString()); + if (!hasMemberRights) { + kickBtn_->hide(); + banBtn_->hide(); + } + } catch (const lmdb::error &e) { + nhlog::db()->warn("lmdb error: {}", e.what()); + } +} + +void +UserProfile::paintEvent(QPaintEvent *) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); +} diff --git a/src/dialogs/UserProfile.h b/src/dialogs/UserProfile.h new file mode 100644
index 00000000..8d5b9c5f --- /dev/null +++ b/src/dialogs/UserProfile.h
@@ -0,0 +1,53 @@ +#pragma once + +#include <QString> +#include <QWidget> + +class Avatar; +class FlatButton; +class QLabel; +class QListWidget; + +namespace dialogs { + +class DeviceItem : public QWidget +{ + Q_OBJECT + +public: + explicit DeviceItem(QWidget *parent, QString deviceName); + +private: + QString name_; + + // Toggle *verifyToggle_; +}; + +class UserProfile : public QWidget +{ + Q_OBJECT +public: + explicit UserProfile(QWidget *parent = nullptr); + + void init(const QString &userId, const QString &roomId); + +protected: + void paintEvent(QPaintEvent *) override; + +private: + Avatar *avatar_; + + QString displayName_; + QString userId_; + + QLabel *userIdLabel_; + QLabel *displayNameLabel_; + + FlatButton *banBtn_; + FlatButton *kickBtn_; + FlatButton *ignoreBtn_; + FlatButton *startChat_; + + QListWidget *devices_; +}; +} // dialogs diff --git a/src/timeline/TimelineItem.cpp b/src/timeline/TimelineItem.cpp
index 696db8de..71b3156c 100644 --- a/src/timeline/TimelineItem.cpp +++ b/src/timeline/TimelineItem.cpp
@@ -23,6 +23,7 @@ #include "ChatPage.h" #include "Config.h" #include "Logging.h" +#include "MainWindow.h" #include "Olm.h" #include "ui/Avatar.h" #include "ui/Painter.h" @@ -562,6 +563,13 @@ TimelineItem::generateBody(const QString &body) void TimelineItem::generateBody(const QString &user_id, const QString &displayname, const QString &body) { + generateUserName(user_id, displayname); + generateBody(body); +} + +void +TimelineItem::generateUserName(const QString &user_id, const QString &displayname) +{ auto sender = displayname; if (displayname.startsWith("@")) { @@ -598,7 +606,9 @@ TimelineItem::generateBody(const QString &user_id, const QString &displayname, c userName_->setFont(f); }); - generateBody(body); + connect(filter, &UserProfileFilter::clicked, this, [this, user_id]() { + MainWindow::instance()->openUserProfile(user_id, room_id_); + }); } void @@ -742,10 +752,7 @@ TimelineItem::addAvatar() auto userid = descriptionMsg_.userid; auto displayName = Cache::displayName(room_id_, userid); - QFontMetrics fm(usernameFont_); - userName_ = new QLabel(this); - userName_->setFont(usernameFont_); - userName_->setText(fm.elidedText(displayName, Qt::ElideRight, 500)); + generateUserName(userid, displayName); setupAvatarLayout(displayName); diff --git a/src/timeline/TimelineItem.h b/src/timeline/TimelineItem.h
index 874c00df..db000078 100644 --- a/src/timeline/TimelineItem.h +++ b/src/timeline/TimelineItem.h
@@ -137,13 +137,13 @@ public: signals: void hoverOff(); void hoverOn(); + void clicked(); protected: bool eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::MouseButtonRelease) { - // QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); - // TODO: Open user profile + emit clicked(); return true; } else if (event->type() == QEvent::HoverLeave) { emit hoverOff(); @@ -274,6 +274,7 @@ private: void generateBody(const QString &body); void generateBody(const QString &user_id, const QString &displayname, const QString &body); void generateTimestamp(const QDateTime &time); + void generateUserName(const QString &userid, const QString &displayname); void setupAvatarLayout(const QString &userName); void setupSimpleLayout(); diff --git a/src/ui/OverlayModal.cpp b/src/ui/OverlayModal.cpp
index 6aa16b07..41e07a91 100644 --- a/src/ui/OverlayModal.cpp +++ b/src/ui/OverlayModal.cpp
@@ -25,11 +25,11 @@ OverlayModal::OverlayModal(QWidget *parent, QWidget *content) , content_{content} , color_{QColor(30, 30, 30, 170)} { - auto layout = new QVBoxLayout(); - layout->addWidget(content); - layout->setAlignment(Qt::AlignCenter); - - setLayout(layout); + layout_ = new QVBoxLayout(this); + layout_->addWidget(content); + layout_->setSpacing(0); + layout_->setContentsMargins(10, 40, 10, 20); + setContentAlignment(Qt::AlignTop | Qt::AlignHCenter); content->setFocus(); } diff --git a/src/ui/OverlayModal.h b/src/ui/OverlayModal.h
index a761e3ed..acba7a7a 100644 --- a/src/ui/OverlayModal.h +++ b/src/ui/OverlayModal.h
@@ -20,6 +20,7 @@ #include <QKeyEvent> #include <QMouseEvent> #include <QPaintEvent> +#include <QVBoxLayout> #include "OverlayWidget.h" @@ -31,6 +32,8 @@ public: void setColor(QColor color) { color_ = color; } void setDismissible(bool state) { isDismissible_ = state; } + void setContentAlignment(QFlags<Qt::AlignmentFlag> flag) { layout_->setAlignment(flag); } + protected: void paintEvent(QPaintEvent *event) override; void keyPressEvent(QKeyEvent *event) override; @@ -38,6 +41,8 @@ protected: private: QWidget *content_; + QVBoxLayout *layout_; + QColor color_; //! Decides whether or not the modal can be removed by clicking into it.