diff --git a/src/Utils.cpp b/src/Utils.cpp index 1d1dbeb2..0d3e9384 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -399,7 +399,6 @@ utils::hashQString(const QString &input) QString utils::generateContrastingHexColor(const QString &input, const QString &background) { - nhlog::ui()->debug("Background hex {}", background.toStdString()); const QColor backgroundCol(background); const qreal backgroundLum = luminance(background); @@ -407,8 +406,6 @@ utils::generateContrastingHexColor(const QString &input, const QString &backgrou auto hash = hashQString(input); // create a hue value based on the hash of the input. auto userHue = qAbs(hash % 360); - nhlog::ui()->debug( - "User Hue {} : {}", input.toStdString(), QString::number(userHue).toStdString()); // start with moderate saturation and lightness values. auto sat = 220; auto lightness = 125; @@ -430,7 +427,6 @@ utils::generateContrastingHexColor(const QString &input, const QString &backgrou // saturation instead. if (lightness == 242 || lightness == 13) { qreal newSat = qBound(26.0, sat * 1.25, 242.0); - nhlog::ui()->info("newSat {}", QString::number(newSat).toStdString()); inputColor.setHsl(userHue, qFloor(newSat), lightness); auto tmpLum = luminance(inputColor); @@ -477,11 +473,6 @@ utils::generateContrastingHexColor(const QString &input, const QString &backgrou // get the hex value of the generated color. auto colorHex = inputColor.name(); - nhlog::ui()->debug("Hex Generated for {}: [hex: {}, contrast: {}, luminance: {}]", - input.toStdString(), - colorHex.toStdString(), - QString::number(contrast).toStdString(), - QString::number(lum).toStdString()); return colorHex; } diff --git a/src/timeline/TimelineItem.cpp b/src/timeline/TimelineItem.cpp index 1c90eade..d23dbf49 100644 --- a/src/timeline/TimelineItem.cpp +++ b/src/timeline/TimelineItem.cpp @@ -14,6 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ +#include #include #include @@ -197,6 +198,12 @@ TimelineItem::init() connect(markAsRead_, &QAction::triggered, this, &TimelineItem::sendReadReceipt); connect(viewRawMessage_, &QAction::triggered, this, &TimelineItem::openRawMessageViewer); + colorGenerating_ = new QFutureWatcher(this); + connect(colorGenerating_, + &QFutureWatcher::finished, + this, + &TimelineItem::finishedGeneratingColor); + topLayout_ = new QHBoxLayout(this); mainLayout_ = new QVBoxLayout; messageLayout_ = new QHBoxLayout; @@ -557,6 +564,12 @@ TimelineItem::TimelineItem(const mtx::events::RoomEvent adjustMessageLayout(); } +TimelineItem::~TimelineItem() +{ + colorGenerating_->cancel(); + colorGenerating_->waitForFinished(); +} + void TimelineItem::markSent() { @@ -607,16 +620,39 @@ TimelineItem::generateBody(const QString &body) void TimelineItem::refreshAuthorColor() { + // Cancel and wait if we are already generating the color. + if (colorGenerating_->isRunning()) { + colorGenerating_->cancel(); + colorGenerating_->waitForFinished(); + } if (userName_) { + // generate user's unique color. + std::function generate = [this]() { + QString userColor = utils::generateContrastingHexColor( + userName_->toolTip(), backgroundColor().name()); + return userColor; + }; + QString userColor = Cache::userColor(userName_->toolTip()); + + // If the color is empty, then generate it asynchronously 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); + colorGenerating_->setFuture(QtConcurrent::run(generate)); + } else { + userName_->setStyleSheet("QLabel { color : " + userColor + "; }"); + } + } +} + +void +TimelineItem::finishedGeneratingColor() +{ + nhlog::ui()->debug("finishedGeneratingColor for: {}", userName_->toolTip().toStdString()); + QString userColor = colorGenerating_->result(); + + if (!userColor.isEmpty()) { + // another TimelineItem might have inserted in the meantime. + if (Cache::userColor(userName_->toolTip()).isEmpty()) { Cache::insertUserColor(userName_->toolTip(), userColor); } userName_->setStyleSheet("QLabel { color : " + userColor + "; }"); @@ -656,17 +692,9 @@ 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 + "; }"); + // Set the user color asynchronously if it hasn't been generated yet, + // otherwise this will just set it. + refreshAuthorColor(); auto filter = new UserProfileFilter(user_id, userName_); userName_->installEventFilter(filter); diff --git a/src/timeline/TimelineItem.h b/src/timeline/TimelineItem.h index f81aa658..7bf6a076 100644 --- a/src/timeline/TimelineItem.h +++ b/src/timeline/TimelineItem.h @@ -26,6 +26,8 @@ #include #include +#include + #include "AvatarProvider.h" #include "RoomInfoListItem.h" #include "Utils.h" @@ -204,6 +206,8 @@ public: const QString &room_id, QWidget *parent); + ~TimelineItem(); + void setBackgroundColor(const QColor &color) { backgroundColor_ = color; } QColor backgroundColor() const { return backgroundColor_; } @@ -229,6 +233,7 @@ signals: public slots: void refreshAuthorColor(); + void finishedGeneratingColor(); protected: void paintEvent(QPaintEvent *event) override; @@ -264,6 +269,8 @@ private: //! has been acknowledged by the server. bool isReceived_ = false; + QFutureWatcher *colorGenerating_; + QString replaceEmoji(const QString &body); QString event_id_; QString room_id_;