Skip to content

Commit d6adece

Browse files
committed
refactor: let mentionable_text_input manage all states
1 parent b68e19b commit d6adece

File tree

4 files changed

+150
-332
lines changed

4 files changed

+150
-332
lines changed

src/home/editing_pane.rs

Lines changed: 7 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,11 @@ use matrix_sdk::{
1010
},
1111
};
1212
use matrix_sdk_ui::timeline::{EventTimelineItem, TimelineEventItemId, TimelineItemContent};
13-
1413
use crate::{
1514
shared::popup_list::enqueue_popup_notification,
1615
sliding_sync::{MatrixRequest, submit_async_request},
1716
};
18-
19-
use crate::room::room_member_manager::{RoomMemberSubscriber, RoomMemberSubscription};
20-
use crate::shared::mentionable_text_input::{MentionableTextInputWidgetExt, MentionableTextInputAction};
21-
use std::sync::{Arc, Mutex};
17+
use crate::shared::mentionable_text_input::MentionableTextInputWidgetExt;
2218

2319
live_design! {
2420
use link::theme::*;
@@ -167,52 +163,6 @@ struct EditingPaneInfo {
167163
room_id: OwnedRoomId,
168164
}
169165

170-
/// Actions specific to EditingPane for internal use
171-
#[derive(Clone, Debug, DefaultNone)]
172-
enum EditingPaneInternalAction {
173-
/// Room members data has been updated
174-
RoomMembersUpdated(Arc<Vec<matrix_sdk::room::RoomMember>>),
175-
None,
176-
}
177-
178-
/// Subscriber for EditingPane to receive room member updates
179-
struct EditingPaneSubscriber {
180-
widget_uid: WidgetUid,
181-
current_room_id: Option<OwnedRoomId>,
182-
}
183-
184-
/// Implement `RoomMemberSubscriber` trait, receive member update notifications
185-
impl RoomMemberSubscriber for EditingPaneSubscriber {
186-
fn on_room_members_updated(
187-
&mut self,
188-
cx: &mut Cx,
189-
room_id: &OwnedRoomId,
190-
members: Arc<Vec<matrix_sdk::room::RoomMember>>,
191-
) {
192-
if let Some(current_room_id) = &self.current_room_id {
193-
if current_room_id == room_id {
194-
// Log with stable identifier
195-
log!(
196-
"EditingPaneSubscriber({:?}) received members update for room {}",
197-
self.widget_uid,
198-
room_id
199-
);
200-
201-
// cx.action(EditingPaneInternalAction::RoomMembersUpdated(members.clone()));
202-
cx.widget_action(
203-
self.widget_uid,
204-
&Scope::empty().path,
205-
EditingPaneInternalAction::RoomMembersUpdated(members),
206-
);
207-
}else{
208-
log!("Ignoring update for different room {} (current: {})", room_id, current_room_id);
209-
}
210-
}
211-
212-
213-
}
214-
}
215-
216166
/// A view that slides in from the bottom of the screen to allow editing a message.
217167
#[derive(Live, LiveHook, Widget)]
218168
pub struct EditingPane {
@@ -225,8 +175,6 @@ pub struct EditingPane {
225175
info: Option<EditingPaneInfo>,
226176
#[rust]
227177
is_animating_out: bool,
228-
#[rust]
229-
member_subscription: Option<RoomMemberSubscription>,
230178
}
231179

232180
impl Widget for EditingPane {
@@ -264,29 +212,6 @@ impl Widget for EditingPane {
264212
if let Event::Actions(actions) = event {
265213
let edit_text_input = self.mentionable_text_input(id!(editing_content.edit_text_input)).text_input(id!(text_input));
266214

267-
// Check for room member update actions and power level updates
268-
for action in actions {
269-
// Check for MentionableTextInputAction::PowerLevelsUpdated
270-
if let Some(MentionableTextInputAction::PowerLevelsUpdated(room_id, can_notify_room)) = action.downcast_ref::<MentionableTextInputAction>() {
271-
// Make sure this is for our current room
272-
if let Some(info) = &self.info {
273-
if &info.room_id == room_id {
274-
let message_input = self.mentionable_text_input(id!(editing_content.edit_text_input));
275-
message_input.set_can_notify_room(*can_notify_room);
276-
}
277-
}
278-
}
279-
280-
if let Some(widget_action) = action.as_widget_action().widget_uid_eq(self.widget_uid()) {
281-
if let Some(update_action) = widget_action.downcast_ref::<EditingPaneInternalAction>() {
282-
if let EditingPaneInternalAction::RoomMembersUpdated(members) = update_action {
283-
self.handle_members_updated(members.clone());
284-
}
285-
continue;
286-
}
287-
}
288-
}
289-
290215
// Hide the editing pane if the cancel button was clicked
291216
// or if the `Escape` key was pressed within the edit text input.
292217
if self.button(id!(cancel_button)).clicked(actions)
@@ -492,7 +417,7 @@ impl EditingPane {
492417
}
493418

494419
/// Shows the editing pane and sets it up to edit the given `event`'s content.
495-
pub fn show(&mut self, cx: &mut Cx, event_tl_item: EventTimelineItem, room_id: OwnedRoomId) {
420+
pub fn show(&mut self, cx: &mut Cx, event_tl_item: EventTimelineItem, room_id: OwnedRoomId, can_notify_room: bool) {
496421
if !event_tl_item.is_editable() {
497422
enqueue_popup_notification("That message cannot be edited.".into());
498423
return;
@@ -501,6 +426,8 @@ impl EditingPane {
501426
log!("EditingPane show: Opening editing pane for room: {}", room_id);
502427

503428
let edit_text_input = self.mentionable_text_input(id!(editing_content.edit_text_input));
429+
edit_text_input.set_can_notify_room(can_notify_room);
430+
504431
match event_tl_item.content() {
505432
TimelineItemContent::Message(message) => {
506433
edit_text_input.set_text(cx, message.body());
@@ -517,11 +444,9 @@ impl EditingPane {
517444
self.info = Some(EditingPaneInfo { event_tl_item, room_id: room_id.clone() });
518445

519446
// Set room ID on the MentionableTextInput
520-
let edit_text_input = self.mentionable_text_input(id!(editing_content.edit_text_input));
521447
edit_text_input.set_room_id(room_id.clone());
522-
523448
// Create room member subscription
524-
self.create_room_subscription(cx, room_id.clone());
449+
edit_text_input.create_room_subscription(cx, room_id);
525450

526451
self.visible = true;
527452
self.button(id!(accept_button)).reset_hover(cx);
@@ -535,50 +460,6 @@ impl EditingPane {
535460
self.animator_play(cx, id!(panel.show));
536461
self.redraw(cx);
537462
}
538-
539-
/// Create room member subscription for the editing pane
540-
fn create_room_subscription(&mut self, cx: &mut Cx, room_id: OwnedRoomId) {
541-
// Cancel previous subscription if any
542-
self.member_subscription = None;
543-
544-
log!("Creating room member subscription for EditingPane, ID: {:?}", self.widget_uid());
545-
546-
// Create new subscriber
547-
let subscriber = Arc::new(Mutex::new(EditingPaneSubscriber {
548-
widget_uid: self.widget_uid(),
549-
current_room_id: Some(room_id.clone()),
550-
}));
551-
552-
// Create and save subscription
553-
self.member_subscription = Some(RoomMemberSubscription::new(cx, room_id.clone(), subscriber));
554-
555-
submit_async_request(MatrixRequest::GetRoomMembers {
556-
room_id: room_id.clone(),
557-
memberships: matrix_sdk::RoomMemberships::JOIN,
558-
local_only: false,
559-
});
560-
561-
// Request power levels data to determine if @room mentions are allowed
562-
submit_async_request(MatrixRequest::GetRoomPowerLevels {
563-
room_id,
564-
});
565-
}
566-
567-
/// Handle room members update event
568-
fn handle_members_updated(&mut self, members: Arc<Vec<matrix_sdk::room::RoomMember>>) {
569-
if let Some(_info) = &self.info {
570-
// Pass room member data to MentionableTextInput
571-
let message_input = self.mentionable_text_input(id!(editing_content.edit_text_input));
572-
message_input.set_room_members(members);
573-
574-
// Also set room ID if it's not already set
575-
if let Some(info) = &self.info {
576-
if message_input.get_room_id().is_none() {
577-
message_input.set_room_id(info.room_id.clone());
578-
}
579-
}
580-
}
581-
}
582463
}
583464

584465
impl EditingPaneRef {
@@ -604,11 +485,11 @@ impl EditingPaneRef {
604485
}
605486

606487
/// See [`EditingPane::show()`].
607-
pub fn show(&self, cx: &mut Cx, event_tl_item: EventTimelineItem, room_id: OwnedRoomId) {
488+
pub fn show(&self, cx: &mut Cx, event_tl_item: EventTimelineItem, room_id: OwnedRoomId, can_notify_room: bool) {
608489
let Some(mut inner) = self.borrow_mut() else {
609490
return;
610491
};
611-
inner.show(cx, event_tl_item, room_id);
492+
inner.show(cx, event_tl_item, room_id, can_notify_room);
612493
}
613494

614495
/// Returns the event that is currently being edited, if any.

src/home/room_screen.rs

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1700,29 +1700,12 @@ impl RoomScreen {
17001700

17011701
if let Some(room_id) = &self.room_id {
17021702
// Send the power level update action so RoomInputBar can update MentionableTextInput
1703-
// log!("Room screen: Sending PowerLevelsUpdated action for room {}", room_id);
1703+
log!("Room screen: Sending PowerLevelsUpdated action for room {}", room_id);
17041704

1705-
// Use different methods for sending the action to be sure it gets delivered
17061705
cx.action(MentionableTextInputAction::PowerLevelsUpdated(
17071706
room_id.clone(),
17081707
can_notify_room
17091708
));
1710-
1711-
// Also try direct widget action
1712-
let input_bar = self.view.view(id!(input_bar)).widget_uid();
1713-
cx.widget_action(
1714-
input_bar,
1715-
&Scope::empty().path,
1716-
MentionableTextInputAction::PowerLevelsUpdated(
1717-
room_id.clone(),
1718-
can_notify_room
1719-
)
1720-
);
1721-
1722-
// Alternative: directly set to mentionable_text_input
1723-
let message_input = self.view.room_input_bar(id!(input_bar))
1724-
.mentionable_text_input(id!(message_input));
1725-
message_input.set_can_notify_room(can_notify_room);
17261709
}
17271710
}
17281711

@@ -2210,10 +2193,21 @@ impl RoomScreen {
22102193
// otherwise a very-tall input bar might show up underneath a shorter editing pane.
22112194
self.view(id!(input_bar)).set_visible(cx, false);
22122195

2196+
// Extract power levels from the current room state to pass directly to the editing pane.
2197+
// This is necessary because:
2198+
// 1. EditingPane uses its own MentionableTextInput instance separate from RoomInputBar
2199+
// 2. While global actions (via cx.action()) are used to broadcast power level updates,
2200+
// the editing pane may be opened before those updates have been processed
2201+
// 3. Explicitly passing the current value ensures immediate consistency between
2202+
// all MentionableTextInput instances in the application
2203+
let can_notify_room = self.tl_state.as_ref()
2204+
.map(|tl| tl.user_power.can_notify_room())
2205+
.unwrap_or(false);
22132206
self.editing_pane(id!(editing_pane)).show(
22142207
cx,
22152208
event_tl_item,
22162209
room_id,
2210+
can_notify_room,
22172211
);
22182212
self.redraw(cx);
22192213
}

0 commit comments

Comments
 (0)