Update libqmatrixclient.
This commit is contained in:
parent
640e3712a2
commit
a243d6069a
|
@ -1 +1 @@
|
|||
Subproject commit 8bd8aaf0858bb0a0ebcac8c3d29cfbb20279164d
|
||||
Subproject commit c0e75a52504a3d31bcca0d4c39745d4d6c1fe917
|
|
@ -97,8 +97,7 @@ void MessageEventModel::setRoom(QMatrixClient::Room* room) {
|
|||
}
|
||||
refreshRow(timelineBaseIndex()); // Refresh the looks
|
||||
if (m_currentRoom->timelineSize() > 1) // Refresh above
|
||||
refreshEventRoles(timelineBaseIndex() + 1/*,
|
||||
{ReadMarkerRole}*/);
|
||||
refreshEventRoles(timelineBaseIndex() + 1, {ReadMarkerRole});
|
||||
if (timelineBaseIndex() > 0) // Refresh below, see #312
|
||||
refreshEventRoles(timelineBaseIndex() - 1,
|
||||
{AboveAuthorRole, AboveSectionRole});
|
||||
|
@ -111,10 +110,9 @@ void MessageEventModel::setRoom(QMatrixClient::Room* room) {
|
|||
&MessageEventModel::endRemoveRows);
|
||||
connect(m_currentRoom, &Room::readMarkerMoved, this, [this] {
|
||||
refreshEventRoles(
|
||||
std::exchange(lastReadEventId,
|
||||
m_currentRoom->readMarkerEventId())/*,
|
||||
{ReadMarkerRole}*/);
|
||||
refreshEventRoles(lastReadEventId /*, {ReadMarkerRole}*/);
|
||||
std::exchange(lastReadEventId, m_currentRoom->readMarkerEventId()),
|
||||
{ReadMarkerRole});
|
||||
refreshEventRoles(lastReadEventId, {ReadMarkerRole});
|
||||
});
|
||||
connect(
|
||||
m_currentRoom, &Room::replacedEvent, this,
|
||||
|
@ -200,6 +198,66 @@ QString MessageEventModel::renderDate(QDateTime timestamp) const {
|
|||
return date.toString(Qt::DefaultLocaleShortDate);
|
||||
}
|
||||
|
||||
bool MessageEventModel::isUserActivityNotable(
|
||||
const QMatrixClient::Room::rev_iter_t& baseIt) const {
|
||||
const auto& senderId = (*baseIt)->senderId();
|
||||
// TODO: Go up and down the timeline (limit to 100 events for
|
||||
// the sake of performance) and collect all messages of
|
||||
// this author; find out if there's anything besides joins, leaves
|
||||
// and redactions; if not, double-check whether the current event is
|
||||
// a part of a re-join without following redactions.
|
||||
using namespace QMatrixClient;
|
||||
bool joinFound = false, redactionsFound = false;
|
||||
// Find the nearest join of this user above, or a no-nonsense event.
|
||||
for (auto it = baseIt,
|
||||
limit =
|
||||
baseIt + std::min<int>(m_currentRoom->timelineEdge() - baseIt, 100);
|
||||
it != limit; ++it) {
|
||||
const auto& e = **it;
|
||||
if (e.senderId() != senderId) continue;
|
||||
if (e.isRedacted()) {
|
||||
redactionsFound = true;
|
||||
continue;
|
||||
}
|
||||
if (auto* me = it->viewAs<QMatrixClient::RoomMemberEvent>()) {
|
||||
if (me->isJoin()) {
|
||||
joinFound = true;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
return true; // Consider all other events notable
|
||||
}
|
||||
// Find the nearest leave of this user below, or a no-nonsense event
|
||||
bool leaveFound = false;
|
||||
for (auto it = baseIt.base() - 1,
|
||||
limit =
|
||||
baseIt.base() +
|
||||
std::min<int>(m_currentRoom->messageEvents().end() - baseIt.base(),
|
||||
100);
|
||||
it != limit; ++it) {
|
||||
const auto& e = **it;
|
||||
if (e.senderId() != senderId) continue;
|
||||
if (e.isRedacted()) {
|
||||
redactionsFound = true;
|
||||
continue;
|
||||
}
|
||||
if (auto* me = it->viewAs<RoomMemberEvent>()) {
|
||||
if (me->isLeave() || me->membership() == MembershipType::Ban) {
|
||||
leaveFound = true;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// If we are here, it means that no notable events have been found in
|
||||
// the timeline vicinity, and probably redactions are there. Doesn't look
|
||||
// notable but let's give some benefit of doubt.
|
||||
if (redactionsFound) return false; // Join + redactions or redactions + leave
|
||||
return !(joinFound && leaveFound); // Join + (maybe profile changes) + leave
|
||||
}
|
||||
|
||||
int MessageEventModel::rowCount(const QModelIndex& parent) const {
|
||||
if (!m_currentRoom || parent.isValid()) return 0;
|
||||
return m_currentRoom->timelineSize();
|
||||
|
@ -218,7 +276,7 @@ QVariant MessageEventModel::data(const QModelIndex& idx, int role) const {
|
|||
std::max(0, row - timelineBaseIndex());
|
||||
const auto pendingIt = m_currentRoom->pendingEvents().crbegin() +
|
||||
std::min(row, timelineBaseIndex());
|
||||
const auto& evt = isPending ? *pendingIt->event() : *timelineIt->event();
|
||||
const auto& evt = isPending ? **pendingIt : **timelineIt;
|
||||
|
||||
using namespace QMatrixClient;
|
||||
if (role == Qt::DisplayRole) {
|
||||
|
@ -262,14 +320,14 @@ QVariant MessageEventModel::data(const QModelIndex& idx, int role) const {
|
|||
: tr("joined the room");
|
||||
}
|
||||
QString text{};
|
||||
if (e.displayName() != e.prevContent()->displayName) {
|
||||
if (e.isRename()) {
|
||||
if (e.displayName().isEmpty())
|
||||
text = tr("cleared the display name");
|
||||
else
|
||||
text =
|
||||
tr("changed the display name to %1").arg(e.displayName());
|
||||
}
|
||||
if (e.avatarUrl() != e.prevContent()->avatarUrl) {
|
||||
if (e.isAvatarUpdate()) {
|
||||
if (!text.isEmpty()) text += " and ";
|
||||
if (e.avatarUrl().isEmpty())
|
||||
text += tr("cleared the avatar");
|
||||
|
@ -485,14 +543,36 @@ QVariant MessageEventModel::data(const QModelIndex& idx, int role) const {
|
|||
if (role == SpecialMarksRole) {
|
||||
if (isPending) return pendingIt->deliveryStatus();
|
||||
|
||||
if (is<RedactionEvent>(evt)) return EventStatus::Hidden;
|
||||
auto* memberEvent = timelineIt->viewAs<RoomMemberEvent>();
|
||||
if (memberEvent) {
|
||||
if ((memberEvent->isJoin() || memberEvent->isLeave()) &&
|
||||
!Settings().value("UI/show_joinleave", true).toBool())
|
||||
return EventStatus::Hidden;
|
||||
}
|
||||
if (evt.isRedacted() || memberEvent) {
|
||||
if (evt.senderId() == m_currentRoom->localUser()->id() ||
|
||||
Settings().value("UI/show_spammy").toBool()) {
|
||||
return EventStatus::Normal;
|
||||
}
|
||||
QElapsedTimer et;
|
||||
et.start();
|
||||
auto hide = !isUserActivityNotable(timelineIt);
|
||||
qDebug() << "Checked user activity for" << evt.id() << "in" << et;
|
||||
if (hide) return EventStatus::Hidden;
|
||||
}
|
||||
|
||||
if (evt.isStateEvent() &&
|
||||
static_cast<const StateEventBase&>(evt).repeatsState() &&
|
||||
!Settings().value("UI/show_noop_events", false).toBool())
|
||||
!Settings().value("UI/show_noop_events").toBool())
|
||||
return EventStatus::Hidden;
|
||||
|
||||
if (is<RedactionEvent>(evt)) return EventStatus::Hidden;
|
||||
if (evt.isRedacted())
|
||||
return Settings().value("UI/show_redacted").toBool()
|
||||
? EventStatus::Redacted
|
||||
: EventStatus::Hidden;
|
||||
|
||||
return evt.isRedacted() ? EventStatus::Redacted : EventStatus::Normal;
|
||||
return EventStatus::Normal;
|
||||
}
|
||||
|
||||
if (role == EventIdRole)
|
||||
|
|
|
@ -38,7 +38,8 @@ class MessageEventModel : public QAbstractListModel {
|
|||
void setRoom(QMatrixClient::Room* room);
|
||||
|
||||
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
|
||||
QVariant data(const QModelIndex& index,
|
||||
int role = Qt::DisplayRole) const override;
|
||||
QHash<int, QByteArray> roleNames() const;
|
||||
|
||||
private slots:
|
||||
|
@ -55,6 +56,8 @@ class MessageEventModel : public QAbstractListModel {
|
|||
QDateTime makeMessageTimestamp(
|
||||
const QMatrixClient::Room::rev_iter_t& baseIt) const;
|
||||
QString renderDate(QDateTime timestamp) const;
|
||||
bool isUserActivityNotable(const QMatrixClient::Room::rev_iter_t& baseIt) const;
|
||||
|
||||
void refreshEventRoles(int row, const QVector<int>& roles = {});
|
||||
void refreshEventRoles(const QString& eventId,
|
||||
const QVector<int>& roles = {});
|
||||
|
|
Loading…
Reference in New Issue