🎨 Split ContactsWindow component + use of dioxus-free-icons

This commit is contained in:
2023-08-04 22:34:09 +02:00
parent 54a50c1ff0
commit 45d5eb704c
7 changed files with 502 additions and 473 deletions

View File

@@ -1,4 +1,6 @@
pub mod avatar_selector;
pub mod control_window;
pub mod contacts;
pub mod contacts_window;
pub mod header;
pub mod login;
pub mod user_infos;

143
src/components/contacts.rs Normal file
View File

@@ -0,0 +1,143 @@
use dioxus::prelude::*;
use dioxus_free_icons::icons::io_icons::IoChevronDown;
use dioxus_free_icons::Icon;
use sir::global_css;
fn ContactsArrow(cx: Scope) -> Element {
cx.render(rsx! {
Icon {
icon: IoChevronDown,
},
})
}
pub fn Contacts(cx: Scope) -> Element {
// TODO: Use @extend once implemented (https://github.com/kaj/rsass/issues/65)
global_css!(
"
.contacts {
height: 72%;
width: 100%;
background-color: white;
font-size: 8pt;
&.active {
ul {
opacity: 0;
}
svg {
transform: rotate(180deg);
}
}
.header {
height: 2%;
width: 98%;
display: flex;
flex-direction: row;
align-items: center;
cursor: pointer;
margin: 0;
margin-left: 1%;
padding-top: 1%;
font-weight: bold;
}
ul {
height: 100%;
margin: 0;
overflow: hidden;
opacity: 1;
transition: 0.4s ease;
}
li {
list-style-type: none;
height: 2%;
margin: 0 auto;
cursor: pointer;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
img {
height: 100%;
aspect-ratio: 1;
}
}
svg {
transition: 0.4s ease;
}
.contact {
list-style-type: none
margin: 0 auto
text-align: left
cursor: pointer
}
}
"
);
let show_contacts = use_state(cx, || false);
let contacts_active = if **show_contacts { "active" } else { "" };
cx.render(rsx! {
div {
class: "contacts {contacts_active}",
p {
class: "header",
onclick: move |_| show_contacts.set(!show_contacts),
ContactsArrow {},
"Online (4)",
},
// TODO: Test overflow
ul {
li {
img {
src: "./images/status_online.png",
},
p {
"Contact AAAAAAAA -",
},
p {
style: "color: darkgrey;",
"i'm sad all day until i get to talk with friends, online friends that is",
},
},
li {
img {
src: "./images/status_busy.png",
},
p {
"Contact BBBBBB -",
},
p {
style: "color: darkgrey;",
"i'm sad all day until i get to talk with friends, online friends that is",
}
},
li {
img {
src: "./images/status_away.png",
},
p {
"Contact CCC -",
},
p {
style: "color: darkgrey;",
"i'm sad all day until i get to talk with friends, online friends that is",
}
},
},
},
})
}

View File

@@ -0,0 +1,187 @@
use dioxus::prelude::*;
use sir::css;
use crate::app_settings::AppSettings;
use crate::components::contacts::Contacts;
use crate::components::header::Header;
use crate::components::user_infos::UserInfos;
pub fn ContactWindow(cx: Scope) -> Element {
let app_context = use_shared_state::<AppSettings>(cx).unwrap();
let root = css!(
"
width: 100%;
height: 100%;
background-color: #ECF6F9;
font-family: \"Tahoma\", sans-serif;
border: thin solid #707070;
border-radius: 8px;
box-shadow: 0 0 5px #00000050;
"
);
let header = css!(
"
height: 10%;
width: 100%;
"
);
let title_bar = css!(
"
height: 60%;
width: 100%;
background:
linear-gradient(180deg, #7DC5E3, #3883A3);
"
);
let user_info = css!(
"
height: 40%;
width: 100%;
background:
linear-gradient(180deg, #00658B, #0077A6);
"
);
let contacts_nav = css!(
"
height: calc(31/1080*100%);
background:
linear-gradient(180deg, #00658B, #0077A6);
"
);
let contacts_nav_inner = css!(
"
margin-left: 1%;
margin-right: 1%;
height: 100%;
display: flex;
align-items: center;
"
);
let search = css!(
"
height: calc(38/1080*100%);
width: 100%;
border-bottom: thin solid #e2eaf3;
"
);
// TODO: Remove following div
let search_inner = css!(
"
height: 100%;
width: 98%;
padding-left: 1%;
display: flex;
flex-direction: row;
align-items: center;
"
);
let search_input = css!(
"
height: calc(23/38*100%);
width: 100%;
margin-right: 1%;
border: thin solid #c7c7c7;
box-shadow: inset 0 0 calc(3/1080*100%) #0000002a;
font-size: 8pt;
padding-left: 1%;
"
);
let footer = css!(
"
height: 10%;
"
);
cx.render(rsx! {
div {
class: "{root}",
div {
class: "{header}",
div {
class: "{title_bar}",
},
div {
class: "{user_info}",
},
UserInfos {},
},
div {
class: "{contacts_nav}",
div {
class: "{contacts_nav_inner}",
button {
class: "aero-button",
style: "background: url(./images/letter.png) center no-repeat",
},
button {
class: "aero-button",
style: "background: url(./images/directory.png) no-repeat center",
},
button {
class: "aero-button",
style: "background: url(./images/news.png) no-repeat center",
},
button {
class: "aero-button flex-right",
style: "background: url(./images/brush.png) no-repeat center",
},
button {
class: "aero-button",
style: "background: url(./images/settings.png) no-repeat center",
},
},
},
div {
class: "{search}",
div {
class: "{search_inner}",
input {
class: "{search_input}",
placeholder: "Find a contact...",
r#type: "text",
},
button {
class: "button",
style: "background: url(./images/add_user.png) no-repeat center",
},
button {
class: "button",
style: "background: url(./images/tbc_transfert.png) no-repeat center",
},
},
},
Contacts {},
div {
class: "{footer}",
},
},
})
}

View File

@@ -1,467 +0,0 @@
use dioxus::prelude::*;
use sir::{css, global_css};
use crate::app_settings::AppSettings;
use crate::components::avatar_selector::AvatarSelector;
use crate::components::header::Header;
pub fn ControlWindow(cx: Scope) -> Element {
let app_context = use_shared_state::<AppSettings>(cx).unwrap();
println!("app_context={:?}", app_context.read());
// TODO: Use @extend once implemented (https://github.com/kaj/rsass/issues/65)
global_css!(
"
.aero-button {
height: 50%;
min-height: 16px;
aspect-ratio: 1;
background-color: transparent;
border: 2px solid transparent;
background-size: contain !important;
margin-right: 1%;
}
.aero-button:hover {
border-image: url(./images/aerobutton_border.png) 2 round;
}
.aero-button:active {
border-image: url(./images/aerobutton_border_down.png) 2 round;
}
.button {
height: 50%;
min-height: 16px;
aspect-ratio: 1;
background-color: transparent;
border: 2px solid transparent;
background-size: contain !important;
margin-right: 1%;
}
.button:hover {
border-image: url(./images/button_border.png) 2 round;
}
.button:active {
border-image: url(./images/button_border_down.png) 2 round;
}
.flex-right {
margin-left: auto;
}
.user-info {
position: relative;
height: 75%;
width: 99%;
top: -75%;
left: 1%;
aspect-ratio: 1;
z-index: 1;
display: flex;
flex-direction: row;
align-items: center;
.avatar-selector {
height: 100%;
aspect-ratio: 1;
}
.info-container {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
height: 100%;
width: 100%;
.user-id {
height: 30%;
width: fit-content;
display: flex;
text-align: begin;
align-items: center;
.user-name {
display: inline-block;
width: fit-content;
color: white;
margin: 0;
}
.user-status {
display: inline-block;
color: #B9DDE7;
width: fit-content;
//margin-left: 1%;
//padding-left: 1%;
}
}
.user-message {
width: fit-content;
height: 30%;
display: flex;
text-align: begin;
align-items: center;
margin: 0;
color: white;
}
}
}
// From https://codepen.io/zoomodesign/pen/yNbVVZ
.contacts {
height: 72%;
width: 100%;
background-color: white;
font-size: 8pt;
&.active {
.arrow {
transform: rotate(45deg) translate(-5px,-5px);
&:before {
transform: translate(10px,0);
}
&:after {
transform: rotate(90deg) translate(10px,0);
}
}
ul {
opacity: 0;
}
}
.header {
height: 2%;
width: 98%;
display: flex;
flex-direction: row;
align-items: center;
cursor: pointer;
margin: 0;
margin-left: 1%;
padding-top: 1%;
font-weight: bold;
}
ul {
height: 100%;
margin: 0;
overflow: hidden;
opacity: 1;
transition: 0.4s ease;
}
li {
list-style-type: none;
height: 2%;
margin: 0 auto;
cursor: pointer;
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
img {
height: 100%;
aspect-ratio: 1;
}
}
.arrow {
width: calc((100%/1080)*10);
aspect-ratio: 1;
display: inline-block;
transition: 0.4s ease;
margin-top: calc((100%/1080)*2);
margin-right: 2%;
text-align: left;
transform: rotate(45deg);
float: right;
&:before, &:after {
position: absolute;
content: '';
display: inline-block;
width: 100%;
height: 15%;
background-color: #000;
transition: 0.4s ease;
}
&:after {
position: absolute;
transform: rotate(90deg);
top: -5px;
left: 5px;
}
}
.contact {
list-style-type: none
margin: 0 auto
text-align: left
cursor: pointer
}
}
"
);
let root = css!(
"
width: 100%;
height: 100%;
background-color: #ECF6F9;
font-family: \"Tahoma\", sans-serif;
border: thin solid #707070;
border-radius: 8px;
box-shadow: 0 0 5px #00000050;
"
);
let header = css!(
"
height: 10%;
width: 100%;
"
);
let title_bar = css!(
"
height: 60%;
width: 100%;
background:
linear-gradient(180deg, #7DC5E3, #3883A3);
"
);
let user_info = css!(
"
height: 40%;
width: 100%;
background:
linear-gradient(180deg, #00658B, #0077A6);
"
);
let contacts_nav = css!(
"
height: calc(31/1080*100%);
background:
linear-gradient(180deg, #00658B, #0077A6);
"
);
let contacts_nav_inner = css!(
"
margin-left: 1%;
margin-right: 1%;
height: 100%;
display: flex;
align-items: center;
"
);
let search = css!(
"
height: calc(38/1080*100%);
width: 100%;
border-bottom: thin solid #e2eaf3;
"
);
// TODO: Remove following div
let search_inner = css!(
"
height: 100%;
width: 98%;
padding-left: 1%;
display: flex;
flex-direction: row;
align-items: center;
"
);
let search_input = css!(
"
height: calc(23/38*100%);
width: 100%;
margin-right: 1%;
border: thin solid #c7c7c7;
box-shadow: inset 0 0 calc(3/1080*100%) #0000002a;
font-size: 8pt;
padding-left: 1%;
"
);
let footer = css!(
"
height: 10%;
"
);
let show_contacts = use_state(cx, || false);
let contacts_active = if **show_contacts { "active" } else { "" };
cx.render(rsx! {
div {
class: "{root}",
div {
class: "{header}",
div {
class: "{title_bar}",
},
div {
class: "{user_info}",
},
div {
class: "user-info",
div {
class: "avatar-selector",
AvatarSelector {},
},
div {
class: "info-container",
div {
class: "aero-button user-id",
p {
class: "user-name",
"SUPER USER"
},
p {
class: "user-status",
"(Busy)",
},
},
div {
class: "aero-button user-message",
p {
"My message",
}
},
},
},
},
div {
class: "{contacts_nav}",
div {
class: "{contacts_nav_inner}",
button {
class: "aero-button",
style: "background: url(./images/letter.png) center no-repeat",
},
button {
class: "aero-button",
style: "background: url(./images/directory.png) no-repeat center",
},
button {
class: "aero-button",
style: "background: url(./images/news.png) no-repeat center",
},
button {
class: "aero-button flex-right",
style: "background: url(./images/brush.png) no-repeat center",
},
button {
class: "aero-button",
style: "background: url(./images/settings.png) no-repeat center",
},
},
},
div {
class: "{search}",
div {
class: "{search_inner}",
input {
class: "{search_input}",
placeholder: "Find a contact...",
r#type: "text",
},
button {
class: "button",
style: "background: url(./images/add_user.png) no-repeat center",
},
button {
class: "button",
style: "background: url(./images/tbc_transfert.png) no-repeat center",
},
},
},
div {
class: "contacts {contacts_active}",
p {
class: "header",
onclick: move |_| show_contacts.set(!show_contacts),
span {
class: "arrow",
},
"Online (4)",
},
// TODO: Test overflow
ul {
li {
img {
src: "./images/status_online.png",
},
p {
"Contact AAAAAAAA -",
},
p {
style: "color: darkgrey;",
"i'm sad all day until i get to talk with friends, online friends that is",
},
},
li {
img {
src: "./images/status_busy.png",
},
p {
"Contact BBBBBB -",
},
p {
style: "color: darkgrey;",
"i'm sad all day until i get to talk with friends, online friends that is",
}
},
li {
img {
src: "./images/status_away.png",
},
p {
"Contact CCC -",
},
p {
style: "color: darkgrey;",
"i'm sad all day until i get to talk with friends, online friends that is",
}
},
},
},
div {
class: "{footer}",
},
},
})
}

View File

@@ -0,0 +1,129 @@
use dioxus::prelude::*;
use dioxus_free_icons::icons::md_navigation_icons::MdArrowDropDown;
use dioxus_free_icons::Icon;
use sir::{css, global_css};
use crate::components::avatar_selector::AvatarSelector;
fn DownArrowIcon(cx: Scope) -> Element {
let style = css!(
"
color: transparent;
path:last-child {
fill: white;
}
"
);
cx.render(rsx! {
Icon {
class: "{style}",
icon: MdArrowDropDown,
}
})
}
pub fn UserInfos(cx: Scope) -> Element {
global_css!(
"
.flex-right {
margin-left: auto;
}
.user-info {
position: relative;
height: 75%;
width: 99%;
top: -75%;
left: 1%;
aspect-ratio: 1;
z-index: 1;
display: flex;
flex-direction: row;
align-items: center;
.avatar-selector {
height: 100%;
aspect-ratio: 1;
}
.info-container {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
height: 100%;
width: 100%;
// font-size: 8pt;
.user-id {
height: 30%;
width: fit-content;
display: flex;
text-align: begin;
align-items: center;
.user-name {
display: inline-block;
width: fit-content;
color: white;
margin: 0;
// font-size: 10pt;
}
.user-status {
display: inline-block;
width: fit-content;
color: #B9DDE7;
}
}
.user-message {
width: fit-content;
height: 30%;
display: flex;
text-align: begin;
align-items: center;
margin: 0;
color: white;
}
}
}"
);
cx.render(rsx! {
div {
class: "user-info",
div {
class: "avatar-selector",
AvatarSelector {},
},
div {
class: "info-container",
div {
class: "aero-button user-id",
p {
class: "user-name",
"SUPER USER"
},
p {
class: "user-status",
"(Busy)",
},
DownArrowIcon {},
},
div {
class: "aero-button user-message",
p {
"My message",
}
DownArrowIcon {},
},
},
},
})
}

View File

@@ -1,6 +1,7 @@
#![allow(non_snake_case)]
use dioxus::prelude::*;
use dioxus_desktop::Config;
use sir::{global_css, AppStyle};
pub mod app_settings;
@@ -8,7 +9,7 @@ pub mod components;
pub mod matrix_client;
use crate::app_settings::AppSettings;
use crate::components::control_window::ControlWindow;
use crate::components::contacts_window::ContactWindow;
use crate::components::login::Login;
mod base;
@@ -27,9 +28,42 @@ fn App(cx: Scope<AppSettings>) -> Element {
font-family: Tahoma, sans-serif;
}
#main {
height: 100%;
width: 100%;
}"
height: 100%;
width: 100%;
}
.aero-button {
height: 50%;
min-height: 16px;
aspect-ratio: 1;
background-color: transparent;
border: 2px solid transparent;
background-size: contain !important;
margin-right: 1%;
}
.aero-button:hover {
border-image: url(./images/aerobutton_border.png) 2 round;
}
.aero-button:active {
border-image: url(./images/aerobutton_border_down.png) 2 round;
}
.button {
height: 50%;
min-height: 16px;
aspect-ratio: 1;
background-color: transparent;
border: 2px solid transparent;
background-size: contain !important;
margin-right: 1%;
}
.button:hover {
border-image: url(./images/button_border.png) 2 round;
}
.button:active {
border-image: url(./images/button_border_down.png) 2 round;
}
"
);
// let window = dioxus_desktop::use_window(cx);
@@ -39,7 +73,7 @@ fn App(cx: Scope<AppSettings>) -> Element {
cx.render(rsx! {
AppStyle {},
// Login {}
ControlWindow {}
ContactWindow {}
})
}