mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-25 20:48:52 +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 notifyForLastEvent();
|
||||
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 findLastViewableEvent(const std::vector<TimelineEvent> &events);
|
||||
|
@ -218,7 +233,9 @@ private:
|
|||
|
||||
// Used to determine whether or not we should prefix a message with the
|
||||
// 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);
|
||||
void removePendingMessage(const QString &txnid);
|
||||
|
@ -226,6 +243,8 @@ private:
|
|||
bool isDuplicate(const QString &event_id) { return eventIds_.contains(event_id); }
|
||||
|
||||
void handleNewUserMessage(PendingMessage msg);
|
||||
bool isDateDifference(const QDateTime &first,
|
||||
const QDateTime &second = QDateTime::currentDateTime()) const;
|
||||
|
||||
// Return nullptr if the event couldn't be parsed.
|
||||
TimelineItem *parseMessageEvent(const mtx::events::collections::TimelineEvents &event,
|
||||
|
@ -238,8 +257,11 @@ private:
|
|||
ScrollBar *scrollbar_;
|
||||
QWidget *scroll_widget_;
|
||||
|
||||
QString lastSender_;
|
||||
QString firstSender_;
|
||||
QDateTime firstMsgTimestamp_;
|
||||
QString lastSender_;
|
||||
QDateTime lastMsgTimestamp_;
|
||||
|
||||
QString room_id_;
|
||||
QString prev_batch_token_;
|
||||
QString local_user_;
|
||||
|
@ -289,7 +311,7 @@ TimelineView::addUserMessage(const QString &url,
|
|||
const QString &mime,
|
||||
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 widget = new Widget(client_, url, trimmed, size, this);
|
||||
|
@ -303,7 +325,8 @@ TimelineView::addUserMessage(const QString &url,
|
|||
|
||||
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();
|
||||
|
||||
|
@ -343,9 +366,9 @@ TimelineView::processMessageEvent(const Event &event, TimelineDirection directio
|
|||
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);
|
||||
|
||||
|
@ -368,9 +391,9 @@ TimelineView::processMessageEvent(const Event &event, TimelineDirection directio
|
|||
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);
|
||||
|
||||
|
|
|
@ -323,6 +323,7 @@ TimelineView::renderTopEvents(const std::vector<TimelineEvent> &events)
|
|||
// Reset the sender of the first message in the timeline
|
||||
// cause we're about to insert a new one.
|
||||
firstSender_.clear();
|
||||
firstMsgTimestamp_ = QDateTime();
|
||||
|
||||
// Parse in reverse order to determine where we should not show sender's
|
||||
// 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
|
||||
// events originate from this batch), set the last sender.
|
||||
if (lastSender_.isEmpty() && !items.empty())
|
||||
lastSender_ = items.at(0)->descriptionMessage().userid;
|
||||
saveLastMessageInfo(items.at(0)->descriptionMessage().userid,
|
||||
items.at(0)->descriptionMessage().datetime);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -453,12 +455,19 @@ TimelineView::updateLastSender(const QString &user_id, TimelineDirection directi
|
|||
}
|
||||
|
||||
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)
|
||||
return lastSender_ != user_id;
|
||||
else
|
||||
return firstSender_ != user_id;
|
||||
if (direction == TimelineDirection::Bottom) {
|
||||
return (lastSender_ != user_id) ||
|
||||
isDateDifference(lastMsgTimestamp_,
|
||||
QDateTime::fromMSecsSinceEpoch(origin_server_ts));
|
||||
} else {
|
||||
return (firstSender_ != user_id) ||
|
||||
isDateDifference(firstMsgTimestamp_,
|
||||
QDateTime::fromMSecsSinceEpoch(origin_server_ts));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -529,7 +538,7 @@ TimelineView::updatePendingMessage(int txn_id, QString event_id)
|
|||
void
|
||||
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 =
|
||||
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();
|
||||
|
||||
lastSender_ = local_user_;
|
||||
saveLastMessageInfo(local_user_, QDateTime::currentDateTime());
|
||||
|
||||
int txn_id = client_->incrementTransactionId();
|
||||
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 (!nextItem && prevItem)
|
||||
lastSender_ = prevItem->descriptionMessage().userid;
|
||||
saveLastMessageInfo(prevItem->descriptionMessage().userid,
|
||||
prevItem->descriptionMessage().datetime);
|
||||
|
||||
// If we deleted the first item in the timeline...
|
||||
if (!prevItem && nextItem)
|
||||
firstSender_ = nextItem->descriptionMessage().userid;
|
||||
saveFirstMessageInfo(nextItem->descriptionMessage().userid,
|
||||
nextItem->descriptionMessage().datetime);
|
||||
|
||||
// If we deleted the only item in the timeline...
|
||||
if (!prevItem && !nextItem) {
|
||||
firstSender_.clear();
|
||||
firstMsgTimestamp_ = QDateTime();
|
||||
lastSender_.clear();
|
||||
lastMsgTimestamp_ = QDateTime();
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
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