Compare commits
3 Commits
cea60ce695
...
73c5b70ba8
Author | SHA1 | Date | |
---|---|---|---|
73c5b70ba8
|
|||
f0463213cf
|
|||
e55992aed5
|
@@ -107,6 +107,12 @@ svg_text_button!(RegisterButton, REGISTER_BUTTON, RegisterText);
|
||||
svg_text_icon!(LoginText, "LOGIN");
|
||||
svg_text_button!(LoginButton, LOGIN_BUTTON, LoginText);
|
||||
|
||||
svg_text_icon!(JoinText, "JOIN");
|
||||
svg_text_button!(JoinButton, JOIN_BUTTON, JoinText);
|
||||
|
||||
svg_text_icon!(RejectText, "REJECT");
|
||||
svg_text_button!(RejectButton, REJECT_BUTTON, RejectText);
|
||||
|
||||
svg_text_icon!(SuccessText, "OK");
|
||||
svg_text_button!(SuccessButton, SUCCESS_BUTTON, SuccessText);
|
||||
|
||||
|
@@ -53,6 +53,14 @@
|
||||
@include button(secondary, 90);
|
||||
}
|
||||
|
||||
.join-button {
|
||||
@include button(secondary, 90);
|
||||
}
|
||||
|
||||
.reject-button {
|
||||
@include button(critical, 90);
|
||||
}
|
||||
|
||||
.success-button {
|
||||
@include button(success, 100);
|
||||
}
|
||||
|
@@ -1,12 +1,18 @@
|
||||
use std::{rc::Rc, time::Duration};
|
||||
|
||||
use base64::{engine::general_purpose, Engine as _};
|
||||
use dioxus::prelude::*;
|
||||
use tracing::{debug, trace, warn};
|
||||
use tracing::{debug, warn};
|
||||
|
||||
use super::{button::Button, icons::SearchIcon, text_input::TextInput};
|
||||
use crate::{
|
||||
domain::model::{common::PresenceState as DomainPresenceState, room::RoomId, space::SpaceId},
|
||||
ui::{
|
||||
components::icons::{ChatsIcon, LogoIcon, RoomsIcon, SpacesIcon},
|
||||
components::{
|
||||
button::{JoinButton, RejectButton},
|
||||
icons::{ChatsIcon, LogoIcon, RoomsIcon, SpacesIcon},
|
||||
},
|
||||
hooks::use_long_press,
|
||||
ACCOUNT, STORE,
|
||||
},
|
||||
};
|
||||
@@ -167,13 +173,16 @@ pub fn Account() -> Element {
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn ConversationAvatar(room_id: RoomId, on_clicked: EventHandler<RoomId>) -> Element {
|
||||
pub fn ConversationAvatar(
|
||||
room_id: RoomId,
|
||||
on_selected: EventHandler<RoomId>,
|
||||
on_pressed: EventHandler<RoomId>,
|
||||
) -> Element {
|
||||
let long_press_duration = Duration::from_millis(500);
|
||||
|
||||
let rooms = STORE.read().rooms();
|
||||
let toto = rooms.get(&room_id).unwrap();
|
||||
|
||||
let room = toto.signal();
|
||||
|
||||
let room_id = room.id();
|
||||
let room = rooms.get(&room_id).unwrap().signal();
|
||||
let room_id = Rc::new(room_id);
|
||||
let room_name = room.name();
|
||||
|
||||
let selected_room_id = use_context::<Signal<Option<RoomId>>>();
|
||||
@@ -193,7 +202,7 @@ pub fn ConversationAvatar(room_id: RoomId, on_clicked: EventHandler<RoomId>) ->
|
||||
};
|
||||
|
||||
let is_selected = match selected_room_id.read().as_ref() {
|
||||
Some(selected_room_id) => *selected_room_id == room_id,
|
||||
Some(selected_room_id) => *selected_room_id == *room_id,
|
||||
None => false,
|
||||
};
|
||||
|
||||
@@ -232,14 +241,24 @@ pub fn ConversationAvatar(room_id: RoomId, on_clicked: EventHandler<RoomId>) ->
|
||||
];
|
||||
let classes_str = classes.join(" ");
|
||||
|
||||
let on_press = {
|
||||
let room_id = room_id.clone();
|
||||
move || {
|
||||
on_selected.call(room_id.as_ref().clone());
|
||||
}
|
||||
};
|
||||
|
||||
let on_long_press = move || {
|
||||
on_pressed.call(room_id.as_ref().clone());
|
||||
};
|
||||
|
||||
let long_press_hook = use_long_press(long_press_duration, on_press, on_long_press);
|
||||
|
||||
rsx! {
|
||||
div {
|
||||
class: "{classes_str}",
|
||||
|
||||
onclick: move |evt| {
|
||||
on_clicked.call(room_id.clone());
|
||||
evt.stop_propagation();
|
||||
},
|
||||
..long_press_hook.handlers,
|
||||
|
||||
{avatar}
|
||||
{invited_badge}
|
||||
@@ -248,7 +267,10 @@ pub fn ConversationAvatar(room_id: RoomId, on_clicked: EventHandler<RoomId>) ->
|
||||
}
|
||||
|
||||
#[component]
|
||||
pub fn ConversationsCarousel(on_selected_conversation: EventHandler<RoomId>) -> Element {
|
||||
pub fn ConversationsCarousel(
|
||||
on_selected_conversation: EventHandler<RoomId>,
|
||||
on_pressed_conversation: EventHandler<RoomId>,
|
||||
) -> Element {
|
||||
let mut ordered_rooms = use_signal(Vec::<RoomId>::new);
|
||||
|
||||
use_effect(move || {
|
||||
@@ -267,7 +289,8 @@ pub fn ConversationsCarousel(on_selected_conversation: EventHandler<RoomId>) ->
|
||||
rsx! {
|
||||
ConversationAvatar {
|
||||
room_id: room.clone(),
|
||||
on_clicked: on_selected_conversation,
|
||||
on_selected: on_selected_conversation,
|
||||
on_pressed: on_pressed_conversation,
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -286,7 +309,7 @@ pub fn ConversationsCarousel(on_selected_conversation: EventHandler<RoomId>) ->
|
||||
|
||||
// If id is None, the Space will handle all the Conversation which have no parent (Space).
|
||||
#[component]
|
||||
pub fn Space(id: Option<SpaceId>) -> Element {
|
||||
pub fn Space(id: Option<SpaceId>, on_pressed_conversation: EventHandler<RoomId>) -> Element {
|
||||
let mut selected_room_id = use_context_provider(|| Signal::new(None::<RoomId>));
|
||||
let mut displayed_rooms = use_context_provider(|| Signal::new(Vec::<RoomId>::new()));
|
||||
|
||||
@@ -362,44 +385,42 @@ pub fn Space(id: Option<SpaceId>) -> Element {
|
||||
},
|
||||
ConversationsCarousel {
|
||||
on_selected_conversation,
|
||||
on_pressed_conversation,
|
||||
},
|
||||
div {
|
||||
class: ClassName::SPACE_CONVERSATION_NAME,
|
||||
p {
|
||||
{selected_room_name},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn Spaces() -> Element {
|
||||
#[component]
|
||||
pub fn Spaces(on_pressed_conversation: EventHandler<RoomId>) -> Element {
|
||||
let spaces = STORE.read().spaces();
|
||||
let space_ids = spaces.keys().clone().last();
|
||||
|
||||
let rendered_spaces = space_ids.map(|id| {
|
||||
rsx! {
|
||||
Space { id: id.clone() }
|
||||
Space { id: id.clone(), on_pressed_conversation }
|
||||
}
|
||||
});
|
||||
|
||||
rsx! {
|
||||
style { {STYLE_SHEET} },
|
||||
|
||||
div {
|
||||
class: ClassName::SPACES,
|
||||
|
||||
{rendered_spaces},
|
||||
|
||||
Space {},
|
||||
Space { on_pressed_conversation },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn Search() -> Element {
|
||||
rsx! {
|
||||
style { {STYLE_SHEET} },
|
||||
|
||||
div {
|
||||
class: ClassName::SEARCH,
|
||||
|
||||
@@ -415,7 +436,60 @@ pub fn Search() -> Element {
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn ConversationOptionsMenu(room_id: RoomId, on_close: EventHandler) -> Element {
|
||||
rsx! {
|
||||
div {
|
||||
class: ClassName::CONVERSATION_OPTIONS_MENU,
|
||||
|
||||
div {
|
||||
class: ClassName::CONVERSATION_OPTIONS_MENU_INNER,
|
||||
|
||||
div {
|
||||
class: ClassName::CONVERSATION_OPTIONS_MENU_INNER_AVATAR,
|
||||
}
|
||||
|
||||
div {
|
||||
class: ClassName::CONVERSATION_OPTIONS_MENU_INNER_NAME,
|
||||
}
|
||||
|
||||
div {
|
||||
class: ClassName::CONVERSATION_OPTIONS_MENU_INNER_TOPIC,
|
||||
}
|
||||
|
||||
div {
|
||||
class: ClassName::CONVERSATION_OPTIONS_MENU_INNER_CONFIG,
|
||||
}
|
||||
|
||||
div {
|
||||
class: ClassName::CONVERSATION_OPTIONS_MENU_INNER_CLOSE_BUTTON,
|
||||
RejectButton {
|
||||
onclick: move |_| on_close(()),
|
||||
}
|
||||
}
|
||||
|
||||
div {
|
||||
class: ClassName::CONVERSATION_OPTIONS_MENU_INNER_JOIN_BUTTON,
|
||||
JoinButton {
|
||||
onclick: move |_| on_close(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn Conversations() -> Element {
|
||||
let mut conversation_options_menu = use_signal(|| None::<Element>);
|
||||
|
||||
let on_conversation_options_menu_close = move |_| {
|
||||
conversation_options_menu.set(None);
|
||||
};
|
||||
|
||||
let on_pressed_conversation = move |room_id: RoomId| {
|
||||
conversation_options_menu.set(Some(rsx! { ConversationOptionsMenu { room_id, on_close: on_conversation_options_menu_close } }));
|
||||
};
|
||||
|
||||
rsx! {
|
||||
style { {STYLE_SHEET} },
|
||||
|
||||
@@ -429,13 +503,14 @@ pub fn Conversations() -> Element {
|
||||
|
||||
div {
|
||||
class: ClassName::CONVERSATIONS_SPACES,
|
||||
Spaces {},
|
||||
Spaces { on_pressed_conversation },
|
||||
},
|
||||
|
||||
div {
|
||||
class: ClassName::CONVERSATIONS_SEARCH,
|
||||
Search {},
|
||||
},
|
||||
}
|
||||
},
|
||||
{conversation_options_menu}
|
||||
}
|
||||
}
|
||||
|
@@ -10,6 +10,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
@mixin extra-marged-button() {
|
||||
@include button-class();
|
||||
}
|
||||
|
||||
.account {
|
||||
$colum-spacing: 5%;
|
||||
$col-width: 8.75%;
|
||||
@@ -89,10 +93,6 @@
|
||||
grid-area: status;
|
||||
}
|
||||
|
||||
@mixin extra-marged-button() {
|
||||
@include button-class();
|
||||
}
|
||||
|
||||
&__spaces {
|
||||
grid-area: spaces;
|
||||
|
||||
@@ -284,22 +284,107 @@
|
||||
$account-height: 15%;
|
||||
$search-height: 5%;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
gap: $gap;
|
||||
display: grid;
|
||||
grid-template-columns: auto;
|
||||
grid-template-rows: min($account-height, 384px) $gap auto $gap min($search-height, 128px);
|
||||
grid-template-areas:
|
||||
"account"
|
||||
"."
|
||||
"spaces"
|
||||
"."
|
||||
"search"
|
||||
;
|
||||
|
||||
&__account {
|
||||
height: $account-height;
|
||||
max-height: 384px;
|
||||
grid-area: account;
|
||||
}
|
||||
|
||||
&__spaces {
|
||||
min-height: calc(100% - $account-height - $search-height - (2 * $gap));
|
||||
grid-area: spaces;
|
||||
}
|
||||
|
||||
&__search {
|
||||
height: $search-height;
|
||||
max-height: 128px;
|
||||
grid-area: search;
|
||||
}
|
||||
|
||||
&__menu {
|
||||
grid-area: spaces;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.conversation-options-menu {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
position: relative;
|
||||
top: -100%;
|
||||
margin-bottom: calc(-100% / $aspect-ratio);
|
||||
|
||||
border-radius: $border-radius;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
|
||||
&__inner {
|
||||
$padding: 5%;
|
||||
// TODO: Thin border
|
||||
@include panel($padding, $padding);
|
||||
|
||||
width: 95%;
|
||||
height: 60%;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 10% 10% 5% 15% 20% 10% 20% 10%;
|
||||
grid-template-rows: 7.5% 7.5% 5% 5% auto 5% 10%;
|
||||
grid-template-areas:
|
||||
"avatar avatar . name name name name name"
|
||||
"avatar avatar . topic topic topic topic topic"
|
||||
"avatar avatar . . . . . ."
|
||||
". . . . . . . ."
|
||||
"config config config config config config config config"
|
||||
". . . . . . . ."
|
||||
". close close close . join join ."
|
||||
;
|
||||
|
||||
&__avatar {
|
||||
grid-area: avatar;
|
||||
|
||||
width: 100%;
|
||||
aspect-ratio: 1;
|
||||
|
||||
background-color: green;
|
||||
}
|
||||
|
||||
&__name {
|
||||
grid-area: name;
|
||||
background-color: orange;
|
||||
}
|
||||
|
||||
&__topic {
|
||||
grid-area: topic;
|
||||
background-color: aqua;
|
||||
}
|
||||
|
||||
&__config {
|
||||
grid-area: config;
|
||||
background-color: purple;
|
||||
}
|
||||
|
||||
button {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__close-button {
|
||||
grid-area: close;
|
||||
}
|
||||
|
||||
&__join-button {
|
||||
grid-area: join;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -619,7 +619,6 @@ pub fn Login() -> Element {
|
||||
});
|
||||
|
||||
if *spinner_animated.read() && SESSION.read().is_logged {
|
||||
debug!("Stop spinner");
|
||||
spinner_animated.set(false);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user