mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-29 14:18:49 +03:00
Show user avatar for messages on different day or time gap > 15 mins
fixes #278
This commit is contained in:
parent
f2954a3616
commit
23accc50d6
2 changed files with 80 additions and 18 deletions
|
@ -186,6 +186,21 @@ private:
|
||||||
void updateLastSender(const QString &user_id, TimelineDirection direction);
|
void updateLastSender(const QString &user_id, TimelineDirection direction);
|
||||||
void notifyForLastEvent();
|
void notifyForLastEvent();
|
||||||
void notifyForLastEvent(const TimelineEvent &event);
|
void notifyForLastEvent(const TimelineEvent &event);
|
||||||
|
//! Keep track of the sender and the timestamp of the current message.
|
||||||
|
void saveLastMessageInfo(const QString &sender, const QDateTime &datetime)
|
||||||
|
{
|
||||||
|
lastSender_ = sender;
|
||||||
|
lastMsgTimestamp_ = datetime;
|
||||||
|
}
|
||||||
|
void saveFirstMessageInfo(const QString &sender, const QDateTime &datetime)
|
||||||
|
{
|
||||||
|
firstSender_ = sender;
|
||||||
|
firstMsgTimestamp_ = datetime;
|
||||||
|
}
|
||||||
|
//! Keep track of the sender and the timestamp of the current message.
|
||||||
|
void saveMessageInfo(const QString &sender,
|
||||||
|
uint64_t origin_server_ts,
|
||||||
|
TimelineDirection direction);
|
||||||
|
|
||||||
TimelineEvent findFirstViewableEvent(const std::vector<TimelineEvent> &events);
|
TimelineEvent findFirstViewableEvent(const std::vector<TimelineEvent> &events);
|
||||||
TimelineEvent findLastViewableEvent(const std::vector<TimelineEvent> &events);
|
TimelineEvent findLastViewableEvent(const std::vector<TimelineEvent> &events);
|
||||||
|
@ -218,7 +233,9 @@ private:
|
||||||
|
|
||||||
// Used to determine whether or not we should prefix a message with the
|
// Used to determine whether or not we should prefix a message with the
|
||||||
// sender's name.
|
// sender's name.
|
||||||
bool isSenderRendered(const QString &user_id, TimelineDirection direction);
|
bool isSenderRendered(const QString &user_id,
|
||||||
|
uint64_t origin_server_ts,
|
||||||
|
TimelineDirection direction);
|
||||||
|
|
||||||
bool isPendingMessage(const QString &txnid, const QString &sender, const QString &userid);
|
bool isPendingMessage(const QString &txnid, const QString &sender, const QString &userid);
|
||||||
void removePendingMessage(const QString &txnid);
|
void removePendingMessage(const QString &txnid);
|
||||||
|
@ -226,6 +243,8 @@ private:
|
||||||
bool isDuplicate(const QString &event_id) { return eventIds_.contains(event_id); }
|
bool isDuplicate(const QString &event_id) { return eventIds_.contains(event_id); }
|
||||||
|
|
||||||
void handleNewUserMessage(PendingMessage msg);
|
void handleNewUserMessage(PendingMessage msg);
|
||||||
|
bool isDateDifference(const QDateTime &first,
|
||||||
|
const QDateTime &second = QDateTime::currentDateTime()) const;
|
||||||
|
|
||||||
// Return nullptr if the event couldn't be parsed.
|
// Return nullptr if the event couldn't be parsed.
|
||||||
TimelineItem *parseMessageEvent(const mtx::events::collections::TimelineEvents &event,
|
TimelineItem *parseMessageEvent(const mtx::events::collections::TimelineEvents &event,
|
||||||
|
@ -238,8 +257,11 @@ private:
|
||||||
ScrollBar *scrollbar_;
|
ScrollBar *scrollbar_;
|
||||||
QWidget *scroll_widget_;
|
QWidget *scroll_widget_;
|
||||||
|
|
||||||
QString lastSender_;
|
|
||||||
QString firstSender_;
|
QString firstSender_;
|
||||||
|
QDateTime firstMsgTimestamp_;
|
||||||
|
QString lastSender_;
|
||||||
|
QDateTime lastMsgTimestamp_;
|
||||||
|
|
||||||
QString room_id_;
|
QString room_id_;
|
||||||
QString prev_batch_token_;
|
QString prev_batch_token_;
|
||||||
QString local_user_;
|
QString local_user_;
|
||||||
|
@ -289,7 +311,7 @@ TimelineView::addUserMessage(const QString &url,
|
||||||
const QString &mime,
|
const QString &mime,
|
||||||
uint64_t size)
|
uint64_t size)
|
||||||
{
|
{
|
||||||
auto with_sender = lastSender_ != local_user_;
|
auto with_sender = (lastSender_ != local_user_) || isDateDifference(lastMsgTimestamp_);
|
||||||
auto trimmed = QFileInfo{filename}.fileName(); // Trim file path.
|
auto trimmed = QFileInfo{filename}.fileName(); // Trim file path.
|
||||||
|
|
||||||
auto widget = new Widget(client_, url, trimmed, size, this);
|
auto widget = new Widget(client_, url, trimmed, size, this);
|
||||||
|
@ -303,7 +325,8 @@ TimelineView::addUserMessage(const QString &url,
|
||||||
|
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
|
|
||||||
lastSender_ = local_user_;
|
// Keep track of the sender and the timestamp of the current message.
|
||||||
|
saveLastMessageInfo(local_user_, QDateTime::currentDateTime());
|
||||||
|
|
||||||
int txn_id = client_->incrementTransactionId();
|
int txn_id = client_->incrementTransactionId();
|
||||||
|
|
||||||
|
@ -343,9 +366,9 @@ TimelineView::processMessageEvent(const Event &event, TimelineDirection directio
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto with_sender = isSenderRendered(sender, direction);
|
auto with_sender = isSenderRendered(sender, event.origin_server_ts, direction);
|
||||||
|
|
||||||
updateLastSender(sender, direction);
|
saveMessageInfo(sender, event.origin_server_ts, direction);
|
||||||
|
|
||||||
auto item = createTimelineItem<Event>(event, with_sender);
|
auto item = createTimelineItem<Event>(event, with_sender);
|
||||||
|
|
||||||
|
@ -368,9 +391,9 @@ TimelineView::processMessageEvent(const Event &event, TimelineDirection directio
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto with_sender = isSenderRendered(sender, direction);
|
auto with_sender = isSenderRendered(sender, event.origin_server_ts, direction);
|
||||||
|
|
||||||
updateLastSender(sender, direction);
|
saveMessageInfo(sender, event.origin_server_ts, direction);
|
||||||
|
|
||||||
auto item = createTimelineItem<Event, Widget>(event, with_sender);
|
auto item = createTimelineItem<Event, Widget>(event, with_sender);
|
||||||
|
|
||||||
|
|
|
@ -323,6 +323,7 @@ TimelineView::renderTopEvents(const std::vector<TimelineEvent> &events)
|
||||||
// Reset the sender of the first message in the timeline
|
// Reset the sender of the first message in the timeline
|
||||||
// cause we're about to insert a new one.
|
// cause we're about to insert a new one.
|
||||||
firstSender_.clear();
|
firstSender_.clear();
|
||||||
|
firstMsgTimestamp_ = QDateTime();
|
||||||
|
|
||||||
// Parse in reverse order to determine where we should not show sender's
|
// Parse in reverse order to determine where we should not show sender's
|
||||||
// name.
|
// name.
|
||||||
|
@ -352,7 +353,8 @@ TimelineView::renderTopEvents(const std::vector<TimelineEvent> &events)
|
||||||
// If this batch is the first being rendered (i.e the first and the last
|
// If this batch is the first being rendered (i.e the first and the last
|
||||||
// events originate from this batch), set the last sender.
|
// events originate from this batch), set the last sender.
|
||||||
if (lastSender_.isEmpty() && !items.empty())
|
if (lastSender_.isEmpty() && !items.empty())
|
||||||
lastSender_ = items.at(0)->descriptionMessage().userid;
|
saveLastMessageInfo(items.at(0)->descriptionMessage().userid,
|
||||||
|
items.at(0)->descriptionMessage().datetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -453,12 +455,19 @@ TimelineView::updateLastSender(const QString &user_id, TimelineDirection directi
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TimelineView::isSenderRendered(const QString &user_id, TimelineDirection direction)
|
TimelineView::isSenderRendered(const QString &user_id,
|
||||||
|
uint64_t origin_server_ts,
|
||||||
|
TimelineDirection direction)
|
||||||
{
|
{
|
||||||
if (direction == TimelineDirection::Bottom)
|
if (direction == TimelineDirection::Bottom) {
|
||||||
return lastSender_ != user_id;
|
return (lastSender_ != user_id) ||
|
||||||
else
|
isDateDifference(lastMsgTimestamp_,
|
||||||
return firstSender_ != user_id;
|
QDateTime::fromMSecsSinceEpoch(origin_server_ts));
|
||||||
|
} else {
|
||||||
|
return (firstSender_ != user_id) ||
|
||||||
|
isDateDifference(firstMsgTimestamp_,
|
||||||
|
QDateTime::fromMSecsSinceEpoch(origin_server_ts));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -529,7 +538,7 @@ TimelineView::updatePendingMessage(int txn_id, QString event_id)
|
||||||
void
|
void
|
||||||
TimelineView::addUserMessage(mtx::events::MessageType ty, const QString &body)
|
TimelineView::addUserMessage(mtx::events::MessageType ty, const QString &body)
|
||||||
{
|
{
|
||||||
auto with_sender = lastSender_ != local_user_;
|
auto with_sender = (lastSender_ != local_user_) || isDateDifference(lastMsgTimestamp_);
|
||||||
|
|
||||||
TimelineItem *view_item =
|
TimelineItem *view_item =
|
||||||
new TimelineItem(ty, local_user_, body, with_sender, room_id_, scroll_widget_);
|
new TimelineItem(ty, local_user_, body, with_sender, room_id_, scroll_widget_);
|
||||||
|
@ -540,7 +549,7 @@ TimelineView::addUserMessage(mtx::events::MessageType ty, const QString &body)
|
||||||
|
|
||||||
QApplication::processEvents();
|
QApplication::processEvents();
|
||||||
|
|
||||||
lastSender_ = local_user_;
|
saveLastMessageInfo(local_user_, QDateTime::currentDateTime());
|
||||||
|
|
||||||
int txn_id = client_->incrementTransactionId();
|
int txn_id = client_->incrementTransactionId();
|
||||||
PendingMessage message(ty, txn_id, body, "", "", -1, "", view_item);
|
PendingMessage message(ty, txn_id, body, "", "", -1, "", view_item);
|
||||||
|
@ -774,16 +783,20 @@ TimelineView::removeEvent(const QString &event_id)
|
||||||
|
|
||||||
// If we deleted the last item in the timeline...
|
// If we deleted the last item in the timeline...
|
||||||
if (!nextItem && prevItem)
|
if (!nextItem && prevItem)
|
||||||
lastSender_ = prevItem->descriptionMessage().userid;
|
saveLastMessageInfo(prevItem->descriptionMessage().userid,
|
||||||
|
prevItem->descriptionMessage().datetime);
|
||||||
|
|
||||||
// If we deleted the first item in the timeline...
|
// If we deleted the first item in the timeline...
|
||||||
if (!prevItem && nextItem)
|
if (!prevItem && nextItem)
|
||||||
firstSender_ = nextItem->descriptionMessage().userid;
|
saveFirstMessageInfo(nextItem->descriptionMessage().userid,
|
||||||
|
nextItem->descriptionMessage().datetime);
|
||||||
|
|
||||||
// If we deleted the only item in the timeline...
|
// If we deleted the only item in the timeline...
|
||||||
if (!prevItem && !nextItem) {
|
if (!prevItem && !nextItem) {
|
||||||
firstSender_.clear();
|
firstSender_.clear();
|
||||||
|
firstMsgTimestamp_ = QDateTime();
|
||||||
lastSender_.clear();
|
lastSender_.clear();
|
||||||
|
lastMsgTimestamp_ = QDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally remove the event.
|
// Finally remove the event.
|
||||||
|
@ -835,3 +848,29 @@ TimelineView::getEventType(const mtx::events::collections::TimelineEvents &event
|
||||||
{
|
{
|
||||||
return mpark::visit([](auto msg) { return msg.type; }, event);
|
return mpark::visit([](auto msg) { return msg.type; }, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TimelineView::saveMessageInfo(const QString &sender,
|
||||||
|
uint64_t origin_server_ts,
|
||||||
|
TimelineDirection direction)
|
||||||
|
{
|
||||||
|
updateLastSender(sender, direction);
|
||||||
|
|
||||||
|
if (direction == TimelineDirection::Bottom)
|
||||||
|
lastMsgTimestamp_ = QDateTime::fromMSecsSinceEpoch(origin_server_ts);
|
||||||
|
else
|
||||||
|
firstMsgTimestamp_ = QDateTime::fromMSecsSinceEpoch(origin_server_ts);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TimelineView::isDateDifference(const QDateTime &first, const QDateTime &second) const
|
||||||
|
{
|
||||||
|
// Check if the dates are in a different day.
|
||||||
|
if (std::abs(first.daysTo(second)) != 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
const uint64_t diffInSeconds = std::abs(first.msecsTo(second)) / 1000;
|
||||||
|
constexpr uint64_t fifteenMins = 15 * 60;
|
||||||
|
|
||||||
|
return diffInSeconds > fifteenMins;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue