Skip to content

Commit 88252db

Browse files
committed
added assertion for saving room panel
1 parent ff9068a commit 88252db

File tree

6 files changed

+52
-89
lines changed

6 files changed

+52
-89
lines changed

src/app.rs

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -371,14 +371,21 @@ impl AppMain for App {
371371
}
372372
if let Event::WindowClosed(_) | Event::Shutdown = event {
373373
if let Some(window_geom) = &self.app_state.window_geom {
374-
if let Err(e) = save_window_state(window_geom) {
375-
log!("Bug! Failed to save window_state: {}", e);
376-
}
374+
let window_geom = window_geom.clone();
375+
cx.spawn_thread(move || {
376+
if let Err(e) = save_window_state(window_geom) {
377+
error!("Bug! Failed to save window_state: {}", e);
378+
}
379+
});
377380
}
378381
if let Some(user_id) = current_user_id(){
379-
if let Err(e) = save_room_panel(&self.app_state.rooms_panel, &user_id) {
380-
log!("Bug! Failed to save room panel: {}", e);
381-
}
382+
let rooms_panel = self.app_state.rooms_panel.clone();
383+
let user_id = user_id.clone();
384+
cx.spawn_thread(move || {
385+
if let Err(e) = save_room_panel(rooms_panel, user_id) {
386+
error!("Bug! Failed to save room panel: {}", e);
387+
}
388+
});
382389
}
383390
}
384391
// Forward events to the MatchEvent trait implementation.
@@ -491,11 +498,6 @@ pub enum RoomsPanelRestoreAction {
491498
/// and is now ready to be restored to the dock UI widget.
492499
/// This will be handled by the top-level App and by each RoomScreen in the dock.
493500
Restore(RoomsPanelState),
494-
/// The given room has not yet been loaded from the homeserver
495-
/// and is waiting to be known by our client so that it can be displayed.
496-
/// Each RoomScreen widget will handle and update its own status
497-
/// to be pending, and should thus display a loading spinner / notice.
498-
Pending(OwnedRoomId),
499501
/// The given room was successfully loaded from the homeserver
500502
/// and is known to our client.
501503
/// The RoomScreen for this room can now fully display the room's timeline.

src/home/main_desktop_ui.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,6 @@ pub struct MainDesktopUI {
8484

8585
impl Widget for MainDesktopUI {
8686
fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
87-
8887
let dock = self.view.dock(id!(dock));
8988
if let Event::Actions(actions) = event {
9089
for action in actions {
@@ -94,24 +93,23 @@ impl Widget for MainDesktopUI {
9493
self.room_order = app_state.rooms_panel.room_order.clone();
9594
self.most_recently_selected_room = app_state.rooms_panel.selected_room.clone();
9695
self.open_rooms = HashMap::with_capacity(app_state.rooms_panel.open_rooms.len());
97-
for (k, v) in app_state.rooms_panel.open_rooms.iter() {
98-
self.open_rooms.insert(LiveId(*k), v.clone());
99-
}
10096
if app_state.rooms_panel.dock_state.is_empty() {
10197
return;
10298
}
10399

104100
if let Some(mut dock) = dock.borrow_mut() {
105101
dock.load_state(cx, app_state.rooms_panel.dock_state.clone());
106-
dock.items().iter().for_each(|(head_liveid, (_, widget))| {
102+
dock.items().iter().for_each(|(tab_id, (_, widget))| {
107103
if let Some(room) =
108-
app_state.rooms_panel.open_rooms.get(&head_liveid.0)
104+
app_state.rooms_panel.open_rooms.get(&tab_id.0)
109105
{
110106
widget.as_room_screen().set_displayed_room(
111107
cx,
112108
room.room_id.clone(),
113109
room.room_name.clone().unwrap_or_default(),
114110
);
111+
// Open rooms should not contain rooms that are not in the dock.
112+
self.open_rooms.insert(LiveId(tab_id.0), room.clone());
115113
}
116114
});
117115
} else {
@@ -337,11 +335,11 @@ impl MatchEvent for MainDesktopUI {
337335
/// or one of the RoomScreen widgets.
338336
#[derive(Clone, DefaultNone, Debug)]
339337
pub enum RoomsPanelAction {
338+
None,
340339
/// Notifies that a room was focused.
341340
RoomFocused(SelectedRoom),
342341
/// Resets the focus to none, meaning that no room has focus.
343342
FocusNone,
344-
None,
345343
}
346344

347345
/// Actions related to saving/restoring the UI state of the dock widget.

src/home/room_screen.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,18 +1052,14 @@ impl Widget for RoomScreen {
10521052

10531053
for action in actions {
10541054
// Handle actions related to restoring the previously-saved state of rooms.
1055-
match action.downcast_ref() {
1056-
Some(RoomsPanelRestoreAction::Success(room_id)) => {
1057-
if self.room_id.as_ref().is_some_and(|r| r == room_id) {
1058-
// Reset room_id before displaying room.
1059-
self.room_id = None;
1060-
self.set_displayed_room(cx, room_id.clone(), self.room_name.clone());
1061-
self.view
1062-
.label(id!(restore_status_label)).set_text(cx, "");
1063-
return;
1064-
}
1055+
if let Some(RoomsPanelRestoreAction::Success(room_id)) = action.downcast_ref() {
1056+
if self.room_id.as_ref().is_some_and(|r| r == room_id) {
1057+
// Reset room_id before displaying room.
1058+
self.room_id = None;
1059+
self.set_displayed_room(cx, room_id.clone(), self.room_name.clone());
1060+
self.view.label(id!(restore_status_label)).set_text(cx, "");
1061+
return;
10651062
}
1066-
_ => {}
10671063
}
10681064
// Handle the highlight animation.
10691065
let Some(tl) = self.tl_state.as_mut() else { continue };

src/home/rooms_list.rs

Lines changed: 9 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -251,13 +251,18 @@ pub struct RoomsList {
251251
}
252252

253253
impl RoomsList {
254+
254255
/// Determines if all known rooms have been loaded.
255256
///
256-
/// Returns `true` if the number of rooms in `all_rooms` equals or exceeds
257+
/// Returns `true` if the number of rooms in `all_joined_rooms` and `invited_rooms` equals or exceeds
257258
/// `max_known_rooms`, or `false` if `max_known_rooms` is `None`.
258-
259-
fn all_known_rooms_loaded(&self) -> bool {
260-
self.max_known_rooms.map_or(false, |max_rooms| self.all_rooms.len() >= max_rooms as usize)
259+
pub fn all_known_rooms_loaded(&self) -> bool {
260+
self.max_known_rooms.is_some_and(|max_rooms| self.all_joined_rooms.len() + self.invited_rooms.len() >= max_rooms as usize)
261+
}
262+
/// Returns `true` if the given `room_id` is already in the `all_joined_rooms` and `invited_rooms` lists.
263+
/// and `false` if it is not.
264+
pub fn is_room_loaded(&self, room_id: &OwnedRoomId) -> bool {
265+
self.all_joined_rooms.contains_key(room_id) || self.invited_rooms.contains_key(room_id)
261266
}
262267
/// Handle all pending updates to the list of all rooms.
263268
fn handle_rooms_list_updates(&mut self, cx: &mut Cx, _event: &Event, _scope: &mut Scope) {
@@ -662,57 +667,6 @@ impl Widget for RoomsList {
662667

663668
}
664669

665-
impl WidgetMatchEvent for RoomsList {
666-
fn handle_actions(&mut self, cx: &mut Cx, actions: &Actions, _scope: &mut Scope) {
667-
for action in actions {
668-
if let RoomsViewAction::Search(keywords) = action.as_widget_action().cast() {
669-
let portal_list = self.view.portal_list(id!(list));
670-
if keywords.is_empty() {
671-
// Reset the displayed rooms list to show all rooms.
672-
self.display_filter = RoomDisplayFilter::default();
673-
self.displayed_rooms = self.all_rooms.keys().cloned().collect();
674-
self.update_status_rooms_count();
675-
portal_list.set_first_id_and_scroll(0, 0.0);
676-
self.redraw(cx);
677-
return;
678-
}
679-
680-
let (filter, sort_fn) = RoomDisplayFilterBuilder::new()
681-
.set_keywords(keywords.clone())
682-
.set_filter_criteria(RoomFilterCriteria::All)
683-
.build();
684-
self.display_filter = filter;
685-
686-
let new_displayed_rooms = if let Some(sort_fn) = sort_fn {
687-
let mut filtered_rooms: Vec<_> = self.all_rooms
688-
.iter()
689-
.filter(|(_, room)| (self.display_filter)(room))
690-
.collect();
691-
692-
filtered_rooms.sort_by(|(_, room_a), (_, room_b)| sort_fn(room_a, room_b));
693-
694-
filtered_rooms
695-
.into_iter()
696-
.map(|(room_id, _)| room_id.clone())
697-
.collect()
698-
} else {
699-
self.all_rooms
700-
.iter()
701-
.filter(|(_, room)| (self.display_filter)(room))
702-
.map(|(room_id, _)| room_id.clone())
703-
.collect()
704-
};
705-
706-
// Update the displayed rooms list and redraw it.
707-
self.displayed_rooms = new_displayed_rooms;
708-
self.update_status_matching_rooms();
709-
portal_list.set_first_id_and_scroll(0, 0.0);
710-
self.redraw(cx);
711-
}
712-
}
713-
}
714-
}
715-
716670
impl RoomsListRef {
717671
/// See [`RoomsList::all_known_rooms_loaded()`].
718672
pub fn all_known_rooms_loaded(

src/persistent_state.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -195,22 +195,25 @@ pub async fn save_session(
195195

196196
/// Save the current display state of the room panel to persistent storage.
197197
pub fn save_room_panel(
198-
rooms_panel_state: &RoomsPanelState,
199-
user_id: &UserId,
198+
rooms_panel_state: RoomsPanelState,
199+
user_id: OwnedUserId,
200200
) -> anyhow::Result<()> {
201201
std::fs::write(
202-
persistent_state_dir(user_id).join(LATEST_DOCK_STATE_FILE_NAME),
202+
persistent_state_dir(&user_id).join(LATEST_DOCK_STATE_FILE_NAME),
203203
rooms_panel_state.dock_state.serialize_ron(),
204204
)?;
205+
for (tab_id, room) in &rooms_panel_state.open_rooms {
206+
assert!(rooms_panel_state.dock_state.contains_key(&LiveId(*tab_id)), "Open room id: {} not found in dock state", &room.room_id);
207+
}
205208
std::fs::write(
206-
persistent_state_dir(user_id).join(ROOMS_PANEL_STATE_FILE_NAME),
209+
persistent_state_dir(&user_id).join(ROOMS_PANEL_STATE_FILE_NAME),
207210
serde_json::to_string(&rooms_panel_state)?,
208211
)?;
209212
Ok(())
210213
}
211214

212215
/// Save the current state of window geometry state to persistent storage.
213-
pub fn save_window_state(window_geom: &WindowGeom) -> anyhow::Result<()> {
216+
pub fn save_window_state(window_geom: WindowGeom) -> anyhow::Result<()> {
214217
let window_geom_state = WindowGeomState {
215218
window_is_fullscreen: window_geom.is_fullscreen,
216219
window_position: crate::utils::DVec2Wrapper(window_geom.position),

src/sliding_sync.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,6 +1796,11 @@ fn handle_ignore_user_list_subscriber(client: Client) {
17961796
});
17971797
}
17981798

1799+
/// Asynchronously loads and restores the rooms panel state from persistent storage for the given user.
1800+
///
1801+
/// If the loaded state contains open rooms and dock state, it logs a message and posts an action
1802+
/// to restore the rooms panel state in the UI. If loading fails, it enqueues a notification
1803+
/// with the error message.
17991804
fn handle_load_rooms_panel_state(user_id: OwnedUserId) {
18001805
Handle::current().spawn(async move {
18011806
match load_rooms_panel_state(&user_id).await {
@@ -1814,6 +1819,11 @@ fn handle_load_rooms_panel_state(user_id: OwnedUserId) {
18141819
});
18151820
}
18161821

1822+
/// Asynchronously loads and restores the window geometry state from persistent storage.
1823+
///
1824+
/// If the loaded state is different from the default, it posts an action to restore
1825+
/// the window's geometry in the UI. If loading fails, it enqueues a notification
1826+
/// with the error message.
18171827
fn handle_load_window_state() {
18181828
Handle::current().spawn(async move {
18191829
match load_window_state().await {

0 commit comments

Comments
 (0)