Skip to content
66 changes: 59 additions & 7 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ use std::collections::HashMap;
use makepad_widgets::{makepad_micro_serde::*, *};
use matrix_sdk::ruma::{OwnedRoomId, RoomId};
use crate::{
avatar_cache::clear_avatar_cache, home::{
avatar_cache::clear_avatar_cache,
register::register_screen::RegisterAction,
home::{
main_desktop_ui::MainDesktopUiAction,
new_message_context_menu::NewMessageContextMenuWidgetRefExt,
room_screen::{clear_timeline_states, MessageAction},
Expand Down Expand Up @@ -40,6 +42,7 @@ live_design! {
use crate::verification_modal::VerificationModal;
use crate::join_leave_room_modal::JoinLeaveRoomModal;
use crate::login::login_screen::LoginScreen;
use crate::register::register_screen::RegisterScreen;
use crate::logout::logout_confirm_modal::LogoutConfirmModal;
use crate::shared::popup_list::*;
use crate::home::new_message_context_menu::*;
Expand Down Expand Up @@ -99,7 +102,10 @@ live_design! {
visible: true
login_screen = <LoginScreen> {}
}

register_screen_view = <View> {
visible: false
register_screen = <RegisterScreen> {}
}
<PopupList> {}

// Context menus should be shown in front of other UI elements,
Expand Down Expand Up @@ -177,6 +183,7 @@ impl LiveRegister for App {
crate::home::live_design(cx);
crate::profile::live_design(cx);
crate::login::live_design(cx);
crate::register::live_design(cx);
crate::logout::live_design(cx);
}
}
Expand Down Expand Up @@ -249,11 +256,55 @@ impl MatchEvent for App {
continue;
}

if let Some(LoginAction::LoginSuccess) = action.downcast_ref() {
log!("Received LoginAction::LoginSuccess, hiding login view.");
self.app_state.logged_in = true;
self.update_login_visibility(cx);
self.ui.redraw(cx);
// Handle login-related actions
if let Some(login_action) = action.downcast_ref::<LoginAction>() {
match login_action {
LoginAction::LoginSuccess => {
log!("Received LoginAction::LoginSuccess, hiding login view.");
self.app_state.logged_in = true;
self.update_login_visibility(cx);
self.ui.redraw(cx);
}
LoginAction::NavigateToRegister => {
log!("Navigating from login to register screen");
self.ui.view(id!(login_screen_view)).set_visible(cx, false);
self.ui.view(id!(register_screen_view)).set_visible(cx, true);
// Reset register button state when showing register screen
let register_button = self.ui.button(id!(register_screen_view.register_screen.register_button));
register_button.set_enabled(cx, true);
register_button.reset_hover(cx);
self.ui.redraw(cx);
}
_ => {}
}
continue;
}

// Handle register-related actions
if let Some(register_action) = action.downcast_ref::<RegisterAction>() {
match register_action {
RegisterAction::NavigateToLogin => {
log!("Navigating from register to login screen");
// Reset the register screen state before hiding it
if let Some(mut register_screen_ref) = self.ui.widget(id!(register_screen_view.register_screen)).borrow_mut::<crate::register::register_screen::RegisterScreen>() {
register_screen_ref.reset_screen_state(cx);
}
self.ui.view(id!(register_screen_view)).set_visible(cx, false);
self.ui.view(id!(login_screen_view)).set_visible(cx, true);
self.ui.redraw(cx);
}
RegisterAction::RegistrationSuccess => {
log!("Registration successful, transitioning to logged in state");
// Clear register screen state after successful registration
if let Some(mut register_screen_ref) = self.ui.widget(id!(register_screen_view.register_screen)).borrow_mut::<crate::register::register_screen::RegisterScreen>() {
register_screen_ref.reset_screen_state(cx);
}
self.app_state.logged_in = true;
self.update_login_visibility(cx);
self.ui.redraw(cx);
}
_ => {}
}
continue;
}

Expand Down Expand Up @@ -514,6 +565,7 @@ impl App {
.close(cx);
}
self.ui.view(id!(login_screen_view)).set_visible(cx, show_login);
self.ui.view(id!(register_screen_view)).set_visible(cx, false);
self.ui.view(id!(home_screen_view)).set_visible(cx, !show_login);
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/home/main_desktop_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ impl MainDesktopUI {
/// Closes all tabs
pub fn close_all_tabs(&mut self, cx: &mut Cx) {
let dock = self.view.dock(id!(dock));
for tab_id in self.open_rooms.keys() {
for tab_id in self.open_rooms.keys() {
dock.close_tab(cx, *tab_id);
}

Expand All @@ -236,6 +236,9 @@ impl MainDesktopUI {
self.tab_to_close = None;
self.room_order.clear();
self.most_recently_selected_room = None;

// Reset state to prevent dock restoration on next login
self.drawn_previously = false;
}

/// Replaces an invite with a joined room in the dock.
Expand Down
7 changes: 6 additions & 1 deletion src/home/rooms_list_header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,11 @@ impl Widget for RoomsListHeader {
if &self.sync_state == new_state {
continue;
}
if new_state == &State::Offline {

// Only show offline notification for actual connection errors
// States like Idle and Running are normal and shouldn't trigger error popups
if matches!(new_state, State::Error | State::Terminated | State::Offline) {
log!("Setting the RoomsListHeader to offline.");
self.view.view(id!(loading_spinner)).set_visible(cx, false);
self.view.view(id!(synced_icon)).set_visible(cx, false);
self.view.view(id!(offline_icon)).set_visible(cx, true);
Expand All @@ -113,6 +117,7 @@ impl Widget for RoomsListHeader {
kind: PopupKind::Error,
});
}
// For all other states (Idle, Running, etc.), just update without error notification
self.sync_state = new_state.clone();
self.redraw(cx);
}
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ pub mod settings;

/// Login screen
pub mod login;
/// Register screen
pub mod register;
/// Logout confirmation and state management
pub mod logout;
/// Core UI content: the main home screen (rooms list), room screen.
Expand Down
11 changes: 6 additions & 5 deletions src/login/login_screen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,8 +286,6 @@ live_design! {
}
}

static MATRIX_SIGN_UP_URL: &str = "https://matrix.org/docs/chat_basics/matrix-for-im/#creating-a-matrix-account";

#[derive(Live, LiveHook, Widget)]
pub struct LoginScreen {
#[deref] view: View,
Expand Down Expand Up @@ -321,8 +319,7 @@ impl MatchEvent for LoginScreen {
let login_status_modal_inner = self.view.login_status_modal(id!(login_status_modal_inner));

if signup_button.clicked(actions) {
log!("Opening URL \"{}\"", MATRIX_SIGN_UP_URL);
let _ = robius_open::Uri::new(MATRIX_SIGN_UP_URL).open();
cx.action(LoginAction::NavigateToRegister);
}

if login_button.clicked(actions)
Expand Down Expand Up @@ -370,6 +367,7 @@ impl MatchEvent for LoginScreen {
}

// Handle login-related actions received from background async tasks.
// Skip processing if the login screen is not visible (e.g., user is on register screen)
match action.downcast_ref() {
Some(LoginAction::CliAutoLogin { user_id, homeserver }) => {
user_id_input.set_text(cx, user_id);
Expand Down Expand Up @@ -454,7 +452,8 @@ impl MatchEvent for LoginScreen {
submit_async_request(MatrixRequest::SpawnSSOServer{
identity_provider_id: format!("oidc-{}",brand),
brand: brand.to_string(),
homeserver_url: homeserver_input.text()
homeserver_url: homeserver_input.text(),
is_registration: false,
});
}
}
Expand Down Expand Up @@ -493,5 +492,7 @@ pub enum LoginAction {
/// When an SSO-based login is pendng, pressing the cancel button will send
/// an HTTP request to this SSO server URL to gracefully shut it down.
SsoSetRedirectUrl(Url),
/// Navigate to the register screen.
NavigateToRegister,
None,
}
9 changes: 9 additions & 0 deletions src/register/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use makepad_widgets::*;

pub mod register_screen;
pub mod register_status_modal;

pub fn live_design(cx: &mut Cx) {
register_screen::live_design(cx);
register_status_modal::live_design(cx);
}
Loading