3 Commits

Author SHA1 Message Date
badd541424 Merge branch 'fix/login-invalid-width-on-mobile' into develop
All checks were successful
ci/woodpecker/push/dockerize Pipeline was successful
ci/woodpecker/push/deploy Pipeline was successful
2024-04-22 15:05:52 +02:00
fcf3d92cf9 🐛 Fix a view in charge to set the Login dimesions according to the screen aspect-ratio 2024-04-22 15:04:26 +02:00
6172167ea8 Add a parameter to the Wallpaper widget to show the app version 2024-04-22 14:44:51 +02:00
12 changed files with 288 additions and 210 deletions

View File

@@ -20,6 +20,7 @@ use crate::base::{login, sync_rooms};
use crate::base::{APP_SETTINGS, ROOMS, SESSION}; use crate::base::{APP_SETTINGS, ROOMS, SESSION};
use crate::ui::components::login::Login; use crate::ui::components::login::Login;
use crate::ui::components::main_window::MainWindow; use crate::ui::components::main_window::MainWindow;
use crate::ui::views::login_view::LoginView;
mod base; mod base;
@@ -92,7 +93,7 @@ fn app() -> Element {
} }
} else { } else {
rsx! { rsx! {
Login {}, LoginView {},
} }
} }
} }

View File

@@ -167,7 +167,6 @@ $colors: (
@function get-color($color-name, $color-level) { @function get-color($color-name, $color-level) {
$color: map.get($colors, $color-name); $color: map.get($colors, $color-name);
@return map.get($color, $color-level); @return map.get($color, $color-level);
} }
$border-default-color: get-color(greyscale, 90); $border-default-color: get-color(greyscale, 90);
@@ -176,9 +175,6 @@ $border-big: solid $border-big-width $border-default-color;
$border-normal-width: 2px; $border-normal-width: 2px;
$border-normal: solid $border-normal-width $border-default-color; $border-normal: solid $border-normal-width $border-default-color;
$form-max-height: 1024px;
$form-aspect-ratio: 1/1.618;
// TODO: Radius should be a percentage(eg: 1024/16px). // TODO: Radius should be a percentage(eg: 1024/16px).
$border-radius: 16px; $border-radius: 16px;

View File

@@ -0,0 +1,19 @@
@import "../base.scss";
$panel-aspect-ratio: 1/1.618;
$panel-padding-v: 5%;
$panel-padding-h: 5%;
%panel {
padding: $panel-padding-v $panel-padding-h;
height: calc(100% - $panel-padding-v - (2 * $border-big-width));
width: calc(100% - $panel-padding-h - (2 * $border-big-width));
flex-shrink: 0;
border: $border-big;
border-color: get-color(primary, 90);
border-radius: $border-radius;
background-color: get-color(greyscale, 0);
}

View File

@@ -15,7 +15,9 @@ pub fn LoadingPage() -> Element {
div { div {
class: ClassName::LOADING, class: ClassName::LOADING,
Wallpaper {}, Wallpaper {
display_version: true
},
div { div {
class: ClassName::LOADING_SPINNER, class: ClassName::LOADING_SPINNER,

View File

@@ -20,8 +20,6 @@ use super::modal::{Modal, Severity};
use super::spinner::Spinner; use super::spinner::Spinner;
use super::text_input::{PasswordInputState, PasswordTextInput, TextInput, TextInputState}; use super::text_input::{PasswordInputState, PasswordTextInput, TextInput, TextInputState};
use super::wallpaper::Wallpaper;
include!(concat!(env!("OUT_DIR"), "/style_vars.rs")); include!(concat!(env!("OUT_DIR"), "/style_vars.rs"));
use style::{ use style::{
@@ -613,7 +611,7 @@ pub fn Login() -> Element {
let avatar = match &*random_avatar_future.read_unchecked() { let avatar = match &*random_avatar_future.read_unchecked() {
Some(svg) => Some(rsx! { Some(svg) => Some(rsx! {
div { div {
class: ClassName::LOGIN_FORM_PHOTO_CONTENT, class: ClassName::LOGIN_AVATAR_CONTENT,
dangerous_inner_html: svg.as_str(), dangerous_inner_html: svg.as_str(),
} }
}), }),
@@ -639,7 +637,6 @@ pub fn Login() -> Element {
to_owned![handlers]; to_owned![handlers];
move |_| { move |_| {
handlers.reset_handlers(); handlers.reset_handlers();
if *current_process.read() == Process::Registration { if *current_process.read() == Process::Registration {
@@ -713,13 +710,13 @@ pub fn Login() -> Element {
} }
}; };
let mut form_classes: [&str; 2] = [ClassName::LOGIN_FORM, ""]; let mut classes: [&str; 2] = [ClassName::LOGIN, ""];
let mut password_classes: [&str; 2] = [ClassName::LOGIN_FORM_PASSWORD, ""]; let mut password_classes: [&str; 2] = [ClassName::LOGIN_PASSWORD, ""];
let mut confirm_password_classes: [&str; 2] = [ClassName::LOGIN_FORM_CONFIRM_PASSWORD, ""]; let mut confirm_password_classes: [&str; 2] = [ClassName::LOGIN_CONFIRM_PASSWORD, ""];
match *current_process.read() { match *current_process.read() {
Process::Registration => { Process::Registration => {
form_classes[1] = ClassName::REGISTER; classes[1] = ClassName::REGISTER;
password_classes[1] = ClassName::SHOW; password_classes[1] = ClassName::SHOW;
confirm_password_classes[1] = ClassName::SHOW; confirm_password_classes[1] = ClassName::SHOW;
@@ -743,92 +740,86 @@ pub fn Login() -> Element {
.as_ref() .as_ref()
.map(|modal_config| rsx!({ generate_modal(modal_config, on_modal_confirm) })); .map(|modal_config| rsx!({ generate_modal(modal_config, on_modal_confirm) }));
let form_classes_str = form_classes.join(" "); let classes_str = classes.join(" ");
let password_classes_str = password_classes.join(" "); let password_classes_str = password_classes.join(" ");
let confirm_password_classes_str = confirm_password_classes.join(" "); let confirm_password_classes_str = confirm_password_classes.join(" ");
rsx! { rsx! {
style { {STYLE_SHEET} }, style { {STYLE_SHEET} },
Wallpaper {},
div { div {
class: ClassName::LOGIN, class: "{classes_str}",
div { div {
class: "{form_classes_str}", class: ClassName::LOGIN_AVATAR,
div { onclick: move |_| {
class: ClassName::LOGIN_FORM_PHOTO, random_avatar_future.restart()
onclick: move |_| {
random_avatar_future.restart()
},
{avatar},
}, },
div { {avatar},
class: ClassName::LOGIN_FORM_HOMESERVER, },
TextInput {
placeholder: "Homeserver URL", div {
value: "{homeserver_url}", class: ClassName::LOGIN_HOMESERVER,
state: homeserver_url_state, TextInput {
oninput: on_input![data, homeserver_url], placeholder: "Homeserver URL",
}, value: "{homeserver_url}",
state: homeserver_url_state,
oninput: on_input![data, homeserver_url],
},
},
div {
class: ClassName::LOGIN_ID,
TextInput {
placeholder: "{id_placeholder}",
value: "{id}",
state: id_state,
oninput: on_input![data, id],
},
},
div {
class: "{password_classes_str}",
PasswordTextInput {
placeholder: "Password",
value: "{password}",
state: password_state,
oninput: on_input![data, password],
}, },
div { },
class: ClassName::LOGIN_FORM_ID,
TextInput { div {
placeholder: "{id_placeholder}", class: "{confirm_password_classes_str}",
value: "{id}", PasswordTextInput {
state: id_state, placeholder: "Confirm Password",
oninput: on_input![data, id], value: "{confirm_password}",
}, state: confirm_password_state,
oninput: on_input![data, confirm_password],
}
},
div {
class: ClassName::LOGIN_SPINNER,
Spinner {
animate: *spinner_animated.read(),
}, },
},
div { div {
class: "{password_classes_str}", class: ClassName::LOGIN_REGISTER_BUTTON,
PasswordTextInput { RegisterButton {
placeholder: "Password", onclick: on_clicked_register,
value: "{password}",
state: password_state,
oninput: on_input![data, password],
},
}, },
},
div { div {
class: "{confirm_password_classes_str}", class: ClassName::LOGIN_LOGIN_BUTTON,
PasswordTextInput { LoginButton {
placeholder: "Confirm Password", focus: true,
value: "{confirm_password}", onclick: on_clicked_login,
state: confirm_password_state,
oninput: on_input![data, confirm_password],
}
},
div {
class: ClassName::LOGIN_FORM_SPINNER,
Spinner {
animate: *spinner_animated.read(),
},
},
div {
class: ClassName::LOGIN_FORM_REGISTER_BUTTON,
RegisterButton {
onclick: on_clicked_register,
},
},
div {
class: ClassName::LOGIN_FORM_LOGIN_BUTTON,
LoginButton {
focus: true,
onclick: on_clicked_login,
},
}, },
}, },
}, },

View File

@@ -1,139 +1,137 @@
@import "../_base.scss" @import "../_base.scss";
@import "./spinner.scss" @import "./_panel.scss";
@import "./spinner.scss";
.login { .login {
height: 100%; @extend %panel;
width: 100%;
display: flex; $aspect-ratio: var(--aspect-ratio);
align-items: center;
justify-content: center;
position: relative; border: $border-big;
top: -100vh; border-color: get-color(primary, 90);
border-radius: $border-radius;
margin-bottom: -100vh; background-color: get-color(greyscale, 0);
&__form { display: grid;
$height: 95%;
height: $height;
max-height: $form-max-height; $button-height: 8%;
aspect-ratio: $form-aspect-ratio; $button-overlap: 5%;
$profile-img-width: 40%;
$edit-padding: 7.5%;
$avatar-padding: 17.5%;
border: $border-big; $spinner-col-width: calc(0% + ($button-overlap * 2));
border-color: get-color(primary, 90);
$profile-img-height: calc($profile-img-width * $aspect-ratio);
$profile-img-ext-width: calc((($profile-img-width - $spinner-col-width) / 2) - $button-overlap);
$center-width: calc((50% - $edit-padding - $avatar-padding - $button-overlap - $profile-img-ext-width) * 2);
$spinner-height: calc(($spinner-col-width + $center-width) * $aspect-ratio / $logo-aspect-ratio);
grid-template-columns: $edit-padding $avatar-padding
$button-overlap $profile-img-ext-width $center-width $profile-img-ext-width $button-overlap
$avatar-padding $edit-padding;
grid-template-rows: $profile-img-height auto 5% 5% 5% 5% 5% 0% 0% 12.5% $spinner-height 12.5% $button-height;
grid-template-areas:
". . . avatar avatar avatar . . ."
". . . . . . . . ."
". homeserver homeserver homeserver homeserver homeserver homeserver homeserver ."
". . . . . . . . ."
". id id id id id id id ."
". . . . . . . . ."
". password password password password password password password ."
". . . . . . . . ."
". confirm confirm confirm confirm confirm confirm confirm ."
". . . . . . . . ."
". . . spinner spinner spinner . . ."
". . . . . . . . ."
"register register register register . login login login login"
;
transition: $transition-duration;
&.register {
grid-template-rows: $profile-img-height auto 5% 5% 5% 5% 5% 5% 5% 5% $spinner-height 5% $button-height;
}
&__avatar {
grid-area: avatar;
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
border: $border-normal;
border-radius: $border-radius; border-radius: $border-radius;
background-color: get-color(greyscale, 0); overflow: hidden;
display: grid; &__content {
height: calc(100% + (2 * $border-normal-width));
$padding-col: 5%; aspect-ratio: 1;
$button-height: 8%;
$button-overlap: 5%;
$profile-img-width: 40%;
$edit-padding: 7.5%;
$photo-padding: 17.5%;
$padding-row: calc(5% * $form-aspect-ratio);
$spinner-col-width: calc(0% + ($button-overlap * 2));
$profile-img-height: calc($profile-img-width * $form-aspect-ratio);
$profile-img-ext-width: calc((($profile-img-width - $spinner-col-width) / 2) - $button-overlap);
$center-width: calc((50% - $padding-col - $edit-padding - $photo-padding - $button-overlap -
$profile-img-ext-width) * 2);
$spinner-height: calc(($spinner-col-width + $center-width) * $form-aspect-ratio / $logo-aspect-ratio);
grid-template-columns: $padding-col $edit-padding $photo-padding
$button-overlap $profile-img-ext-width $center-width $profile-img-ext-width $button-overlap
$photo-padding $edit-padding $padding-col;
grid-template-rows: $padding-row $profile-img-height auto 5% 5% 5% 5% 5% 0% 0% 8.5% $spinner-height 8.5% $button-height $padding-row;
grid-template-areas:
". . . . . . . . . . ."
". . . photo photo photo photo photo . . ."
". . . . . . . . . . ."
". . homeserver homeserver homeserver homeserver homeserver homeserver homeserver . ."
". . . . . . . . . . ."
". . id id id id id id id . ."
". . . . . . . . . . ."
". . password password password password password password password . ."
". . . . . . . . . . ."
". . confirm confirm confirm confirm confirm confirm confirm . ."
". . . . . . . . . . ."
". . . . spinner spinner spinner . . . ."
". . . . . . . . . . ."
". register register register register . login login login login ."
". . . . . . . . . . ."
;
transition: $transition-duration;
&.register {
grid-template-rows: $padding-row $profile-img-height auto 5% 5% 5% 5% 5% 5% 5% 5% $spinner-height 5% $button-height $padding-row;
}
&__photo {
grid-area: photo;
display: flex;
align-items: center;
justify-content: center;
border: $border-normal;
border-radius: $border-radius;
overflow: hidden;
&__content {
height: calc(100% + (2 * $border-normal-width));
aspect-ratio: 1;
}
}
input {
font-family: inherit;
}
&__homeserver {
grid-area: homeserver;
}
&__id {
grid-area: id;
}
&__password {
grid-area: password;
}
&__confirm-password {
grid-area: confirm;
display: none;
&.show {
display: initial;
}
}
&__spinner {
grid-area: spinner;
svg {
width: 100%;
height: 100%;
}
}
button {
width: 100%;
}
&__register-button {
grid-area: register;
}
&__login-button {
grid-area: login;
} }
} }
&__homeserver {
grid-area: homeserver;
height: 100%;
}
&__id {
grid-area: id;
height: 100%;
}
&__password {
grid-area: password;
height: 100%;
}
&__confirm-password {
grid-area: confirm;
display: none;
height: 100%;
&.show {
display: initial;
}
}
&__spinner {
grid-area: spinner;
height: 100%;
width: 100%;
svg {
width: 100%;
height: 100%;
}
}
button {
height: 100%;
width: 100%;
}
&__register-button {
grid-area: register;
height: 100%;
}
&__login-button {
grid-area: login;
height: 100%;
}
} }

View File

@@ -5,7 +5,10 @@ const GIT_VERSION: &str = git_version!();
turf::style_sheet!("src/ui/components/wallpaper.scss"); turf::style_sheet!("src/ui/components/wallpaper.scss");
pub fn Wallpaper() -> Element { #[component]
pub fn Wallpaper(display_version: Option<bool>) -> Element {
let version = display_version.map(|flag| if flag { Some(GIT_VERSION) } else { None });
rsx! { rsx! {
style { {STYLE_SHEET} }, style { {STYLE_SHEET} },
div { div {
@@ -17,7 +20,7 @@ pub fn Wallpaper() -> Element {
div { div {
class: ClassName::WALLPAPER_VERSION, class: ClassName::WALLPAPER_VERSION,
{GIT_VERSION}, {version},
} }
} }
} }

View File

@@ -22,7 +22,7 @@
&__version { &__version {
position: absolute; position: absolute;
top: 97vh; top: 97.5vh;
font-size: 1.5vh; font-size: 1.5vh;
color: get-color(greyscale, 80); color: get-color(greyscale, 80);

View File

@@ -1 +1,2 @@
pub(crate) mod components; pub(crate) mod components;
pub(crate) mod views;

View File

@@ -0,0 +1,25 @@
use dioxus::prelude::*;
use crate::ui::components::login::Login;
use crate::ui::components::wallpaper::Wallpaper;
turf::style_sheet!("src/ui/views/login_view.scss");
pub fn LoginView() -> Element {
rsx! {
style { {STYLE_SHEET} },
Wallpaper {
display_version: true
}
div {
class: ClassName::LOGIN_VIEW,
div {
class: ClassName::LOGIN_VIEW_LOGIN_PANEL,
Login {}
}
}
}
}

View File

@@ -0,0 +1,41 @@
@import "../_base.scss";
@import "../components/_panel.scss";
.login-view {
$panel-max-height: 1024px;
height: 100%;
width: 100%;
position: relative;
top: -100vh;
margin-bottom: -100vh;
display: flex;
flex-direction: row;
justify-content: safe center;
align-items: safe center;
&__login-panel {
@media (max-aspect-ratio: $panel-aspect-ratio) {
width: 95%;
}
@media (min-aspect-ratio: $panel-aspect-ratio) {
height: 100%;
}
aspect-ratio: $panel-aspect-ratio;
max-height: $panel-max-height;
flex-shrink: 0;
scroll-snap-align: center;
display: flex;
align-items: center;
justify-content: center;
// Variables inherited by children
--aspect-ratio: #{$panel-aspect-ratio};
}
}

1
src/ui/views/mod.rs Normal file
View File

@@ -0,0 +1 @@
pub(crate) mod login_view;