diff --git a/Cargo.toml b/Cargo.toml index 67ae498..4771c13 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ tokio = "1.29.1" dirs = "5.0.1" ctrlc-async = "3.2.2" tracing-subscriber = "0.3.17" +dioxus-free-icons = { version = "0.6.0", features = ["material-design-icons-navigation", "ionicons"] } [build] target = "x86_64-unknown-linux-gnu" diff --git a/src/components.rs b/src/components.rs index ce11cfa..31b9630 100644 --- a/src/components.rs +++ b/src/components.rs @@ -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; diff --git a/src/components/contacts.rs b/src/components/contacts.rs new file mode 100644 index 0000000..922fcc3 --- /dev/null +++ b/src/components/contacts.rs @@ -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", + } + }, + }, + }, + }) +} diff --git a/src/components/contacts_window.rs b/src/components/contacts_window.rs new file mode 100644 index 0000000..a84a85e --- /dev/null +++ b/src/components/contacts_window.rs @@ -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::(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}", + }, + }, + }) +} diff --git a/src/components/control_window.rs b/src/components/control_window.rs deleted file mode 100644 index 17df33e..0000000 --- a/src/components/control_window.rs +++ /dev/null @@ -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::(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}", - }, - }, - }) -} diff --git a/src/components/user_infos.rs b/src/components/user_infos.rs new file mode 100644 index 0000000..db1fa3e --- /dev/null +++ b/src/components/user_infos.rs @@ -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 {}, + }, + }, + }, + }) +} diff --git a/src/main.rs b/src/main.rs index b66ce5d..bf29218 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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) -> 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) -> Element { cx.render(rsx! { AppStyle {}, // Login {} - ControlWindow {} + ContactWindow {} }) }