update ui
This commit is contained in:
@@ -1,11 +1,10 @@
|
||||
use instant::Duration;
|
||||
|
||||
use anyhow::{Error, anyhow};
|
||||
use gpui::prelude::FluentBuilder;
|
||||
use gpui::{
|
||||
AppContext, Context, Entity, IntoElement, ParentElement, Render, SharedString, Styled,
|
||||
Subscription, Task, Window, div,
|
||||
};
|
||||
use instant::Duration;
|
||||
use nostr_connect::prelude::*;
|
||||
use state::{CoopAuthUrlHandler, NostrRegistry, USER_KEYRING};
|
||||
use theme::ActiveTheme;
|
||||
@@ -36,7 +35,7 @@ pub struct ImportIdentity {
|
||||
|
||||
impl ImportIdentity {
|
||||
pub fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let key_input = cx.new(|cx| InputState::new(window, cx));
|
||||
let key_input = cx.new(|cx| InputState::new(window, cx).placeholder("nsec or bunker://"));
|
||||
let pass_input = cx.new(|cx| InputState::new(window, cx).masked(true));
|
||||
let error = cx.new(|_| None);
|
||||
|
||||
@@ -135,7 +134,6 @@ impl ImportIdentity {
|
||||
})?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}));
|
||||
}
|
||||
@@ -208,40 +206,45 @@ impl Render for ImportIdentity {
|
||||
|
||||
v_flex()
|
||||
.size_full()
|
||||
.gap_2()
|
||||
.gap_4()
|
||||
.text_sm()
|
||||
.child(
|
||||
v_flex()
|
||||
.gap_1()
|
||||
.text_color(cx.theme().text_muted)
|
||||
.child("Continue with existing key or bunker connection")
|
||||
.child(Input::new(&self.key_input)),
|
||||
.gap_2()
|
||||
.child(
|
||||
v_flex()
|
||||
.gap_1()
|
||||
.text_color(cx.theme().text_muted)
|
||||
.child("Continue with existing key or bunker connection")
|
||||
.child(Input::new(&self.key_input)),
|
||||
)
|
||||
.when(require_password, |this| {
|
||||
this.child(
|
||||
v_flex()
|
||||
.gap_1()
|
||||
.text_color(cx.theme().text_muted)
|
||||
.child("Decrypt Password:")
|
||||
.child(Input::new(&self.pass_input)),
|
||||
)
|
||||
})
|
||||
.when(key_warning, |this| {
|
||||
this.child(
|
||||
div()
|
||||
.text_xs()
|
||||
.text_color(cx.theme().text_warning)
|
||||
.child(div().font_semibold().child("Warning"))
|
||||
.child(div().child(MSG)),
|
||||
)
|
||||
}),
|
||||
)
|
||||
.when(require_password, |this| {
|
||||
this.child(
|
||||
v_flex()
|
||||
.gap_1()
|
||||
.text_color(cx.theme().text_muted)
|
||||
.child("Decrypt Password:")
|
||||
.child(Input::new(&self.pass_input)),
|
||||
)
|
||||
})
|
||||
.when(key_warning, |this| {
|
||||
this.child(
|
||||
div()
|
||||
.v_flex()
|
||||
.text_xs()
|
||||
.text_color(cx.theme().text_warning)
|
||||
.child(div().font_semibold().child("Warning"))
|
||||
.child(div().child(MSG)),
|
||||
)
|
||||
})
|
||||
.child(
|
||||
Button::new("login")
|
||||
.label("Continue")
|
||||
.primary()
|
||||
.font_semibold()
|
||||
.loading(self.loading)
|
||||
.disabled(self.loading)
|
||||
.on_click(cx.listener(move |this, _, window, cx| {
|
||||
.on_click(cx.listener(move |this, _ev, window, cx| {
|
||||
this.login(window, cx);
|
||||
})),
|
||||
)
|
||||
|
||||
@@ -28,6 +28,7 @@ use crate::dialogs::import::ImportIdentity;
|
||||
use crate::dialogs::restore::RestoreEncryption;
|
||||
use crate::dialogs::settings;
|
||||
use crate::panels::{backup, contact_list, greeter, messaging_relays, profile, relay_list, trash};
|
||||
use crate::sidebar::Sidebar;
|
||||
|
||||
mod dialogs;
|
||||
mod panels;
|
||||
@@ -60,6 +61,7 @@ enum Command {
|
||||
}
|
||||
|
||||
pub struct Workspace {
|
||||
sidebar: Entity<Sidebar>,
|
||||
/// App's Dock Area
|
||||
dock: Entity<DockArea>,
|
||||
|
||||
@@ -79,14 +81,10 @@ impl Workspace {
|
||||
let device = DeviceRegistry::global(cx);
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
|
||||
let dock = cx.new(|cx| {
|
||||
let mut this = DockArea::new(window, cx);
|
||||
let left = DockItem::panel(Arc::new(sidebar::init(window, cx)));
|
||||
this.set_left_dock(left, Some(SIDEBAR_WIDTH), true, window, cx);
|
||||
this
|
||||
});
|
||||
|
||||
let sidebar = cx.new(|cx| Sidebar::new(window, cx));
|
||||
let dock = cx.new(|cx| DockArea::new(window, cx));
|
||||
let image_cache = CoopImageCache::new(IMAGE_CACHE_SIZE, cx);
|
||||
|
||||
let mut subscriptions = smallvec![];
|
||||
|
||||
subscriptions.push(
|
||||
@@ -245,6 +243,7 @@ impl Workspace {
|
||||
});
|
||||
|
||||
Self {
|
||||
sidebar,
|
||||
dock,
|
||||
image_cache,
|
||||
tasks: vec![],
|
||||
@@ -826,8 +825,19 @@ impl Render for Workspace {
|
||||
.child(self.titlebar_left(cx))
|
||||
.child(self.titlebar_right(cx)),
|
||||
)
|
||||
// Dock
|
||||
.child(self.dock.clone()),
|
||||
// Main
|
||||
.child(
|
||||
h_flex()
|
||||
.size_full()
|
||||
.child(
|
||||
div()
|
||||
.flex_shrink_0()
|
||||
.h_full()
|
||||
.w(SIDEBAR_WIDTH)
|
||||
.child(self.sidebar.clone()),
|
||||
)
|
||||
.child(self.dock.clone()),
|
||||
),
|
||||
),
|
||||
)
|
||||
// Notifications
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
use instant::Duration;
|
||||
|
||||
use anyhow::Error;
|
||||
use gpui::{
|
||||
AnyElement, App, AppContext, ClipboardItem, Context, Entity, EventEmitter, FocusHandle,
|
||||
Focusable, IntoElement, ParentElement, Render, SharedString, Styled, Task, Window, div,
|
||||
};
|
||||
use instant::Duration;
|
||||
use nostr_sdk::prelude::*;
|
||||
use state::USER_KEYRING;
|
||||
use theme::ActiveTheme;
|
||||
@@ -155,12 +154,7 @@ impl Render for BackupPanel {
|
||||
.text_color(cx.theme().text_muted)
|
||||
.child(SharedString::from("Public Key:")),
|
||||
)
|
||||
.child(
|
||||
Input::new(&self.npub_input)
|
||||
.small()
|
||||
.bordered(false)
|
||||
.disabled(true),
|
||||
),
|
||||
.child(Input::new(&self.npub_input).small().disabled(true)),
|
||||
)
|
||||
.child(
|
||||
v_flex()
|
||||
@@ -173,12 +167,7 @@ impl Render for BackupPanel {
|
||||
.text_color(cx.theme().text_muted)
|
||||
.child(SharedString::from("Secret Key:")),
|
||||
)
|
||||
.child(
|
||||
Input::new(&self.nsec_input)
|
||||
.small()
|
||||
.bordered(false)
|
||||
.disabled(true),
|
||||
),
|
||||
.child(Input::new(&self.nsec_input).small().disabled(true)),
|
||||
)
|
||||
.child(
|
||||
Button::new("copy")
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use std::collections::HashSet;
|
||||
use instant::Duration;
|
||||
|
||||
use anyhow::Error;
|
||||
use gpui::prelude::FluentBuilder;
|
||||
@@ -8,6 +7,7 @@ use gpui::{
|
||||
InteractiveElement, IntoElement, ParentElement, Render, SharedString, Styled, Subscription,
|
||||
Task, TextAlign, Window, div, rems,
|
||||
};
|
||||
use instant::Duration;
|
||||
use nostr_sdk::prelude::*;
|
||||
use person::PersonRegistry;
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
@@ -303,12 +303,7 @@ impl Render for ContactListPanel {
|
||||
h_flex()
|
||||
.gap_1()
|
||||
.w_full()
|
||||
.child(
|
||||
Input::new(&self.input)
|
||||
.small()
|
||||
.bordered(false)
|
||||
.cleanable(true),
|
||||
)
|
||||
.child(Input::new(&self.input).small().cleanable(true))
|
||||
.child(
|
||||
Button::new("add")
|
||||
.icon(IconName::Plus)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use std::collections::HashSet;
|
||||
use instant::Duration;
|
||||
|
||||
use anyhow::{Error, anyhow};
|
||||
use gpui::prelude::FluentBuilder;
|
||||
@@ -8,6 +7,7 @@ use gpui::{
|
||||
InteractiveElement, IntoElement, ParentElement, Render, SharedString, Styled, Subscription,
|
||||
Task, TextAlign, Window, div, rems,
|
||||
};
|
||||
use instant::Duration;
|
||||
use nostr_sdk::prelude::*;
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
use state::NostrRegistry;
|
||||
@@ -320,12 +320,7 @@ impl Render for MessagingRelayPanel {
|
||||
h_flex()
|
||||
.gap_1()
|
||||
.w_full()
|
||||
.child(
|
||||
Input::new(&self.input)
|
||||
.small()
|
||||
.bordered(false)
|
||||
.cleanable(true),
|
||||
)
|
||||
.child(Input::new(&self.input).small().cleanable(true))
|
||||
.child(
|
||||
Button::new("add")
|
||||
.icon(IconName::Plus)
|
||||
|
||||
@@ -353,7 +353,7 @@ impl Render for ProfilePanel {
|
||||
.text_color(cx.theme().text_muted)
|
||||
.child(SharedString::from("What should people call you?")),
|
||||
)
|
||||
.child(Input::new(&self.name_input).bordered(false).small()),
|
||||
.child(Input::new(&self.name_input).small()),
|
||||
)
|
||||
.child(
|
||||
v_flex()
|
||||
@@ -364,7 +364,7 @@ impl Render for ProfilePanel {
|
||||
.text_color(cx.theme().text_muted)
|
||||
.child(SharedString::from("A short introduction about you:")),
|
||||
)
|
||||
.child(Input::new(&self.bio_input).bordered(false).small()),
|
||||
.child(Input::new(&self.bio_input).small()),
|
||||
)
|
||||
.child(
|
||||
v_flex()
|
||||
@@ -375,7 +375,7 @@ impl Render for ProfilePanel {
|
||||
.text_color(cx.theme().text_muted)
|
||||
.child(SharedString::from("Website:")),
|
||||
)
|
||||
.child(Input::new(&self.website_input).bordered(false).small()),
|
||||
.child(Input::new(&self.website_input).small()),
|
||||
)
|
||||
.child(
|
||||
v_flex()
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use std::collections::HashSet;
|
||||
use instant::Duration;
|
||||
|
||||
use anyhow::{Error, anyhow};
|
||||
use gpui::prelude::FluentBuilder;
|
||||
@@ -8,6 +7,7 @@ use gpui::{
|
||||
InteractiveElement, IntoElement, ParentElement, Render, SharedString, Styled, Subscription,
|
||||
Task, TextAlign, Window, div, px, rems,
|
||||
};
|
||||
use instant::Duration;
|
||||
use nostr_sdk::prelude::*;
|
||||
use serde::Deserialize;
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
@@ -371,12 +371,7 @@ impl Render for RelayListPanel {
|
||||
h_flex()
|
||||
.gap_1()
|
||||
.w_full()
|
||||
.child(
|
||||
Input::new(&self.input)
|
||||
.small()
|
||||
.bordered(false)
|
||||
.cleanable(true),
|
||||
)
|
||||
.child(Input::new(&self.input).small().cleanable(true))
|
||||
.child(
|
||||
Button::new("metadata")
|
||||
.map(|this| {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use std::collections::HashSet;
|
||||
use std::ops::Range;
|
||||
use instant::Duration;
|
||||
|
||||
use anyhow::Error;
|
||||
use chat::{ChatEvent, ChatRegistry, Room, RoomKind};
|
||||
@@ -12,11 +11,12 @@ use gpui::{
|
||||
ParentElement, Render, SharedString, Styled, Subscription, Task, UniformListScrollHandle,
|
||||
Window, div, uniform_list,
|
||||
};
|
||||
use instant::Duration;
|
||||
use nostr_sdk::prelude::*;
|
||||
use person::PersonRegistry;
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
use state::{FIND_DELAY, IMAGE_CACHE_SIZE, NostrRegistry};
|
||||
use theme::{ActiveTheme, SIDEBAR_WIDTH, TABBAR_HEIGHT};
|
||||
use theme::{ActiveTheme, SIDEBAR_WIDTH};
|
||||
use ui::button::{Button, ButtonVariants};
|
||||
use ui::dock::{Panel, PanelEvent};
|
||||
use ui::indicator::Indicator;
|
||||
@@ -29,13 +29,8 @@ mod entry;
|
||||
|
||||
const INPUT_PLACEHOLDER: &str = "Find or start a conversation";
|
||||
|
||||
pub fn init(window: &mut Window, cx: &mut App) -> Entity<Sidebar> {
|
||||
cx.new(|cx| Sidebar::new(window, cx))
|
||||
}
|
||||
|
||||
/// Sidebar.
|
||||
pub struct Sidebar {
|
||||
name: SharedString,
|
||||
focus_handle: FocusHandle,
|
||||
scroll_handle: UniformListScrollHandle,
|
||||
|
||||
@@ -80,7 +75,7 @@ pub struct Sidebar {
|
||||
}
|
||||
|
||||
impl Sidebar {
|
||||
fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
pub fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||
let chat = ChatRegistry::global(cx);
|
||||
let filter = cx.new(|_| RoomKind::Ongoing);
|
||||
let contact_list = cx.new(|_| None);
|
||||
@@ -135,7 +130,6 @@ impl Sidebar {
|
||||
);
|
||||
|
||||
Self {
|
||||
name: "Sidebar".into(),
|
||||
focus_handle: cx.focus_handle(),
|
||||
scroll_handle: UniformListScrollHandle::new(),
|
||||
find_input,
|
||||
@@ -474,7 +468,7 @@ impl Sidebar {
|
||||
|
||||
impl Panel for Sidebar {
|
||||
fn panel_id(&self) -> SharedString {
|
||||
self.name.clone()
|
||||
"Sidebar".into()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -488,8 +482,11 @@ impl Focusable for Sidebar {
|
||||
|
||||
impl Render for Sidebar {
|
||||
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
let nostr = NostrRegistry::global(cx);
|
||||
let chat = ChatRegistry::global(cx);
|
||||
let loading = chat.read(cx).loading();
|
||||
let logged_in = nostr.read(cx).current_user().is_some();
|
||||
let loading = chat.read(cx).loading() && logged_in;
|
||||
|
||||
let total_rooms = chat.read(cx).count(self.filter.read(cx), cx);
|
||||
|
||||
// Whether the find panel should be shown
|
||||
@@ -507,27 +504,21 @@ impl Render for Sidebar {
|
||||
.size_full()
|
||||
.gap_2()
|
||||
.child(
|
||||
h_flex()
|
||||
.h(TABBAR_HEIGHT)
|
||||
.border_b_1()
|
||||
.border_color(cx.theme().border)
|
||||
.bg(cx.theme().tab_background)
|
||||
.child(
|
||||
Input::new(&self.find_input)
|
||||
.appearance(false)
|
||||
.bordered(false)
|
||||
.small()
|
||||
.text_xs()
|
||||
.when(!self.find_input.read(cx).loading, |this| {
|
||||
this.suffix(
|
||||
Button::new("find-icon")
|
||||
.icon(IconName::Search)
|
||||
.tooltip("Press Enter to search")
|
||||
.transparent()
|
||||
.small(),
|
||||
)
|
||||
}),
|
||||
),
|
||||
h_flex().px_2().child(
|
||||
Input::new(&self.find_input)
|
||||
.small()
|
||||
.text_xs()
|
||||
.disabled(loading)
|
||||
.when(!self.find_input.read(cx).loading, |this| {
|
||||
this.suffix(
|
||||
Button::new("find-icon")
|
||||
.icon(IconName::Search)
|
||||
.tooltip("Press Enter to search")
|
||||
.transparent()
|
||||
.small(),
|
||||
)
|
||||
}),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
@@ -608,17 +599,13 @@ impl Render for Sidebar {
|
||||
.items_center()
|
||||
.justify_center()
|
||||
.text_center()
|
||||
.child(div().text_sm().font_semibold().child("No conversations"))
|
||||
.child(
|
||||
div()
|
||||
.text_sm()
|
||||
.font_semibold()
|
||||
.child(SharedString::from("No conversations")),
|
||||
)
|
||||
.child(div().text_xs().text_color(cx.theme().text_muted).child(
|
||||
SharedString::from(
|
||||
"Start a conversation with someone to get started.",
|
||||
),
|
||||
)),
|
||||
.text_xs()
|
||||
.text_color(cx.theme().text_muted)
|
||||
.child("Start a conversation with someone to get started."),
|
||||
),
|
||||
),
|
||||
)
|
||||
})
|
||||
@@ -643,7 +630,7 @@ impl Render for Sidebar {
|
||||
.font_semibold()
|
||||
.text_color(cx.theme().text_muted)
|
||||
.child(Icon::new(IconName::ChevronDown))
|
||||
.child(SharedString::from("Results")),
|
||||
.child("Results"),
|
||||
)
|
||||
.child(
|
||||
uniform_list(
|
||||
@@ -748,7 +735,7 @@ impl Render for Sidebar {
|
||||
.font_semibold()
|
||||
.text_color(cx.theme().text_muted)
|
||||
.child(Indicator::new().small().color(cx.theme().icon_accent))
|
||||
.child(SharedString::from("Getting messages...")),
|
||||
.child("Getting messages..."),
|
||||
),
|
||||
)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user