atagen

macltok

public
Star0
Watch0

Commit 3e5a785a7273

tarball

atagen <boss@atagen.co>2026-10-28 07:57 UTC

3 files changed+53-13
normalise: read push rules once per room list and power levels once per room

Room::notification_mode and user_defined_notification_mode each build NotificationSettings, which reads the push rules from the store and registers an event handler, so a 492 room list did that 984 times, and can_pin and can_edit_packs read the same power levels twice. The room list is on the path to the first room opening after a reload.
Modified file: src/normalise/image_pack.rs+9 additions−3 deletions
@@ -6,6 +6,7 @@ use ruma::{
66 events::{
77 GlobalAccountDataEventType, StateEventType,
88 image_pack::{PackImage as SourceImage, PackInfo, PackUsage as SourceUsage},
9+ room::power_levels::RoomPowerLevels,
910 },
1011 serde::{JsonObject, Raw},
1112 };
@@ -54,9 +55,14 @@ type EnabledRooms = BTreeMap<OwnedRoomId, BTreeMap<String, Raw<JsonObject>>>;
5455
5556 pub(crate) async fn can_edit_packs(room: &Room) -> bool {
5657 room.state() == RoomState::Joined
57- && room.power_levels().await.is_ok_and(|levels| {
58- levels.user_can_send_state(room.own_user_id(), StateEventType::from(ROOM_PACKS))
59- })
58+ && room
59+ .power_levels()
60+ .await
61+ .is_ok_and(|levels| can_edit_packs_with(room, &levels))
62+}
63+
64+pub(crate) fn can_edit_packs_with(room: &Room, levels: &RoomPowerLevels) -> bool {
65+ levels.user_can_send_state(room.own_user_id(), StateEventType::from(ROOM_PACKS))
6066 }
6167
6268 /// what an id from `ImagePack::id` points at. room ids hold colons, so it's matched
Modified file: src/normalise/mod.rs+1 additions−1 deletions
@@ -10,7 +10,7 @@ mod timeline;
1010
1111 pub(crate) use context::{apply_profiles, normalise_context, resolve_replies};
1212 pub(crate) use image_pack::{
13- ENABLED_ROOMS, ROOM_PACKS, USER_PACK, can_edit_packs, effective_usage, image_packs,
13+ ENABLED_ROOMS, ROOM_PACKS, USER_PACK, can_edit_packs_with, effective_usage, image_packs,
1414 resolve_pack_id, stored_pack,
1515 };
1616 pub(crate) use link_preview::{ROOM_PREVIEW_URLS, server_preview, url_previews_allowed};
Modified file: src/normalise/room.rs+43 additions−9 deletions
@@ -3,6 +3,7 @@ use matrix_sdk::{
33 Client, Room, RoomState,
44 deserialized_responses::SyncOrStrippedState,
55 latest_events::LatestEventValue,
6+ notification_settings::{IsEncrypted, IsOneToOne, NotificationSettings},
67 ruma::events::{
78 AnyMessageLikeEventContent, AnySyncMessageLikeEvent, AnySyncTimelineEvent, StateEventType,
89 SyncStateEvent,
@@ -23,8 +24,10 @@ use crate::{
2324 };
2425
2526 pub(crate) async fn room_summaries(client: &Client, spaces: &SpaceService) -> Vec<RoomSummary> {
27+ let settings = client.notification_settings().await;
28+ let settings = &settings;
2629 let mut summaries = stream::iter(client.rooms())
27- .map(|room| async move { room_summary(&room, spaces).await })
30+ .map(|room| async move { room_summary(&room, spaces, settings).await })
2831 .buffer_unordered(16)
2932 .collect::<Vec<_>>()
3033 .await;
@@ -38,16 +41,46 @@ pub(crate) async fn room_summaries(client: &Client, spaces: &SpaceService) -> Ve
3841 summaries
3942 }
4043
41-async fn room_summary(room: &Room, spaces: &SpaceService) -> RoomSummary {
44+async fn room_summary(
45+ room: &Room,
46+ spaces: &SpaceService,
47+ settings: &NotificationSettings,
48+) -> RoomSummary {
4249 let name = room
4350 .display_name()
4451 .await
4552 .map(|name| name.to_string())
4653 .unwrap_or_else(|_| room.room_id().to_string());
47- let custom_notification_mode = room.user_defined_notification_mode().await;
54+ let joined = room.state() == RoomState::Joined;
55+ let custom_notification_mode = if joined {
56+ settings
57+ .get_user_defined_room_notification_mode(room.room_id())
58+ .await
59+ } else {
60+ None
61+ };
62+ if let Some(mode) = custom_notification_mode {
63+ room.update_cached_user_defined_notification_mode(mode);
64+ }
4865 let effective_notification_mode = match custom_notification_mode {
4966 Some(mode) => Some(mode),
50- None => room.notification_mode().await,
67+ None if joined => match room.latest_encryption_state().await {
68+ Ok(state) => Some(
69+ settings
70+ .get_default_room_notification_mode(
71+ IsEncrypted::from(state.is_encrypted()),
72+ IsOneToOne::from(room.active_members_count() == 2),
73+ )
74+ .await,
75+ ),
76+ Err(_) => None,
77+ },
78+ None => None,
79+ };
80+ let power_levels = if joined {
81+ room.power_levels().await.ok()
82+ } else {
83+ None
5184 };
5285 let inviter = match room.state() {
5386 RoomState::Invited => room
@@ -114,12 +147,13 @@ async fn room_summary(room: &Room, spaces: &SpaceService) -> RoomSummary {
114147 } else {
115148 None
116149 },
117- can_edit_packs: super::can_edit_packs(room).await,
150+ can_edit_packs: power_levels
151+ .as_ref()
152+ .is_some_and(|levels| super::can_edit_packs_with(room, levels)),
118153 pinned_events: room.pinned_event_ids().unwrap_or_default(),
119- can_pin: room.state() == RoomState::Joined
120- && room.power_levels().await.is_ok_and(|levels| {
121- levels.user_can_send_state(room.own_user_id(), StateEventType::RoomPinnedEvents)
122- }),
154+ can_pin: power_levels.as_ref().is_some_and(|levels| {
155+ levels.user_can_send_state(room.own_user_id(), StateEventType::RoomPinnedEvents)
156+ }),
123157 }
124158 }