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_;