+
+
-
-
diff --git a/public/app.css b/public/app.css
index b7f53d9..5084bee 100644
--- a/public/app.css
+++ b/public/app.css
@@ -279,6 +279,8 @@ ul {
.rooms-list {
padding: 0;
gap: 0;
+ height: fit-content;
+ min-height: 78px;
}
.list {
@@ -416,10 +418,26 @@ ul {
}
}
+@keyframes fade-in-left {
+ 0% {
+ opacity: 0;
+ transform: translate(0, 0);
+ }
+
+ 100% {
+ opacity: 1;
+ transform: translate(0, 0);
+ }
+}
+
.fade-in {
animation: fade-in 0.5s;
}
+.fade-in-left {
+ animation: fade-in-left 0.2s;
+}
+
@keyframes fade-in {
0% {
opacity: 0;
@@ -491,6 +509,10 @@ ul {
right: 10px;
}
+.hover-menu--show {
+ display: block !important;
+}
+
.hover-menu__option {
border: 1px solid transparent;
width: 100%;
@@ -837,6 +859,15 @@ ul {
}
.nav {
+ display: flex;
+ align-items: center;
+ width: 100%;
+ padding: 1rem 0;
+ background: var(--background);
+ justify-content: space-around;
+}
+
+.nav-wrapper {
color: var(--text-1);
display: flex;
gap: 0.5rem;
@@ -865,8 +896,7 @@ ul {
}
.helper {
- width: fit-content;
- height: fit-content;
+ width: 100%;
min-height: 100px;
min-width: 150px;
max-width: 390px;
@@ -874,17 +904,29 @@ ul {
border-radius: var(--size-1);
padding: var(--size-3);
transition: opacity 0.2s ease-out, background-color 0.2s ease-out;
- background: var(--background-button);
+ background: var(--background-modal);
text-align: left;
border: 1px solid transparent;
+ cursor: pointer;
+ display: flex;
+ flex-direction: column;
+ gap: var(--size-0)
}
.helper__title {
- padding-top: var(--size-2);
+ font-size: 1.15em;
}
.helper__description {
- padding-top: var(--size-0);
+ font-size: 1em;
+}
+
+.helper__subtitle {
+ padding-top: var(--size-2);
+}
+
+.helper__example {
+ font-size: 1em;
}
.loading__title {
@@ -1462,4 +1504,148 @@ ul {
.room-view-wrapper--skeleton {
width: 100%;
-}
\ No newline at end of file
+}
+
+.room-view--wrap {
+ flex-direction: column;
+ align-items: center;
+ max-width: 200px;
+ box-shadow: 0px 2px 4px 1px rgba(0, 0, 0, 0.05);
+ margin: 5px;
+ border-radius: 12px;
+}
+
+.room-list--wrap {
+ justify-content: center;
+ align-items: flex-start;
+ flex-direction: row;
+ flex-wrap: wrap;
+ max-width: 660px;
+ margin: auto;
+}
+
+.room-menu {
+ width: 200px;
+ background: var(--background);
+ box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.18);
+ padding: 12px 6px;
+ position: absolute;
+ right: 0;
+ top: 64px;
+ border-radius: 8px;
+}
+
+.room-menu__item {
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+}
+
+.room-menu__cta {
+ border: none;
+ color: var(--text-1);
+ border-radius: 0;
+ padding: 0 8px;
+ display: flex;
+ cursor: pointer;
+ align-items: center;
+ gap: 4px;
+}
+
+.preview-room {
+ display: flex;
+ flex-direction: column;
+ gap: 24px;
+ justify-content: center;
+ align-items: center;
+ height: 100%;
+}
+
+.preview-room__title {
+ margin-top: 24px;
+ color: var(--text-1);
+ text-align: center;
+}
+
+.preview-room__content {
+ display: flex;
+ flex-direction: column;
+ gap: 12px;
+ justify-content: center;
+ width: 60%;
+}
+
+.chat-list__static {
+ display: flex;
+ flex-grow: 1;
+ align-items: center;
+ justify-content: center;
+}
+
+.chat-list__content {
+ display: flex;
+ flex-grow: 1;
+ align-items: center;
+ justify-content: center;
+}
+
+.guest {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ box-shadow: 0px 2px 4px 1px rgba(0, 0, 0, 0.15);
+ padding: 12px 24px;
+ position: absolute;
+ width: 100%;
+ bottom: 24px;
+ border-radius: 8px;
+ gap: 24px;
+}
+
+.guest__cta {
+ width: 160px;
+}
+
+
+@media only screen and (max-width: 576px) {
+ .page {
+ overflow: hidden;
+ }
+
+ .chat-list {
+ width: fit-content;
+ margin-right: 16px;
+ }
+
+ .chat-list__rooms {
+ width: 70vw;
+ border: 1px solid transparent;
+ background: var(--background-modal);
+ border-radius: 16px;
+ }
+
+ .chat-list__static {
+ width: calc(100vw - 32px);
+ margin: 0 16px;
+ }
+
+ .chat-list__active-room {
+ width: calc(100vw - 32px);
+ margin: 0 16px;
+ }
+
+ .header {
+ position: relative;
+ z-index: 10;
+ }
+
+ .chat-list-wrapper {
+ width: 100vw;
+ overflow-x: auto;
+ scroll-behavior: smooth;
+ }
+
+ .menu {
+ width: 100vw;
+ }
+}
diff --git a/public/login.css b/public/login.css
index 284e59e..6cf3d60 100644
--- a/public/login.css
+++ b/public/login.css
@@ -33,6 +33,9 @@
opacity: 0.8;
}
+.button--skeleton {
+ height: 44px;
+}
.input-wrapper {
height: 2.625rem;
@@ -174,6 +177,10 @@
margin: auto;
}
+.login-form__title--skeleton {
+ height: 32px;
+}
+
.login-form__description {
color: var(--text-subdued);
text-align: center;
@@ -186,6 +193,10 @@
margin: auto;
}
+.login-form__description--skeleton {
+ height: 24px;
+}
+
.login-form__form__head {
display: flex;
gap: 16px;
@@ -236,4 +247,118 @@
.login-form {
width: 100%;
}
+}
+
+.welcome__content {
+ margin-top: 60px;
+}
+
+.communities {
+ column-count: 3;
+ gap: 1em;
+ margin: auto;
+ position: relative;
+ z-index: 10;
+ max-width: fit-content;
+}
+
+.communities-container {
+ position: relative;
+}
+
+.communities-background {
+ position: absolute;
+ z-index: 1;
+ height: 100%;
+ width: 100%;
+ background: transparent;
+ box-shadow: 0px 0px 12px -4px rgba(0, 0, 0, 0.2);
+}
+
+.community {
+ border: 1px solid var(--border);
+ background: var(--background-modal);
+ border-radius: 24px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 32px 12px;
+ gap: 20px;
+ margin: 0 0 1em;
+ max-width: 150px;
+}
+
+.community__blanck {
+ height: 40px;
+}
+
+.community--center::before {
+ content: "";
+ position: absolute;
+ height: 80%;
+ width: 80%;
+ border-radius: 100px;
+ background: transparent;
+ border: 1px solid var(--border);
+ z-index: -1;
+}
+
+.community--center::after {
+ content: "";
+ position: absolute;
+ height: 65%;
+ width: 65%;
+ border-radius: 100px;
+ background: transparent;
+ border: 1px solid var(--border);
+ z-index: -1;
+}
+
+.community__content {
+ border-radius: 24px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.community__content--purple {
+ background: var(--gradient-purple);
+}
+
+.community__content--gray {
+ background: var(--gradient-gray);
+}
+
+.community__content--yellow {
+ background: var(--gradient-yellow);
+}
+
+.community__content--blue {
+ background: var(--gradient-blue);
+}
+
+.community__content--pink {
+ background: var(--gradient-pink);
+}
+
+.community__content--green {
+ background: var(--gradient-green);
+}
+
+.community__icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: var(--font-size-3);
+ padding: 12px;
+}
+
+.community__title {
+ font-size: var(--font-size-1);
+ color: #898A90
+}
+
+.community__title--skeleton {
+ height: var(--font-size-1);
}
\ No newline at end of file
diff --git a/src/components/atoms/community.rs b/src/components/atoms/community.rs
new file mode 100644
index 0000000..f72bf88
--- /dev/null
+++ b/src/components/atoms/community.rs
@@ -0,0 +1,31 @@
+use dioxus::prelude::*;
+
+#[derive(PartialEq, Props)]
+pub struct CommunityProps<'a> {
+ class: Option<&'a str>,
+ title: &'a str,
+ icon: &'a str,
+ background: &'a str,
+}
+
+pub fn Community<'a>(cx: Scope<'a, CommunityProps<'a>>) -> Element<'a> {
+ let content__background = format!("community__content--{}", cx.props.background);
+ let class_content = cx.props.class.unwrap_or("");
+
+ render!(rsx!(
+ section {
+ class: "community {class_content}",
+ div{
+ class: "community__content {content__background}",
+ div {
+ class: "community__icon",
+ "{cx.props.icon}"
+ }
+ }
+ span {
+ class: "community__title",
+ "{cx.props.title}"
+ }
+ }
+ ))
+}
diff --git a/src/components/atoms/mod.rs b/src/components/atoms/mod.rs
index 66d1587..918bdeb 100644
--- a/src/components/atoms/mod.rs
+++ b/src/components/atoms/mod.rs
@@ -2,6 +2,7 @@ pub mod attach;
pub mod avatar;
pub mod button;
pub mod card;
+pub mod community;
pub mod header;
pub mod header_main;
pub mod helper;
@@ -23,6 +24,7 @@ pub use attach::Attach;
pub use avatar::Avatar;
pub use button::Button;
pub use card::Card;
+pub use community::Community;
pub use header::Header;
pub use header_main::HeaderMain;
pub use helper::Helper;
diff --git a/src/components/molecules/menu.rs b/src/components/molecules/menu.rs
index 8f0c874..f291eb0 100644
--- a/src/components/molecules/menu.rs
+++ b/src/components/molecules/menu.rs
@@ -8,6 +8,7 @@ use crate::hooks::use_auth::LogoutError;
use crate::hooks::use_notification::use_notification;
use crate::hooks::use_auth::use_auth;
use crate::hooks::use_client::use_client;
+use crate::hooks::use_session::use_session;
use crate::pages::route::Route;
#[derive(Props)]
@@ -20,6 +21,7 @@ pub fn Menu<'a>(cx: Scope<'a, MenuProps<'a>>) -> Element<'a> {
let nav = use_navigator(cx);
let client = use_client(cx);
let auth = use_auth(cx);
+ let session = use_session(cx);
let notification = use_notification(cx);
let key_profile = translate!(i18, "menu.profile");
@@ -30,10 +32,10 @@ pub fn Menu<'a>(cx: Scope<'a, MenuProps<'a>>) -> Element<'a> {
let log_out = move || {
cx.spawn({
- to_owned![client, auth, notification, key_logout_error_server, key_chat_common_error_default_server];
+ to_owned![client, auth, session, notification, key_logout_error_server, key_chat_common_error_default_server];
async move {
- auth.logout(&client).await
+ auth.logout(&client, session.is_guest()).await
}.unwrap_or_else(move |e: LogoutError| {
let message = match e {
LogoutError::Failed |LogoutError::DefaultClient => key_logout_error_server,
@@ -47,20 +49,24 @@ pub fn Menu<'a>(cx: Scope<'a, MenuProps<'a>>) -> Element<'a> {
cx.render(rsx! {
div {
- class: "menu",
+ class: "menu fade-in-left",
div {
class: "menu__content",
ul {
- li {
- MenuItem {
- title: "{key_profile}",
- icon: cx.render(rsx!(Icon {height: 24, width: 24, stroke: "var(--text-1)", icon: UserCircle})),
- on_click: move |event| {
- cx.props.on_click.call(event);
- nav.push(Route::Profile {});
- }
- }
- }
+ if !session.is_guest() {
+ rsx!(
+ li {
+ MenuItem {
+ title: "{key_profile}",
+ icon: cx.render(rsx!(Icon {height: 24, width: 24, stroke: "var(--text-1)", icon: UserCircle})),
+ on_click: move |event| {
+ cx.props.on_click.call(event);
+ nav.push(Route::Profile {});
+ }
+ }
+ }
+ )
+ }
li {
MenuItem {
diff --git a/src/components/organisms/login_form.rs b/src/components/organisms/login_form.rs
index 7a2c185..d743f50 100644
--- a/src/components/organisms/login_form.rs
+++ b/src/components/organisms/login_form.rs
@@ -11,6 +11,7 @@ pub enum FormLoginEvent {
Login,
FilledForm,
ClearData,
+ Guest,
}
#[derive(Props)]
@@ -119,6 +120,17 @@ pub fn LoginForm<'a>(cx: Scope<'a, LoginFormProps<'a>>) -> Element<'a> {
},
translate!(i18, "onboard.signup.cta"),
}
+ p {
+ class: "login-form__cta--another",
+ translate!(i18, "onboard.guest.description")
+ button {
+ class: "login-form__form__text login__form__text--color button button--tertiary",
+ onclick: move |_| {
+ cx.props.on_handle.call(FormLoginEvent::Guest)
+ },
+ translate!(i18, "onboard.guest.cta")
+ }
+ }
),
BeforeSession::Signup => rsx!(
translate!(i18, "onboard.login.description")
@@ -129,6 +141,38 @@ pub fn LoginForm<'a>(cx: Scope<'a, LoginFormProps<'a>>) -> Element<'a> {
},
translate!(i18, "onboard.login.cta"),
}
+ p {
+ class: "login-form__cta--another",
+ translate!(i18, "onboard.guest.description")
+ button {
+ class: "login-form__form__text login__form__text--color button button--tertiary",
+ onclick: move |_| {
+ cx.props.on_handle.call(FormLoginEvent::Guest)
+ },
+ translate!(i18, "onboard.guest.cta")
+ }
+ }
+ ),
+ BeforeSession::Guest => rsx!(
+ translate!(i18, "onboard.login.description")
+ button {
+ class: "login-form__form__text login__form__text--color button button--tertiary",
+ onclick: move |_| {
+ cx.props.on_handle.call(FormLoginEvent::Login)
+ },
+ translate!(i18, "onboard.login.cta"),
+ }
+ p {
+ class: "login-form__cta--another",
+ translate!(i18, "onboard.signup.description")
+ button {
+ class: "login-form__form__text login__form__text--color button button--tertiary",
+ onclick: move |_| {
+ cx.props.on_handle.call(FormLoginEvent::CreateAccount)
+ },
+ translate!(i18, "onboard.signup.cta"),
+ }
+ }
)
}
}
diff --git a/src/hooks/use_auth.rs b/src/hooks/use_auth.rs
index e27b29d..5ed003f 100644
--- a/src/hooks/use_auth.rs
+++ b/src/hooks/use_auth.rs
@@ -249,12 +249,15 @@ impl UseAuthState {
*self.logged_in.write() = LoggedIn(option);
}
- pub async fn logout(&self, client: &UseClientState) -> Result<(), LogoutError> {
- client
- .get()
- .logout()
- .await
- .map_err(|_| LogoutError::Failed)?;
+ pub async fn logout(&self, client: &UseClientState, is_guest: bool) -> Result<(), LogoutError> {
+ if !is_guest {
+ client
+ .get()
+ .logout()
+ .await
+ .map_err(|_| LogoutError::Failed)?;
+ }
+
::delete("session_file");
client
diff --git a/src/hooks/use_init_app.rs b/src/hooks/use_init_app.rs
index 2584716..e9e0cc8 100644
--- a/src/hooks/use_init_app.rs
+++ b/src/hooks/use_init_app.rs
@@ -21,6 +21,7 @@ use super::{use_attach::AttachFile, use_modal::ModalState};
pub enum BeforeSession {
Login,
Signup,
+ Guest,
}
#[derive(Clone, Debug)]
@@ -49,7 +50,7 @@ pub fn use_init_app(cx: &ScopeState) {
use_shared_state_provider::