@@ -27,8 +27,10 @@ use ui::button::{Button, ButtonVariants};
|
|||||||
use ui::dock_area::dock::DockPlacement;
|
use ui::dock_area::dock::DockPlacement;
|
||||||
use ui::dock_area::panel::PanelView;
|
use ui::dock_area::panel::PanelView;
|
||||||
use ui::dock_area::{ClosePanel, DockArea, DockItem};
|
use ui::dock_area::{ClosePanel, DockArea, DockItem};
|
||||||
|
use ui::indicator::Indicator;
|
||||||
use ui::modal::ModalButtonProps;
|
use ui::modal::ModalButtonProps;
|
||||||
use ui::popup_menu::PopupMenuExt;
|
use ui::popup_menu::PopupMenuExt;
|
||||||
|
use ui::tooltip::Tooltip;
|
||||||
use ui::{h_flex, ContextModal, IconName, Root, Sizable, StyledExt};
|
use ui::{h_flex, ContextModal, IconName, Root, Sizable, StyledExt};
|
||||||
|
|
||||||
use crate::views::compose::compose_button;
|
use crate::views::compose::compose_button;
|
||||||
@@ -327,11 +329,31 @@ impl ChatSpace {
|
|||||||
fn render_titlebar_left_side(
|
fn render_titlebar_left_side(
|
||||||
&mut self,
|
&mut self,
|
||||||
_window: &mut Window,
|
_window: &mut Window,
|
||||||
_cx: &Context<Self>,
|
cx: &Context<Self>,
|
||||||
) -> impl IntoElement {
|
) -> impl IntoElement {
|
||||||
let compose_button = compose_button().into_any_element();
|
let registry = Registry::read_global(cx);
|
||||||
|
let loading = registry.loading;
|
||||||
|
|
||||||
h_flex().gap_1().child(compose_button)
|
h_flex()
|
||||||
|
.gap_2()
|
||||||
|
.child(compose_button())
|
||||||
|
.when(loading, |this| {
|
||||||
|
this.child(
|
||||||
|
h_flex()
|
||||||
|
.id("downloading")
|
||||||
|
.px_4()
|
||||||
|
.h_6()
|
||||||
|
.gap_1()
|
||||||
|
.text_xs()
|
||||||
|
.rounded_full()
|
||||||
|
.bg(cx.theme().elevated_surface_background)
|
||||||
|
.child(shared_t!("loading.label"))
|
||||||
|
.child(Indicator::new().xsmall())
|
||||||
|
.tooltip(|window, cx| {
|
||||||
|
Tooltip::new(t!("loading.tooltip"), window, cx).into()
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_titlebar_right_side(
|
fn render_titlebar_right_side(
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ use global::nostr_client;
|
|||||||
use gpui::prelude::FluentBuilder;
|
use gpui::prelude::FluentBuilder;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
div, img, list, px, red, rems, white, Action, AnyElement, App, AppContext, ClipboardItem,
|
div, img, list, px, red, rems, white, Action, AnyElement, App, AppContext, ClipboardItem,
|
||||||
Context, Element, Empty, Entity, EventEmitter, Flatten, FocusHandle, Focusable,
|
Context, Element, Entity, EventEmitter, Flatten, FocusHandle, Focusable, InteractiveElement,
|
||||||
InteractiveElement, IntoElement, ListAlignment, ListState, MouseButton, ObjectFit,
|
IntoElement, ListAlignment, ListState, MouseButton, ObjectFit, ParentElement,
|
||||||
ParentElement, PathPromptOptions, Render, RetainAllImageCache, SharedString,
|
PathPromptOptions, Render, RetainAllImageCache, SharedString, StatefulInteractiveElement,
|
||||||
StatefulInteractiveElement, Styled, StyledImage, Subscription, Window,
|
Styled, StyledImage, Subscription, Window,
|
||||||
};
|
};
|
||||||
use gpui_tokio::Tokio;
|
use gpui_tokio::Tokio;
|
||||||
use i18n::t;
|
use i18n::t;
|
||||||
@@ -712,7 +712,7 @@ impl Chat {
|
|||||||
window.open_modal(cx, move |this, _window, cx| {
|
window.open_modal(cx, move |this, _window, cx| {
|
||||||
this.title(SharedString::new(t!("chat.logs_title"))).child(
|
this.title(SharedString::new(t!("chat.logs_title"))).child(
|
||||||
div()
|
div()
|
||||||
.w_full()
|
.pb_4()
|
||||||
.flex()
|
.flex()
|
||||||
.flex_col()
|
.flex_col()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ use ui::actions::OpenProfile;
|
|||||||
use ui::avatar::Avatar;
|
use ui::avatar::Avatar;
|
||||||
use ui::context_menu::ContextMenuExt;
|
use ui::context_menu::ContextMenuExt;
|
||||||
use ui::modal::ModalButtonProps;
|
use ui::modal::ModalButtonProps;
|
||||||
|
use ui::skeleton::Skeleton;
|
||||||
use ui::{h_flex, ContextModal, StyledExt};
|
use ui::{h_flex, ContextModal, StyledExt};
|
||||||
|
|
||||||
use crate::views::screening;
|
use crate::views::screening;
|
||||||
@@ -23,60 +24,109 @@ use crate::views::screening;
|
|||||||
pub struct RoomListItem {
|
pub struct RoomListItem {
|
||||||
ix: usize,
|
ix: usize,
|
||||||
base: Div,
|
base: Div,
|
||||||
room_id: u64,
|
room_id: Option<u64>,
|
||||||
public_key: PublicKey,
|
public_key: Option<PublicKey>,
|
||||||
name: SharedString,
|
name: Option<SharedString>,
|
||||||
avatar: SharedString,
|
avatar: Option<SharedString>,
|
||||||
created_at: SharedString,
|
created_at: Option<SharedString>,
|
||||||
kind: RoomKind,
|
kind: Option<RoomKind>,
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
handler: Rc<dyn Fn(&ClickEvent, &mut Window, &mut App)>,
|
handler: Option<Rc<dyn Fn(&ClickEvent, &mut Window, &mut App)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RoomListItem {
|
impl RoomListItem {
|
||||||
pub fn new(
|
pub fn new(ix: usize) -> Self {
|
||||||
ix: usize,
|
|
||||||
room_id: u64,
|
|
||||||
public_key: PublicKey,
|
|
||||||
name: SharedString,
|
|
||||||
avatar: SharedString,
|
|
||||||
created_at: SharedString,
|
|
||||||
kind: RoomKind,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
ix,
|
ix,
|
||||||
public_key,
|
base: h_flex().h_9().w_full().px_1p5().gap_2(),
|
||||||
room_id,
|
room_id: None,
|
||||||
name,
|
public_key: None,
|
||||||
avatar,
|
name: None,
|
||||||
created_at,
|
avatar: None,
|
||||||
kind,
|
created_at: None,
|
||||||
base: h_flex().h_9().w_full().px_1p5(),
|
kind: None,
|
||||||
handler: Rc::new(|_, _, _| {}),
|
handler: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn room_id(mut self, room_id: u64) -> Self {
|
||||||
|
self.room_id = Some(room_id);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn public_key(mut self, public_key: PublicKey) -> Self {
|
||||||
|
self.public_key = Some(public_key);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name(mut self, name: SharedString) -> Self {
|
||||||
|
self.name = Some(name);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn avatar(mut self, avatar: SharedString) -> Self {
|
||||||
|
self.avatar = Some(avatar);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn created_at(mut self, created_at: SharedString) -> Self {
|
||||||
|
self.created_at = Some(created_at);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn kind(mut self, kind: RoomKind) -> Self {
|
||||||
|
self.kind = Some(kind);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn on_click(
|
pub fn on_click(
|
||||||
mut self,
|
mut self,
|
||||||
handler: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static,
|
handler: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
self.handler = Rc::new(handler);
|
self.handler = Some(Rc::new(handler));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderOnce for RoomListItem {
|
impl RenderOnce for RoomListItem {
|
||||||
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
|
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||||
let public_key = self.public_key;
|
|
||||||
let room_id = self.room_id;
|
|
||||||
let kind = self.kind;
|
|
||||||
let handler = self.handler.clone();
|
|
||||||
let hide_avatar = AppSettings::get_hide_user_avatars(cx);
|
let hide_avatar = AppSettings::get_hide_user_avatars(cx);
|
||||||
let require_screening = AppSettings::get_screening(cx);
|
let require_screening = AppSettings::get_screening(cx);
|
||||||
|
|
||||||
|
let (
|
||||||
|
Some(public_key),
|
||||||
|
Some(room_id),
|
||||||
|
Some(name),
|
||||||
|
Some(avatar),
|
||||||
|
Some(created_at),
|
||||||
|
Some(kind),
|
||||||
|
Some(handler),
|
||||||
|
) = (
|
||||||
|
self.public_key,
|
||||||
|
self.room_id,
|
||||||
|
self.name,
|
||||||
|
self.avatar,
|
||||||
|
self.created_at,
|
||||||
|
self.kind,
|
||||||
|
self.handler,
|
||||||
|
)
|
||||||
|
else {
|
||||||
|
return self
|
||||||
|
.base
|
||||||
|
.id(self.ix)
|
||||||
|
.child(Skeleton::new().flex_shrink_0().size_6().rounded_full())
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.flex_1()
|
||||||
|
.flex()
|
||||||
|
.justify_between()
|
||||||
|
.child(Skeleton::new().w_32().h_2p5().rounded_sm())
|
||||||
|
.child(Skeleton::new().w_6().h_2p5().rounded_sm()),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
self.base
|
self.base
|
||||||
.id(self.ix)
|
.id(self.ix)
|
||||||
.gap_2()
|
|
||||||
.text_sm()
|
.text_sm()
|
||||||
.rounded(cx.theme().radius)
|
.rounded(cx.theme().radius)
|
||||||
.when(!hide_avatar, |this| {
|
.when(!hide_avatar, |this| {
|
||||||
@@ -86,7 +136,7 @@ impl RenderOnce for RoomListItem {
|
|||||||
.size_6()
|
.size_6()
|
||||||
.rounded_full()
|
.rounded_full()
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.child(Avatar::new(self.avatar).size(rems(1.5))),
|
.child(Avatar::new(avatar).size(rems(1.5))),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.child(
|
.child(
|
||||||
@@ -102,14 +152,14 @@ impl RenderOnce for RoomListItem {
|
|||||||
.text_ellipsis()
|
.text_ellipsis()
|
||||||
.truncate()
|
.truncate()
|
||||||
.font_medium()
|
.font_medium()
|
||||||
.child(self.name),
|
.child(name),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.flex_shrink_0()
|
.flex_shrink_0()
|
||||||
.text_xs()
|
.text_xs()
|
||||||
.text_color(cx.theme().text_placeholder)
|
.text_color(cx.theme().text_placeholder)
|
||||||
.child(self.created_at),
|
.child(created_at),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.context_menu(move |this, _window, _cx| {
|
.context_menu(move |this, _window, _cx| {
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ use global::constants::{BOOTSTRAP_RELAYS, SEARCH_RELAYS};
|
|||||||
use global::nostr_client;
|
use global::nostr_client;
|
||||||
use gpui::prelude::FluentBuilder;
|
use gpui::prelude::FluentBuilder;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
div, relative, uniform_list, AnyElement, App, AppContext, Context, Entity, EventEmitter,
|
div, uniform_list, AnyElement, App, AppContext, Context, Entity, EventEmitter, FocusHandle,
|
||||||
FocusHandle, Focusable, IntoElement, ParentElement, Render, RetainAllImageCache, SharedString,
|
Focusable, IntoElement, ParentElement, Render, RetainAllImageCache, SharedString, Styled,
|
||||||
Styled, Subscription, Task, Window,
|
Subscription, Task, Window,
|
||||||
};
|
};
|
||||||
use gpui_tokio::Tokio;
|
use gpui_tokio::Tokio;
|
||||||
use i18n::t;
|
use i18n::t;
|
||||||
@@ -26,16 +26,15 @@ use smallvec::{smallvec, SmallVec};
|
|||||||
use theme::ActiveTheme;
|
use theme::ActiveTheme;
|
||||||
use ui::button::{Button, ButtonRounded, ButtonVariants};
|
use ui::button::{Button, ButtonRounded, ButtonVariants};
|
||||||
use ui::dock_area::panel::{Panel, PanelEvent};
|
use ui::dock_area::panel::{Panel, PanelEvent};
|
||||||
use ui::indicator::Indicator;
|
|
||||||
use ui::input::{InputEvent, InputState, TextInput};
|
use ui::input::{InputEvent, InputState, TextInput};
|
||||||
use ui::popup_menu::PopupMenu;
|
use ui::popup_menu::PopupMenu;
|
||||||
use ui::skeleton::Skeleton;
|
|
||||||
use ui::{v_flex, ContextModal, IconName, Selectable, Sizable, StyledExt};
|
use ui::{v_flex, ContextModal, IconName, Selectable, Sizable, StyledExt};
|
||||||
|
|
||||||
mod list_item;
|
mod list_item;
|
||||||
|
|
||||||
const FIND_DELAY: u64 = 600;
|
const FIND_DELAY: u64 = 600;
|
||||||
const FIND_LIMIT: usize = 10;
|
const FIND_LIMIT: usize = 10;
|
||||||
|
const TOTAL_SKELETONS: usize = 3;
|
||||||
|
|
||||||
pub fn init(window: &mut Window, cx: &mut App) -> Entity<Sidebar> {
|
pub fn init(window: &mut Window, cx: &mut App) -> Entity<Sidebar> {
|
||||||
Sidebar::new(window, cx)
|
Sidebar::new(window, cx)
|
||||||
@@ -547,61 +546,6 @@ impl Sidebar {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_loading_modal(&self, window: &mut Window, cx: &mut Context<Self>) {
|
|
||||||
let title = SharedString::new(t!("sidebar.loading_modal_title"));
|
|
||||||
let text_1 = SharedString::new(t!("sidebar.loading_modal_body_1"));
|
|
||||||
let text_2 = SharedString::new(t!("sidebar.loading_modal_body_2"));
|
|
||||||
let desc = SharedString::new(t!("sidebar.loading_modal_description"));
|
|
||||||
|
|
||||||
window.open_modal(cx, move |this, _window, cx| {
|
|
||||||
this.show_close(true)
|
|
||||||
.keyboard(true)
|
|
||||||
.title(title.clone())
|
|
||||||
.child(
|
|
||||||
v_flex()
|
|
||||||
.pb_4()
|
|
||||||
.gap_2()
|
|
||||||
.child(
|
|
||||||
div()
|
|
||||||
.flex()
|
|
||||||
.flex_col()
|
|
||||||
.gap_2()
|
|
||||||
.text_sm()
|
|
||||||
.child(text_1.clone())
|
|
||||||
.child(text_2.clone()),
|
|
||||||
)
|
|
||||||
.child(
|
|
||||||
div()
|
|
||||||
.text_xs()
|
|
||||||
.text_color(cx.theme().text_muted)
|
|
||||||
.child(desc.clone()),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
fn skeletons(&self, total: i32) -> impl IntoIterator<Item = impl IntoElement> {
|
|
||||||
(0..total).map(|_| {
|
|
||||||
div()
|
|
||||||
.h_9()
|
|
||||||
.w_full()
|
|
||||||
.px_1p5()
|
|
||||||
.flex()
|
|
||||||
.items_center()
|
|
||||||
.gap_2()
|
|
||||||
.child(Skeleton::new().flex_shrink_0().size_6().rounded_full())
|
|
||||||
.child(
|
|
||||||
div()
|
|
||||||
.flex_1()
|
|
||||||
.flex()
|
|
||||||
.justify_between()
|
|
||||||
.child(Skeleton::new().w_32().h_2p5().rounded_sm())
|
|
||||||
.child(Skeleton::new().w_6().h_2p5().rounded_sm()),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn list_items(
|
fn list_items(
|
||||||
&self,
|
&self,
|
||||||
rooms: &[Entity<Room>],
|
rooms: &[Entity<Room>],
|
||||||
@@ -622,17 +566,17 @@ impl Sidebar {
|
|||||||
});
|
});
|
||||||
|
|
||||||
items.push(
|
items.push(
|
||||||
RoomListItem::new(
|
RoomListItem::new(ix)
|
||||||
ix,
|
.room_id(room_id)
|
||||||
room_id,
|
.name(this.display_name(cx))
|
||||||
this.members[0],
|
.avatar(this.display_image(proxy, cx))
|
||||||
this.display_name(cx),
|
.created_at(this.ago())
|
||||||
this.display_image(proxy, cx),
|
.public_key(this.members[0])
|
||||||
this.ago(),
|
.kind(this.kind)
|
||||||
this.kind,
|
.on_click(handler),
|
||||||
)
|
|
||||||
.on_click(handler),
|
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
items.push(RoomListItem::new(ix));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -669,6 +613,7 @@ impl Focusable for Sidebar {
|
|||||||
impl Render for Sidebar {
|
impl Render for Sidebar {
|
||||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
let registry = Registry::read_global(cx);
|
let registry = Registry::read_global(cx);
|
||||||
|
let loading = registry.loading;
|
||||||
|
|
||||||
// Get rooms from either search results or the chat registry
|
// Get rooms from either search results or the chat registry
|
||||||
let rooms = if let Some(results) = self.local_result.read(cx).as_ref() {
|
let rooms = if let Some(results) = self.local_result.read(cx).as_ref() {
|
||||||
@@ -684,6 +629,15 @@ impl Render for Sidebar {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Get total rooms count
|
||||||
|
let mut total_rooms = rooms.len();
|
||||||
|
|
||||||
|
// If loading in progress
|
||||||
|
// Add 3 skeletons to the room list
|
||||||
|
if loading {
|
||||||
|
total_rooms += TOTAL_SKELETONS;
|
||||||
|
}
|
||||||
|
|
||||||
v_flex()
|
v_flex()
|
||||||
.image_cache(self.image_cache.clone())
|
.image_cache(self.image_cache.clone())
|
||||||
.size_full()
|
.size_full()
|
||||||
@@ -723,76 +677,55 @@ impl Render for Sidebar {
|
|||||||
.overflow_y_hidden()
|
.overflow_y_hidden()
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.flex_none()
|
|
||||||
.px_1()
|
.px_1()
|
||||||
.w_full()
|
.h_flex()
|
||||||
.h_9()
|
.gap_2()
|
||||||
.flex()
|
.flex_none()
|
||||||
.items_center()
|
|
||||||
.justify_between()
|
|
||||||
.child(
|
.child(
|
||||||
div()
|
Button::new("all")
|
||||||
.flex()
|
.label(t!("sidebar.all_button"))
|
||||||
.items_center()
|
.tooltip(t!("sidebar.all_conversations_tooltip"))
|
||||||
.gap_2()
|
.when_some(self.indicator.read(cx).as_ref(), |this, kind| {
|
||||||
.child(
|
this.when(kind == &RoomKind::Ongoing, |this| {
|
||||||
Button::new("all")
|
this.child(
|
||||||
.label(t!("sidebar.all_button"))
|
div().size_1().rounded_full().bg(cx.theme().cursor),
|
||||||
.tooltip(t!("sidebar.all_conversations_tooltip"))
|
|
||||||
.when_some(
|
|
||||||
self.indicator.read(cx).as_ref(),
|
|
||||||
|this, kind| {
|
|
||||||
this.when(kind == &RoomKind::Ongoing, |this| {
|
|
||||||
this.child(
|
|
||||||
div()
|
|
||||||
.size_1()
|
|
||||||
.rounded_full()
|
|
||||||
.bg(cx.theme().cursor),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
.small()
|
})
|
||||||
.bold()
|
})
|
||||||
.secondary()
|
.small()
|
||||||
.rounded(ButtonRounded::Full)
|
.bold()
|
||||||
.selected(self.filter(&RoomKind::Ongoing, cx))
|
.secondary()
|
||||||
.on_click(cx.listener(|this, _, _, cx| {
|
.rounded(ButtonRounded::Full)
|
||||||
this.set_filter(RoomKind::Ongoing, cx);
|
.selected(self.filter(&RoomKind::Ongoing, cx))
|
||||||
})),
|
.on_click(cx.listener(|this, _, _, cx| {
|
||||||
)
|
this.set_filter(RoomKind::Ongoing, cx);
|
||||||
.child(
|
})),
|
||||||
Button::new("requests")
|
)
|
||||||
.label(t!("sidebar.requests_button"))
|
.child(
|
||||||
.tooltip(t!("sidebar.requests_tooltip"))
|
Button::new("requests")
|
||||||
.when_some(
|
.label(t!("sidebar.requests_button"))
|
||||||
self.indicator.read(cx).as_ref(),
|
.tooltip(t!("sidebar.requests_tooltip"))
|
||||||
|this, kind| {
|
.when_some(self.indicator.read(cx).as_ref(), |this, kind| {
|
||||||
this.when(kind != &RoomKind::Ongoing, |this| {
|
this.when(kind != &RoomKind::Ongoing, |this| {
|
||||||
this.child(
|
this.child(
|
||||||
div()
|
div().size_1().rounded_full().bg(cx.theme().cursor),
|
||||||
.size_1()
|
|
||||||
.rounded_full()
|
|
||||||
.bg(cx.theme().cursor),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
.small()
|
})
|
||||||
.bold()
|
})
|
||||||
.secondary()
|
.small()
|
||||||
.rounded(ButtonRounded::Full)
|
.bold()
|
||||||
.selected(!self.filter(&RoomKind::Ongoing, cx))
|
.secondary()
|
||||||
.on_click(cx.listener(|this, _, _, cx| {
|
.rounded(ButtonRounded::Full)
|
||||||
this.set_filter(RoomKind::default(), cx);
|
.selected(!self.filter(&RoomKind::Ongoing, cx))
|
||||||
})),
|
.on_click(cx.listener(|this, _, _, cx| {
|
||||||
),
|
this.set_filter(RoomKind::default(), cx);
|
||||||
|
})),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
uniform_list(
|
uniform_list(
|
||||||
"rooms",
|
"rooms",
|
||||||
rooms.len(),
|
total_rooms,
|
||||||
cx.processor(move |this, range, _window, cx| {
|
cx.processor(move |this, range, _window, cx| {
|
||||||
this.list_items(&rooms, range, cx)
|
this.list_items(&rooms, range, cx)
|
||||||
}),
|
}),
|
||||||
@@ -800,59 +733,5 @@ impl Render for Sidebar {
|
|||||||
.h_full(),
|
.h_full(),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.when(registry.loading, |this| {
|
|
||||||
let title = SharedString::new(t!("sidebar.retrieving_messages"));
|
|
||||||
let desc = SharedString::new(t!("sidebar.retrieving_messages_description"));
|
|
||||||
|
|
||||||
this.child(
|
|
||||||
div().absolute().bottom_3().px_3().w_full().child(
|
|
||||||
div()
|
|
||||||
.p_1()
|
|
||||||
.w_full()
|
|
||||||
.rounded_full()
|
|
||||||
.flex()
|
|
||||||
.items_center()
|
|
||||||
.justify_between()
|
|
||||||
.bg(cx.theme().panel_background)
|
|
||||||
.shadow_sm()
|
|
||||||
// Loading
|
|
||||||
.child(div().flex_shrink_0().pl_1().child(Indicator::new().small()))
|
|
||||||
// Title
|
|
||||||
.child(
|
|
||||||
v_flex()
|
|
||||||
.flex_1()
|
|
||||||
.items_center()
|
|
||||||
.justify_center()
|
|
||||||
.text_center()
|
|
||||||
.child(
|
|
||||||
div()
|
|
||||||
.text_sm()
|
|
||||||
.font_semibold()
|
|
||||||
.line_height(relative(1.2))
|
|
||||||
.child(title.clone()),
|
|
||||||
)
|
|
||||||
.child(
|
|
||||||
div()
|
|
||||||
.text_xs()
|
|
||||||
.text_color(cx.theme().text_muted)
|
|
||||||
.child(desc.clone()),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
// Info button
|
|
||||||
.child(
|
|
||||||
Button::new("help")
|
|
||||||
.icon(IconName::Info)
|
|
||||||
.tooltip(t!("sidebar.why_seeing_this_tooltip"))
|
|
||||||
.small()
|
|
||||||
.ghost()
|
|
||||||
.rounded(ButtonRounded::Full)
|
|
||||||
.flex_shrink_0()
|
|
||||||
.on_click(cx.listener(move |this, _, window, cx| {
|
|
||||||
this.open_loading_modal(window, cx)
|
|
||||||
})),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ pub const WAIT_FOR_FINISH: u64 = 60;
|
|||||||
pub const DEFAULT_MODAL_WIDTH: f32 = 420.;
|
pub const DEFAULT_MODAL_WIDTH: f32 = 420.;
|
||||||
|
|
||||||
/// Default width of the sidebar.
|
/// Default width of the sidebar.
|
||||||
pub const DEFAULT_SIDEBAR_WIDTH: f32 = 280.;
|
pub const DEFAULT_SIDEBAR_WIDTH: f32 = 240.;
|
||||||
|
|
||||||
/// Image Resize Service
|
/// Image Resize Service
|
||||||
pub const IMAGE_RESIZE_SERVICE: &str = "https://wsrv.nl";
|
pub const IMAGE_RESIZE_SERVICE: &str = "https://wsrv.nl";
|
||||||
|
|||||||
@@ -335,17 +335,9 @@ sidebar:
|
|||||||
en: "Incoming new conversations"
|
en: "Incoming new conversations"
|
||||||
trusted_contacts_tooltip:
|
trusted_contacts_tooltip:
|
||||||
en: "Only show rooms from trusted contacts"
|
en: "Only show rooms from trusted contacts"
|
||||||
retrieving_messages:
|
|
||||||
en: "Retrieving messages"
|
loading:
|
||||||
retrieving_messages_description:
|
label:
|
||||||
en: "This may take some time"
|
en: "Downloading messages"
|
||||||
why_seeing_this_tooltip:
|
tooltip:
|
||||||
en: "Why you're seeing this"
|
en: "This may take a while. Please be patient."
|
||||||
loading_modal_title:
|
|
||||||
en: "Retrieving Your Messages"
|
|
||||||
loading_modal_body_1:
|
|
||||||
en: "Coop is downloading all your messages from the messaging relays. Depending on your total number of messages, this process may take up to 15 minutes if you're using Nostr Connect."
|
|
||||||
loading_modal_body_2:
|
|
||||||
en: "Please be patient - you only need to do this full download once. Next time, Coop will only download new messages."
|
|
||||||
loading_modal_description:
|
|
||||||
en: "You still can use the app normally while messages are processing in the background"
|
|
||||||
|
|||||||
Reference in New Issue
Block a user