Add a button to cycle through unread highlights
BUG: 465095
This commit is contained in:
committed by
James Graham
parent
fd44ff972a
commit
58ea229b67
@@ -169,6 +169,7 @@ NeoChatRoom::NeoChatRoom(Connection *connection, QString roomId, JoinState joinS
|
||||
const auto neochatconnection = static_cast<NeoChatConnection *>(connection);
|
||||
Q_ASSERT(neochatconnection);
|
||||
connect(neochatconnection, &NeoChatConnection::globalUrlPreviewEnabledChanged, this, &NeoChatRoom::urlPreviewEnabledChanged);
|
||||
connect(this, &Room::fullyReadMarkerMoved, this, &NeoChatRoom::invalidateLastUnreadHighlightId);
|
||||
}
|
||||
|
||||
bool NeoChatRoom::visible() const
|
||||
@@ -1843,4 +1844,52 @@ void NeoChatRoom::report(const QString &reason)
|
||||
connection()->callApi<NeochatReportRoomJob>(id(), reason);
|
||||
}
|
||||
|
||||
QString NeoChatRoom::findNextUnreadHighlightId()
|
||||
{
|
||||
const QString startEventId = !m_lastUnreadHighlightId.isEmpty() ? m_lastUnreadHighlightId : lastFullyReadEventId();
|
||||
const auto startIt = findInTimeline(startEventId);
|
||||
if (startIt == historyEdge()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
for (auto it = startIt.base(); it != messageEvents().cend(); ++it) {
|
||||
const RoomEvent *ev = it->event();
|
||||
if (highlights.contains(ev)) {
|
||||
m_lastUnreadHighlightId = ev->id();
|
||||
Q_EMIT highlightCycleStartedChanged();
|
||||
return m_lastUnreadHighlightId;
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_lastUnreadHighlightId.isEmpty()) {
|
||||
m_lastUnreadHighlightId.clear();
|
||||
Q_EMIT highlightCycleStartedChanged();
|
||||
return findNextUnreadHighlightId();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool NeoChatRoom::highlightCycleStarted() const
|
||||
{
|
||||
return !m_lastUnreadHighlightId.isEmpty();
|
||||
}
|
||||
|
||||
void NeoChatRoom::invalidateLastUnreadHighlightId(const QString &fromEventId, const QString &toEventId)
|
||||
{
|
||||
Q_UNUSED(fromEventId);
|
||||
|
||||
if (m_lastUnreadHighlightId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto lastIt = findInTimeline(m_lastUnreadHighlightId);
|
||||
const auto newReadIt = findInTimeline(toEventId);
|
||||
|
||||
// opposite comparision because both are reverse iterators :p
|
||||
if (newReadIt <= lastIt) {
|
||||
m_lastUnreadHighlightId.clear();
|
||||
Q_EMIT highlightCycleStartedChanged();
|
||||
}
|
||||
}
|
||||
|
||||
#include "moc_neochatroom.cpp"
|
||||
|
||||
@@ -208,6 +208,11 @@ class NeoChatRoom : public Quotient::Room
|
||||
*/
|
||||
Q_PROPERTY(QString pinnedMessage READ pinnedMessage NOTIFY pinnedMessageChanged)
|
||||
|
||||
/**
|
||||
* @brief Whether the highlight finding cycle has started.
|
||||
*/
|
||||
Q_PROPERTY(bool highlightCycleStarted READ highlightCycleStarted NOTIFY highlightCycleStartedChanged)
|
||||
|
||||
public:
|
||||
explicit NeoChatRoom(Quotient::Connection *connection, QString roomId, Quotient::JoinState joinState = {});
|
||||
|
||||
@@ -627,6 +632,19 @@ public:
|
||||
*/
|
||||
Q_INVOKABLE void report(const QString &reason);
|
||||
|
||||
/**
|
||||
* @brief Returns the ID of the next unread highlight in the room.
|
||||
*
|
||||
* Each call advances the internal highlight cursor. Once the last unread highlight
|
||||
* is reached, the cycle is reset.
|
||||
*/
|
||||
Q_INVOKABLE QString findNextUnreadHighlightId();
|
||||
|
||||
/**
|
||||
* @brief Whether the highlight finding cycle has started.
|
||||
*/
|
||||
bool highlightCycleStarted() const;
|
||||
|
||||
private:
|
||||
bool m_visible = false;
|
||||
|
||||
@@ -662,11 +680,15 @@ private:
|
||||
QString m_pinnedMessage;
|
||||
void loadPinnedMessage();
|
||||
|
||||
QString m_lastUnreadHighlightId;
|
||||
|
||||
private Q_SLOTS:
|
||||
void updatePushNotificationState(QString type);
|
||||
|
||||
void cacheLastEvent();
|
||||
|
||||
void invalidateLastUnreadHighlightId(const QString &fromEventId, const QString &toEventId);
|
||||
|
||||
Q_SIGNALS:
|
||||
void cachedInputChanged();
|
||||
void busyChanged();
|
||||
@@ -692,6 +714,7 @@ Q_SIGNALS:
|
||||
void extraEventNotFound(const QString &eventId);
|
||||
void inviteTimestampChanged();
|
||||
void pinnedMessageChanged();
|
||||
void highlightCycleStartedChanged();
|
||||
|
||||
/**
|
||||
* @brief Request a message be shown to the user of the given type.
|
||||
|
||||
@@ -193,9 +193,7 @@ QQC2.ScrollView {
|
||||
room: _private.room
|
||||
}
|
||||
|
||||
KirigamiComponents.FloatingButton {
|
||||
id: goReadMarkerFab
|
||||
|
||||
ColumnLayout {
|
||||
anchors {
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
@@ -203,28 +201,59 @@ QQC2.ScrollView {
|
||||
rightMargin: Kirigami.Units.largeSpacing
|
||||
}
|
||||
|
||||
implicitWidth: Kirigami.Settings.hasTransientTouchInput ? Kirigami.Units.gridUnit * 3 : Kirigami.Units.gridUnit * 2
|
||||
implicitHeight: Kirigami.Settings.hasTransientTouchInput ? Kirigami.Units.gridUnit * 3 : Kirigami.Units.gridUnit * 2
|
||||
spacing: Kirigami.Units.largeSpacing
|
||||
|
||||
padding: Kirigami.Units.largeSpacing
|
||||
KirigamiComponents.FloatingButton {
|
||||
id: goReadMarkerFab
|
||||
|
||||
z: 2
|
||||
visible: !_private.room?.partiallyReadStats.empty()
|
||||
implicitWidth: Kirigami.Settings.hasTransientTouchInput ? Kirigami.Units.gridUnit * 3 : Kirigami.Units.gridUnit * 2
|
||||
implicitHeight: Kirigami.Settings.hasTransientTouchInput ? Kirigami.Units.gridUnit * 3 : Kirigami.Units.gridUnit * 2
|
||||
|
||||
text: _private.room.readMarkerLoaded ? i18nc("@action:button", "Jump to first unread message") : i18nc("@action:button", "Jump to oldest loaded message")
|
||||
icon.name: "go-up"
|
||||
onClicked: {
|
||||
goReadMarkerFab.textChanged()
|
||||
root.goToEvent(_private.room.lastFullyReadEventId);
|
||||
}
|
||||
Kirigami.Action {
|
||||
shortcut: "Shift+PgUp"
|
||||
onTriggered: goReadMarkerFab.clicked()
|
||||
padding: Kirigami.Units.largeSpacing
|
||||
|
||||
z: 2
|
||||
visible: !_private.room?.partiallyReadStats.empty()
|
||||
|
||||
text: _private.room.readMarkerLoaded ? i18nc("@action:button", "Jump to first unread message") : i18nc("@action:button", "Jump to oldest loaded message")
|
||||
icon.name: "go-up"
|
||||
onClicked: {
|
||||
goReadMarkerFab.textChanged()
|
||||
root.goToEvent(_private.room.lastFullyReadEventId);
|
||||
}
|
||||
Kirigami.Action {
|
||||
shortcut: "Shift+PgUp"
|
||||
onTriggered: goReadMarkerFab.clicked()
|
||||
}
|
||||
|
||||
QQC2.ToolTip.text: goReadMarkerFab.text
|
||||
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
QQC2.ToolTip.visible: goReadMarkerFab.hovered
|
||||
}
|
||||
KirigamiComponents.FloatingButton {
|
||||
id: goUnreadHighlightFab
|
||||
|
||||
QQC2.ToolTip.text: goReadMarkerFab.text
|
||||
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
QQC2.ToolTip.visible: goReadMarkerFab.hovered
|
||||
implicitWidth: Kirigami.Settings.hasTransientTouchInput ? Kirigami.Units.gridUnit * 3 : Kirigami.Units.gridUnit * 2
|
||||
implicitHeight: Kirigami.Settings.hasTransientTouchInput ? Kirigami.Units.gridUnit * 3 : Kirigami.Units.gridUnit * 2
|
||||
|
||||
padding: Kirigami.Units.largeSpacing
|
||||
|
||||
z: 2
|
||||
visible: _private.room?.highlightCount > 0
|
||||
|
||||
text: _private.room?.highlightCycleStarted ? i18nc("@action:button", "Jump to next unread highlight") : i18nc("@action:button", "Jump to first unread message")
|
||||
icon.name: "mail-unread-symbolic"
|
||||
onClicked: {
|
||||
const eventId = _private.room.findNextUnreadHighlightId();
|
||||
if (eventId !== "") {
|
||||
goUnreadHighlightFab.textChanged();
|
||||
root.goToEvent(eventId);
|
||||
}
|
||||
}
|
||||
|
||||
QQC2.ToolTip.text: goUnreadHighlightFab.text
|
||||
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
QQC2.ToolTip.visible: goUnreadHighlightFab.hovered
|
||||
}
|
||||
}
|
||||
KirigamiComponents.FloatingButton {
|
||||
id: goMarkAsReadFab
|
||||
|
||||
Reference in New Issue
Block a user