diff options
author | Nicolas Werner <nicolas.werner@hotmail.de> | 2022-11-03 23:26:59 +0100 |
---|---|---|
committer | Nicolas Werner <nicolas.werner@hotmail.de> | 2022-11-03 23:26:59 +0100 |
commit | 76347f1c6f3aa41654fb989d1726d7ce4b56795e (patch) | |
tree | becfd58880d00bb18fafcb30422fa1e2494184ce /src | |
parent | Make the higlight ring a bit less in your face (diff) | |
download | nheko-76347f1c6f3aa41654fb989d1726d7ce4b56795e.tar.xz |
Continue fetching past messages when searching
Diffstat (limited to 'src')
-rw-r--r-- | src/Cache.cpp | 98 | ||||
-rw-r--r-- | src/timeline/EventStore.cpp | 11 | ||||
-rw-r--r-- | src/timeline/TimelineFilter.cpp | 32 | ||||
-rw-r--r-- | src/timeline/TimelineFilter.h | 4 | ||||
-rw-r--r-- | src/timeline/TimelineModel.cpp | 1 | ||||
-rw-r--r-- | src/timeline/TimelineModel.h | 2 |
6 files changed, 94 insertions, 54 deletions
diff --git a/src/Cache.cpp b/src/Cache.cpp index 3426ccfe..b577f201 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -1013,20 +1013,22 @@ Cache::getOlmSessions(const std::string &curve25519) { using namespace mtx::crypto; - auto txn = lmdb::txn::begin(env_); - auto db = getOlmSessionsDb(txn, curve25519); - - std::string_view session_id, unused; - std::vector<std::string> res; + try { + auto txn = ro_txn(env_); + auto db = getOlmSessionsDb(txn, curve25519); - auto cursor = lmdb::cursor::open(txn, db); - while (cursor.get(session_id, unused, MDB_NEXT)) - res.emplace_back(session_id); - cursor.close(); + std::string_view session_id, unused; + std::vector<std::string> res; - txn.commit(); + auto cursor = lmdb::cursor::open(txn, db); + while (cursor.get(session_id, unused, MDB_NEXT)) + res.emplace_back(session_id); + cursor.close(); - return res; + return res; + } catch (...) { + return {}; + } } void @@ -2173,18 +2175,22 @@ Cache::roomIds() std::string Cache::previousBatchToken(const std::string &room_id) { - auto txn = lmdb::txn::begin(env_, nullptr); - auto orderDb = getEventOrderDb(txn, room_id); + auto txn = ro_txn(env_); + try { + auto orderDb = getEventOrderDb(txn, room_id); - auto cursor = lmdb::cursor::open(txn, orderDb); - std::string_view indexVal, val; - if (!cursor.get(indexVal, val, MDB_FIRST)) { - return ""; - } + auto cursor = lmdb::cursor::open(txn, orderDb); + std::string_view indexVal, val; + if (!cursor.get(indexVal, val, MDB_FIRST)) { + return ""; + } - auto j = nlohmann::json::parse(val); + auto j = nlohmann::json::parse(val); - return j.value("prev_batch", ""); + return j.value("prev_batch", ""); + } catch (...) { + return ""; + } } Cache::Messages @@ -3206,10 +3212,10 @@ Cache::pendingEvents(const std::string &room_id) std::optional<mtx::events::collections::TimelineEvent> Cache::firstPendingMessage(const std::string &room_id) { - auto txn = lmdb::txn::begin(env_); + auto txn = ro_txn(env_); auto pending = getPendingMessagesDb(txn, room_id); - { + try { auto pendingCursor = lmdb::cursor::open(txn, pending); std::string_view tsIgnored, pendingTxn; while (pendingCursor.get(tsIgnored, pendingTxn, MDB_NEXT)) { @@ -3225,7 +3231,6 @@ Cache::firstPendingMessage(const std::string &room_id) from_json(nlohmann::json::parse(event), te); pendingCursor.close(); - txn.commit(); return te; } catch (std::exception &e) { nhlog::db()->error("Failed to parse message from cache {}", e.what()); @@ -3233,10 +3238,8 @@ Cache::firstPendingMessage(const std::string &room_id) continue; } } + } catch (const lmdb::error &e) { } - - txn.commit(); - return std::nullopt; } @@ -3998,33 +4001,36 @@ Cache::hasEnoughPowerLevel(const std::vector<mtx::events::EventType> &eventTypes using namespace mtx::events; using namespace mtx::events::state; - auto txn = lmdb::txn::begin(env_); - auto db = getStatesDb(txn, room_id); + auto txn = ro_txn(env_); + try { + auto db = getStatesDb(txn, room_id); - int64_t min_event_level = std::numeric_limits<int64_t>::max(); - int64_t user_level = std::numeric_limits<int64_t>::min(); + int64_t min_event_level = std::numeric_limits<int64_t>::max(); + int64_t user_level = std::numeric_limits<int64_t>::min(); - std::string_view event; - bool res = db.get(txn, to_string(EventType::RoomPowerLevels), event); + std::string_view event; + bool res = db.get(txn, to_string(EventType::RoomPowerLevels), event); - if (res) { - try { - StateEvent<PowerLevels> msg = - nlohmann::json::parse(std::string_view(event.data(), event.size())) - .get<StateEvent<PowerLevels>>(); + if (res) { + try { + StateEvent<PowerLevels> msg = + nlohmann::json::parse(std::string_view(event.data(), event.size())) + .get<StateEvent<PowerLevels>>(); - user_level = msg.content.user_level(user_id); + user_level = msg.content.user_level(user_id); - for (const auto &ty : eventTypes) - min_event_level = std::min(min_event_level, msg.content.state_level(to_string(ty))); - } catch (const nlohmann::json::exception &e) { - nhlog::db()->warn("failed to parse m.room.power_levels event: {}", e.what()); + for (const auto &ty : eventTypes) + min_event_level = + std::min(min_event_level, msg.content.state_level(to_string(ty))); + } catch (const nlohmann::json::exception &e) { + nhlog::db()->warn("failed to parse m.room.power_levels event: {}", e.what()); + } } - } - - txn.commit(); - return user_level >= min_event_level; + return user_level >= min_event_level; + } catch (...) { + return false; + } } std::vector<std::string> diff --git a/src/timeline/EventStore.cpp b/src/timeline/EventStore.cpp index de813196..65efc0b4 100644 --- a/src/timeline/EventStore.cpp +++ b/src/timeline/EventStore.cpp @@ -80,8 +80,8 @@ EventStore::EventStore(std::string room_id, QObject *) emit beginInsertRows(toExternalIdx(newFirst), toExternalIdx(this->first - 1)); this->first = newFirst; emit endInsertRows(); - emit fetchedMore(); emit dataChanged(toExternalIdx(oldFirst), toExternalIdx(oldFirst)); + emit fetchedMore(); } else { auto range = cache::client()->getTimelineRange(room_id_); @@ -725,10 +725,11 @@ EventStore::decryptEvent(const IdIndex &idx, case olm::DecryptionErrorCode::ParsingFailed: break; case olm::DecryptionErrorCode::ReplayAttack: - nhlog::crypto()->critical("Reply attack while decryptiong event {} in room {} from {}!", - e.event_id, - room_id_, - e.sender); + nhlog::crypto()->critical( + "Replay attack while decryptiong event {} in room {} from {}!", + e.event_id, + room_id_, + e.sender); break; case olm::DecryptionErrorCode::NoError: // unreachable diff --git a/src/timeline/TimelineFilter.cpp b/src/timeline/TimelineFilter.cpp index 15d2590c..cd17a7f6 100644 --- a/src/timeline/TimelineFilter.cpp +++ b/src/timeline/TimelineFilter.cpp @@ -19,8 +19,10 @@ TimelineFilter::setThreadId(const QString &t) if (this->threadId != t) { this->threadId = t; invalidateFilter(); + + fetchMore({}); + emit threadIdChanged(); } - emit threadIdChanged(); } void @@ -30,21 +32,45 @@ TimelineFilter::setContentFilter(const QString &c) if (this->contentFilter != c) { this->contentFilter = c; invalidateFilter(); + + fetchMore({}); + emit contentFilterChanged(); + } +} + +void +TimelineFilter::fetchAgain() +{ + if (threadId.isEmpty() && contentFilter.isEmpty()) + return; + + if (auto s = source()) { + if (rowCount() == cachedCount && s->canFetchMore(QModelIndex())) + s->fetchMore(QModelIndex()); + else + cachedCount = rowCount(); } - emit contentFilterChanged(); } void TimelineFilter::setSource(TimelineModel *s) { if (auto orig = this->source(); orig != s) { - if (orig) + cachedCount = 0; + + if (orig) { disconnect(orig, &TimelineModel::currentIndexChanged, this, &TimelineFilter::currentIndexChanged); + disconnect(orig, &TimelineModel::fetchedMore, this, &TimelineFilter::fetchAgain); + } + this->setSourceModel(s); + connect(s, &TimelineModel::currentIndexChanged, this, &TimelineFilter::currentIndexChanged); + connect(s, &TimelineModel::fetchedMore, this, &TimelineFilter::fetchAgain); + emit sourceChanged(); invalidateFilter(); } diff --git a/src/timeline/TimelineFilter.h b/src/timeline/TimelineFilter.h index 3b04650e..a602f84f 100644 --- a/src/timeline/TimelineFilter.h +++ b/src/timeline/TimelineFilter.h @@ -45,9 +45,13 @@ signals: void sourceChanged(); void currentIndexChanged(); +private slots: + void fetchAgain(); + protected: bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override; private: QString threadId, contentFilter; + int cachedCount = 0; }; diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index b20e36bc..6b764081 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -449,6 +449,7 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj connect(&events, &EventStore::fetchedMore, this, [this]() { setPaginationInProgress(false); updateLastMessage(); + emit fetchedMore(); }); connect(&events, &EventStore::fetchedMore, this, &TimelineModel::checkAfterFetch); connect(&events, diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index 9cd60e5d..9daeeb3a 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -465,6 +465,8 @@ signals: void scrollTargetChanged(); + void fetchedMore(); + private: template<typename T> void sendEncryptedMessage(mtx::events::RoomEvent<T> msg, mtx::events::EventType eventType); |