diff --git a/src/main.rs b/src/main.rs index a42630b..592256b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,6 +20,7 @@ use crate::base::{login, sync_rooms}; use crate::base::{APP_SETTINGS, ROOMS, SESSION}; use crate::ui::components::login::Login; use crate::ui::components::main_window::MainWindow; +use crate::ui::views::login_view::LoginView; mod base; @@ -92,7 +93,7 @@ fn app() -> Element { } } else { rsx! { - Login {}, + LoginView {}, } } } diff --git a/src/ui/_base.scss b/src/ui/_base.scss index 0f4e718..3aadd1f 100644 --- a/src/ui/_base.scss +++ b/src/ui/_base.scss @@ -167,7 +167,6 @@ $colors: ( @function get-color($color-name, $color-level) { $color: map.get($colors, $color-name); @return map.get($color, $color-level); - } $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: 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). $border-radius: 16px; diff --git a/src/ui/components/_panel.scss b/src/ui/components/_panel.scss new file mode 100644 index 0000000..4c18199 --- /dev/null +++ b/src/ui/components/_panel.scss @@ -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); +} diff --git a/src/ui/components/login.rs b/src/ui/components/login.rs index fc0870b..87f981d 100644 --- a/src/ui/components/login.rs +++ b/src/ui/components/login.rs @@ -20,8 +20,6 @@ use super::modal::{Modal, Severity}; use super::spinner::Spinner; use super::text_input::{PasswordInputState, PasswordTextInput, TextInput, TextInputState}; -use super::wallpaper::Wallpaper; - include!(concat!(env!("OUT_DIR"), "/style_vars.rs")); use style::{ @@ -613,7 +611,7 @@ pub fn Login() -> Element { let avatar = match &*random_avatar_future.read_unchecked() { Some(svg) => Some(rsx! { div { - class: ClassName::LOGIN_FORM_PHOTO_CONTENT, + class: ClassName::LOGIN_AVATAR_CONTENT, dangerous_inner_html: svg.as_str(), } }), @@ -639,7 +637,6 @@ pub fn Login() -> Element { to_owned![handlers]; move |_| { - handlers.reset_handlers(); 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 password_classes: [&str; 2] = [ClassName::LOGIN_FORM_PASSWORD, ""]; - let mut confirm_password_classes: [&str; 2] = [ClassName::LOGIN_FORM_CONFIRM_PASSWORD, ""]; + let mut classes: [&str; 2] = [ClassName::LOGIN, ""]; + let mut password_classes: [&str; 2] = [ClassName::LOGIN_PASSWORD, ""]; + let mut confirm_password_classes: [&str; 2] = [ClassName::LOGIN_CONFIRM_PASSWORD, ""]; match *current_process.read() { Process::Registration => { - form_classes[1] = ClassName::REGISTER; + classes[1] = ClassName::REGISTER; password_classes[1] = ClassName::SHOW; confirm_password_classes[1] = ClassName::SHOW; @@ -743,92 +740,86 @@ pub fn Login() -> Element { .as_ref() .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 confirm_password_classes_str = confirm_password_classes.join(" "); rsx! { style { {STYLE_SHEET} }, - Wallpaper {}, - div { - class: ClassName::LOGIN, + class: "{classes_str}", div { - class: "{form_classes_str}", + class: ClassName::LOGIN_AVATAR, - div { - class: ClassName::LOGIN_FORM_PHOTO, - - onclick: move |_| { - random_avatar_future.restart() - }, - - {avatar}, + onclick: move |_| { + random_avatar_future.restart() }, - div { - class: ClassName::LOGIN_FORM_HOMESERVER, - TextInput { - placeholder: "Homeserver URL", - value: "{homeserver_url}", - state: homeserver_url_state, - oninput: on_input![data, homeserver_url], - }, + {avatar}, + }, + + div { + class: ClassName::LOGIN_HOMESERVER, + TextInput { + 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 { - placeholder: "{id_placeholder}", - value: "{id}", - state: id_state, - oninput: on_input![data, id], - }, + }, + + div { + class: "{confirm_password_classes_str}", + PasswordTextInput { + placeholder: "Confirm Password", + value: "{confirm_password}", + state: confirm_password_state, + oninput: on_input![data, confirm_password], + } + }, + + div { + class: ClassName::LOGIN_SPINNER, + Spinner { + animate: *spinner_animated.read(), }, + }, - div { - class: "{password_classes_str}", - PasswordTextInput { - placeholder: "Password", - value: "{password}", - state: password_state, - oninput: on_input![data, password], - }, - + div { + class: ClassName::LOGIN_REGISTER_BUTTON, + RegisterButton { + onclick: on_clicked_register, }, + }, - div { - class: "{confirm_password_classes_str}", - PasswordTextInput { - placeholder: "Confirm Password", - value: "{confirm_password}", - 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, - }, + div { + class: ClassName::LOGIN_LOGIN_BUTTON, + LoginButton { + focus: true, + onclick: on_clicked_login, }, }, }, diff --git a/src/ui/components/login.scss b/src/ui/components/login.scss index 45cd1db..59692c4 100644 --- a/src/ui/components/login.scss +++ b/src/ui/components/login.scss @@ -1,139 +1,137 @@ -@import "../_base.scss" -@import "./spinner.scss" +@import "../_base.scss"; +@import "./_panel.scss"; +@import "./spinner.scss"; .login { - height: 100%; - width: 100%; + @extend %panel; - display: flex; - align-items: center; - justify-content: center; + $aspect-ratio: var(--aspect-ratio); - position: relative; - top: -100vh; + border: $border-big; + border-color: get-color(primary, 90); + border-radius: $border-radius; - margin-bottom: -100vh; + background-color: get-color(greyscale, 0); - &__form { - $height: 95%; - height: $height; + display: grid; - max-height: $form-max-height; - aspect-ratio: $form-aspect-ratio; + $button-height: 8%; + $button-overlap: 5%; + $profile-img-width: 40%; + $edit-padding: 7.5%; + $avatar-padding: 17.5%; - border: $border-big; - border-color: get-color(primary, 90); + $spinner-col-width: calc(0% + ($button-overlap * 2)); + + $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; - background-color: get-color(greyscale, 0); + overflow: hidden; - display: grid; - - $padding-col: 5%; - $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; + &__content { + height: calc(100% + (2 * $border-normal-width)); + aspect-ratio: 1; } } + + &__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%; + } } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index ac15021..1cccdfe 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -1 +1,2 @@ pub(crate) mod components; +pub(crate) mod views; diff --git a/src/ui/views/login_view.rs b/src/ui/views/login_view.rs new file mode 100644 index 0000000..50d527d --- /dev/null +++ b/src/ui/views/login_view.rs @@ -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 {} + } + } + } +} diff --git a/src/ui/views/login_view.scss b/src/ui/views/login_view.scss new file mode 100644 index 0000000..4b40530 --- /dev/null +++ b/src/ui/views/login_view.scss @@ -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}; + } +} diff --git a/src/ui/views/mod.rs b/src/ui/views/mod.rs new file mode 100644 index 0000000..1701ad6 --- /dev/null +++ b/src/ui/views/mod.rs @@ -0,0 +1 @@ +pub(crate) mod login_view;