summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/Cache.cpp39
-rw-r--r--src/ChatPage.cpp4
-rw-r--r--src/RoomList.cpp2
-rw-r--r--src/timeline/TimelineModel.cpp39
4 files changed, 71 insertions, 13 deletions
diff --git a/src/Cache.cpp b/src/Cache.cpp

index aca01c1a..8cfc4b55 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp
@@ -960,9 +960,15 @@ Cache::saveState(const mtx::responses::Sync &res) for (const auto &room : res.rooms.join) { if (!room.second.ephemeral.receipts.empty()) { std::vector<QString> receipts; - for (const auto &receipt : room.second.ephemeral.receipts) - if (receipt.first != user_id) - receipts.push_back(QString::fromStdString(receipt.first)); + for (const auto &receipt : room.second.ephemeral.receipts) { + for (const auto &receiptUsersTs : receipt.second) { + if (receiptUsersTs.first != user_id) { + receipts.push_back( + QString::fromStdString(receipt.first)); + break; + } + } + } if (!receipts.empty()) emit newReadReceipts(QString::fromStdString(room.first), receipts); } @@ -1314,16 +1320,33 @@ Cache::getLastMessageInfo(lmdb::txn &txn, const std::string &room_id) std::string timestamp, msg; - QSettings settings; const auto local_user = utils::localUser(); + DescInfo fallbackDesc{}; + auto cursor = lmdb::cursor::open(txn, db); while (cursor.get(timestamp, msg, MDB_NEXT)) { auto obj = json::parse(msg); - if (obj.count("event") == 0 || !(obj["event"]["type"] == "m.room.message" || - obj["event"]["type"] == "m.sticker" || - obj["event"]["type"] == "m.room.encrypted")) + if (obj.count("event") == 0) + continue; + + if (fallbackDesc.event_id.isEmpty() && obj["event"]["type"] == "m.room.member" && + obj["event"]["state_key"] == local_user.toStdString() && + obj["event"]["content"]["membership"] == "join") { + uint64_t ts = obj["event"]["origin_server_ts"]; + auto time = QDateTime::fromMSecsSinceEpoch(ts); + fallbackDesc = DescInfo{QString::fromStdString(obj["event"]["event_id"]), + local_user, + tr("You joined this room"), + utils::descriptiveTime(time), + ts, + time}; + } + + if (!(obj["event"]["type"] == "m.room.message" || + obj["event"]["type"] == "m.sticker" || + obj["event"]["type"] == "m.room.encrypted")) continue; mtx::events::collections::TimelineEvent event; @@ -1335,7 +1358,7 @@ Cache::getLastMessageInfo(lmdb::txn &txn, const std::string &room_id) } cursor.close(); - return DescInfo{}; + return fallbackDesc; } std::map<QString, bool> diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp
index 689e9ca4..ae3c7a11 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp
@@ -1009,13 +1009,13 @@ ChatPage::trySync() cache::saveState(res); olm::handle_to_device_messages(res.to_device); - emit syncUI(res.rooms); - auto updates = cache::roomUpdates(res); emit syncTopBar(updates); emit syncRoomlist(updates); + emit syncUI(res.rooms); + emit syncTags(cache::roomTagUpdates(res)); // if we process a lot of syncs (1 every 200ms), this means we clean the diff --git a/src/RoomList.cpp b/src/RoomList.cpp
index 981b1f11..85a22026 100644 --- a/src/RoomList.cpp +++ b/src/RoomList.cpp
@@ -384,7 +384,7 @@ RoomList::sortRoomsByLastMessage() { isSortPending_ = false; - std::sort(begin(rooms_sort_cache_), end(rooms_sort_cache_), room_sort{}); + std::stable_sort(begin(rooms_sort_cache_), end(rooms_sort_cache_), room_sort{}); int newIndex = 0; for (const auto &roomWidget : rooms_sort_cache_) { diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp
index 836fd59f..388a5842 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp
@@ -324,16 +324,24 @@ TimelineModel::data(const QString &id, int role) const } case Id: return id; - case State: + case State: { + auto containsOthers = [](const auto &vec) { + for (const auto &e : vec) + if (e.second != http::client()->user_id().to_string()) + return true; + return false; + }; + // only show read receipts for messages not from us if (acc::sender(event) != http::client()->user_id().to_string()) return qml_mtx_events::Empty; else if (pending.contains(id)) return qml_mtx_events::Sent; - else if (read.contains(id) || cache::readReceipts(id, room_id_).size() > 1) + else if (read.contains(id) || containsOthers(cache::readReceipts(id, room_id_))) return qml_mtx_events::Read; else return qml_mtx_events::Received; + } case IsEncrypted: { return std::holds_alternative< mtx::events::EncryptedEvent<mtx::events::msg::Encrypted>>(events[id]); @@ -525,6 +533,20 @@ isMessage(const mtx::events::EncryptedEvent<T> &) return true; } +// Workaround. We also want to see a room at the top, if we just joined it +auto +isYourJoin(const mtx::events::StateEvent<mtx::events::state::Member> &e) +{ + return e.content.membership == mtx::events::state::Membership::Join && + e.state_key == http::client()->user_id().to_string(); +} +template<typename T> +auto +isYourJoin(const mtx::events::Event<T> &) +{ + return false; +} + void TimelineModel::updateLastMessage() { @@ -537,6 +559,19 @@ TimelineModel::updateLastMessage() } } + if (std::visit([](const auto &e) -> bool { return isYourJoin(e); }, event)) { + auto time = mtx::accessors::origin_server_ts(event); + uint64_t ts = time.toMSecsSinceEpoch(); + emit manager_->updateRoomsLastMessage( + room_id_, + DescInfo{QString::fromStdString(mtx::accessors::event_id(event)), + QString::fromStdString(http::client()->user_id().to_string()), + tr("You joined this room"), + utils::descriptiveTime(time), + ts, + time}); + return; + } if (!std::visit([](const auto &e) -> bool { return isMessage(e); }, event)) continue;