Update libqmatrixclient.

This commit is contained in:
Black Hat 2018-08-06 20:13:51 +08:00
parent 640e3712a2
commit a243d6069a
3 changed files with 97 additions and 14 deletions

@ -1 +1 @@
Subproject commit 8bd8aaf0858bb0a0ebcac8c3d29cfbb20279164d Subproject commit c0e75a52504a3d31bcca0d4c39745d4d6c1fe917

View File

@ -97,8 +97,7 @@ void MessageEventModel::setRoom(QMatrixClient::Room* room) {
} }
refreshRow(timelineBaseIndex()); // Refresh the looks refreshRow(timelineBaseIndex()); // Refresh the looks
if (m_currentRoom->timelineSize() > 1) // Refresh above if (m_currentRoom->timelineSize() > 1) // Refresh above
refreshEventRoles(timelineBaseIndex() + 1/*, refreshEventRoles(timelineBaseIndex() + 1, {ReadMarkerRole});
{ReadMarkerRole}*/);
if (timelineBaseIndex() > 0) // Refresh below, see #312 if (timelineBaseIndex() > 0) // Refresh below, see #312
refreshEventRoles(timelineBaseIndex() - 1, refreshEventRoles(timelineBaseIndex() - 1,
{AboveAuthorRole, AboveSectionRole}); {AboveAuthorRole, AboveSectionRole});
@ -111,10 +110,9 @@ void MessageEventModel::setRoom(QMatrixClient::Room* room) {
&MessageEventModel::endRemoveRows); &MessageEventModel::endRemoveRows);
connect(m_currentRoom, &Room::readMarkerMoved, this, [this] { connect(m_currentRoom, &Room::readMarkerMoved, this, [this] {
refreshEventRoles( refreshEventRoles(
std::exchange(lastReadEventId, std::exchange(lastReadEventId, m_currentRoom->readMarkerEventId()),
m_currentRoom->readMarkerEventId())/*, {ReadMarkerRole});
{ReadMarkerRole}*/); refreshEventRoles(lastReadEventId, {ReadMarkerRole});
refreshEventRoles(lastReadEventId /*, {ReadMarkerRole}*/);
}); });
connect( connect(
m_currentRoom, &Room::replacedEvent, this, m_currentRoom, &Room::replacedEvent, this,
@ -200,6 +198,66 @@ QString MessageEventModel::renderDate(QDateTime timestamp) const {
return date.toString(Qt::DefaultLocaleShortDate); 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 { int MessageEventModel::rowCount(const QModelIndex& parent) const {
if (!m_currentRoom || parent.isValid()) return 0; if (!m_currentRoom || parent.isValid()) return 0;
return m_currentRoom->timelineSize(); return m_currentRoom->timelineSize();
@ -218,7 +276,7 @@ QVariant MessageEventModel::data(const QModelIndex& idx, int role) const {
std::max(0, row - timelineBaseIndex()); std::max(0, row - timelineBaseIndex());
const auto pendingIt = m_currentRoom->pendingEvents().crbegin() + const auto pendingIt = m_currentRoom->pendingEvents().crbegin() +
std::min(row, timelineBaseIndex()); std::min(row, timelineBaseIndex());
const auto& evt = isPending ? *pendingIt->event() : *timelineIt->event(); const auto& evt = isPending ? **pendingIt : **timelineIt;
using namespace QMatrixClient; using namespace QMatrixClient;
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
@ -262,14 +320,14 @@ QVariant MessageEventModel::data(const QModelIndex& idx, int role) const {
: tr("joined the room"); : tr("joined the room");
} }
QString text{}; QString text{};
if (e.displayName() != e.prevContent()->displayName) { if (e.isRename()) {
if (e.displayName().isEmpty()) if (e.displayName().isEmpty())
text = tr("cleared the display name"); text = tr("cleared the display name");
else else
text = text =
tr("changed the display name to %1").arg(e.displayName()); 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 (!text.isEmpty()) text += " and ";
if (e.avatarUrl().isEmpty()) if (e.avatarUrl().isEmpty())
text += tr("cleared the avatar"); text += tr("cleared the avatar");
@ -485,14 +543,36 @@ QVariant MessageEventModel::data(const QModelIndex& idx, int role) const {
if (role == SpecialMarksRole) { if (role == SpecialMarksRole) {
if (isPending) return pendingIt->deliveryStatus(); 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() && if (evt.isStateEvent() &&
static_cast<const StateEventBase&>(evt).repeatsState() && static_cast<const StateEventBase&>(evt).repeatsState() &&
!Settings().value("UI/show_noop_events", false).toBool()) !Settings().value("UI/show_noop_events").toBool())
return EventStatus::Hidden; 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) if (role == EventIdRole)

View File

@ -38,7 +38,8 @@ class MessageEventModel : public QAbstractListModel {
void setRoom(QMatrixClient::Room* room); void setRoom(QMatrixClient::Room* room);
int rowCount(const QModelIndex& parent = QModelIndex()) const override; 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; QHash<int, QByteArray> roleNames() const;
private slots: private slots:
@ -55,6 +56,8 @@ class MessageEventModel : public QAbstractListModel {
QDateTime makeMessageTimestamp( QDateTime makeMessageTimestamp(
const QMatrixClient::Room::rev_iter_t& baseIt) const; const QMatrixClient::Room::rev_iter_t& baseIt) const;
QString renderDate(QDateTime timestamp) 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(int row, const QVector<int>& roles = {});
void refreshEventRoles(const QString& eventId, void refreshEventRoles(const QString& eventId,
const QVector<int>& roles = {}); const QVector<int>& roles = {});