From 162ea2775a6cdbd2435340ba3ce5addd5a6fcb8c Mon Sep 17 00:00:00 2001 From: Demolemon11 Date: Thu, 21 Nov 2024 12:22:10 +0800 Subject: [PATCH] Show notice if user cannot post in the room --- src/home/room_screen.rs | 20 +++++++++--------- src/sliding_sync.rs | 45 ++++++++++++++++++++++++++++++++--------- 2 files changed, 47 insertions(+), 18 deletions(-) diff --git a/src/home/room_screen.rs b/src/home/room_screen.rs index 840cfff5..3953f2bb 100644 --- a/src/home/room_screen.rs +++ b/src/home/room_screen.rs @@ -1434,8 +1434,6 @@ impl RoomScreen { /// /// Redraws this RoomScreen view if any updates were applied. fn process_timeline_updates(&mut self, cx: &mut Cx, portal_list: &PortalListRef) { - // Check if the user has permission to send message in this room. - self.check_user_permission(); let top_space = self.view(id!(top_space)); let bottom_input = self.view(id!(bottom_input)); let no_send_permisson_notice = self.view(id!(no_send_permisson_notice)); @@ -1581,15 +1579,15 @@ impl RoomScreen { // if the list of typing users gets updated many times in a row. typing_users = users; } - TimelineUpdate::SendPermission(can_send) => { - if can_send == -1 { - bottom_input.set_visible(false); - no_send_permisson_notice.set_visible(true) - } - else { + TimelineUpdate::SendPermission(can_user_post_message) => { + if can_user_post_message { bottom_input.set_visible(true); no_send_permisson_notice.set_visible(false) } + else { + bottom_input.set_visible(false); + no_send_permisson_notice.set_visible(true) + } } } @@ -1705,6 +1703,8 @@ impl RoomScreen { /// Invoke this when this timeline is being shown, /// e.g., when the user navigates to this timeline. fn show_timeline(&mut self, cx: &mut Cx) { + self.check_user_permission(); + let room_id = self.room_id.clone() .expect("BUG: Timeline::show_timeline(): no room_id was set."); // just an optional sanity check @@ -1963,6 +1963,8 @@ impl RoomScreen { } tl.last_scrolled_index = first_index; } + + /// Send request as `MatrixRequest` to check post permission. fn check_user_permission(&self) { if let Some(room_id) = self.room_id.clone() { submit_async_request(MatrixRequest::CheckUserSendPermission { room_id }) @@ -2031,7 +2033,7 @@ pub enum TimelineUpdate { users: Vec, }, /// if the user has permission to send messages in this room - SendPermission(i64), + SendPermission(bool), } /// The global set of all timeline states, one entry per room. diff --git a/src/sliding_sync.rs b/src/sliding_sync.rs index be58dc21..3b451686 100644 --- a/src/sliding_sync.rs +++ b/src/sliding_sync.rs @@ -9,7 +9,7 @@ use matrix_sdk::{ config::RequestConfig, event_handler::EventHandlerDropGuard, media::MediaRequest, room::{Receipts, RoomMember}, ruma::{ api::client::{receipt::create_receipt::v3::ReceiptType, session::get_login_types::v3::LoginType}, events::{ receipt::ReceiptThread, room::{ - message::{ForwardThread, RoomMessageEventContent}, MediaSource + message::{ForwardThread, RoomMessageEventContent}, power_levels::RoomPowerLevelsEventContent, MediaSource }, FullStateEventContent }, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedMxcUri, OwnedRoomAliasId, OwnedRoomId, OwnedUserId, UserId }, sliding_sync::VersionBuilder, Client, Room @@ -716,12 +716,10 @@ async fn async_worker( let _check_user_send_permission_task = Handle::current().spawn(async move { let room = timeline.room(); - let can_send = room.get_user_power_level(user_id).await.unwrap_or(0); - - if let Err(_) = sender.send(TimelineUpdate::SendPermission(can_send)) { + let can_user_post_message = room.can_user_send_message(user_id, matrix_sdk::ruma::events::MessageLikeEventType::Message).await.unwrap_or(true); + if let Err(_) = sender.send(TimelineUpdate::SendPermission(can_user_post_message)) { error!("Failed to send the result of user send permission") } - SignalToUI::set_ui_signal(); }); } } @@ -1172,7 +1170,7 @@ async fn update_room( if let Some(old_latest_event) = old_room.latest_event().await { if new_latest_event.timestamp() > old_latest_event.timestamp() { log!("Updating latest event for room {}", new_room_id); - room_avatar_changed = update_latest_event(new_room_id.clone(), &new_latest_event); + (room_avatar_changed, _) = update_latest_event(new_room_id.clone(), &new_latest_event); } } } @@ -1588,11 +1586,14 @@ async fn timeline_subscriber_handler( // Update the latest event for this room. if let Some(new_latest) = new_latest_event { if latest_event.as_ref().map_or(true, |ev| ev.timestamp() < new_latest.timestamp()) { - let room_avatar_changed = update_latest_event(room_id.clone(), &new_latest); + let (room_avatar_changed, can_user_post_message) = update_latest_event(room_id.clone(), &new_latest); latest_event = Some(new_latest); if room_avatar_changed { spawn_fetch_room_avatar(room.clone()); } + if let Err(_) = sender.send(TimelineUpdate::SendPermission(can_user_post_message)) { + error!("Failed to send the result of user send permission") + } } } } @@ -1612,8 +1613,9 @@ async fn timeline_subscriber_handler( fn update_latest_event( room_id: OwnedRoomId, event_tl_item: &EventTimelineItem, -) -> bool { +) -> (bool, bool) { let mut room_avatar_changed = false; + let mut can_user_post_message = true; let (timestamp, latest_message_text) = get_latest_event_details(event_tl_item, &room_id); @@ -1629,6 +1631,9 @@ fn update_latest_event( AnyOtherFullStateEventContent::RoomAvatar(_avatar_event) => { room_avatar_changed = true; } + AnyOtherFullStateEventContent::RoomPowerLevels(user_power_level_event) => { + can_user_post_message = check_post_permission_from_event(user_power_level_event) + } _ => { } } _ => { } @@ -1638,7 +1643,7 @@ fn update_latest_event( timestamp, latest_message_text, }); - room_avatar_changed + (room_avatar_changed, can_user_post_message) } @@ -1674,3 +1679,25 @@ fn avatar_from_room_name(room_name: &str) -> RoomPreviewAvatar { .unwrap_or_default() ) } + +/// Check if user can post message from event. +fn check_post_permission_from_event(full_state_event_content: &FullStateEventContent) -> bool { + let mut can_user_post_message = true; + + match full_state_event_content { + FullStateEventContent::Original { content, prev_content: _ } => { + if let Some(client) = CLIENT.get() { + if let Some(user_id) = client.user_id() { + if let Some(power) = content.users.get(user_id) { + if power.is_negative() { + can_user_post_message = false + } + } + } + }; + }, + _ => { } + } + + can_user_post_message +}