diff --git a/src/timeline/TimelineItem.cpp b/src/timeline/TimelineItem.cpp
index e962d468..1c90eade 100644
--- a/src/timeline/TimelineItem.cpp
+++ b/src/timeline/TimelineItem.cpp
@@ -192,7 +192,8 @@ TimelineItem::init()
emit eventRedacted(event_id_);
});
});
-
+ connect(
+ ChatPage::instance(), &ChatPage::themeChanged, this, &TimelineItem::refreshAuthorColor);
connect(markAsRead_, &QAction::triggered, this, &TimelineItem::sendReadReceipt);
connect(viewRawMessage_, &QAction::triggered, this, &TimelineItem::openRawMessageViewer);
@@ -594,7 +595,7 @@ TimelineItem::markReceived(bool isEncrypted)
void
TimelineItem::generateBody(const QString &body)
{
- body_ = new TextLabel(body, this);
+ body_ = new TextLabel(replaceEmoji(body), this);
body_->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextBrowserInteraction);
connect(body_, &TextLabel::userProfileTriggered, this, [](const QString &user_id) {
@@ -603,6 +604,24 @@ TimelineItem::generateBody(const QString &body)
});
}
+void
+TimelineItem::refreshAuthorColor()
+{
+ if (userName_) {
+ QString userColor = Cache::userColor(userName_->toolTip());
+ if (userColor.isEmpty()) {
+ // This attempts to refresh this item since it's not drawn
+ // which allows us to get the background color accurately.
+ qApp->style()->polish(this);
+ // generate user's unique color.
+ auto backCol = backgroundColor().name();
+ userColor =
+ utils::generateContrastingHexColor(userName_->toolTip(), backCol);
+ Cache::insertUserColor(userName_->toolTip(), userColor);
+ }
+ userName_->setStyleSheet("QLabel { color : " + userColor + "; }");
+ }
+}
// The username/timestamp is displayed along with the message body.
void
TimelineItem::generateBody(const QString &user_id, const QString &displayname, const QString &body)
@@ -623,7 +642,7 @@ TimelineItem::generateUserName(const QString &user_id, const QString &displaynam
}
QFont usernameFont;
- usernameFont.setPointSizeF(usernameFont.pointSizeF());
+ usernameFont.setPointSizeF(usernameFont.pointSizeF() * 1.1);
usernameFont.setWeight(QFont::Medium);
QFontMetrics fm(usernameFont);
@@ -637,6 +656,18 @@ TimelineItem::generateUserName(const QString &user_id, const QString &displaynam
userName_->setAlignment(Qt::AlignLeft | Qt::AlignTop);
userName_->setFixedWidth(QFontMetrics(userName_->font()).width(userName_->text()));
+ // TimelineItem isn't displayed. This forces the QSS to get
+ // loaded.
+ QString userColor = Cache::userColor(user_id);
+ if (userColor.isEmpty()) {
+ qApp->style()->polish(this);
+ // generate user's unique color.
+ auto backCol = backgroundColor().name();
+ userColor = utils::generateContrastingHexColor(user_id, backCol);
+ Cache::insertUserColor(user_id, userColor);
+ }
+ userName_->setStyleSheet("QLabel { color : " + userColor + "; }");
+
auto filter = new UserProfileFilter(user_id, userName_);
userName_->installEventFilter(filter);
userName_->setCursor(Qt::PointingHandCursor);
@@ -667,6 +698,25 @@ TimelineItem::generateTimestamp(const QDateTime &time)
QString("<span style=\"color: #999\"> %1 </span>").arg(time.toString("HH:mm")));
}
+QString
+TimelineItem::replaceEmoji(const QString &body)
+{
+ QString fmtBody = "";
+
+ QVector<uint> utf32_string = body.toUcs4();
+
+ for (auto &code : utf32_string) {
+ // TODO: Be more precise here.
+ if (code > 9000)
+ fmtBody += QString("<span style=\"font-family: emoji;\">") +
+ QString::fromUcs4(&code, 1) + "</span>";
+ else
+ fmtBody += QString::fromUcs4(&code, 1);
+ }
+
+ return fmtBody;
+}
+
void
TimelineItem::setupAvatarLayout(const QString &userName)
{
@@ -837,4 +887,4 @@ TimelineItem::openRawMessageViewer() const
"failed to serialize event ({}, {})", room_id, event_id);
}
});
-}
+}
\ No newline at end of file
diff --git a/src/timeline/TimelineItem.h b/src/timeline/TimelineItem.h
index 8159e370..f81aa658 100644
--- a/src/timeline/TimelineItem.h
+++ b/src/timeline/TimelineItem.h
@@ -132,6 +132,8 @@ private:
class TimelineItem : public QWidget
{
Q_OBJECT
+ Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor)
+
public:
TimelineItem(const mtx::events::RoomEvent<mtx::events::msg::Notice> &e,
bool with_sender,
@@ -202,6 +204,9 @@ public:
const QString &room_id,
QWidget *parent);
+ void setBackgroundColor(const QColor &color) { backgroundColor_ = color; }
+ QColor backgroundColor() const { return backgroundColor_; }
+
void setUserAvatar(const QImage &pixmap);
DescInfo descriptionMessage() const { return descriptionMsg_; }
QString eventId() const { return event_id_; }
@@ -222,6 +227,9 @@ signals:
void eventRedacted(const QString &event_id);
void redactionFailed(const QString &msg);
+public slots:
+ void refreshAuthorColor();
+
protected:
void paintEvent(QPaintEvent *event) override;
void contextMenuEvent(QContextMenuEvent *event) override;
@@ -256,6 +264,7 @@ private:
//! has been acknowledged by the server.
bool isReceived_ = false;
+ QString replaceEmoji(const QString &body);
QString event_id_;
QString room_id_;
@@ -282,6 +291,8 @@ private:
QLabel *timestamp_;
QLabel *userName_;
TextLabel *body_;
+
+ QColor backgroundColor_;
};
template<class Widget>
diff --git a/src/timeline/widgets/ImageItem.cpp b/src/timeline/widgets/ImageItem.cpp
index f06b9a5b..4ee9e42a 100644
--- a/src/timeline/widgets/ImageItem.cpp
+++ b/src/timeline/widgets/ImageItem.cpp
@@ -158,6 +158,7 @@ ImageItem::mousePressEvent(QMouseEvent *event)
} else {
auto imgDialog = new dialogs::ImageOverlay(image_);
imgDialog->show();
+ connect(imgDialog, &dialogs::ImageOverlay::saving, this, &ImageItem::saveAs);
}
}
|