Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 31 additions & 16 deletions src/home/invite_screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::ops::Deref;
use makepad_widgets::*;
use matrix_sdk::ruma::OwnedRoomId;

use crate::{app::AppStateAction, home::rooms_list::RoomsListRef, join_leave_room_modal::{JoinLeaveModalKind, JoinLeaveRoomModalAction}, room::{BasicRoomDetails, FetchedRoomAvatar}, shared::{avatar::AvatarWidgetRefExt, popup_list::{enqueue_popup_notification, PopupItem, PopupKind}, restore_status_view::RestoreStatusViewWidgetExt}, sliding_sync::{submit_async_request, MatrixRequest}, utils::{self, RoomNameId}};
use crate::{app::AppStateAction, home::rooms_list::RoomsListRef, join_leave_room_modal::{JoinLeaveModalKind, JoinLeaveRoomModalAction}, room::{BasicRoomDetails, FetchedRoomAvatar, loading_screen::RoomLoadingScreenWidgetExt}, shared::{avatar::AvatarWidgetRefExt, popup_list::{PopupItem, PopupKind, enqueue_popup_notification}}, sliding_sync::{MatrixRequest, submit_async_request}, utils::{self, RoomNameId}};

use super::rooms_list::{InviteState, InviterInfo};

Expand All @@ -22,7 +22,7 @@ live_design! {
use crate::shared::styles::*;
use crate::shared::avatar::*;
use crate::shared::icon_button::*;
use crate::shared::restore_status_view::*;
use crate::room::loading_screen::RoomLoadingScreen;

pub InviteScreen = {{InviteScreen}}<ScrollXYView> {
width: Fill,
Expand All @@ -36,7 +36,7 @@ live_design! {
draw_bg: {
color: (COLOR_PRIMARY_DARKER),
}
restore_status_view = <RestoreStatusView> {}
loading_screen = <RoomLoadingScreen> { visible: false }

// This view is only shown if `inviter` is Some.
inviter_view = <View> {
Expand Down Expand Up @@ -394,11 +394,14 @@ impl Widget for InviteScreen {

fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep {
if !self.is_loaded {
let mut restore_status_view = self.view.restore_status_view(ids!(restore_status_view));
if let Some(room_name) = &self.room_name_id {
restore_status_view.set_content(cx, self.all_rooms_loaded, room_name);
}
return restore_status_view.draw(cx, scope);
let mut loading_screen = self.view.room_loading_screen(ids!(loading_screen));
let (title, details) = if let Some(room_name) = &self.room_name_id {
self.loading_screen_content(room_name)
} else {
("Loading...".to_string(), None)
};
loading_screen.show(cx, Some(&title), details.as_deref());
return loading_screen.draw(cx, scope);
}
let Some(info) = self.info.as_ref() else {
// If we don't have any info, just return.
Expand Down Expand Up @@ -534,16 +537,28 @@ impl InviteScreen {
self.redraw(cx);
}

let restore_status_view = self.view.restore_status_view(ids!(restore_status_view));
let loading_screen = self.view.room_loading_screen(ids!(loading_screen));
if !self.is_loaded {
restore_status_view.set_content(
cx,
self.all_rooms_loaded,
room_name_id,
);
restore_status_view.set_visible(cx, true);
let (title, details) = self.loading_screen_content(room_name_id);
loading_screen.show(cx, Some(&title), details.as_deref());
} else {
loading_screen.hide(cx);
}
}

fn loading_screen_content(&self, room_name: &RoomNameId) -> (String, Option<String>) {
if self.all_rooms_loaded {
(
format!(
"Room {room_name} was not found in the homeserver's list of all rooms."
),
Some("You may close this screen.".to_owned()),
)
} else {
restore_status_view.set_visible(cx, false);
(
"Waiting for this room to be loaded from the homeserver".to_owned(),
None,
)
}
}
}
Expand Down
71 changes: 70 additions & 1 deletion src/home/main_desktop_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use ruma::OwnedRoomId;
use tokio::sync::Notify;
use std::{collections::HashMap, sync::Arc};

use crate::{app::{AppState, AppStateAction, SavedDockState, SelectedRoom}, home::{navigation_tab_bar::{NavigationBarAction, SelectedTab}, rooms_list::RoomsListRef, space_lobby::SpaceLobbyScreenWidgetRefExt}, utils::RoomNameId};
use crate::{app::{AppState, AppStateAction, SavedDockState, SelectedRoom}, home::{navigation_tab_bar::{NavigationBarAction, SelectedTab}, rooms_list::RoomsListRef, space_lobby::SpaceLobbyScreenWidgetRefExt}, room::loading_screen::{RoomLoadingScreenAction, RoomLoadingScreenWidgetRefExt, get_room_loading_screen_actions, loading_tab_live_id}, utils::RoomNameId};
use super::{invite_screen::InviteScreenWidgetRefExt, room_screen::RoomScreenWidgetRefExt, rooms_list::RoomsListAction};

live_design! {
Expand All @@ -18,6 +18,7 @@ live_design! {
use crate::home::room_screen::RoomScreen;
use crate::home::invite_screen::InviteScreen;
use crate::home::space_lobby::SpaceLobbyScreen;
use crate::room::loading_screen::RoomLoadingScreen;

pub MainDesktopUI = {{MainDesktopUI}} {
dock = <Dock> {
Expand Down Expand Up @@ -59,6 +60,7 @@ live_design! {
room_screen = <RoomScreen> {}
invite_screen = <InviteScreen> {}
space_lobby_screen = <SpaceLobbyScreen> {}
loading_screen = <RoomLoadingScreen> { visible: true }
}
}
}
Expand All @@ -77,6 +79,9 @@ pub struct MainDesktopUI {
#[rust]
open_rooms: HashMap<LiveId, SelectedRoom>,

#[rust]
loading_tabs: HashMap<LiveId, (Option<String>, Option<String>)>,

/// The tab that should be closed in the next draw event
#[rust]
tab_to_close: Option<LiveId>,
Expand Down Expand Up @@ -114,6 +119,19 @@ impl LiveHook for MainDesktopUI {

impl Widget for MainDesktopUI {
fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
if let Event::Signal = event {
for action in get_room_loading_screen_actions() {
match action {
RoomLoadingScreenAction::ShowTab { tab_id, tab_name, title, details } => {
self.show_loading_tab(cx, tab_id, &tab_name, title.as_deref(), details.as_deref());
}
RoomLoadingScreenAction::HideTab { tab_id } => {
self.close_loading_tab(cx, tab_id);
}
}
}
}

self.widget_match_event(cx, event, scope); // invokes `WidgetMatchEvent` impl
self.view.handle_event(cx, event, scope);
}
Expand Down Expand Up @@ -143,6 +161,11 @@ impl MainDesktopUI {

let dock = self.view.dock(ids!(dock));

let loading_id = loading_tab_live_id(room.room_id().as_str());
if self.loading_tabs.remove(&loading_id).is_some() {
dock.close_tab(cx, loading_id);
}

// If the room is already open, select (jump to) its existing tab
let room_id_as_live_id = LiveId::from_str(room.room_id().as_str());
if self.open_rooms.contains_key(&room_id_as_live_id) {
Expand Down Expand Up @@ -389,6 +412,52 @@ impl MainDesktopUI {
app_state.selected_room = selected_room;
self.redraw(cx);
}

fn show_loading_tab(&mut self, cx: &mut Cx, tab_id: LiveId, tab_name: &str, title: Option<&str>, details: Option<&str>) {
let dock_ref = self.view.dock(ids!(dock));

// If the tab already exists and is a loading tab, just update it and select it.
let mut should_select_existing = false;
if let Some(mut dock) = dock_ref.borrow_mut() {
if let Some((_, widget)) = dock.items().get(&tab_id) {
widget.as_room_loading_screen().show(cx, title, details);
self.loading_tabs.insert(tab_id, (title.map(str::to_owned), details.map(str::to_owned)));
should_select_existing = true;
}
}

if should_select_existing {
dock_ref.select_tab(cx, tab_id);
return;
}

// Otherwise, create a new loading tab at the end.
let (tab_bar, _pos) = dock_ref.find_tab_bar_of_tab(id!(home_tab)).unwrap();
let new_tab_widget = dock_ref.create_and_select_tab(
cx,
tab_bar,
tab_id,
id!(loading_screen),
tab_name.to_string(),
id!(CloseableTab),
None,
);

if let Some(widget) = new_tab_widget {
widget.as_room_loading_screen().show(cx, title, details);
self.loading_tabs.insert(tab_id, (title.map(str::to_owned), details.map(str::to_owned)));
dock_ref.select_tab(cx, tab_id);
} else {
error!("BUG: failed to create loading tab for {tab_name}");
}

}

fn close_loading_tab(&mut self, cx: &mut Cx, tab_id: LiveId) {
if self.loading_tabs.remove(&tab_id).is_some() {
self.view.dock(ids!(dock)).close_tab(cx, tab_id);
}
}
}

impl WidgetMatchEvent for MainDesktopUI {
Expand Down
49 changes: 40 additions & 9 deletions src/home/room_screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ use crate::{
user_profile::{ShowUserProfileAction, UserProfile, UserProfileAndRoomId, UserProfilePaneInfo, UserProfileSlidingPaneRef, UserProfileSlidingPaneWidgetExt},
user_profile_cache,
},
room::{BasicRoomDetails, room_input_bar::RoomInputBarState, typing_notice::TypingNoticeWidgetExt},
room::{BasicRoomDetails, loading_screen::RoomLoadingScreenWidgetExt, room_input_bar::RoomInputBarState, typing_notice::TypingNoticeWidgetExt},
shared::{
avatar::{AvatarState, AvatarWidgetRefExt}, callout_tooltip::{CalloutTooltipOptions, TooltipAction, TooltipPosition}, confirmation_modal::ConfirmationModalContent, html_or_plaintext::{HtmlOrPlaintextRef, HtmlOrPlaintextWidgetRefExt, RobrixHtmlLinkAction}, image_viewer::{ImageViewerAction, ImageViewerMetaData, LoadState}, jump_to_bottom_button::{JumpToBottomButtonWidgetExt, UnreadMessageCount}, popup_list::{PopupItem, PopupKind, enqueue_popup_notification}, restore_status_view::RestoreStatusViewWidgetExt, styles::*, text_or_image::{TextOrImageAction, TextOrImageRef, TextOrImageWidgetRefExt}, timestamp::TimestampWidgetRefExt
avatar::{AvatarState, AvatarWidgetRefExt}, callout_tooltip::{CalloutTooltipOptions, TooltipAction, TooltipPosition}, confirmation_modal::ConfirmationModalContent, html_or_plaintext::{HtmlOrPlaintextRef, HtmlOrPlaintextWidgetRefExt, RobrixHtmlLinkAction}, image_viewer::{ImageViewerAction, ImageViewerMetaData, LoadState}, jump_to_bottom_button::{JumpToBottomButtonWidgetExt, UnreadMessageCount}, popup_list::{PopupItem, PopupKind, enqueue_popup_notification}, styles::*, text_or_image::{TextOrImageAction, TextOrImageRef, TextOrImageWidgetRefExt}, timestamp::TimestampWidgetRefExt
},
sliding_sync::{BackwardsPaginateUntilEventRequest, MatrixRequest, PaginationDirection, TimelineEndpoints, TimelineRequestSender, UserPowerLevels, get_client, submit_async_request, take_timeline_endpoints}, utils::{self, ImageFormat, MEDIA_THUMBNAIL_FORMAT, RoomNameId, unix_time_millis_to_datetime}
};
Expand Down Expand Up @@ -78,7 +78,7 @@ live_design! {
use crate::room::typing_notice::*;
use crate::home::room_read_receipt::*;
use crate::rooms_list::*;
use crate::shared::restore_status_view::*;
use crate::room::loading_screen::RoomLoadingScreen;
use crate::home::link_preview::LinkPreview;
use link::tsp_link::TspSignIndicator;

Expand Down Expand Up @@ -516,7 +516,7 @@ live_design! {
color: (COLOR_PRIMARY_DARKER)
}

restore_status_view = <RestoreStatusView> {}
loading_screen = <RoomLoadingScreen> { visible: false }

// Widgets within this view will get shifted upwards when the on-screen keyboard is shown.
keyboard_view = <KeyboardView> {
Expand Down Expand Up @@ -976,15 +976,16 @@ impl Widget for RoomScreen {


fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep {
// If the room isn't loaded yet, we show the restore status label only.
// If the room isn't loaded yet, we show the loading screen only.
if !self.is_loaded {
let Some(room_name) = &self.room_name_id else {
// No room selected yet, nothing to show.
return DrawStep::done();
};
let mut restore_status_view = self.view.restore_status_view(ids!(restore_status_view));
restore_status_view.set_content(cx, self.all_rooms_loaded, room_name);
return restore_status_view.draw(cx, scope);
let mut loading_screen = self.view.room_loading_screen(ids!(loading_screen));
let (title, details) = self.loading_screen_content(room_name);
loading_screen.show(cx, Some(&title), details.as_deref());
return loading_screen.draw(cx, scope);
}
if self.tl_state.is_none() {
// Tl_state may not be ready after dock loading.
Expand Down Expand Up @@ -1166,6 +1167,36 @@ impl RoomScreen {
self.room_name_id.as_ref().map(|r| r.room_id())
}

fn loading_screen_content(&self, room_name: &RoomNameId) -> (String, Option<String>) {
if self.all_rooms_loaded {
(
format!(
"Room {room_name} was not found in the homeserver's list of all rooms."
),
Some("You may close this screen.".to_owned()),
)
} else {
(
"Waiting for this room to be loaded from the homeserver".to_owned(),
None,
)
}
}

fn update_loading_screen(&mut self, cx: &mut Cx) {
let loading_screen = self.view.room_loading_screen(ids!(loading_screen));
if self.is_loaded {
loading_screen.hide(cx);
return;
}
let Some(room_name) = &self.room_name_id else {
loading_screen.hide(cx);
return;
};
let (title, details) = self.loading_screen_content(room_name);
loading_screen.show(cx, Some(&title), details.as_deref());
}

/// Processes all pending background updates to the currently-shown timeline.
///
/// Redraws this RoomScreen view if any updates were applied.
Expand Down Expand Up @@ -2154,7 +2185,7 @@ impl RoomScreen {
self.is_loaded = is_loaded_now;
}

self.view.restore_status_view(ids!(restore_status_view)).set_visible(cx, !self.is_loaded);
self.update_loading_screen(cx);

// Kick off a back pagination request if it's the first time loading this room,
// because we want to show the user some messages as soon as possible
Expand Down
12 changes: 11 additions & 1 deletion src/home/space_lobby.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use matrix_sdk_ui::spaces::SpaceRoom;
use ruma::room::JoinRuleSummary;
use tokio::sync::mpsc::UnboundedSender;
use crate::{
home::rooms_list::RoomsListRef, shared::avatar::{AvatarState, AvatarWidgetExt, AvatarWidgetRefExt}, space_service_sync::{SpaceRequest, SpaceRoomExt, SpaceRoomListAction}, utils::{self, RoomNameId}
home::rooms_list::RoomsListRef, room::loading_screen::RoomLoadingScreenWidgetExt, shared::avatar::{AvatarState, AvatarWidgetExt, AvatarWidgetRefExt}, space_service_sync::{SpaceRequest, SpaceRoomExt, SpaceRoomListAction}, utils::{self, RoomNameId}
};


Expand All @@ -26,6 +26,7 @@ live_design! {
use crate::shared::styles::*;
use crate::shared::helpers::*;
use crate::shared::avatar::*;
use crate::room::loading_screen::RoomLoadingScreen;

ICON_COLLAPSE = dep("crate://self/resources/icons/triangle_fill.svg")

Expand Down Expand Up @@ -378,6 +379,8 @@ live_design! {
color: #fff
}

loading_screen = <RoomLoadingScreen> { visible: false }

// Header with parent space info
header = <View> {
width: Fill,
Expand Down Expand Up @@ -739,6 +742,13 @@ impl Widget for SpaceLobbyScreen {
}

fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep {
if self.is_loading {
let mut loading_screen = self.view.room_loading_screen(ids!(loading_screen));
loading_screen.show(cx, Some("Loading rooms and spaces..."), None);
return loading_screen.draw(cx, scope);
}
self.view.room_loading_screen(ids!(loading_screen)).hide(cx);

while let Some(widget_to_draw) = self.view.draw_walk(cx, scope, walk).step() {
let portal_list_ref = widget_to_draw.as_portal_list();
let Some(mut list) = portal_list_ref.borrow_mut() else { continue };
Expand Down
Loading