mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-10-30 09:30:47 +03:00
Fix stuck notifications because of edits
Does not fix the read status yet, for that we need to compare read receipts for all events after the last visible event.
This commit is contained in:
parent
6e2ae1d812
commit
bdb6e6b79e
5 changed files with 120 additions and 4 deletions
|
@ -1896,6 +1896,84 @@ Cache::getTimelineIndex(const std::string &room_id, std::string_view event_id)
|
|||
return *val.data<uint64_t>();
|
||||
}
|
||||
|
||||
std::optional<uint64_t>
|
||||
Cache::getEventIndex(const std::string &room_id, std::string_view event_id)
|
||||
{
|
||||
if (event_id.empty())
|
||||
return {};
|
||||
|
||||
auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY);
|
||||
|
||||
lmdb::dbi orderDb{0};
|
||||
try {
|
||||
orderDb = getEventToOrderDb(txn, room_id);
|
||||
} catch (lmdb::runtime_error &e) {
|
||||
nhlog::db()->error("Can't open db for room '{}', probably doesn't exist yet. ({})",
|
||||
room_id,
|
||||
e.what());
|
||||
return {};
|
||||
}
|
||||
|
||||
lmdb::val indexVal{event_id.data(), event_id.size()}, val;
|
||||
|
||||
bool success = lmdb::dbi_get(txn, orderDb, indexVal, val);
|
||||
if (!success) {
|
||||
nhlog::db()->critical("Could not find event id: {}", event_id);
|
||||
return {};
|
||||
}
|
||||
|
||||
return *val.data<uint64_t>();
|
||||
}
|
||||
|
||||
std::optional<std::pair<uint64_t, std::string>>
|
||||
Cache::lastInvisibleEventAfter(const std::string &room_id, std::string_view event_id)
|
||||
{
|
||||
if (event_id.empty())
|
||||
return {};
|
||||
|
||||
auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY);
|
||||
|
||||
lmdb::dbi orderDb{0};
|
||||
lmdb::dbi eventOrderDb{0};
|
||||
lmdb::dbi timelineDb{0};
|
||||
try {
|
||||
orderDb = getEventToOrderDb(txn, room_id);
|
||||
eventOrderDb = getEventOrderDb(txn, room_id);
|
||||
timelineDb = getMessageToOrderDb(txn, room_id);
|
||||
} catch (lmdb::runtime_error &e) {
|
||||
nhlog::db()->error("Can't open db for room '{}', probably doesn't exist yet. ({})",
|
||||
room_id,
|
||||
e.what());
|
||||
return {};
|
||||
}
|
||||
|
||||
lmdb::val eventIdVal{event_id.data(), event_id.size()}, indexVal;
|
||||
|
||||
bool success = lmdb::dbi_get(txn, orderDb, eventIdVal, indexVal);
|
||||
if (!success) {
|
||||
return {};
|
||||
}
|
||||
uint64_t prevIdx = *indexVal.data<uint64_t>();
|
||||
std::string prevId{eventIdVal.data(), eventIdVal.size()};
|
||||
|
||||
auto cursor = lmdb::cursor::open(txn, eventOrderDb);
|
||||
cursor.get(indexVal, MDB_SET);
|
||||
while (cursor.get(indexVal, eventIdVal, MDB_NEXT)) {
|
||||
std::string evId =
|
||||
json::parse(std::string_view(eventIdVal.data(), eventIdVal.size()))["event_id"]
|
||||
.get<std::string>();
|
||||
lmdb::val temp;
|
||||
if (lmdb::dbi_get(txn, timelineDb, lmdb::val(evId.data(), evId.size()), temp)) {
|
||||
return std::pair{prevIdx, std::string(prevId)};
|
||||
} else {
|
||||
prevIdx = *indexVal.data<uint64_t>();
|
||||
prevId = std::move(evId);
|
||||
}
|
||||
}
|
||||
|
||||
return std::pair{prevIdx, std::string(prevId)};
|
||||
}
|
||||
|
||||
std::optional<uint64_t>
|
||||
Cache::getArrivalIndex(const std::string &room_id, std::string_view event_id)
|
||||
{
|
||||
|
@ -4253,6 +4331,18 @@ readReceipts(const QString &event_id, const QString &room_id)
|
|||
return instance_->readReceipts(event_id, room_id);
|
||||
}
|
||||
|
||||
std::optional<uint64_t>
|
||||
getEventIndex(const std::string &room_id, std::string_view event_id)
|
||||
{
|
||||
return instance_->getEventIndex(room_id, event_id);
|
||||
}
|
||||
|
||||
std::optional<std::pair<uint64_t, std::string>>
|
||||
lastInvisibleEventAfter(const std::string &room_id, std::string_view event_id)
|
||||
{
|
||||
return instance_->lastInvisibleEventAfter(room_id, event_id);
|
||||
}
|
||||
|
||||
QByteArray
|
||||
image(const QString &url)
|
||||
{
|
||||
|
|
|
@ -168,6 +168,12 @@ using UserReceipts = std::multimap<uint64_t, std::string, std::greater<uint64_t>
|
|||
UserReceipts
|
||||
readReceipts(const QString &event_id, const QString &room_id);
|
||||
|
||||
//! get index of the event in the event db, not representing the visual index
|
||||
std::optional<uint64_t>
|
||||
getEventIndex(const std::string &room_id, std::string_view event_id);
|
||||
std::optional<std::pair<uint64_t, std::string>>
|
||||
lastInvisibleEventAfter(const std::string &room_id, std::string_view event_id);
|
||||
|
||||
QByteArray
|
||||
image(const QString &url);
|
||||
QByteArray
|
||||
|
|
|
@ -204,6 +204,11 @@ public:
|
|||
std::optional<TimelineRange> getTimelineRange(const std::string &room_id);
|
||||
std::optional<uint64_t> getTimelineIndex(const std::string &room_id,
|
||||
std::string_view event_id);
|
||||
std::optional<uint64_t> getEventIndex(const std::string &room_id,
|
||||
std::string_view event_id);
|
||||
std::optional<std::pair<uint64_t, std::string>> lastInvisibleEventAfter(
|
||||
const std::string &room_id,
|
||||
std::string_view event_id);
|
||||
std::optional<std::string> getTimelineEventId(const std::string &room_id, uint64_t index);
|
||||
std::optional<uint64_t> getArrivalIndex(const std::string &room_id,
|
||||
std::string_view event_id);
|
||||
|
|
|
@ -740,10 +740,25 @@ TimelineModel::setCurrentIndex(int index)
|
|||
|
||||
auto oldIndex = idToIndex(currentId);
|
||||
currentId = indexToId(index);
|
||||
emit currentIndexChanged(index);
|
||||
if (index != oldIndex)
|
||||
emit currentIndexChanged(index);
|
||||
|
||||
if ((oldIndex > index || oldIndex == -1) && !currentId.startsWith("m")) {
|
||||
readEvent(currentId.toStdString());
|
||||
if (!currentId.startsWith("m")) {
|
||||
auto oldReadIndex =
|
||||
cache::getEventIndex(roomId().toStdString(), currentReadId.toStdString());
|
||||
auto nextEventIndexAndId =
|
||||
cache::lastInvisibleEventAfter(roomId().toStdString(), currentId.toStdString());
|
||||
|
||||
if (nextEventIndexAndId &&
|
||||
(!oldReadIndex || *oldReadIndex < nextEventIndexAndId->first)) {
|
||||
readEvent(nextEventIndexAndId->second);
|
||||
currentReadId = QString::fromStdString(nextEventIndexAndId->second);
|
||||
|
||||
nhlog::net()->info("Marked as read {}, index {}, oldReadIndex {}",
|
||||
nextEventIndexAndId->second,
|
||||
nextEventIndexAndId->first,
|
||||
*oldReadIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -329,7 +329,7 @@ private:
|
|||
bool decryptDescription = true;
|
||||
bool m_paginationInProgress = false;
|
||||
|
||||
QString currentId;
|
||||
QString currentId, currentReadId;
|
||||
QString reply_, edit_;
|
||||
std::vector<QString> typingUsers_;
|
||||
|
||||
|
|
Loading…
Reference in a new issue