Skip to content
Merged
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
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ These are generally sorted in order of priority. If you're interested in helping
- [ ] Collapsible/expandable view of contiguous "small" events: https://github.com/project-robius/robrix/issues/118
- [ ] Display multimedia (audio/video/gif) message events: https://github.com/project-robius/robrix/issues/120
- [x] User settings screen
- [ ] Dedicated view of spaces
- [x] Dedicated view of spaces: https://github.com/project-robius/robrix/pull/636
- [x] Link previews beneath messages: https://github.com/project-robius/robrix/issues/81, https://github.com/project-robius/robrix/pull/585
- [ ] Search messages within a room: https://github.com/project-robius/robrix/issues/122
- [ ] Room browser, search for public rooms
Expand All @@ -195,7 +195,7 @@ These are generally sorted in order of priority. If you're interested in helping
- [ ] Administrative abilities: ban, kick, etc
- [ ] Room creation/settings/info screen
- [ ] Room members pane
- [ ] Offline mode with persistent event cache: https://github.com/project-robius/robrix/pull/445
- [x] Offline mode with persistent event cache: https://github.com/project-robius/robrix/pull/445


## Packaging Robrix for Distribution on Desktop Platforms
Expand Down Expand Up @@ -270,4 +270,4 @@ You can immediately double-click the `Robrix.app` bundle to run it, or you can d
If you'd like to modify the .dmg background, here is the [Google Drawings file used to generate the MacOS .dmg background image](https://docs.google.com/drawings/d/10ALUgNV7v-4bRTIE5Wb2vNyXpl2Gj3YJcl7Q2AGpvDw/edit?usp=sharing).

## Credits
X logo: https://www.vecteezy.com/png/42148611-new-twitter-x-logo-twitter-icon-x-social-media-icon (shobumiah)
* X logo: https://www.vecteezy.com/png/42148611-new-twitter-x-logo-twitter-icon-x-social-media-icon (shobumiah)
49 changes: 49 additions & 0 deletions resources/icons/hierarchy.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
80 changes: 45 additions & 35 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,32 @@
//!
//! See `handle_startup()` for the first code that runs on app startup.

// Ignore clippy warnings in `DeRon` macro derive bodies.
#![allow(clippy::question_mark)]

use std::collections::HashMap;
use makepad_widgets::{makepad_micro_serde::*, *};
use makepad_widgets::*;
use matrix_sdk::ruma::{OwnedRoomId, RoomId};
use serde::{Deserialize, Serialize};
use crate::{
avatar_cache::clear_avatar_cache, home::{
main_desktop_ui::MainDesktopUiAction, new_message_context_menu::NewMessageContextMenuWidgetRefExt, room_screen::{clear_timeline_states, MessageAction}, rooms_list::{clear_all_invited_rooms, enqueue_rooms_list_update, RoomsListAction, RoomsListRef, RoomsListUpdate}
}, join_leave_room_modal::{
avatar_cache::clear_avatar_cache,
home::{
main_desktop_ui::MainDesktopUiAction, new_message_context_menu::NewMessageContextMenuWidgetRefExt, room_screen::{MessageAction, clear_timeline_states}, rooms_list::{RoomsListAction, RoomsListRef, RoomsListUpdate, clear_all_invited_rooms, enqueue_rooms_list_update}
},
join_leave_room_modal::{
JoinLeaveModalKind, JoinLeaveRoomModalAction, JoinLeaveRoomModalWidgetRefExt
}, login::login_screen::LoginAction, logout::logout_confirm_modal::{LogoutAction, LogoutConfirmModalAction, LogoutConfirmModalWidgetRefExt}, persistence, profile::user_profile_cache::clear_user_profile_cache, room::BasicRoomDetails, shared::callout_tooltip::{
},
login::login_screen::LoginAction,
logout::logout_confirm_modal::{LogoutAction, LogoutConfirmModalAction, LogoutConfirmModalWidgetRefExt},
persistence,
profile::user_profile_cache::clear_user_profile_cache,
room::BasicRoomDetails,
shared::callout_tooltip::{
CalloutTooltipWidgetRefExt,
TooltipAction,
}, sliding_sync::current_user_id, utils::RoomNameId, verification::VerificationAction, verification_modal::{
VerificationModalAction,
VerificationModalWidgetRefExt,
}
},
serialization::{LiveIdSerde, DockItemSerde},
sliding_sync::current_user_id,
utils::RoomNameId,
verification::VerificationAction,
verification_modal::{VerificationModalAction, VerificationModalWidgetRefExt},
};

live_design! {
Expand Down Expand Up @@ -533,11 +541,8 @@ impl App {
destination_room: &BasicRoomDetails,
) {
// A closure that closes the given `room_to_close`, if it exists in an open tab.
let close_room_closure_opt = room_to_close.and_then(|to_close|
self.app_state.saved_dock_state.open_rooms
.iter()
.find_map(|(tab_id, r)| (r.room_id() == to_close).then_some(*tab_id))
).map(|tab_id| {
let close_room_closure_opt = room_to_close.map(|to_close| {
let tab_id = LiveId::from_str(to_close.as_str());
let widget_uid = self.ui.widget_uid();
move |cx: &mut Cx| {
cx.widget_action(
Expand All @@ -549,9 +554,8 @@ impl App {
});

// If the successor room is not loaded, show a join modal.
let rooms_list_ref = cx.get_global::<RoomsListRef>();
let destination_room_id = destination_room.room_name_id.room_id();
if !rooms_list_ref.is_room_loaded(destination_room_id) {
if !cx.get_global::<RoomsListRef>().is_room_loaded(destination_room_id) {
log!("Destination room {} not loaded, showing join modal...", destination_room_id);
self.waiting_to_navigate_to_joined_room = Some((
destination_room.clone(),
Expand Down Expand Up @@ -590,54 +594,59 @@ impl App {

/// App-wide state that is stored persistently across multiple app runs
/// and shared/updated across various parts of the app.
#[derive(Clone, Default, Debug, DeRon, SerRon)]
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
pub struct AppState {
/// The currently-selected room, which is highlighted (selected) in the RoomsList
/// and considered "active" in the main rooms screen.
pub selected_room: Option<SelectedRoom>,
/// A saved "snapshot" of the dock's UI state.
pub saved_dock_state: SavedDockState,
/// The saved "snapshot" of the dock's UI layout/state for the main "all rooms" home view.
pub saved_dock_state_home: SavedDockState,
/// The saved "snapshot" of the dock's UI layout/state for each space,
/// keyed by the space ID.
pub saved_dock_state_per_space: HashMap<OwnedRoomId, SavedDockState>,
/// Whether a user is currently logged in to Robrix or not.
pub logged_in: bool,
}

/// A snapshot of the main dock: all state needed to restore the dock tabs/layout.
#[derive(Clone, Default, Debug, DeRon, SerRon)]
#[derive(Clone, Default, Debug, Serialize, Deserialize)]
pub struct SavedDockState {
/// All items contained in the dock, keyed by their LiveId.
pub dock_items: HashMap<LiveId, DockItem>,
/// The rooms that are currently open, keyed by the LiveId of their tab.
pub open_rooms: HashMap<LiveId, SelectedRoom>,
/// All items contained in the dock, keyed by their room or space ID.
pub dock_items: HashMap<LiveIdSerde, DockItemSerde>,
/// The rooms that are currently open, keyed by their room or space ID.
pub open_rooms: HashMap<LiveIdSerde, SelectedRoom>,
/// The order in which the rooms were opened, in chronological order
/// from first opened (at the beginning) to last opened (at the end).
pub room_order: Vec<SelectedRoom>,
/// The selected room tab in this dock when the dock state was saved.
pub selected_room: Option<SelectedRoom>,
}


/// Represents a room currently or previously selected by the user.
///
/// One `SelectedRoom` is considered equal to another if their `room_id`s are equal.
#[derive(Clone, Debug, SerRon, DeRon)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum SelectedRoom {
JoinedRoom {
room_name_id: RoomNameId,
},
InvitedRoom {
room_name_id: RoomNameId,
},
JoinedRoom { room_name_id: RoomNameId },
InvitedRoom { room_name_id: RoomNameId },
Space { space_name_id: RoomNameId },
}

impl SelectedRoom {
pub fn room_id(&self) -> &OwnedRoomId {
match self {
SelectedRoom::JoinedRoom { room_name_id } => room_name_id.room_id(),
SelectedRoom::InvitedRoom { room_name_id } => room_name_id.room_id(),
SelectedRoom::Space { space_name_id } => space_name_id.room_id(),
}
}

pub fn room_name(&self) -> &RoomNameId {
match self {
SelectedRoom::JoinedRoom { room_name_id } => room_name_id,
SelectedRoom::InvitedRoom { room_name_id } => room_name_id,
SelectedRoom::Space { space_name_id } => space_name_id,
}
}

Expand Down Expand Up @@ -679,7 +688,8 @@ pub enum AppStateAction {
/// The given room has successfully been upgraded from being displayed
/// as an InviteScreen to a RoomScreen.
UpgradedInviteToJoinedRoom(OwnedRoomId),
/// The app state was restored from persistent storage.
/// The given app state was loaded from persistent storage
/// and is ready to be restored.
RestoreAppStateFromPersistentState(AppState),
/// The given room was successfully loaded from the homeserver
/// and is now known to our client.
Expand Down
6 changes: 3 additions & 3 deletions src/home/home_screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,8 @@ impl Widget for HomeScreen {
self.view.redraw(cx);
}
}
Some(NavigationBarAction::GoToSpace { space_id }) => {
let new_space_selection = SelectedTab::Space { space_id: space_id.clone() };
Some(NavigationBarAction::GoToSpace { space_name_id }) => {
let new_space_selection = SelectedTab::Space { space_name_id: space_name_id.clone() };
if self.selection != new_space_selection {
self.previous_selection = self.selection.clone();
self.selection = new_space_selection;
Expand Down Expand Up @@ -395,7 +395,7 @@ impl HomeScreen {
SelectedTab::Home => id!(home_page),
SelectedTab::Settings => id!(settings_page),
SelectedTab::AddRoom => id!(add_room_page),
SelectedTab::Space { .. } => id!(home_page), // TODO: show the SpacesScreen
SelectedTab::Space { .. } => id!(home_page),
},
)
}
Expand Down
Loading