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! { rsx! {
style { {STYLE_SHEET} } style { {STYLE_SHEET} }
@@ -142,14 +152,61 @@ fn LayoutSmall() -> Element {
} }
{conversation_panels.iter()} {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::TAB_AVATAR_IMAGE,
background_image: format!("url(data:image/jpeg;base64,{encoded})"),
}
}
}
} else {
VNode::empty()
};
rsx! {
div {
class: ClassName::TAB,
{room_avatar}
div { div {
class: ClassName::CONVERSATIONS_VIEW_TAIL, 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 { fn LayoutBig() -> Element {
let mut carousel_div = use_signal(|| None::<Rc<MountedData>>); let mut carousel_div = use_signal(|| None::<Rc<MountedData>>);
let mut first_div = use_signal(|| None::<Rc<MountedData>>); let mut first_div = use_signal(|| None::<Rc<MountedData>>);
@@ -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! { rsx! {
style { {STYLE_SHEET} } style { {STYLE_SHEET} }
@@ -217,7 +284,11 @@ fn LayoutBig() -> Element {
div { div {
class: ClassName::CONVERSATIONS_VIEW_BIG_CONVERSATIONS, class: ClassName::CONVERSATIONS_VIEW_BIG_CONVERSATIONS,
div {
class: ClassName::CONVERSATIONS_VIEW_BIG_CONVERSATIONS_TABS_BAR,
TabsBar { room_ids: displayed_room_ids}
}
div { div {
class: ClassName::CONVERSATIONS_VIEW_BIG_CONVERSATIONS_PANELS, class: ClassName::CONVERSATIONS_VIEW_BIG_CONVERSATIONS_PANELS,
@@ -244,10 +315,6 @@ fn LayoutBig() -> Element {
} }
{conversation_panels.iter()} {conversation_panels.iter()}
div {
class: ClassName::CONVERSATIONS_VIEW_TAIL,
}
} }
} }
} }
@@ -255,7 +322,7 @@ fn LayoutBig() -> Element {
} }
pub fn Conversations() -> Element { pub fn Conversations() -> Element {
let mut layout = use_signal(|| None::<VNode>); let mut use_big_layout = use_signal(|| false);
rsx! { rsx! {
style { {STYLE_SHEET} } style { {STYLE_SHEET} }
@@ -269,21 +336,20 @@ pub fn Conversations() -> Element {
onresize: move |cx| { onresize: move |cx| {
let data = cx.data(); let data = cx.data();
let mut use_big_layout = false;
if let Ok(size) = data.get_border_box_size() { if let Ok(size) = data.get_border_box_size() {
// Use LayoutBig if the layout can contain 2 panels side by side // Use LayoutBig if the layout can contain 2 panels side by side
let component_width = size.height * INNER_PANEL_HEIGHT_RATIO * ASPECT_RATIO; let component_width = size.height * INNER_PANEL_HEIGHT_RATIO * ASPECT_RATIO;
let breakpoint_width = component_width * 2_f64; 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%; width: 100%;
flex-grow: 0; flex-grow: 0;
// overflow: scroll;
// scrollbar-width: none;
} }
&__panels { &__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;
}
}