diff --git a/src/Cache.cpp b/src/Cache.cpp
index 79a5ea04..4213e901 100644
--- a/src/Cache.cpp
+++ b/src/Cache.cpp
@@ -3006,49 +3006,54 @@ Cache::getMember(const std::string &room_id, const std::string &user_id)
std::vector<RoomMember>
Cache::getMembers(const std::string &room_id, std::size_t startIndex, std::size_t len)
{
- auto txn = ro_txn(env_);
- auto db = getMembersDb(txn, room_id);
- auto cursor = lmdb::cursor::open(txn, db);
+ try {
+ auto txn = ro_txn(env_);
+ auto db = getMembersDb(txn, room_id);
+ auto cursor = lmdb::cursor::open(txn, db);
- std::size_t currentIndex = 0;
+ std::size_t currentIndex = 0;
- const auto endIndex = std::min(startIndex + len, db.size(txn));
+ const auto endIndex = std::min(startIndex + len, db.size(txn));
- std::vector<RoomMember> members;
+ std::vector<RoomMember> members;
- std::string_view user_id, user_data;
- while (cursor.get(user_id, user_data, MDB_NEXT)) {
- if (currentIndex < startIndex) {
- currentIndex += 1;
- continue;
- }
+ std::string_view user_id, user_data;
+ while (cursor.get(user_id, user_data, MDB_NEXT)) {
+ if (currentIndex < startIndex) {
+ currentIndex += 1;
+ continue;
+ }
- if (currentIndex >= endIndex)
- break;
+ if (currentIndex >= endIndex)
+ break;
- try {
- MemberInfo tmp = nlohmann::json::parse(user_data).get<MemberInfo>();
- members.emplace_back(RoomMember{QString::fromStdString(std::string(user_id)),
- QString::fromStdString(tmp.name)});
- } catch (const nlohmann::json::exception &e) {
- nhlog::db()->warn("{}", e.what());
- }
+ try {
+ MemberInfo tmp = nlohmann::json::parse(user_data).get<MemberInfo>();
+ members.emplace_back(RoomMember{QString::fromStdString(std::string(user_id)),
+ QString::fromStdString(tmp.name)});
+ } catch (const nlohmann::json::exception &e) {
+ nhlog::db()->warn("{}", e.what());
+ }
- currentIndex += 1;
- }
+ currentIndex += 1;
+ }
- cursor.close();
+ cursor.close();
- return members;
+ return members;
+ } catch (const lmdb::error &e) {
+ nhlog::db()->error("Failed to retrieve members from db in room {}: {}", room_id, e.what());
+ return {};
+ }
}
std::vector<RoomMember>
Cache::getMembersFromInvite(const std::string &room_id, std::size_t startIndex, std::size_t len)
{
- auto txn = ro_txn(env_);
- std::vector<RoomMember> members;
-
try {
+ auto txn = ro_txn(env_);
+ std::vector<RoomMember> members;
+
auto db = getInviteMembersDb(txn, room_id);
auto cursor = lmdb::cursor::open(txn, db);
@@ -3079,11 +3084,12 @@ Cache::getMembersFromInvite(const std::string &room_id, std::size_t startIndex,
}
cursor.close();
+
+ return members;
} catch (const lmdb::error &e) {
- nhlog::db()->warn("Failed to retrieve members {}", e.what());
+ nhlog::db()->error("Failed to retrieve members from db in room {}: {}", room_id, e.what());
+ return {};
}
-
- return members;
}
bool
@@ -4033,17 +4039,22 @@ Cache::roomMembers(const std::string &room_id)
{
auto txn = ro_txn(env_);
- std::vector<std::string> members;
- std::string_view user_id, unused;
+ try {
+ std::vector<std::string> members;
+ std::string_view user_id, unused;
- auto db = getMembersDb(txn, room_id);
+ auto db = getMembersDb(txn, room_id);
- auto cursor = lmdb::cursor::open(txn, db);
- while (cursor.get(user_id, unused, MDB_NEXT))
- members.emplace_back(user_id);
- cursor.close();
+ auto cursor = lmdb::cursor::open(txn, db);
+ while (cursor.get(user_id, unused, MDB_NEXT))
+ members.emplace_back(user_id);
+ cursor.close();
- return members;
+ return members;
+ } catch (const lmdb::error &e) {
+ nhlog::db()->error("Failed to retrieve members from db in room {}: {}", room_id, e.what());
+ return {};
+ }
}
crypto::Trust
diff --git a/src/Utils.cpp b/src/Utils.cpp
index b85d7916..ffbaecab 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -881,3 +881,63 @@ utils::markRoomAsDirect(QString roomid, std::vector<RoomMember> members)
});
});
}
+
+std::vector<std::string>
+utils::roomVias(const std::string &roomid)
+{
+ std::vector<std::string> vias;
+
+ {
+ auto members = cache::getMembers(roomid, 0, 100);
+ if (!members.empty()) {
+ vias.push_back(http::client()->user_id().hostname());
+ for (const auto &m : members) {
+ if (vias.size() >= 4)
+ break;
+
+ auto user_id =
+ mtx::identifiers::parse<mtx::identifiers::User>(m.user_id.toStdString());
+
+ auto server = user_id.hostname();
+ if (std::find(begin(vias), end(vias), server) == vias.end())
+ vias.push_back(server);
+ }
+ }
+ }
+
+ if (vias.empty()) {
+ auto members = cache::getMembersFromInvite(roomid, 0, 100);
+ if (!members.empty()) {
+ vias.push_back(http::client()->user_id().hostname());
+ for (const auto &m : members) {
+ if (vias.size() >= 4)
+ break;
+
+ auto user_id =
+ mtx::identifiers::parse<mtx::identifiers::User>(m.user_id.toStdString());
+
+ auto server = user_id.hostname();
+ if (std::find(begin(vias), end(vias), server) == vias.end())
+ vias.push_back(server);
+ }
+ }
+ }
+
+ if (vias.empty()) {
+ auto parents = cache::client()->getParentRoomIds(roomid);
+ for (const auto &p : parents) {
+ auto child =
+ cache::client()->getStateEvent<mtx::events::state::space::Child>(p, roomid);
+ if (child && child->content.via)
+ vias.insert(vias.end(), child->content.via->begin(), child->content.via->end());
+ }
+
+ std::sort(begin(vias), end(vias));
+ auto last = std::unique(begin(vias), end(vias));
+ vias.erase(last, end(vias));
+
+ // if (vias.size()> 3)
+ // vias.erase(begin(vias)+3, end(vias));
+ }
+ return vias;
+}
diff --git a/src/Utils.h b/src/Utils.h
index 96acd993..8f8b9cad 100644
--- a/src/Utils.h
+++ b/src/Utils.h
@@ -311,4 +311,7 @@ removeDirectFromRoom(QString roomid);
void
markRoomAsDirect(QString roomid, std::vector<RoomMember> members);
+
+std::vector<std::string>
+roomVias(const std::string &roomid);
}
diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp
index 1869d2e0..fe4e7850 100644
--- a/src/timeline/RoomlistModel.cpp
+++ b/src/timeline/RoomlistModel.cpp
@@ -645,15 +645,8 @@ void
RoomlistModel::joinPreview(QString roomid)
{
if (previewedRooms.contains(roomid)) {
- std::vector<std::string> vias;
- auto parents = cache::client()->getParentRoomIds(roomid.toStdString());
- for (const auto &p : parents) {
- auto child = cache::client()->getStateEvent<mtx::events::state::space::Child>(
- p, roomid.toStdString());
- if (child && child->content.via)
- vias.insert(vias.end(), child->content.via->begin(), child->content.via->end());
- }
- ChatPage::instance()->joinRoomVia(roomid.toStdString(), vias, false);
+ ChatPage::instance()->joinRoomVia(
+ roomid.toStdString(), utils::roomVias(roomid.toStdString()), false);
}
}
void
diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index 5818d9d8..c60940a7 100644
--- a/src/timeline/TimelineModel.cpp
+++ b/src/timeline/TimelineModel.cpp
@@ -1813,16 +1813,12 @@ TimelineModel::getRoomVias(const QString &roomId)
{
QStringList vias;
- vias.push_back(QStringLiteral("via=%1").arg(QString(
- QUrl::toPercentEncoding(QString::fromStdString(http::client()->user_id().hostname())))));
- auto members = cache::getMembers(roomId.toStdString(), 0, 100);
- for (const auto &m : members) {
+ for (const auto &m : utils::roomVias(roomId.toStdString())) {
if (vias.size() >= 4)
break;
- auto user_id = mtx::identifiers::parse<mtx::identifiers::User>(m.user_id.toStdString());
- QString server = QStringLiteral("via=%1").arg(
- QString(QUrl::toPercentEncoding(QString::fromStdString(user_id.hostname()))));
+ QString server =
+ QStringLiteral("via=%1").arg(QString(QUrl::toPercentEncoding(QString::fromStdString(m))));
if (!vias.contains(server))
vias.push_back(server);
|