2 Commits

2 changed files with 140 additions and 16 deletions

View File

@@ -100,6 +100,16 @@ fn LayoutSmall() -> Element {
}
}
// Add tail div to dynamic rendered conversation_panels avoids side effects on layout changes
conversation_panels.push(
rsx! {
div {
class: ClassName::CONVERSATIONS_VIEW_TAIL,
}
}
.unwrap(),
);
rsx! {
style { {STYLE_SHEET} }
@@ -142,12 +152,59 @@ fn LayoutSmall() -> Element {
}
{conversation_panels.iter()}
}
}
}
#[component]
fn Tab(room_id: RoomId) -> Element {
let rooms = STORE.read().rooms();
let room = rooms.get(&room_id).unwrap().signal();
let room_avatar = if let Some(content) = room.avatar() {
let encoded = general_purpose::STANDARD.encode(content);
rsx! {
div {
class: ClassName::TAB_AVATAR_IMAGE,
div {
class: ClassName::CONVERSATIONS_VIEW_TAIL,
class: ClassName::TAB_AVATAR_IMAGE,
background_image: format!("url(data:image/jpeg;base64,{encoded})"),
}
}
}
} else {
VNode::empty()
};
rsx! {
div {
class: ClassName::TAB,
{room_avatar}
div {
class: ClassName::TAB_NAME,
{room.name()}
}
}
}
}
#[component]
fn TabsBar(room_ids: HashSet<RoomId>) -> Element {
let tabs = room_ids
.iter()
.map(|room_id| rsx! { Tab { room_id: room_id.clone() }});
rsx! {
div {
class: ClassName::TABS_BAR,
{tabs}
}
}
}
fn LayoutBig() -> Element {
@@ -202,6 +259,16 @@ fn LayoutBig() -> Element {
}
}
// Add tail div to dynamic rendered conversation_panels avoids side effects on layout changes
conversation_panels.push(
rsx! {
div {
class: ClassName::CONVERSATIONS_VIEW_TAIL,
}
}
.unwrap(),
);
rsx! {
style { {STYLE_SHEET} }
@@ -217,7 +284,11 @@ fn LayoutBig() -> Element {
div {
class: ClassName::CONVERSATIONS_VIEW_BIG_CONVERSATIONS,
div {
class: ClassName::CONVERSATIONS_VIEW_BIG_CONVERSATIONS_TABS_BAR,
TabsBar { room_ids: displayed_room_ids}
}
div {
class: ClassName::CONVERSATIONS_VIEW_BIG_CONVERSATIONS_PANELS,
@@ -244,10 +315,6 @@ fn LayoutBig() -> Element {
}
{conversation_panels.iter()}
div {
class: ClassName::CONVERSATIONS_VIEW_TAIL,
}
}
}
}
@@ -255,7 +322,7 @@ fn LayoutBig() -> Element {
}
pub fn Conversations() -> Element {
let mut layout = use_signal(|| None::<VNode>);
let mut use_big_layout = use_signal(|| false);
rsx! {
style { {STYLE_SHEET} }
@@ -269,21 +336,20 @@ pub fn Conversations() -> Element {
onresize: move |cx| {
let data = cx.data();
let mut use_big_layout = false;
if let Ok(size) = data.get_border_box_size() {
// Use LayoutBig if the layout can contain 2 panels side by side
let component_width = size.height * INNER_PANEL_HEIGHT_RATIO * ASPECT_RATIO;
let breakpoint_width = component_width * 2_f64;
use_big_layout = size.width > breakpoint_width;
use_big_layout.set(size.width > breakpoint_width);
}
// let layout_result = rsx! { if use_big_layout { LayoutBig {} } else { LayoutSmall {} }};
let layout_result = rsx! { LayoutBig {} };
layout.set(Some(layout_result.unwrap()));
},
{layout}
if use_big_layout() {
LayoutBig {}
} else {
LayoutSmall {}
}
}
}
}

View File

@@ -125,9 +125,6 @@ $inner-panel-height-ratio: 0.95;
width: 100%;
flex-grow: 0;
// overflow: scroll;
// scrollbar-width: none;
}
&__panels {
@@ -155,3 +152,64 @@ $inner-panel-height-ratio: 0.95;
}
}
}
.tabs-bar {
$gap: min(1vw, 8px);
height: 100%;
width: 100%;
display: flex;
gap: $gap;
overflow: scroll;
scrollbar-width: none;
white-space: nowrap;
}
.tab {
$gap: min(1vw, 8px);
height: 100%;
min-width: 0px;
max-width: 100%;
flex-shrink: 0;
display: inline-flex;
align-items: center;
gap: $gap;
border: $border-normal;
border-color: get-color(primary, 90);
border-radius: $border-radius;
padding: calc($gap / 2) $gap;
font-size: 2vh;
background-color: get-color(greyscale, 0);
&__avatar-image {
height: 100%;
aspect-ratio: 1;
border: $border-thin;
border-color: get-color(greyscale, 90);
border-radius: $border-radius;
background-size: cover;
}
&__name {
display: inline-block;
margin: 0px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
cursor: default3;
}
}