feat: show facepill on tabpanel
This commit is contained in:
@@ -35,7 +35,7 @@ impl RenderOnce for Message {
|
||||
.border_l_2()
|
||||
.border_color(cx.theme().background)
|
||||
.hover(|this| {
|
||||
this.bg(cx.theme().accent.step(cx, ColorScaleStep::TWO))
|
||||
this.bg(cx.theme().accent.step(cx, ColorScaleStep::ONE))
|
||||
.border_color(cx.theme().accent.step(cx, ColorScaleStep::NINE))
|
||||
})
|
||||
.child(
|
||||
|
||||
@@ -386,8 +386,15 @@ impl Panel for ChatPanel {
|
||||
self.id.clone()
|
||||
}
|
||||
|
||||
fn panel_metadata(&self) -> Option<Metadata> {
|
||||
None
|
||||
fn panel_facepile(&self, cx: &WindowContext) -> Option<Vec<String>> {
|
||||
Some(
|
||||
self.room
|
||||
.read(cx)
|
||||
.members
|
||||
.iter()
|
||||
.map(|member| member.avatar())
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
fn title(&self, _cx: &WindowContext) -> AnyElement {
|
||||
|
||||
@@ -13,7 +13,6 @@ smallvec.workspace = true
|
||||
anyhow.workspace = true
|
||||
itertools.workspace = true
|
||||
chrono.workspace = true
|
||||
nostr-sdk.workspace = true
|
||||
|
||||
paste = "1"
|
||||
regex = "1"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,6 @@ use gpui::{
|
||||
AnyElement, AnyView, AppContext, EventEmitter, FocusHandle, FocusableView, Global, Hsla,
|
||||
IntoElement, SharedString, View, WeakView, WindowContext,
|
||||
};
|
||||
use nostr_sdk::prelude::Metadata;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
pub enum PanelEvent {
|
||||
@@ -38,8 +37,8 @@ pub trait Panel: EventEmitter<PanelEvent> + FocusableView {
|
||||
/// Once you have defined a panel id, this must not be changed.
|
||||
fn panel_id(&self) -> SharedString;
|
||||
|
||||
/// The optional metadata of the panel
|
||||
fn panel_metadata(&self) -> Option<Metadata> {
|
||||
/// The optional facepile of the panel
|
||||
fn panel_facepile(&self, _cx: &WindowContext) -> Option<Vec<String>> {
|
||||
None
|
||||
}
|
||||
|
||||
@@ -76,7 +75,7 @@ pub trait Panel: EventEmitter<PanelEvent> + FocusableView {
|
||||
|
||||
pub trait PanelView: 'static + Send + Sync {
|
||||
fn panel_id(&self, cx: &WindowContext) -> SharedString;
|
||||
fn panel_metadata(&self, cx: &WindowContext) -> Option<Metadata>;
|
||||
fn panel_facepile(&self, cx: &WindowContext) -> Option<Vec<String>>;
|
||||
fn title(&self, _cx: &WindowContext) -> AnyElement;
|
||||
fn closeable(&self, cx: &WindowContext) -> bool;
|
||||
fn zoomable(&self, cx: &WindowContext) -> bool;
|
||||
@@ -92,8 +91,8 @@ impl<T: Panel> PanelView for View<T> {
|
||||
self.read(cx).panel_id()
|
||||
}
|
||||
|
||||
fn panel_metadata(&self, cx: &WindowContext) -> Option<Metadata> {
|
||||
self.read(cx).panel_metadata()
|
||||
fn panel_facepile(&self, cx: &WindowContext) -> Option<Vec<String>> {
|
||||
self.read(cx).panel_facepile(cx)
|
||||
}
|
||||
|
||||
fn title(&self, cx: &WindowContext) -> AnyElement {
|
||||
|
||||
@@ -516,26 +516,25 @@ impl TabPanel {
|
||||
.gap_1()
|
||||
.text_ellipsis()
|
||||
.text_xs()
|
||||
.child(div().when_some(
|
||||
panel.panel_metadata(cx),
|
||||
|this, metadata| {
|
||||
if let Some(picture) = metadata.picture {
|
||||
this.flex_shrink_0().child(
|
||||
img(format!(
|
||||
"https://wsrv.nl/?url={}&w=100&h=100&n=-1",
|
||||
picture
|
||||
))
|
||||
.size_4()
|
||||
.rounded_full()
|
||||
.object_fit(ObjectFit::Cover),
|
||||
)
|
||||
} else {
|
||||
this.flex_shrink_0().child(
|
||||
img("brand/avatar.png").size_4().rounded_full(),
|
||||
)
|
||||
}
|
||||
},
|
||||
))
|
||||
.when_some(panel.panel_facepile(cx), |this, facepill| {
|
||||
this.child(
|
||||
div()
|
||||
.flex()
|
||||
.flex_row_reverse()
|
||||
.items_center()
|
||||
.justify_start()
|
||||
.children(facepill.into_iter().enumerate().rev().map(
|
||||
|(ix, face)| {
|
||||
div().when(ix > 0, |div| div.ml_neg_1()).child(
|
||||
img(face)
|
||||
.size_4()
|
||||
.rounded_full()
|
||||
.object_fit(ObjectFit::Cover),
|
||||
)
|
||||
},
|
||||
)),
|
||||
)
|
||||
})
|
||||
.child(panel.title(cx)),
|
||||
)
|
||||
.when(state.draggable, |this| {
|
||||
@@ -595,7 +594,7 @@ impl TabPanel {
|
||||
active = false;
|
||||
}
|
||||
|
||||
Tab::new(("tab", ix), panel.title(cx), panel.panel_metadata(cx))
|
||||
Tab::new(("tab", ix), panel.title(cx), panel.panel_facepile(cx))
|
||||
.py_2()
|
||||
.selected(active)
|
||||
.disabled(disabled)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use std::time::Duration;
|
||||
|
||||
use gpui::{ModelContext, Timer};
|
||||
use std::time::Duration;
|
||||
|
||||
static INTERVAL: Duration = Duration::from_millis(500);
|
||||
static PAUSE_DELAY: Duration = Duration::from_millis(300);
|
||||
@@ -72,6 +71,7 @@ impl BlinkCursor {
|
||||
|
||||
// delay 500ms to start the blinking
|
||||
let epoch = self.next_epoch();
|
||||
|
||||
cx.spawn(|this, mut cx| async move {
|
||||
Timer::after(PAUSE_DELAY).await;
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ use crate::theme::ActiveTheme;
|
||||
use crate::Selectable;
|
||||
use gpui::prelude::FluentBuilder;
|
||||
use gpui::*;
|
||||
use nostr_sdk::prelude::*;
|
||||
|
||||
pub mod tab_bar;
|
||||
|
||||
@@ -12,7 +11,7 @@ pub struct Tab {
|
||||
id: ElementId,
|
||||
base: Stateful<Div>,
|
||||
label: AnyElement,
|
||||
metadata: Option<Metadata>,
|
||||
facepill: Option<Vec<String>>,
|
||||
prefix: Option<AnyElement>,
|
||||
suffix: Option<AnyElement>,
|
||||
disabled: bool,
|
||||
@@ -23,7 +22,7 @@ impl Tab {
|
||||
pub fn new(
|
||||
id: impl Into<ElementId>,
|
||||
label: impl IntoElement,
|
||||
metadata: Option<Metadata>,
|
||||
facepill: Option<Vec<String>>,
|
||||
) -> Self {
|
||||
let id: ElementId = id.into();
|
||||
|
||||
@@ -31,11 +30,11 @@ impl Tab {
|
||||
id: id.clone(),
|
||||
base: div().id(id),
|
||||
label: label.into_any_element(),
|
||||
metadata,
|
||||
disabled: false,
|
||||
selected: false,
|
||||
prefix: None,
|
||||
suffix: None,
|
||||
facepill,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,19 +142,25 @@ impl RenderOnce for Tab {
|
||||
.gap_1()
|
||||
.text_ellipsis()
|
||||
.text_xs()
|
||||
.child(div().when_some(self.metadata, |this, metadata| {
|
||||
if let Some(picture) = metadata.picture {
|
||||
this.flex_shrink_0().child(
|
||||
img(format!("https://wsrv.nl/?url={}&w=100&h=100&n=-1", picture))
|
||||
.size_4()
|
||||
.rounded_full()
|
||||
.object_fit(ObjectFit::Cover),
|
||||
)
|
||||
} else {
|
||||
this.flex_shrink_0()
|
||||
.child(img("brand/avatar.png").size_4().rounded_full())
|
||||
}
|
||||
}))
|
||||
.when_some(self.facepill, |this, facepill| {
|
||||
this.child(
|
||||
div()
|
||||
.flex()
|
||||
.flex_row_reverse()
|
||||
.items_center()
|
||||
.justify_start()
|
||||
.children(facepill.into_iter().enumerate().rev().map(
|
||||
|(ix, face)| {
|
||||
div().when(ix > 0, |div| div.ml_neg_1()).child(
|
||||
img(face)
|
||||
.size_4()
|
||||
.rounded_full()
|
||||
.object_fit(ObjectFit::Cover),
|
||||
)
|
||||
},
|
||||
)),
|
||||
)
|
||||
})
|
||||
.child(self.label),
|
||||
)
|
||||
.when_some(self.suffix, |this, suffix| this.child(suffix))
|
||||
|
||||
Reference in New Issue
Block a user