diff --git a/src/ChatPage.cc b/src/ChatPage.cc
index 5862e559..9f20d54f 100644
--- a/src/ChatPage.cc
+++ b/src/ChatPage.cc
@@ -138,6 +138,11 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent)
room_list_->updateUnreadMessageCount(roomid, count);
});
+ connect(view_manager_,
+ &TimelineViewManager::updateRoomsLastMessage,
+ room_list_,
+ &RoomList::updateRoomDescription);
+
connect(room_list_,
SIGNAL(totalUnreadMessageCountUpdated(int)),
this,
diff --git a/src/RoomInfoListItem.cc b/src/RoomInfoListItem.cc
index 379e4000..c9d7338f 100644
--- a/src/RoomInfoListItem.cc
+++ b/src/RoomInfoListItem.cc
@@ -135,10 +135,34 @@ void RoomInfoListItem::paintEvent(QPaintEvent *event)
font.setPixelSize(conf::fontSize);
p.setFont(font);
- auto description = metrics.elidedText(state_.getTopic(), Qt::ElideRight, width() * descPercentage - 2 * Padding - IconSize);
- p.drawText(QPoint(2 * Padding + IconSize, bottom_y), description);
+ auto msgStampWidth = QFontMetrics(font).width(lastMsgInfo_.timestamp) + 5;
+
+ // The limit is the space between the end of the avatar and the start of the timestamp.
+ int usernameLimit = std::max(0, width() - 3 * Padding - msgStampWidth - IconSize - 20);
+ auto userName = metrics.elidedText(lastMsgInfo_.username, Qt::ElideRight, usernameLimit);
+
+ font.setBold(true);
+ p.setFont(font);
+ p.drawText(QPoint(2 * Padding + IconSize, bottom_y), userName);
+
+ int nameWidth = QFontMetrics(font).width(userName);
+
+ font.setBold(false);
+ p.setFont(font);
+
+ // The limit is the space between the end of the username and the start of the timestamp.
+ int descriptionLimit = std::max(0, width() - 3 * Padding - msgStampWidth - IconSize - nameWidth - 5);
+ auto description = metrics.elidedText(lastMsgInfo_.body, Qt::ElideRight, descriptionLimit);
+ p.drawText(QPoint(2 * Padding + IconSize + nameWidth, bottom_y), description);
+
+ // We either show the bubble or the last message timestamp.
+ if (unreadMsgCount_ == 0) {
+ font.setBold(true);
+ p.drawText(QPoint(width() - Padding - msgStampWidth, bottom_y), lastMsgInfo_.timestamp);
+ }
}
+ font.setBold(false);
p.setPen(Qt::NoPen);
// We using the first letter of room's name.
diff --git a/src/RoomList.cc b/src/RoomList.cc
index 55c71b19..042391a2 100644
--- a/src/RoomList.cc
+++ b/src/RoomList.cc
@@ -174,10 +174,19 @@ void RoomList::highlightSelectedRoom(const QString &room_id)
void RoomList::updateRoomAvatar(const QString &roomid, const QPixmap &img)
{
if (!rooms_.contains(roomid)) {
- qDebug() << "Avatar update on non existent room" << roomid;
+ qWarning() << "Avatar update on non existent room" << roomid;
return;
}
- auto list_item = rooms_.value(roomid);
- list_item->setAvatar(img.toImage());
+ rooms_.value(roomid)->setAvatar(img.toImage());
+}
+
+void RoomList::updateRoomDescription(const QString &roomid, const DescInfo &info)
+{
+ if (!rooms_.contains(roomid)) {
+ qWarning() << "Description update on non existent room" << roomid << info.body;
+ return;
+ }
+
+ rooms_.value(roomid)->setDescriptionMessage(info);
}
diff --git a/src/TimelineItem.cc b/src/TimelineItem.cc
index 24b1c90f..ee2377ef 100644
--- a/src/TimelineItem.cc
+++ b/src/TimelineItem.cc
@@ -72,6 +72,7 @@ TimelineItem::TimelineItem(const QString &userid, const QString &color, QString
: QWidget(parent)
{
init();
+ descriptionMsg_ = {"You: ", body, descriptiveTime(QDateTime::currentDateTime())};
body.replace(URL_REGEX, URL_HTML);
auto displayName = TimelineViewManager::displayName(userid);
@@ -94,6 +95,7 @@ TimelineItem::TimelineItem(QString body, QWidget *parent)
: QWidget(parent)
{
init();
+ descriptionMsg_ = {"You: ", body, descriptiveTime(QDateTime::currentDateTime())};
body.replace(URL_REGEX, URL_HTML);
@@ -119,6 +121,10 @@ TimelineItem::TimelineItem(ImageItem *image,
auto timestamp = QDateTime::fromMSecsSinceEpoch(event.timestamp());
auto displayName = TimelineViewManager::displayName(event.sender());
+ descriptionMsg_ = {displayName,
+ " sent an image",
+ descriptiveTime(QDateTime::fromMSecsSinceEpoch(event.timestamp()))};
+
generateTimestamp(timestamp);
generateBody(displayName, color, "");
@@ -141,6 +147,9 @@ TimelineItem::TimelineItem(ImageItem *image, const events::MessageEvent<msgs::Im
: QWidget(parent)
{
init();
+ descriptionMsg_ = {TimelineViewManager::displayName(event.sender()),
+ " sent an image",
+ descriptiveTime(QDateTime::fromMSecsSinceEpoch(event.timestamp()))};
auto timestamp = QDateTime::fromMSecsSinceEpoch(event.timestamp());
generateTimestamp(timestamp);
@@ -162,6 +171,10 @@ TimelineItem::TimelineItem(const events::MessageEvent<msgs::Notice> &event, bool
: QWidget(parent)
{
init();
+ descriptionMsg_ = {
+ TimelineViewManager::displayName(event.sender()),
+ " sent a notification",
+ descriptiveTime(QDateTime::fromMSecsSinceEpoch(event.timestamp()))};
auto body = event.content().body().trimmed().toHtmlEscaped();
auto timestamp = QDateTime::fromMSecsSinceEpoch(event.timestamp());
@@ -199,6 +212,11 @@ TimelineItem::TimelineItem(const events::MessageEvent<msgs::Text> &event, bool w
auto body = event.content().body().trimmed().toHtmlEscaped();
auto timestamp = QDateTime::fromMSecsSinceEpoch(event.timestamp());
+ descriptionMsg_ = {
+ TimelineViewManager::displayName(event.sender()),
+ QString(": %1").arg(body),
+ descriptiveTime(QDateTime::fromMSecsSinceEpoch(event.timestamp()))};
+
generateTimestamp(timestamp);
body.replace(URL_REGEX, URL_HTML);
@@ -352,6 +370,23 @@ void TimelineItem::setUserAvatar(const QImage &avatar)
userAvatar_->setImage(avatar);
}
+QString TimelineItem::descriptiveTime(const QDateTime &then)
+{
+ auto now = QDateTime::currentDateTime();
+
+ auto days = then.daysTo(now);
+
+ if (days == 0) {
+ return then.toString("HH:mm");
+ } else if (days < 2) {
+ return QString("Yesterday");
+ } else if (days < 365) {
+ return then.toString("dd/MM");
+ }
+
+ return then.toString("dd/MM/yy");
+}
+
TimelineItem::~TimelineItem()
{
}
diff --git a/src/TimelineView.cc b/src/TimelineView.cc
index 5968f9cf..be2fc067 100644
--- a/src/TimelineView.cc
+++ b/src/TimelineView.cc
@@ -179,6 +179,10 @@ void TimelineView::addBackwardsEvents(const QString &room_id, const RoomMessages
prev_batch_token_ = msgs.end();
isPaginationInProgress_ = false;
isPaginationScrollPending_ = true;
+
+ // Exclude the top stretch.
+ if (!msgs.chunk().isEmpty() && scroll_layout_->count() > 1)
+ notifyForLastEvent();
}
TimelineItem *TimelineView::parseMessageEvent(const QJsonObject &event, TimelineDirection direction)
@@ -295,6 +299,10 @@ int TimelineView::addEvents(const Timeline &timeline)
client_->messages(room_id_, prev_batch_token_);
}
+ // Exclude the top stretch.
+ if (!timeline.events().isEmpty() && scroll_layout_->count() > 1)
+ notifyForLastEvent();
+
return message_count;
}
@@ -441,3 +449,14 @@ void TimelineView::addUserTextMessage(const QString &body, int txn_id)
pending_msgs_.push_back(message);
}
+
+void TimelineView::notifyForLastEvent()
+{
+ auto lastItem = scroll_layout_->itemAt(scroll_layout_->count() - 1);
+ auto *lastTimelineItem = qobject_cast<TimelineItem *>(lastItem->widget());
+
+ if (lastTimelineItem)
+ emit updateLastTimelineMessage(room_id_, lastTimelineItem->descriptionMessage());
+ else
+ qWarning() << "Cast to TimelineView failed" << room_id_;
+}
diff --git a/src/TimelineViewManager.cc b/src/TimelineViewManager.cc
index 3715d1b6..455335f7 100644
--- a/src/TimelineViewManager.cc
+++ b/src/TimelineViewManager.cc
@@ -80,6 +80,11 @@ void TimelineViewManager::initialize(const Rooms &rooms)
TimelineView *view = new TimelineView(it.value().timeline(), client_, it.key());
views_.insert(it.key(), QSharedPointer<TimelineView>(view));
+ connect(view,
+ &TimelineView::updateLastTimelineMessage,
+ this,
+ &TimelineViewManager::updateRoomsLastMessage);
+
// Add the view in the widget stack.
addWidget(view);
}
@@ -92,6 +97,11 @@ void TimelineViewManager::initialize(const QList<QString> &rooms)
TimelineView *view = new TimelineView(client_, roomid);
views_.insert(roomid, QSharedPointer<TimelineView>(view));
+ connect(view,
+ &TimelineView::updateLastTimelineMessage,
+ this,
+ &TimelineViewManager::updateRoomsLastMessage);
+
// Add the view in the widget stack.
addWidget(view);
}
|