Skip to content

Commit

Permalink
Properly handle events when the user profile pane is shown (#80)
Browse files Browse the repository at this point in the history
Events that flow into the RoomScreen either get forwarded to
the underlying timeline view or the user profile sliding pane.
If the pane is currently shown, mouse/touch/tap events are now forwarded
to the pane *ONLY*, and not the underlying timeline.
This prevents the underlying timeline from being scrolled or clicked
when it is partially "hidden" underneath the sliding pane view,
which would be confusing to most users.
Other events (e.g., draw events) are always forwarded to the underlying
timeline.
If the pane is not shown, events are also forwarded to the timeline view,
as normal.

Solution suggested by @jmbejar.
  • Loading branch information
kevinaboos authored Jul 15, 2024
1 parent a164ef2 commit a5ff746
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 4 deletions.
17 changes: 14 additions & 3 deletions src/home/room_screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,8 @@ impl Widget for RoomScreen {

// Handle events and actions at the RoomScreen level.
fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope){
let pane = self.user_profile_sliding_pane(id!(user_profile_sliding_pane));

if let Event::Actions(actions) = event {
// Handle the send message button being clicked.
if self.button(id!(send_message_button)).clicked(&actions) {
Expand Down Expand Up @@ -584,7 +586,6 @@ impl Widget for RoomScreen {
for action in actions {
// Handle the action that requests to show the user profile sliding pane.
if let ShowUserProfileAction::ShowUserProfile(avatar_info) = action.as_widget_action().cast() {
let pane = self.user_profile_sliding_pane(id!(user_profile_sliding_pane));
pane.set_info(UserProfileInfo {
avatar_info,
room_name: self.room_name.clone(),
Expand All @@ -596,10 +597,20 @@ impl Widget for RoomScreen {
}
}
}
// Forward the event to the inner view, and thus, the inner timeline.
self.view.handle_event(cx, event, scope)

// Only forward visibility-related events (touch/tap/scroll) to the inner timeline view
// if the user profile sliding pane is not visible.
if event.requires_visibility() && pane.is_currently_shown(cx) {
// Forward the event to the user profile sliding pane,
// preventing the underlying timeline view from receiving it.
pane.handle_event(cx, event, scope);
} else {
// Forward the event to the inner timeline view.
self.view.handle_event(cx, event, scope);
}
}
}

impl RoomScreenRef {
/// Sets this `RoomScreen` widget to display the timeline for the given room.
pub fn set_displayed_room(&self, room_name: String, room_id: OwnedRoomId) {
Expand Down
12 changes: 11 additions & 1 deletion src/profile/user_profile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ live_design! {
width: Fill, height: Fit
padding: {left: 15}
draw_text: {
wrap: Line,
wrap: Word,
text_style: <USERNAME_TEXT_STYLE>{},
color: #000
}
Expand Down Expand Up @@ -427,6 +427,14 @@ impl Widget for UserProfileSlidingPane {
}

impl UserProfileSlidingPaneRef {
/// Returns `true` if the pane is both currently visible *and*
/// animator is in the `show` state.
pub fn is_currently_shown(&self, cx: &mut Cx) -> bool {
self.borrow().map_or(false, |inner|
inner.visible && inner.animator_in_state(cx, id!(panel.show))
)
}

pub fn set_info(&self, info: UserProfileInfo) {
if let Some(mut inner) = self.borrow_mut() {
inner.info = Some(info);
Expand All @@ -441,4 +449,6 @@ impl UserProfileSlidingPaneRef {
inner.redraw(cx);
}
}


}

0 comments on commit a5ff746

Please sign in to comment.