parent
a62792fa3b
commit
c93efebd23
|
@ -1,6 +1,10 @@
|
||||||
import QtQuick 2.9
|
import QtQuick 2.9
|
||||||
import QtQuick.Controls 2.2
|
import QtQuick.Controls 2.2
|
||||||
|
|
||||||
|
import Spectral 0.1
|
||||||
|
|
||||||
|
import "qrc:/js/md.js" as Markdown
|
||||||
|
|
||||||
TextArea {
|
TextArea {
|
||||||
property real progress: 0
|
property real progress: 0
|
||||||
|
|
||||||
|
|
|
@ -12,14 +12,14 @@ Menu {
|
||||||
checkable: true
|
checkable: true
|
||||||
checked: model && model.category === RoomType.Favorite
|
checked: model && model.category === RoomType.Favorite
|
||||||
|
|
||||||
onTriggered: model.category === RoomType.Favorite ? model.currentRoom.removeTag("m.favourite") : model.currentRoom.addTag("m.favourite", "1")
|
onTriggered: model.category === RoomType.Favorite ? model.currentRoom.removeTag("m.favourite") : model.currentRoom.addTag("m.favourite", 1.0)
|
||||||
}
|
}
|
||||||
MenuItem {
|
MenuItem {
|
||||||
text: "Deprioritize"
|
text: "Deprioritize"
|
||||||
checkable: true
|
checkable: true
|
||||||
checked: model && model.category === RoomType.Deprioritized
|
checked: model && model.category === RoomType.Deprioritized
|
||||||
|
|
||||||
onTriggered: model.category === RoomType.Deprioritized ? model.currentRoom.removeTag("m.lowpriority") : model.currentRoom.addTag("m.lowpriority", "1")
|
onTriggered: model.category === RoomType.Deprioritized ? model.currentRoom.removeTag("m.lowpriority") : model.currentRoom.addTag("m.lowpriority", 1.0)
|
||||||
}
|
}
|
||||||
MenuSeparator {}
|
MenuSeparator {}
|
||||||
MenuItem {
|
MenuItem {
|
||||||
|
|
|
@ -87,12 +87,7 @@ void MessageEventModel::setRoom(SpectralRoom* room) {
|
||||||
{AboveEventTypeRole, AboveAuthorRole,
|
{AboveEventTypeRole, AboveAuthorRole,
|
||||||
AboveSectionRole, AboveTimeRole});
|
AboveSectionRole, AboveTimeRole});
|
||||||
}
|
}
|
||||||
|
});
|
||||||
for (auto i = m_currentRoom->maxTimelineIndex() - biggest;
|
|
||||||
i <= m_currentRoom->maxTimelineIndex() - lowest; ++i)
|
|
||||||
refreshLastUserEvents(i);
|
|
||||||
},
|
|
||||||
Qt::QueuedConnection);
|
|
||||||
connect(m_currentRoom, &Room::pendingEventAboutToAdd, this,
|
connect(m_currentRoom, &Room::pendingEventAboutToAdd, this,
|
||||||
[this] { beginInsertRows({}, 0, 0); });
|
[this] { beginInsertRows({}, 0, 0); });
|
||||||
connect(m_currentRoom, &Room::pendingEventAdded, this,
|
connect(m_currentRoom, &Room::pendingEventAdded, this,
|
||||||
|
@ -112,7 +107,6 @@ void MessageEventModel::setRoom(SpectralRoom* room) {
|
||||||
movingEvent = false;
|
movingEvent = false;
|
||||||
}
|
}
|
||||||
refreshRow(timelineBaseIndex()); // Refresh the looks
|
refreshRow(timelineBaseIndex()); // Refresh the looks
|
||||||
refreshLastUserEvents(0);
|
|
||||||
if (m_currentRoom->timelineSize() > 1) // Refresh above
|
if (m_currentRoom->timelineSize() > 1) // Refresh above
|
||||||
refreshEventRoles(timelineBaseIndex() + 1, {ReadMarkerRole});
|
refreshEventRoles(timelineBaseIndex() + 1, {ReadMarkerRole});
|
||||||
if (timelineBaseIndex() > 0) // Refresh below, see #312
|
if (timelineBaseIndex() > 0) // Refresh below, see #312
|
||||||
|
@ -132,11 +126,6 @@ void MessageEventModel::setRoom(SpectralRoom* room) {
|
||||||
{ReadMarkerRole});
|
{ReadMarkerRole});
|
||||||
refreshEventRoles(lastReadEventId, {ReadMarkerRole});
|
refreshEventRoles(lastReadEventId, {ReadMarkerRole});
|
||||||
});
|
});
|
||||||
connect(m_currentRoom, &Room::replacedEvent, this,
|
|
||||||
[this](const RoomEvent* newEvent) {
|
|
||||||
refreshLastUserEvents(refreshEvent(newEvent->id()) -
|
|
||||||
timelineBaseIndex());
|
|
||||||
});
|
|
||||||
connect(m_currentRoom, &Room::fileTransferProgress, this,
|
connect(m_currentRoom, &Room::fileTransferProgress, this,
|
||||||
&MessageEventModel::refreshEvent);
|
&MessageEventModel::refreshEvent);
|
||||||
connect(m_currentRoom, &Room::fileTransferCompleted, this,
|
connect(m_currentRoom, &Room::fileTransferCompleted, this,
|
||||||
|
@ -220,82 +209,6 @@ 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
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageEventModel::refreshLastUserEvents(int baseTimelineRow) {
|
|
||||||
if (!m_currentRoom || m_currentRoom->timelineSize() <= baseTimelineRow)
|
|
||||||
return;
|
|
||||||
const auto& timelineBottom = m_currentRoom->messageEvents().rbegin();
|
|
||||||
const auto& lastSender = (*(timelineBottom + baseTimelineRow))->senderId();
|
|
||||||
const auto limit = timelineBottom + std::min(baseTimelineRow + 100,
|
|
||||||
m_currentRoom->timelineSize());
|
|
||||||
for (auto it = timelineBottom + std::max(baseTimelineRow - 100, 0);
|
|
||||||
it != limit; ++it) {
|
|
||||||
if ((*it)->senderId() == lastSender) {
|
|
||||||
auto idx = index(it - timelineBottom);
|
|
||||||
emit dataChanged(idx, idx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
||||||
|
@ -500,20 +413,6 @@ QVariant MessageEventModel::data(const QModelIndex& idx, int role) const {
|
||||||
if (isPending) return pendingIt->deliveryStatus();
|
if (isPending) return pendingIt->deliveryStatus();
|
||||||
|
|
||||||
if (is<RedactionEvent>(evt)) return EventStatus::Hidden;
|
if (is<RedactionEvent>(evt)) return EventStatus::Hidden;
|
||||||
auto* memberEvent = timelineIt->viewAs<RoomMemberEvent>();
|
|
||||||
if (memberEvent) {
|
|
||||||
if ((memberEvent->isJoin() || memberEvent->isLeave()))
|
|
||||||
return EventStatus::Hidden;
|
|
||||||
}
|
|
||||||
if (memberEvent || evt.isRedacted()) {
|
|
||||||
if (evt.senderId() == m_currentRoom->localUser()->id()) {
|
|
||||||
// QElapsedTimer et; et.start();
|
|
||||||
auto hide = !isUserActivityNotable(timelineIt);
|
|
||||||
// qDebug() << "Checked user activity for" << evt.id() <<
|
|
||||||
// "in" << et;
|
|
||||||
if (hide) return EventStatus::Hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (evt.isRedacted()) return EventStatus::Redacted;
|
if (evt.isRedacted()) return EventStatus::Redacted;
|
||||||
|
|
||||||
if (evt.isStateEvent() &&
|
if (evt.isStateEvent() &&
|
||||||
|
|
|
@ -59,10 +59,7 @@ 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 refreshLastUserEvents(int baseRow);
|
|
||||||
void refreshEventRoles(int row, const QVector<int>& roles = {});
|
void refreshEventRoles(int row, const QVector<int>& roles = {});
|
||||||
int refreshEventRoles(const QString& eventId, const QVector<int>& roles = {});
|
int refreshEventRoles(const QString& eventId, const QVector<int>& roles = {});
|
||||||
|
|
||||||
|
|
|
@ -178,11 +178,3 @@ void SpectralRoom::saveViewport(int topIndex, int bottomIndex) {
|
||||||
setFirstDisplayedEvent(maxTimelineIndex() - topIndex);
|
setFirstDisplayedEvent(maxTimelineIndex() - topIndex);
|
||||||
setLastDisplayedEvent(maxTimelineIndex() - bottomIndex);
|
setLastDisplayedEvent(maxTimelineIndex() - bottomIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpectralRoom::getPreviousContent(int limit) {
|
|
||||||
setBusy(true);
|
|
||||||
QMetaObject::invokeMethod(
|
|
||||||
this,
|
|
||||||
[=] { Room::getPreviousContent(limit); },
|
|
||||||
Qt::QueuedConnection);
|
|
||||||
}
|
|
||||||
|
|
|
@ -52,8 +52,6 @@ class SpectralRoom : public Room {
|
||||||
Q_INVOKABLE int savedBottomVisibleIndex() const;
|
Q_INVOKABLE int savedBottomVisibleIndex() const;
|
||||||
Q_INVOKABLE void saveViewport(int topIndex, int bottomIndex);
|
Q_INVOKABLE void saveViewport(int topIndex, int bottomIndex);
|
||||||
|
|
||||||
Q_INVOKABLE void getPreviousContent(int limit = 10);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString m_cachedInput;
|
QString m_cachedInput;
|
||||||
QSet<const QMatrixClient::RoomEvent*> highlights;
|
QSet<const QMatrixClient::RoomEvent*> highlights;
|
||||||
|
|
Loading…
Reference in New Issue