diff --git a/src/app.rs b/src/app.rs index 1c6afec4..5f44fdee 100644 --- a/src/app.rs +++ b/src/app.rs @@ -378,14 +378,12 @@ impl MatchEvent for App { // Handle the user selecting a room to view (a RoomPreview in the RoomsList). if let RoomListAction::Selected { room_index: _, room_id, room_name } = action.as_widget_action().cast() { // Set the title of the RoomScreen's header to the room name. - stack_navigation.set_title( - live_id!(rooms_stack_view), - &room_name.unwrap_or_else(|| format!("Room {}", &room_id)), - ); + let displayed_room_name = room_name.unwrap_or_else(|| format!("Room ID {}", &room_id)); + stack_navigation.set_title(live_id!(rooms_stack_view), &displayed_room_name); // Get a reference to the `RoomScreen` widget and tell it which room's data to show. stack_navigation .room_screen(id!(rooms_stack_view.room_screen)) - .set_displayed_room(room_id); + .set_displayed_room(displayed_room_name, room_id); } } } diff --git a/src/home/room_screen.rs b/src/home/room_screen.rs index 181e8b5f..002f4c80 100644 --- a/src/home/room_screen.rs +++ b/src/home/room_screen.rs @@ -19,10 +19,9 @@ use matrix_sdk_ui::timeline::{ }; use rangemap::RangeSet; -use unicode_segmentation::UnicodeSegmentation; use crate::{ media_cache::{MediaCache, MediaCacheEntry, AVATAR_CACHE}, - profile::user_profile::{ShowUserProfileAction, UserProfileSlidingPaneWidgetExt}, + profile::user_profile::{ShowUserProfileAction, UserProfileInfo, UserProfileSlidingPaneWidgetExt}, shared::{avatar::{AvatarRef, AvatarWidgetRefExt}, html_or_plaintext::HtmlOrPlaintextWidgetRefExt, text_or_image::TextOrImageWidgetRefExt}, sliding_sync::{submit_async_request, take_timeline_update_receiver, MatrixRequest}, utils::{self, unix_time_millis_to_datetime, MediaFormatConst}, @@ -549,6 +548,7 @@ live_design! { struct RoomScreen { #[deref] view: View, #[rust] room_id: Option, + #[rust] room_name: String, } impl Widget for RoomScreen { fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep { @@ -583,9 +583,12 @@ impl Widget for RoomScreen { for action in actions { // Handle the action that requests to show the user profile sliding pane. - if let ShowUserProfileAction::ShowUserProfile(room_id, user_id) = action.as_widget_action().cast() { + 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(room_id, user_id); + pane.set_info(UserProfileInfo { + avatar_info, + room_name: self.room_name.clone(), + }); pane.show(cx); // TODO: Hack for error that when you first open the modal, doesnt draw until an event // this forces the entire ui to rerender, still weird that only happens the first time. @@ -599,8 +602,9 @@ impl Widget for RoomScreen { } impl RoomScreenRef { /// Sets this `RoomScreen` widget to display the timeline for the given room. - pub fn set_displayed_room(&self, room_id: OwnedRoomId) { + pub fn set_displayed_room(&self, room_name: String, room_id: OwnedRoomId) { let Some(mut room_screen) = self.borrow_mut() else { return }; + room_screen.room_name = room_name; room_screen.room_id = Some(room_id.clone()); room_screen.timeline(id!(timeline)).set_room(room_id); } @@ -1689,19 +1693,6 @@ fn set_avatar_and_get_username( let user_id = event_tl_item.sender(); - // A closure to set the item's avatar to text data, - // skipping the first `skip` characters of the given `name`. - let set_avatar_text = |name: &str, skip: usize| { - avatar.show_text( - Some((room_id.to_owned(), user_id.to_owned())), - name.graphemes(true) - .skip(skip) - .next() - .map(ToString::to_string) - .unwrap_or_default() - ); - }; - // Set sender to the display name if available, otherwise the user id. match event_tl_item.sender_profile() { TimelineDetails::Ready(profile) => { @@ -1725,29 +1716,33 @@ fn set_avatar_and_get_username( }; // Set the username to the display name if available, otherwise the user ID after the '@'. - let (skip, un) = if let Some(dn) = profile.display_name.as_ref() { - (0, dn.to_owned()) - } else { - (1, user_id.to_string()) - }; - username = un; + username = profile.display_name + .as_ref() + .cloned() + .unwrap_or_else(|| user_id.to_string()); // Draw the avatar image if available, otherwise set the avatar to text. let drew_avatar_img = avatar_img.map(|data| avatar.show_image( - Some((room_id.to_owned(), user_id.to_owned())), + Some((username.clone(), user_id.to_owned(), room_id.to_owned(), data.clone())), |img| utils::load_png_or_jpg(&img, cx, &data) ).is_ok() ).unwrap_or(false); if !drew_avatar_img { - set_avatar_text(&username, skip); + avatar.show_text( + Some((user_id.to_owned(), room_id.to_owned())), + username.clone(), + ); } } other => { // log!("populate_message_view(): sender profile not ready yet for event {_other:?}"); username = user_id.to_string(); - set_avatar_text(&username, 1); + avatar.show_text( + Some((user_id.to_owned(), room_id.to_owned())), + username.clone(), + ); // If there was an error fetching the profile, treat that condition as fully drawn, // since we don't yet have a good way to re-request profile information. profile_drawn = matches!(other, TimelineDetails::Error(_)); diff --git a/src/home/rooms_list.rs b/src/home/rooms_list.rs index 263536b4..cfd4df51 100644 --- a/src/home/rooms_list.rs +++ b/src/home/rooms_list.rs @@ -351,7 +351,7 @@ impl Widget for RoomsList { } RoomPreviewAvatar::Image(ref img_bytes) => { let _ = item.avatar(id!(avatar)).show_image( - None, + None, // don't make room preview avatars clickable. |img| utils::load_png_or_jpg(&img, cx, img_bytes) ); } diff --git a/src/profile/user_profile.rs b/src/profile/user_profile.rs index 16261f7b..62d2cb7c 100644 --- a/src/profile/user_profile.rs +++ b/src/profile/user_profile.rs @@ -1,5 +1,9 @@ +use std::ops::Deref; use makepad_widgets::*; -use matrix_sdk::ruma::{OwnedRoomId, OwnedUserId}; +use crate::{ + shared::avatar::{AvatarInfo, AvatarWidgetExt}, + utils, +}; live_design! { import makepad_draw::shader::std::*; @@ -27,7 +31,7 @@ live_design! { // Customized button widget, based on the RoundedView shaders with some modifications // which is a better fit with our application UI design MoxinButton =