Skip to content

Commit

Permalink
Add login screen.
Browse files Browse the repository at this point in the history
  • Loading branch information
fmzbl committed Oct 11, 2024
1 parent 65632f2 commit ce68053
Show file tree
Hide file tree
Showing 4 changed files with 275 additions and 4 deletions.
32 changes: 28 additions & 4 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ use makepad_widgets::*;
use matrix_sdk::ruma::OwnedRoomId;

use crate::{
home::rooms_list::RoomListAction,
verification::VerificationAction,
verification_modal::{VerificationModalAction, VerificationModalWidgetRefExt},
home::rooms_list::RoomListAction, login::login_screen::LoginAction, verification::VerificationAction, verification_modal::{VerificationModalAction, VerificationModalWidgetRefExt}
};

live_design! {
Expand All @@ -18,6 +16,7 @@ live_design! {
import crate::home::room_screen::RoomScreen;
import crate::profile::my_profile_screen::MyProfileScreen;
import crate::verification_modal::VerificationModal;
import crate::login::login_screen::LoginScreen;

ICON_CHAT = dep("crate://self/resources/icons/chat.svg")
ICON_CONTACTS = dep("crate://self/resources/icons/contacts.svg")
Expand Down Expand Up @@ -102,6 +101,12 @@ live_design! {
}
}

// StackNavigationView without header
SimpleStackNavigationView = <StackNavigationView> {
header = <View> {width: 0, height: 0}
margin: 0
}

App = {{App}} {
ui: <Window> {
window: {inner_size: vec2(1280, 800)},
Expand All @@ -113,7 +118,16 @@ live_design! {
width: Fill, height: Fill,
flow: Overlay,

home_screen = <HomeScreen> {}
navigation = <StackNavigation> {
root_view = {
login_screen = <LoginScreen> {}
}
stack_navigation_view_home_screen = <SimpleStackNavigationView> {
body = {
home_screen = <HomeScreen> {}
}
}
}

verification_modal = <Modal> {
content: {
Expand Down Expand Up @@ -148,6 +162,7 @@ impl LiveRegister for App {
crate::verification_modal::live_design(cx);
crate::home::live_design(cx);
crate::profile::live_design(cx);
crate::login::live_design(cx);
}
}

Expand All @@ -166,6 +181,14 @@ impl MatchEvent for App {

fn handle_actions(&mut self, cx: &mut Cx, actions: &Actions) {
for action in actions {
match action.as_widget_action().cast() {
LoginAction::LoginSuccess => {
let mut navigation = self.ui.stack_navigation(id!(navigation));
navigation.show_stack_view_by_id(live_id!(stack_navigation_view_home_screen), cx)
}
LoginAction::None => { }
}

match action.as_widget_action().cast() {
// A room has been selected, update the app state and navigate to the main content view.
RoomListAction::Selected {
Expand Down Expand Up @@ -244,6 +267,7 @@ impl AppMain for App {
#[derive(Default, Debug)]
pub struct AppState {
pub rooms_panel: RoomsPanelState,
pub login_state: bool,
}

#[derive(Default, Debug)]
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ pub use makepad_widgets;
pub mod app;
pub mod persistent_state;

/// Login screen
pub mod login;
/// Core UI content: the main home screen (rooms list), room screen.
pub mod home;
/// User profile info and a user profile sliding pane.
Expand Down
238 changes: 238 additions & 0 deletions src/login/login_screen.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
use makepad_widgets::*;

live_design! {
import makepad_widgets::base::*;
import makepad_widgets::theme_desktop_dark::*;
import makepad_draw::shader::std::*;

import crate::shared::styles::*;
import crate::shared::icon_button::*;

IMG_APP_LOGO = dep("crate://self/packaging/robrix_logo_alpha.png")

LoginTextInput = <TextInput> {
width: Fill, height: Fit, margin: 0
align: {y: 0.5}
draw_bg: {
color: (COLOR_PRIMARY)
instance radius: 2.0
instance border_width: 0.8
instance border_color: #D0D5DD
instance inset: vec4(0.0, 0.0, 0.0, 0.0)

fn get_color(self) -> vec4 {
return self.color
}

fn get_border_color(self) -> vec4 {
return self.border_color
}

fn pixel(self) -> vec4 {
let sdf = Sdf2d::viewport(self.pos * self.rect_size)
sdf.box(
self.inset.x + self.border_width,
self.inset.y + self.border_width,
self.rect_size.x - (self.inset.x + self.inset.z + self.border_width * 2.0),
self.rect_size.y - (self.inset.y + self.inset.w + self.border_width * 2.0),
max(1.0, self.radius)
)
sdf.fill_keep(self.get_color())
if self.border_width > 0.0 {
sdf.stroke(self.get_border_color(), self.border_width)
}
return sdf.result;
}
}

draw_text: {
color: (MESSAGE_TEXT_COLOR),
text_style: <MESSAGE_TEXT_STYLE>{},

fn get_color(self) -> vec4 {
return mix(
self.color,
#B,
self.is_empty
)
}
}


// TODO find a way to override colors
draw_cursor: {
instance focus: 0.0
uniform border_radius: 0.5
fn pixel(self) -> vec4 {
let sdf = Sdf2d::viewport(self.pos * self.rect_size);
sdf.box(
0.,
0.,
self.rect_size.x,
self.rect_size.y,
self.border_radius
)
sdf.fill(mix(#fff, #bbb, self.focus));
return sdf.result
}
}

// TODO find a way to override colors
draw_selection: {
instance hover: 0.0
instance focus: 0.0
uniform border_radius: 2.0
fn pixel(self) -> vec4 {
let sdf = Sdf2d::viewport(self.pos * self.rect_size);
sdf.box(
0.,
0.,
self.rect_size.x,
self.rect_size.y,
self.border_radius
)
sdf.fill(mix(#eee, #ddd, self.focus)); // Pad color
return sdf.result
}
}
}

LoginScreen = {{LoginScreen}} {
show_bg: true,
draw_bg: {
color: (COLOR_PRIMARY)
}
align: {x: 0.5, y: 0.5}

<RoundedView> {
width: Fit, height: Fit
flow: Down
align: {x: 0.5, y: 0.5}
padding: 50
spacing: 20.0

show_bg: true,
draw_bg: {
color: (COLOR_SECONDARY)
}

logo_image = <Image> {
fit: Smallest,
width: 80
source: (IMG_APP_LOGO),
}

title = <Label> {
width: Fit, height: Fit
draw_text: {
color: (COLOR_TEXT)
text_style: <TITLE_TEXT>{font_size: 16.0}
}
text: "Login to Robrix"
}

username_input = <LoginTextInput> {
width: 300, height: 40
empty_message: "Username"
}

password_input = <LoginTextInput> {
width: 300, height: 40
empty_message: "Password"
// password: true
}

login_button = <RobrixIconButton > {
width: 300, height: 40
draw_text: {
color: (COLOR_PRIMARY)
text_style: <REGULAR_TEXT> {}
}

draw_bg: {
color: (COLOR_SELECTED_PRIMARY)
}
text: "Login"
}

error_message = <Label> {
width: 300, height: Fit
draw_text: {
color: (COLOR_DANGER_RED)
text_style: <REGULAR_TEXT> {}
}
text: ""
}

success_message = <Label> {
width: 300, height: Fit
draw_text: {
color: (COLOR_ACCEPT_GREEN)
text_style: <REGULAR_TEXT> {}
}
text: ""
}
}
}
}

#[derive(Live, LiveHook, Widget)]
pub struct LoginScreen {
#[deref]
view: View,
}

impl Widget for LoginScreen {
fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
let widget_uid = self.widget_uid();

self.view.handle_event(cx, event, scope);

let password_input = self.view.text_input(id!(password_input));
let error_message_label = self.view.label(id!(error_message));
let success_message_label = self.view.label(id!(success_message));
let login_button = self.view.button(id!(login_button));

let username = self.view.text_input(id!(username_input)).text();
let password = self.view.text_input(id!(password_input)).text();

if let Event::Actions(actions) = event {
if login_button.clicked(actions) {
if username.is_empty() || password.is_empty() {
error_message_label.set_text("Please enter both username and password.");
} else {
// TODO: Implement actual login logic
let mut login_successful = false;

if password == "aa" {login_successful = true}

if login_successful {
cx.widget_action(
widget_uid,
&scope.path,
LoginAction::LoginSuccess,
);
error_message_label.set_text("");
success_message_label.set_text("Login successful!");
} else {
password_input.set_text("");
error_message_label.set_text("Incorrect username or password.");
}


}
self.redraw(cx);
}
}
}

fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep {
self.view.draw_walk(cx, scope, walk)
}
}

#[derive(Clone, DefaultNone, Debug)]
pub enum LoginAction {
None,
LoginSuccess,
}
7 changes: 7 additions & 0 deletions src/login/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use makepad_widgets::*;

pub mod login_screen;

pub fn live_design(cx: &mut Cx) {
login_screen::live_design(cx);
}

0 comments on commit ce68053

Please sign in to comment.