Add highlight support.

square-messages
Black Hat 2018-09-06 12:34:15 +08:00
parent c3bf4d75e5
commit cfc32289d1
9 changed files with 63 additions and 8 deletions

View File

@ -48,7 +48,7 @@ RowLayout {
id: genericBubble
highlighted: !sentByMe
colored: highlighted && eventType === "notice"
colored: highlighted && (eventType === "notice" || highlight)
contentItem: ColumnLayout {
id: messageColumn

View File

@ -241,6 +241,8 @@ Item {
boundsBehavior: Flickable.DragOverBounds
maximumFlickVelocity: 2048
cacheBuffer: 200
model: MessageEventModel {
id: messageEventModel
room: currentRoom

View File

@ -123,7 +123,7 @@ Item {
Rectangle {
anchors.fill: parent
visible: highlighted
visible: highlightCount > 0 || highlighted
color: Material.accent
opacity: 0.1
}

View File

@ -12,7 +12,12 @@
MatriqueRoom::MatriqueRoom(Connection* connection, QString roomId,
JoinState joinState)
: Room(connection, std::move(roomId), joinState) {}
: Room(connection, std::move(roomId), joinState) {
connect(this, &MatriqueRoom::notificationCountChanged, this,
&MatriqueRoom::countChanged);
connect(this, &MatriqueRoom::highlightCountChanged, this,
&MatriqueRoom::countChanged);
}
void MatriqueRoom::chooseAndUploadFile() {
auto localFile = QFileDialog::getOpenFileUrl(Q_NULLPTR, tr("Save File as"));
@ -87,3 +92,35 @@ QString MatriqueRoom::lastEvent() {
return user(lastEvent->senderId())->displayname() + ": " +
lastEvent->contentJson().value("body").toString();
}
bool MatriqueRoom::isEventHighlighted(const RoomEvent* e) const {
return highlights.contains(e);
}
void MatriqueRoom::checkForHighlights(const QMatrixClient::TimelineItem& ti) {
auto localUserId = localUser()->id();
if (ti->senderId() == localUserId) return;
if (auto* e = ti.viewAs<RoomMessageEvent>()) {
const auto& text = e->plainBody();
if (text.contains(localUserId) ||
text.contains(roomMembername(localUserId)))
highlights.insert(e);
}
}
void MatriqueRoom::onAddNewTimelineEvents(timeline_iter_t from) {
std::for_each(from, messageEvents().cend(),
[this](const TimelineItem& ti) { checkForHighlights(ti); });
}
void MatriqueRoom::onAddHistoricalTimelineEvents(rev_iter_t from) {
std::for_each(from, messageEvents().crend(),
[this](const TimelineItem& ti) { checkForHighlights(ti); });
}
void MatriqueRoom::countChanged() {
if (displayed() && !hasUnreadMessages()) {
resetNotificationCount();
resetHighlightCount();
}
}

View File

@ -30,13 +30,23 @@ class MatriqueRoom : public Room {
QString getUsersTyping();
QString lastEvent();
bool isEventHighlighted(const QMatrixClient::RoomEvent* e) const;
private:
QString m_cachedInput;
QSet<const QMatrixClient::RoomEvent*> highlights;
QString getMIME(const QUrl& fileUrl) const;
void postFile(const QUrl& localFile, const QUrl& mxcUrl);
void checkForHighlights(const QMatrixClient::TimelineItem& ti);
void onAddNewTimelineEvents(timeline_iter_t from) override;
void onAddHistoricalTimelineEvents(rev_iter_t from) override;
private slots:
void countChanged();
signals:
void cachedInputChanged();

View File

@ -45,7 +45,7 @@ MessageEventModel::MessageEventModel(QObject* parent)
MessageEventModel::~MessageEventModel() {}
void MessageEventModel::setRoom(QMatrixClient::Room* room) {
void MessageEventModel::setRoom(MatriqueRoom* room) {
if (room == m_currentRoom) return;
beginResetModel();
@ -567,6 +567,8 @@ QVariant MessageEventModel::data(const QModelIndex& idx, int role) const {
};
}
if (role == HighlightRole) return m_currentRoom->isEventHighlighted(&evt);
if (role == ReadMarkerRole) return evt.id() == lastReadEventId;
if (role == SpecialMarksRole) {

View File

@ -2,13 +2,14 @@
#define MESSAGEEVENTMODEL_H
#include "room.h"
#include "matriqueroom.h"
#include <QtCore/QAbstractListModel>
class MessageEventModel : public QAbstractListModel {
Q_OBJECT
Q_PROPERTY(
QMatrixClient::Room* room READ getRoom WRITE setRoom NOTIFY roomChanged)
MatriqueRoom* room READ getRoom WRITE setRoom NOTIFY roomChanged)
public:
enum EventRoles {
@ -35,8 +36,8 @@ class MessageEventModel : public QAbstractListModel {
explicit MessageEventModel(QObject* parent = nullptr);
~MessageEventModel();
QMatrixClient::Room* getRoom() { return m_currentRoom; }
void setRoom(QMatrixClient::Room* room);
MatriqueRoom* getRoom() { return m_currentRoom; }
void setRoom(MatriqueRoom* room);
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index,
@ -48,7 +49,7 @@ class MessageEventModel : public QAbstractListModel {
void refreshRow(int row);
private:
QMatrixClient::Room* m_currentRoom = nullptr;
MatriqueRoom* m_currentRoom = nullptr;
QString lastReadEventId;
int rowBelowInserted = -1;
bool movingEvent = 0;

View File

@ -153,6 +153,7 @@ QVariant RoomListModel::data(const QModelIndex& index, int role) const {
return RoomType::Normal;
}
if (role == UnreadCountRole) return room->unreadCount();
if (role == HighlightCountRole) return room->highlightCount();
if (role == LastEventRole) return room->lastEvent();
if (role == CurrentRoomRole) return QVariant::fromValue(room);
return QVariant();
@ -185,6 +186,7 @@ QHash<int, QByteArray> RoomListModel::roleNames() const {
roles[TopicRole] = "topic";
roles[CategoryRole] = "category";
roles[UnreadCountRole] = "unreadCount";
roles[HighlightCountRole] = "highlightCount";
roles[LastEventRole] = "lastEvent";
roles[CurrentRoomRole] = "currentRoom";
return roles;

View File

@ -35,6 +35,7 @@ class RoomListModel : public QAbstractListModel {
TopicRole,
CategoryRole,
UnreadCountRole,
HighlightCountRole,
LastEventRole,
CurrentRoomRole,
};