clean up
Some checks failed
Rust / build (ubuntu-latest, stable) (push) Failing after 1m58s
Rust / build (ubuntu-latest, stable) (pull_request) Failing after 1m50s
Rust / build (macos-latest, stable) (push) Has been cancelled
Rust / build (windows-latest, stable) (push) Has been cancelled
Rust / build (macos-latest, stable) (pull_request) Has been cancelled
Rust / build (windows-latest, stable) (pull_request) Has been cancelled
Some checks failed
Rust / build (ubuntu-latest, stable) (push) Failing after 1m58s
Rust / build (ubuntu-latest, stable) (pull_request) Failing after 1m50s
Rust / build (macos-latest, stable) (push) Has been cancelled
Rust / build (windows-latest, stable) (push) Has been cancelled
Rust / build (macos-latest, stable) (pull_request) Has been cancelled
Rust / build (windows-latest, stable) (pull_request) Has been cancelled
This commit is contained in:
3
assets/icons/group.svg
Normal file
3
assets/icons/group.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
|
||||||
|
<circle cx="12" cy="8.75" r="3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><circle cx="4" cy="9.80005" r="2" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><circle cx="20" cy="9.80005" r="2" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M7.25 16.625V16.5C7.25 13.8766 9.37665 11.75 12 11.75C14.6234 11.75 16.75 13.8766 16.75 16.5V16.625C16.75 17.5225 16.0225 18.25 15.125 18.25H8.875C7.97754 18.25 7.25 17.5225 7.25 16.625Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M4.25 17.2602H2.75C1.64543 17.2602 0.706551 16.3538 0.919944 15.2701C1.25877 13.5493 2.15049 12.3257 4 11.8301" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/><path d="M19.75 17.2601H21.25C22.3546 17.2601 23.2935 16.3538 23.08 15.27C22.7412 13.5493 21.8495 12.3257 20 11.8301" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -691,14 +691,12 @@ impl ChatRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Trigger a refresh of the opened chat rooms by their IDs
|
/// Trigger a refresh of the opened chat rooms by their IDs
|
||||||
pub fn refresh_rooms(&mut self, ids: Option<Vec<u64>>, cx: &mut Context<Self>) {
|
pub fn refresh_rooms(&mut self, ids: &[u64], cx: &mut Context<Self>) {
|
||||||
if let Some(ids) = ids {
|
for room in self.rooms.iter() {
|
||||||
for room in self.rooms.iter() {
|
if ids.contains(&room.read(cx).id) {
|
||||||
if ids.contains(&room.read(cx).id) {
|
room.update(cx, |this, cx| {
|
||||||
room.update(cx, |this, cx| {
|
this.emit_refresh(cx);
|
||||||
this.emit_refresh(cx);
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ impl ImportKey {
|
|||||||
|
|
||||||
// Update the signer
|
// Update the signer
|
||||||
nostr.update(cx, |this, cx| {
|
nostr.update(cx, |this, cx| {
|
||||||
this.set_signer(keys, cx);
|
this.add_key_signer(&keys, cx);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
self.set_error("Invalid key", cx);
|
self.set_error("Invalid key", cx);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use nostr_sdk::prelude::*;
|
|||||||
use person::PersonRegistry;
|
use person::PersonRegistry;
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
use state::{NostrRegistry, FIND_DELAY};
|
use state::{NostrRegistry, FIND_DELAY};
|
||||||
use theme::{ActiveTheme, TABBAR_HEIGHT};
|
use theme::{ActiveTheme, SIDEBAR_WIDTH, TABBAR_HEIGHT};
|
||||||
use ui::button::{Button, ButtonVariants};
|
use ui::button::{Button, ButtonVariants};
|
||||||
use ui::dock_area::panel::{Panel, PanelEvent};
|
use ui::dock_area::panel::{Panel, PanelEvent};
|
||||||
use ui::indicator::Indicator;
|
use ui::indicator::Indicator;
|
||||||
@@ -585,10 +585,11 @@ impl Render for Sidebar {
|
|||||||
)
|
)
|
||||||
.when(!show_find_panel && !loading && total_rooms == 0, |this| {
|
.when(!show_find_panel && !loading && total_rooms == 0, |this| {
|
||||||
this.child(
|
this.child(
|
||||||
div().px_2().child(
|
div().px_2().w(SIDEBAR_WIDTH).child(
|
||||||
v_flex()
|
v_flex()
|
||||||
.p_3()
|
.p_3()
|
||||||
.h_24()
|
.h_24()
|
||||||
|
.w_full()
|
||||||
.border_2()
|
.border_2()
|
||||||
.border_dashed()
|
.border_dashed()
|
||||||
.border_color(cx.theme().border_variant)
|
.border_color(cx.theme().border_variant)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use gpui::{
|
|||||||
use person::PersonRegistry;
|
use person::PersonRegistry;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
use state::{NostrRegistry, RelayState};
|
use state::{NostrRegistry, RelayState, SignerEvent};
|
||||||
use theme::{ActiveTheme, Theme, ThemeRegistry, SIDEBAR_WIDTH};
|
use theme::{ActiveTheme, Theme, ThemeRegistry, SIDEBAR_WIDTH};
|
||||||
use title_bar::TitleBar;
|
use title_bar::TitleBar;
|
||||||
use ui::avatar::Avatar;
|
use ui::avatar::Avatar;
|
||||||
@@ -42,6 +42,7 @@ pub fn init(window: &mut Window, cx: &mut App) -> Entity<Workspace> {
|
|||||||
#[action(namespace = workspace, no_json)]
|
#[action(namespace = workspace, no_json)]
|
||||||
enum Command {
|
enum Command {
|
||||||
ToggleTheme,
|
ToggleTheme,
|
||||||
|
ToggleAccount,
|
||||||
|
|
||||||
RefreshEncryption,
|
RefreshEncryption,
|
||||||
RefreshRelayList,
|
RefreshRelayList,
|
||||||
@@ -85,19 +86,19 @@ impl Workspace {
|
|||||||
);
|
);
|
||||||
|
|
||||||
subscriptions.push(
|
subscriptions.push(
|
||||||
// Observe the nostr entity
|
// Observe the npubs entity
|
||||||
cx.observe_in(&nostr, window, move |this, nostr, window, cx| {
|
cx.observe_in(&npubs, window, move |this, npubs, window, cx| {
|
||||||
if nostr.read(cx).connected {
|
if !npubs.read(cx).is_empty() {
|
||||||
this.set_layout(window, cx);
|
this.account_selector(window, cx);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
subscriptions.push(
|
subscriptions.push(
|
||||||
// Observe the npubs entity
|
// Subscribe to the signer events
|
||||||
cx.observe_in(&npubs, window, move |this, npubs, window, cx| {
|
cx.subscribe_in(&nostr, window, move |this, _state, event, window, cx| {
|
||||||
if !npubs.read(cx).is_empty() {
|
if let SignerEvent::Set = event {
|
||||||
this.account_selector(window, cx);
|
this.set_center_layout(window, cx);
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@@ -141,11 +142,16 @@ impl Workspace {
|
|||||||
let ids = this.panel_ids(cx);
|
let ids = this.panel_ids(cx);
|
||||||
|
|
||||||
chat.update(cx, |this, cx| {
|
chat.update(cx, |this, cx| {
|
||||||
this.refresh_rooms(ids, cx);
|
this.refresh_rooms(&ids, cx);
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Set the layout at the end of cycle
|
||||||
|
cx.defer_in(window, |this, window, cx| {
|
||||||
|
this.set_layout(window, cx);
|
||||||
|
});
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
titlebar,
|
titlebar,
|
||||||
dock,
|
dock,
|
||||||
@@ -170,49 +176,40 @@ impl Workspace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get all panel ids
|
/// Get all panel ids
|
||||||
fn panel_ids(&self, cx: &App) -> Option<Vec<u64>> {
|
fn panel_ids(&self, cx: &App) -> Vec<u64> {
|
||||||
let ids: Vec<u64> = self
|
self.dock
|
||||||
.dock
|
|
||||||
.read(cx)
|
.read(cx)
|
||||||
.items
|
.items
|
||||||
.panel_ids(cx)
|
.panel_ids(cx)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|panel| panel.parse::<u64>().ok())
|
.filter_map(|panel| panel.parse::<u64>().ok())
|
||||||
.collect();
|
.collect()
|
||||||
|
|
||||||
Some(ids)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the dock layout
|
/// Set the dock layout
|
||||||
fn set_layout(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
fn set_layout(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
let weak_dock = self.dock.downgrade();
|
|
||||||
|
|
||||||
// Sidebar
|
|
||||||
let left = DockItem::panel(Arc::new(sidebar::init(window, cx)));
|
let left = DockItem::panel(Arc::new(sidebar::init(window, cx)));
|
||||||
|
|
||||||
// Main workspace
|
// Update the dock layout with sidebar on the left
|
||||||
let center = DockItem::split_with_sizes(
|
|
||||||
Axis::Vertical,
|
|
||||||
vec![DockItem::tabs(
|
|
||||||
vec![Arc::new(greeter::init(window, cx))],
|
|
||||||
None,
|
|
||||||
&weak_dock,
|
|
||||||
window,
|
|
||||||
cx,
|
|
||||||
)],
|
|
||||||
vec![None],
|
|
||||||
&weak_dock,
|
|
||||||
window,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Update the dock layout
|
|
||||||
self.dock.update(cx, |this, cx| {
|
self.dock.update(cx, |this, cx| {
|
||||||
this.set_left_dock(left, Some(SIDEBAR_WIDTH), true, window, cx);
|
this.set_left_dock(left, Some(SIDEBAR_WIDTH), true, window, cx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the center dock layout
|
||||||
|
fn set_center_layout(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
|
let dock = self.dock.downgrade();
|
||||||
|
let greeeter = Arc::new(greeter::init(window, cx));
|
||||||
|
let tabs = DockItem::tabs(vec![greeeter], None, &dock, window, cx);
|
||||||
|
let center = DockItem::split(Axis::Vertical, vec![tabs], &dock, window, cx);
|
||||||
|
|
||||||
|
// Update the layout with center dock
|
||||||
|
self.dock.update(cx, |this, cx| {
|
||||||
this.set_center(center, window, cx);
|
this.set_center(center, window, cx);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Handle command events
|
||||||
fn on_command(&mut self, command: &Command, window: &mut Window, cx: &mut Context<Self>) {
|
fn on_command(&mut self, command: &Command, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
match command {
|
match command {
|
||||||
Command::ShowSettings => {
|
Command::ShowSettings => {
|
||||||
@@ -305,6 +302,9 @@ impl Workspace {
|
|||||||
Command::ToggleTheme => {
|
Command::ToggleTheme => {
|
||||||
self.theme_selector(window, cx);
|
self.theme_selector(window, cx);
|
||||||
}
|
}
|
||||||
|
Command::ToggleAccount => {
|
||||||
|
self.account_selector(window, cx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -508,6 +508,11 @@ impl Workspace {
|
|||||||
Box::new(Command::ToggleTheme),
|
Box::new(Command::ToggleTheme),
|
||||||
)
|
)
|
||||||
.separator()
|
.separator()
|
||||||
|
.menu_with_icon(
|
||||||
|
"Accounts",
|
||||||
|
IconName::Group,
|
||||||
|
Box::new(Command::ToggleAccount),
|
||||||
|
)
|
||||||
.menu_with_icon(
|
.menu_with_icon(
|
||||||
"Settings",
|
"Settings",
|
||||||
IconName::Settings,
|
IconName::Settings,
|
||||||
@@ -516,19 +521,6 @@ impl Workspace {
|
|||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.when(nostr.read(cx).creating, |this| {
|
|
||||||
this.child(div().text_xs().text_color(cx.theme().text_muted).child(
|
|
||||||
SharedString::from("Coop is creating a new identity for you..."),
|
|
||||||
))
|
|
||||||
})
|
|
||||||
.when(!nostr.read(cx).connected, |this| {
|
|
||||||
this.child(
|
|
||||||
div()
|
|
||||||
.text_xs()
|
|
||||||
.text_color(cx.theme().text_muted)
|
|
||||||
.child(SharedString::from("Connecting...")),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
|||||||
@@ -40,10 +40,9 @@ pub const WOT_RELAYS: [&str; 1] = ["wss://relay.vertexlab.io"];
|
|||||||
pub const SEARCH_RELAYS: [&str; 2] = ["wss://antiprimal.net", "wss://search.nos.today"];
|
pub const SEARCH_RELAYS: [&str; 2] = ["wss://antiprimal.net", "wss://search.nos.today"];
|
||||||
|
|
||||||
/// Default bootstrap relays
|
/// Default bootstrap relays
|
||||||
pub const BOOTSTRAP_RELAYS: [&str; 4] = [
|
pub const BOOTSTRAP_RELAYS: [&str; 3] = [
|
||||||
"wss://nos.lol",
|
|
||||||
"wss://relay.damus.io",
|
|
||||||
"wss://relay.primal.net",
|
"wss://relay.primal.net",
|
||||||
|
"wss://indexer.coracle.social",
|
||||||
"wss://user.kindpag.es",
|
"wss://user.kindpag.es",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -42,16 +42,6 @@ struct GlobalNostrRegistry(Entity<NostrRegistry>);
|
|||||||
|
|
||||||
impl Global for GlobalNostrRegistry {}
|
impl Global for GlobalNostrRegistry {}
|
||||||
|
|
||||||
/// Signer event.
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
|
||||||
pub enum SignerEvent {
|
|
||||||
/// A new signer has been set
|
|
||||||
Set,
|
|
||||||
|
|
||||||
/// An error occurred
|
|
||||||
Error(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Nostr Registry
|
/// Nostr Registry
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct NostrRegistry {
|
pub struct NostrRegistry {
|
||||||
@@ -75,12 +65,6 @@ pub struct NostrRegistry {
|
|||||||
/// Relay list state
|
/// Relay list state
|
||||||
pub relay_list_state: RelayState,
|
pub relay_list_state: RelayState,
|
||||||
|
|
||||||
/// Whether Coop is connected to all bootstrap relays
|
|
||||||
pub connected: bool,
|
|
||||||
|
|
||||||
/// Whether Coop is creating a new signer
|
|
||||||
pub creating: bool,
|
|
||||||
|
|
||||||
/// Tasks for asynchronous operations
|
/// Tasks for asynchronous operations
|
||||||
tasks: Vec<Task<Result<(), Error>>>,
|
tasks: Vec<Task<Result<(), Error>>>,
|
||||||
}
|
}
|
||||||
@@ -140,8 +124,6 @@ impl NostrRegistry {
|
|||||||
app_keys,
|
app_keys,
|
||||||
gossip,
|
gossip,
|
||||||
relay_list_state: RelayState::Idle,
|
relay_list_state: RelayState::Idle,
|
||||||
connected: false,
|
|
||||||
creating: false,
|
|
||||||
tasks: vec![],
|
tasks: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,12 +143,6 @@ impl NostrRegistry {
|
|||||||
self.npubs.clone()
|
self.npubs.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the connected status of the client
|
|
||||||
fn set_connected(&mut self, cx: &mut Context<Self>) {
|
|
||||||
self.connected = true;
|
|
||||||
cx.notify();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Connect to the bootstrapping relays
|
/// Connect to the bootstrapping relays
|
||||||
fn connect(&mut self, cx: &mut Context<Self>) {
|
fn connect(&mut self, cx: &mut Context<Self>) {
|
||||||
let client = self.client();
|
let client = self.client();
|
||||||
@@ -185,13 +161,12 @@ impl NostrRegistry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Connect to all added relays
|
// Connect to all added relays
|
||||||
client.connect().and_wait(Duration::from_secs(5)).await;
|
client.connect().and_wait(Duration::from_secs(2)).await;
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
// Update the state
|
// Update the state
|
||||||
this.update(cx, |this, cx| {
|
this.update(cx, |this, cx| {
|
||||||
this.set_connected(cx);
|
|
||||||
this.get_npubs(cx);
|
this.get_npubs(cx);
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@@ -317,12 +292,6 @@ impl NostrRegistry {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set whether Coop is creating a new signer
|
|
||||||
fn set_creating(&mut self, creating: bool, cx: &mut Context<Self>) {
|
|
||||||
self.creating = creating;
|
|
||||||
cx.notify();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a new identity
|
/// Create a new identity
|
||||||
fn create_identity(&mut self, cx: &mut Context<Self>) {
|
fn create_identity(&mut self, cx: &mut Context<Self>) {
|
||||||
let client = self.client();
|
let client = self.client();
|
||||||
@@ -335,9 +304,6 @@ impl NostrRegistry {
|
|||||||
// Create a write credential task
|
// Create a write credential task
|
||||||
let write_credential = cx.write_credentials(&username, &username, &secret);
|
let write_credential = cx.write_credentials(&username, &username, &secret);
|
||||||
|
|
||||||
// Set the creating signer status
|
|
||||||
self.set_creating(true, cx);
|
|
||||||
|
|
||||||
// Run async tasks in background
|
// Run async tasks in background
|
||||||
let task: Task<Result<(), Error>> = cx.background_spawn(async move {
|
let task: Task<Result<(), Error>> = cx.background_spawn(async move {
|
||||||
let signer = async_keys.into_nostr_signer();
|
let signer = async_keys.into_nostr_signer();
|
||||||
@@ -394,8 +360,8 @@ impl NostrRegistry {
|
|||||||
// Wait for the task to complete
|
// Wait for the task to complete
|
||||||
task.await?;
|
task.await?;
|
||||||
|
|
||||||
|
// Set signer
|
||||||
this.update(cx, |this, cx| {
|
this.update(cx, |this, cx| {
|
||||||
this.set_creating(false, cx);
|
|
||||||
this.set_signer(keys, cx);
|
this.set_signer(keys, cx);
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@@ -416,8 +382,8 @@ impl NostrRegistry {
|
|||||||
cx.spawn(async move |_cx| {
|
cx.spawn(async move |_cx| {
|
||||||
let (_, secret) = read_credential
|
let (_, secret) = read_credential
|
||||||
.await
|
.await
|
||||||
.map_err(|_| anyhow!("Failed to get signer"))?
|
.map_err(|_| anyhow!("Failed to get signer. Please re-import the secret key"))?
|
||||||
.ok_or_else(|| anyhow!("Failed to get signer"))?;
|
.ok_or_else(|| anyhow!("Failed to get signer. Please re-import the secret key"))?;
|
||||||
|
|
||||||
// Try to parse as a direct secret key first
|
// Try to parse as a direct secret key first
|
||||||
if let Ok(secret_key) = SecretKey::from_slice(&secret) {
|
if let Ok(secret_key) = SecretKey::from_slice(&secret) {
|
||||||
@@ -507,7 +473,7 @@ impl NostrRegistry {
|
|||||||
let secret = keys.secret_key().to_secret_bytes();
|
let secret = keys.secret_key().to_secret_bytes();
|
||||||
|
|
||||||
// Write the credential to the keyring
|
// Write the credential to the keyring
|
||||||
let write_credential = cx.write_credentials(&username, &username, &secret);
|
let write_credential = cx.write_credentials(&username, "keys", &secret);
|
||||||
|
|
||||||
self.tasks.push(cx.spawn(async move |this, cx| {
|
self.tasks.push(cx.spawn(async move |this, cx| {
|
||||||
match write_credential.await {
|
match write_credential.await {
|
||||||
@@ -546,7 +512,7 @@ impl NostrRegistry {
|
|||||||
Ok((public_key, uri)) => {
|
Ok((public_key, uri)) => {
|
||||||
let username = public_key.to_bech32().unwrap();
|
let username = public_key.to_bech32().unwrap();
|
||||||
let write_credential = this.read_with(cx, |_this, cx| {
|
let write_credential = this.read_with(cx, |_this, cx| {
|
||||||
cx.write_credentials(&username, &username, uri.to_string().as_bytes())
|
cx.write_credentials(&username, "nostrconnect", uri.to_string().as_bytes())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
match write_credential.await {
|
match write_credential.await {
|
||||||
@@ -1020,6 +986,16 @@ fn default_messaging_relays() -> Vec<RelayUrl> {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Signer event.
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub enum SignerEvent {
|
||||||
|
/// A new signer has been set
|
||||||
|
Set,
|
||||||
|
|
||||||
|
/// An error occurred
|
||||||
|
Error(String),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
||||||
pub enum RelayState {
|
pub enum RelayState {
|
||||||
#[default]
|
#[default]
|
||||||
|
|||||||
@@ -2,10 +2,11 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use gpui::prelude::FluentBuilder;
|
use gpui::prelude::FluentBuilder;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, div, px, AnyElement, AnyView, App, AppContext, Axis, Bounds, Context, Edges, Entity,
|
actions, div, px, AnyElement, AnyView, App, AppContext, Axis, Bounds, Context, Decorations,
|
||||||
EntityId, EventEmitter, Focusable, InteractiveElement as _, IntoElement, ParentElement as _,
|
Edges, Entity, EntityId, EventEmitter, Focusable, InteractiveElement as _, IntoElement,
|
||||||
Pixels, Render, SharedString, Styled, Subscription, WeakEntity, Window,
|
ParentElement as _, Pixels, Render, SharedString, Styled, Subscription, WeakEntity, Window,
|
||||||
};
|
};
|
||||||
|
use theme::CLIENT_SIDE_DECORATION_ROUNDING;
|
||||||
|
|
||||||
use crate::dock_area::dock::{Dock, DockPlacement};
|
use crate::dock_area::dock::{Dock, DockPlacement};
|
||||||
use crate::dock_area::panel::{Panel, PanelEvent, PanelStyle, PanelView};
|
use crate::dock_area::panel::{Panel, PanelEvent, PanelStyle, PanelView};
|
||||||
@@ -202,19 +203,16 @@ impl DockItem {
|
|||||||
/// Returns all panel ids
|
/// Returns all panel ids
|
||||||
pub fn panel_ids(&self, cx: &App) -> Vec<SharedString> {
|
pub fn panel_ids(&self, cx: &App) -> Vec<SharedString> {
|
||||||
match self {
|
match self {
|
||||||
Self::Tabs { view, .. } => view.read(cx).panel_ids(cx),
|
|
||||||
Self::Split { items, .. } => {
|
|
||||||
let mut total = vec![];
|
|
||||||
|
|
||||||
for item in items.iter() {
|
|
||||||
if let DockItem::Tabs { view, .. } = item {
|
|
||||||
total.extend(view.read(cx).panel_ids(cx));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
total
|
|
||||||
}
|
|
||||||
Self::Panel { .. } => vec![],
|
Self::Panel { .. } => vec![],
|
||||||
|
Self::Tabs { view, .. } => view.read(cx).panel_ids(cx),
|
||||||
|
Self::Split { items, .. } => items
|
||||||
|
.iter()
|
||||||
|
.filter_map(|item| match item {
|
||||||
|
DockItem::Tabs { view, .. } => Some(view.read(cx).panel_ids(cx)),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.flatten()
|
||||||
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -745,6 +743,7 @@ impl EventEmitter<DockEvent> for DockArea {}
|
|||||||
impl Render for DockArea {
|
impl Render for DockArea {
|
||||||
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 view = cx.entity().clone();
|
let view = cx.entity().clone();
|
||||||
|
let decorations = window.window_decorations();
|
||||||
|
|
||||||
div()
|
div()
|
||||||
.id("dock-area")
|
.id("dock-area")
|
||||||
@@ -754,7 +753,17 @@ impl Render for DockArea {
|
|||||||
.on_prepaint(move |bounds, _, cx| view.update(cx, |r, _| r.bounds = bounds))
|
.on_prepaint(move |bounds, _, cx| view.update(cx, |r, _| r.bounds = bounds))
|
||||||
.map(|this| {
|
.map(|this| {
|
||||||
if let Some(zoom_view) = self.zoom_view.clone() {
|
if let Some(zoom_view) = self.zoom_view.clone() {
|
||||||
this.child(zoom_view)
|
this.map(|this| match decorations {
|
||||||
|
Decorations::Server => this,
|
||||||
|
Decorations::Client { tiling } => this
|
||||||
|
.when(!(tiling.top || tiling.right), |div| {
|
||||||
|
div.rounded_br(CLIENT_SIDE_DECORATION_ROUNDING)
|
||||||
|
})
|
||||||
|
.when(!(tiling.top || tiling.left), |div| {
|
||||||
|
div.rounded_bl(CLIENT_SIDE_DECORATION_ROUNDING)
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.child(zoom_view)
|
||||||
} else {
|
} else {
|
||||||
// render dock
|
// render dock
|
||||||
this.child(
|
this.child(
|
||||||
|
|||||||
@@ -1080,8 +1080,10 @@ impl TabPanel {
|
|||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
if let Some(panel) = self.active_panel(cx) {
|
if self.panels.len() > 1 {
|
||||||
self.remove_panel(&panel, window, cx);
|
if let Some(panel) = self.active_panel(cx) {
|
||||||
|
self.remove_panel(&panel, window, cx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ pub enum IconName {
|
|||||||
Sun,
|
Sun,
|
||||||
Ship,
|
Ship,
|
||||||
Shield,
|
Shield,
|
||||||
|
Group,
|
||||||
UserKey,
|
UserKey,
|
||||||
Upload,
|
Upload,
|
||||||
Usb,
|
Usb,
|
||||||
@@ -133,6 +134,7 @@ impl IconNamed for IconName {
|
|||||||
Self::UserKey => "icons/user-key.svg",
|
Self::UserKey => "icons/user-key.svg",
|
||||||
Self::Upload => "icons/upload.svg",
|
Self::Upload => "icons/upload.svg",
|
||||||
Self::Usb => "icons/usb.svg",
|
Self::Usb => "icons/usb.svg",
|
||||||
|
Self::Group => "icons/group.svg",
|
||||||
Self::PanelLeft => "icons/panel-left.svg",
|
Self::PanelLeft => "icons/panel-left.svg",
|
||||||
Self::PanelLeftOpen => "icons/panel-left-open.svg",
|
Self::PanelLeftOpen => "icons/panel-left-open.svg",
|
||||||
Self::PanelRight => "icons/panel-right.svg",
|
Self::PanelRight => "icons/panel-right.svg",
|
||||||
|
|||||||
@@ -249,7 +249,6 @@ impl Render for Root {
|
|||||||
div()
|
div()
|
||||||
.id("window")
|
.id("window")
|
||||||
.size_full()
|
.size_full()
|
||||||
.bg(gpui::transparent_black())
|
|
||||||
.map(|div| match decorations {
|
.map(|div| match decorations {
|
||||||
Decorations::Server => div,
|
Decorations::Server => div,
|
||||||
Decorations::Client { tiling } => div
|
Decorations::Client { tiling } => div
|
||||||
|
|||||||
Reference in New Issue
Block a user