Continue redesign for the v1 stable release #5
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -4651,6 +4651,7 @@ version = "0.3.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"common",
|
"common",
|
||||||
|
"device",
|
||||||
"flume",
|
"flume",
|
||||||
"gpui",
|
"gpui",
|
||||||
"log",
|
"log",
|
||||||
|
|||||||
@@ -287,7 +287,7 @@ impl Room {
|
|||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(", ");
|
.join(", ");
|
||||||
|
|
||||||
if profiles.len() > 2 {
|
if profiles.len() > 3 {
|
||||||
name = format!("{}, +{}", name, profiles.len() - 2);
|
name = format!("{}, +{}", name, profiles.len() - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,9 @@ use ui::divider::Divider;
|
|||||||
use ui::indicator::Indicator;
|
use ui::indicator::Indicator;
|
||||||
use ui::input::{InputEvent, InputState, TextInput};
|
use ui::input::{InputEvent, InputState, TextInput};
|
||||||
use ui::notification::Notification;
|
use ui::notification::Notification;
|
||||||
use ui::{h_flex, v_flex, Disableable, IconName, Selectable, Sizable, StyledExt, WindowExtension};
|
use ui::{
|
||||||
|
h_flex, v_flex, Disableable, Icon, IconName, Selectable, Sizable, StyledExt, WindowExtension,
|
||||||
|
};
|
||||||
|
|
||||||
mod entry;
|
mod entry;
|
||||||
|
|
||||||
@@ -635,10 +637,12 @@ impl Render for Sidebar {
|
|||||||
.border_b_1()
|
.border_b_1()
|
||||||
.border_color(cx.theme().border_variant)
|
.border_color(cx.theme().border_variant)
|
||||||
.child(
|
.child(
|
||||||
div()
|
h_flex()
|
||||||
|
.gap_0p5()
|
||||||
.text_xs()
|
.text_xs()
|
||||||
.font_semibold()
|
.font_semibold()
|
||||||
.text_color(cx.theme().text_muted)
|
.text_color(cx.theme().text_muted)
|
||||||
|
.child(Icon::new(IconName::ChevronDown))
|
||||||
.child(SharedString::from("Results")),
|
.child(SharedString::from("Results")),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
@@ -660,10 +664,12 @@ impl Render for Sidebar {
|
|||||||
.gap_1()
|
.gap_1()
|
||||||
.flex_1()
|
.flex_1()
|
||||||
.child(
|
.child(
|
||||||
div()
|
h_flex()
|
||||||
|
.gap_0p5()
|
||||||
.text_xs()
|
.text_xs()
|
||||||
.font_semibold()
|
.font_semibold()
|
||||||
.text_color(cx.theme().text_muted)
|
.text_color(cx.theme().text_muted)
|
||||||
|
.child(Icon::new(IconName::ChevronDown))
|
||||||
.child(SharedString::from("Suggestions")),
|
.child(SharedString::from("Suggestions")),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ use gpui::{
|
|||||||
use nostr_sdk::prelude::*;
|
use nostr_sdk::prelude::*;
|
||||||
use person::PersonRegistry;
|
use person::PersonRegistry;
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
use state::NostrRegistry;
|
use state::{NostrRegistry, RelayState};
|
||||||
use theme::{SIDEBAR_WIDTH, TITLEBAR_HEIGHT};
|
use theme::{ActiveTheme, SIDEBAR_WIDTH, TITLEBAR_HEIGHT};
|
||||||
use titlebar::TitleBar;
|
use titlebar::TitleBar;
|
||||||
use ui::avatar::Avatar;
|
use ui::avatar::Avatar;
|
||||||
use ui::button::{Button, ButtonVariants};
|
use ui::button::{Button, ButtonVariants};
|
||||||
@@ -102,7 +102,7 @@ impl Workspace {
|
|||||||
subscriptions.push(
|
subscriptions.push(
|
||||||
// Observe the NIP-65 state
|
// Observe the NIP-65 state
|
||||||
cx.observe(&nip65_state, move |this, state, cx| {
|
cx.observe(&nip65_state, move |this, state, cx| {
|
||||||
if state.read(cx).idle() {
|
if state.read(cx).idle() || state.read(cx).checking() {
|
||||||
this.get_current_user(cx);
|
this.get_current_user(cx);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
@@ -202,9 +202,12 @@ impl Workspace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn titlebar_left(&mut self, _window: &mut Window, cx: &Context<Self>) -> impl IntoElement {
|
fn titlebar_left(&mut self, _window: &mut Window, cx: &Context<Self>) -> impl IntoElement {
|
||||||
|
let nostr = NostrRegistry::global(cx);
|
||||||
|
let nip65 = nostr.read(cx).nip65_state();
|
||||||
|
let nip17 = nostr.read(cx).nip17_state();
|
||||||
|
|
||||||
h_flex()
|
h_flex()
|
||||||
.h(TITLEBAR_HEIGHT)
|
.h(TITLEBAR_HEIGHT)
|
||||||
.w(SIDEBAR_WIDTH)
|
|
||||||
.flex_shrink_0()
|
.flex_shrink_0()
|
||||||
.justify_between()
|
.justify_between()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
@@ -229,14 +232,51 @@ impl Workspace {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
.map(|this| match nip65.read(cx) {
|
||||||
|
RelayState::Checking => this.child(
|
||||||
fn titlebar_center(&mut self, _window: &mut Window, _cx: &Context<Self>) -> impl IntoElement {
|
div()
|
||||||
h_flex().h(TITLEBAR_HEIGHT).flex_1()
|
.text_xs()
|
||||||
|
.text_color(cx.theme().text_muted)
|
||||||
|
.child(SharedString::from("Fetching user's relay list...")),
|
||||||
|
),
|
||||||
|
RelayState::NotConfigured => this.child(
|
||||||
|
h_flex()
|
||||||
|
.h_6()
|
||||||
|
.w_full()
|
||||||
|
.px_1()
|
||||||
|
.text_xs()
|
||||||
|
.text_color(cx.theme().warning_foreground)
|
||||||
|
.bg(cx.theme().warning_background)
|
||||||
|
.rounded_xs()
|
||||||
|
.child(SharedString::from("User hasn't configured a relay list")),
|
||||||
|
),
|
||||||
|
_ => this,
|
||||||
|
})
|
||||||
|
.map(|this| match nip17.read(cx) {
|
||||||
|
RelayState::Checking => {
|
||||||
|
this.child(div().text_xs().text_color(cx.theme().text_muted).child(
|
||||||
|
SharedString::from("Fetching user's messaging relay list..."),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
RelayState::NotConfigured => this.child(
|
||||||
|
h_flex()
|
||||||
|
.h_6()
|
||||||
|
.w_full()
|
||||||
|
.px_1()
|
||||||
|
.text_xs()
|
||||||
|
.text_color(cx.theme().warning_foreground)
|
||||||
|
.bg(cx.theme().warning_background)
|
||||||
|
.rounded_xs()
|
||||||
|
.child(SharedString::from(
|
||||||
|
"User hasn't configured a messaging relay list",
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
_ => this,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn titlebar_right(&mut self, _window: &mut Window, _cx: &Context<Self>) -> impl IntoElement {
|
fn titlebar_right(&mut self, _window: &mut Window, _cx: &Context<Self>) -> impl IntoElement {
|
||||||
h_flex().h(TITLEBAR_HEIGHT).w(SIDEBAR_WIDTH).flex_shrink_0()
|
h_flex().h(TITLEBAR_HEIGHT).flex_shrink_0()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,12 +287,11 @@ impl Render for Workspace {
|
|||||||
|
|
||||||
// Titlebar elements
|
// Titlebar elements
|
||||||
let left = self.titlebar_left(window, cx).into_any_element();
|
let left = self.titlebar_left(window, cx).into_any_element();
|
||||||
let center = self.titlebar_center(window, cx).into_any_element();
|
|
||||||
let right = self.titlebar_right(window, cx).into_any_element();
|
let right = self.titlebar_right(window, cx).into_any_element();
|
||||||
|
|
||||||
// Update title bar children
|
// Update title bar children
|
||||||
self.titlebar.update(cx, |this, _cx| {
|
self.titlebar.update(cx, |this, _cx| {
|
||||||
this.set_children(vec![left, center, right]);
|
this.set_children(vec![left, right]);
|
||||||
});
|
});
|
||||||
|
|
||||||
div()
|
div()
|
||||||
|
|||||||
@@ -9,6 +9,20 @@ pub enum DeviceState {
|
|||||||
Set,
|
Set,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl DeviceState {
|
||||||
|
pub fn initial(&self) -> bool {
|
||||||
|
matches!(self, DeviceState::Initial)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn requesting(&self) -> bool {
|
||||||
|
matches!(self, DeviceState::Requesting)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set(&self) -> bool {
|
||||||
|
matches!(self, DeviceState::Set)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Announcement
|
/// Announcement
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct Announcement {
|
pub struct Announcement {
|
||||||
|
|||||||
@@ -30,12 +30,12 @@ pub struct DeviceRegistry {
|
|||||||
/// Device signer
|
/// Device signer
|
||||||
pub device_signer: Entity<Option<Arc<dyn NostrSigner>>>,
|
pub device_signer: Entity<Option<Arc<dyn NostrSigner>>>,
|
||||||
|
|
||||||
|
/// Device state
|
||||||
|
pub state: DeviceState,
|
||||||
|
|
||||||
/// Device requests
|
/// Device requests
|
||||||
requests: Entity<HashSet<Event>>,
|
requests: Entity<HashSet<Event>>,
|
||||||
|
|
||||||
/// Device state
|
|
||||||
state: DeviceState,
|
|
||||||
|
|
||||||
/// Async tasks
|
/// Async tasks
|
||||||
tasks: Vec<Task<Result<(), Error>>>,
|
tasks: Vec<Task<Result<(), Error>>>,
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ publish.workspace = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
common = { path = "../common" }
|
common = { path = "../common" }
|
||||||
state = { path = "../state" }
|
state = { path = "../state" }
|
||||||
|
device = { path = "../device" }
|
||||||
|
|
||||||
gpui.workspace = true
|
gpui.workspace = true
|
||||||
nostr-sdk.workspace = true
|
nostr-sdk.workspace = true
|
||||||
|
|||||||
@@ -5,11 +5,12 @@ use std::time::Duration;
|
|||||||
|
|
||||||
use anyhow::{anyhow, Error};
|
use anyhow::{anyhow, Error};
|
||||||
use common::EventUtils;
|
use common::EventUtils;
|
||||||
|
use device::Announcement;
|
||||||
use gpui::{App, AppContext, Context, Entity, Global, Task};
|
use gpui::{App, AppContext, Context, Entity, Global, Task};
|
||||||
use nostr_sdk::prelude::*;
|
use nostr_sdk::prelude::*;
|
||||||
pub use person::*;
|
pub use person::*;
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
use state::{Announcement, NostrRegistry, BOOTSTRAP_RELAYS, TIMEOUT};
|
use state::{NostrRegistry, BOOTSTRAP_RELAYS, TIMEOUT};
|
||||||
|
|
||||||
mod person;
|
mod person;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
|
|
||||||
|
use device::Announcement;
|
||||||
use gpui::SharedString;
|
use gpui::SharedString;
|
||||||
use nostr_sdk::prelude::*;
|
use nostr_sdk::prelude::*;
|
||||||
use state::Announcement;
|
|
||||||
|
|
||||||
const IMAGE_RESIZER: &str = "https://wsrv.nl";
|
const IMAGE_RESIZER: &str = "https://wsrv.nl";
|
||||||
|
|
||||||
|
|||||||
@@ -12,13 +12,11 @@ use nostr_lmdb::NostrLmdb;
|
|||||||
use nostr_sdk::prelude::*;
|
use nostr_sdk::prelude::*;
|
||||||
|
|
||||||
mod constants;
|
mod constants;
|
||||||
mod device;
|
|
||||||
mod event;
|
mod event;
|
||||||
mod nip05;
|
mod nip05;
|
||||||
mod signer;
|
mod signer;
|
||||||
|
|
||||||
pub use constants::*;
|
pub use constants::*;
|
||||||
pub use device::*;
|
|
||||||
pub use event::*;
|
pub use event::*;
|
||||||
pub use nip05::*;
|
pub use nip05::*;
|
||||||
pub use signer::*;
|
pub use signer::*;
|
||||||
@@ -154,13 +152,13 @@ impl NostrRegistry {
|
|||||||
let client = self.client();
|
let client = self.client();
|
||||||
|
|
||||||
self.tasks.push(cx.background_spawn(async move {
|
self.tasks.push(cx.background_spawn(async move {
|
||||||
// Add bootstrap relay to the relay pool
|
// Add search relay to the relay pool
|
||||||
for url in BOOTSTRAP_RELAYS.into_iter() {
|
for url in SEARCH_RELAYS.into_iter() {
|
||||||
client.add_relay(url).await?;
|
client.add_relay(url).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add search relay to the relay pool
|
// Add bootstrap relay to the relay pool
|
||||||
for url in SEARCH_RELAYS.into_iter() {
|
for url in BOOTSTRAP_RELAYS.into_iter() {
|
||||||
client.add_relay(url).await?;
|
client.add_relay(url).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,6 +402,12 @@ impl NostrRegistry {
|
|||||||
let client = self.client();
|
let client = self.client();
|
||||||
let nip65 = self.nip65.downgrade();
|
let nip65 = self.nip65.downgrade();
|
||||||
|
|
||||||
|
// Set state to checking
|
||||||
|
self.nip65.update(cx, |this, cx| {
|
||||||
|
*this = RelayState::Checking;
|
||||||
|
cx.notify();
|
||||||
|
});
|
||||||
|
|
||||||
let task: Task<Result<RelayState, Error>> = cx.background_spawn(async move {
|
let task: Task<Result<RelayState, Error>> = cx.background_spawn(async move {
|
||||||
let signer = client.signer().context("Signer not found")?;
|
let signer = client.signer().context("Signer not found")?;
|
||||||
let public_key = signer.get_public_key().await?;
|
let public_key = signer.get_public_key().await?;
|
||||||
@@ -479,6 +483,12 @@ impl NostrRegistry {
|
|||||||
let client = self.client();
|
let client = self.client();
|
||||||
let nip17 = self.nip17.downgrade();
|
let nip17 = self.nip17.downgrade();
|
||||||
|
|
||||||
|
// Set state to checking
|
||||||
|
self.nip17.update(cx, |this, cx| {
|
||||||
|
*this = RelayState::Checking;
|
||||||
|
cx.notify();
|
||||||
|
});
|
||||||
|
|
||||||
let task: Task<Result<RelayState, Error>> = cx.background_spawn(async move {
|
let task: Task<Result<RelayState, Error>> = cx.background_spawn(async move {
|
||||||
let signer = client.signer().context("Signer not found")?;
|
let signer = client.signer().context("Signer not found")?;
|
||||||
let public_key = signer.get_public_key().await?;
|
let public_key = signer.get_public_key().await?;
|
||||||
@@ -966,6 +976,10 @@ impl RelayState {
|
|||||||
matches!(self, RelayState::Idle)
|
matches!(self, RelayState::Idle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn checking(&self) -> bool {
|
||||||
|
matches!(self, RelayState::Checking)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn not_configured(&self) -> bool {
|
pub fn not_configured(&self) -> bool {
|
||||||
matches!(self, RelayState::NotConfigured)
|
matches!(self, RelayState::NotConfigured)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user