diff --git a/Cargo.lock b/Cargo.lock
index f265c2e..512449f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -252,14 +252,15 @@ dependencies = [
[[package]]
name = "async-executor"
-version = "1.13.1"
+version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec"
+checksum = "bb812ffb58524bdd10860d7d974e2f01cc0950c2438a74ee5ec2e2280c6c4ffa"
dependencies = [
"async-task",
"concurrent-queue",
"fastrand 2.3.0",
"futures-lite 2.6.0",
+ "pin-project-lite",
"slab",
]
@@ -439,7 +440,7 @@ dependencies = [
"gpui",
"log",
"nostr-sdk",
- "reqwest 0.12.15",
+ "reqwest 0.12.15 (registry+https://github.com/rust-lang/crates.io-index)",
"smol",
"tempfile",
]
@@ -781,9 +782,9 @@ checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
[[package]]
name = "bytemuck"
-version = "1.22.0"
+version = "1.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540"
+checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c"
dependencies = [
"bytemuck_derive",
]
@@ -979,9 +980,9 @@ dependencies = [
[[package]]
name = "chrono"
-version = "0.4.40"
+version = "0.4.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
+checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
dependencies = [
"android-tzdata",
"iana-time-zone",
@@ -1135,7 +1136,7 @@ dependencies = [
[[package]]
name = "collections"
version = "0.1.0"
-source = "git+https://github.com/zed-industries/zed#f060918b578bb3b565adb9daf3a387d40496ca92"
+source = "git+https://github.com/zed-industries/zed#1a4d7249f6cf59dc37f64c8f745f0dee47a4e9ce"
dependencies = [
"indexmap",
"rustc-hash 2.1.1",
@@ -1524,7 +1525,7 @@ dependencies = [
[[package]]
name = "derive_refineable"
version = "0.1.0"
-source = "git+https://github.com/zed-industries/zed#f060918b578bb3b565adb9daf3a387d40496ca92"
+source = "git+https://github.com/zed-industries/zed#1a4d7249f6cf59dc37f64c8f745f0dee47a4e9ce"
dependencies = [
"proc-macro2",
"quote",
@@ -2315,7 +2316,7 @@ dependencies = [
[[package]]
name = "gpui"
version = "0.1.0"
-source = "git+https://github.com/zed-industries/zed#f060918b578bb3b565adb9daf3a387d40496ca92"
+source = "git+https://github.com/zed-industries/zed#1a4d7249f6cf59dc37f64c8f745f0dee47a4e9ce"
dependencies = [
"anyhow",
"as-raw-xcb-connection",
@@ -2407,7 +2408,7 @@ dependencies = [
[[package]]
name = "gpui_macros"
version = "0.1.0"
-source = "git+https://github.com/zed-industries/zed#f060918b578bb3b565adb9daf3a387d40496ca92"
+source = "git+https://github.com/zed-industries/zed#1a4d7249f6cf59dc37f64c8f745f0dee47a4e9ce"
dependencies = [
"proc-macro2",
"quote",
@@ -2631,7 +2632,7 @@ dependencies = [
[[package]]
name = "http_client"
version = "0.1.0"
-source = "git+https://github.com/zed-industries/zed#f060918b578bb3b565adb9daf3a387d40496ca92"
+source = "git+https://github.com/zed-industries/zed#1a4d7249f6cf59dc37f64c8f745f0dee47a4e9ce"
dependencies = [
"anyhow",
"bytes",
@@ -2648,7 +2649,7 @@ dependencies = [
[[package]]
name = "http_client_tls"
version = "0.1.0"
-source = "git+https://github.com/zed-industries/zed#f060918b578bb3b565adb9daf3a387d40496ca92"
+source = "git+https://github.com/zed-industries/zed#1a4d7249f6cf59dc37f64c8f745f0dee47a4e9ce"
dependencies = [
"rustls",
"rustls-platform-verifier",
@@ -3140,9 +3141,9 @@ dependencies = [
[[package]]
name = "kurbo"
-version = "0.11.1"
+version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89234b2cc610a7dd927ebde6b41dd1a5d4214cffaef4cf1fb2195d592f92518f"
+checksum = "1077d333efea6170d9ccb96d3c3026f300ca0773da4938cc4c811daa6df68b0c"
dependencies = [
"arrayvec",
"smallvec",
@@ -3389,7 +3390,7 @@ dependencies = [
[[package]]
name = "media"
version = "0.1.0"
-source = "git+https://github.com/zed-industries/zed#f060918b578bb3b565adb9daf3a387d40496ca92"
+source = "git+https://github.com/zed-industries/zed#1a4d7249f6cf59dc37f64c8f745f0dee47a4e9ce"
dependencies = [
"anyhow",
"bindgen 0.71.1",
@@ -3537,12 +3538,6 @@ dependencies = [
"tempfile",
]
-[[package]]
-name = "negentropy"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e664971378a3987224f7a0e10059782035e89899ae403718ee07de85bec42afe"
-
[[package]]
name = "negentropy"
version = "0.5.0"
@@ -3587,7 +3582,7 @@ checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
[[package]]
name = "nostr"
version = "0.41.0"
-source = "git+https://github.com/rust-nostr/nostr#2423323593f967a7c0d3136a1b0c3c89ee219d99"
+source = "git+https://github.com/rust-nostr/nostr#7edeac7becbec534e89b0e3cc1aedf7f64691e2a"
dependencies = [
"aes",
"base64",
@@ -3600,7 +3595,7 @@ dependencies = [
"getrandom 0.2.16",
"instant",
"regex",
- "reqwest 0.12.15",
+ "reqwest 0.12.15 (registry+https://github.com/rust-lang/crates.io-index)",
"scrypt",
"secp256k1",
"serde",
@@ -3612,7 +3607,7 @@ dependencies = [
[[package]]
name = "nostr-connect"
version = "0.41.0"
-source = "git+https://github.com/rust-nostr/nostr#2423323593f967a7c0d3136a1b0c3c89ee219d99"
+source = "git+https://github.com/rust-nostr/nostr#7edeac7becbec534e89b0e3cc1aedf7f64691e2a"
dependencies = [
"async-utility",
"nostr",
@@ -3624,7 +3619,7 @@ dependencies = [
[[package]]
name = "nostr-database"
version = "0.41.0"
-source = "git+https://github.com/rust-nostr/nostr#2423323593f967a7c0d3136a1b0c3c89ee219d99"
+source = "git+https://github.com/rust-nostr/nostr#7edeac7becbec534e89b0e3cc1aedf7f64691e2a"
dependencies = [
"flatbuffers",
"lru",
@@ -3635,7 +3630,7 @@ dependencies = [
[[package]]
name = "nostr-lmdb"
version = "0.41.0"
-source = "git+https://github.com/rust-nostr/nostr#2423323593f967a7c0d3136a1b0c3c89ee219d99"
+source = "git+https://github.com/rust-nostr/nostr#7edeac7becbec534e89b0e3cc1aedf7f64691e2a"
dependencies = [
"async-utility",
"heed",
@@ -3648,14 +3643,13 @@ dependencies = [
[[package]]
name = "nostr-relay-pool"
version = "0.41.0"
-source = "git+https://github.com/rust-nostr/nostr#2423323593f967a7c0d3136a1b0c3c89ee219d99"
+source = "git+https://github.com/rust-nostr/nostr#7edeac7becbec534e89b0e3cc1aedf7f64691e2a"
dependencies = [
"async-utility",
"async-wsocket",
"atomic-destructor",
"lru",
- "negentropy 0.3.1",
- "negentropy 0.5.0",
+ "negentropy",
"nostr",
"nostr-database",
"tokio",
@@ -3665,7 +3659,7 @@ dependencies = [
[[package]]
name = "nostr-sdk"
version = "0.41.0"
-source = "git+https://github.com/rust-nostr/nostr#2423323593f967a7c0d3136a1b0c3c89ee219d99"
+source = "git+https://github.com/rust-nostr/nostr#7edeac7becbec534e89b0e3cc1aedf7f64691e2a"
dependencies = [
"async-utility",
"nostr",
@@ -4822,7 +4816,7 @@ dependencies = [
[[package]]
name = "refineable"
version = "0.1.0"
-source = "git+https://github.com/zed-industries/zed#f060918b578bb3b565adb9daf3a387d40496ca92"
+source = "git+https://github.com/zed-industries/zed#1a4d7249f6cf59dc37f64c8f745f0dee47a4e9ce"
dependencies = [
"derive_refineable",
"workspace-hack",
@@ -4857,53 +4851,6 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
-[[package]]
-name = "reqwest"
-version = "0.12.8"
-source = "git+https://github.com/zed-industries/reqwest.git?rev=fd110f6998da16bbca97b6dddda9be7827c50e29#fd110f6998da16bbca97b6dddda9be7827c50e29"
-dependencies = [
- "base64",
- "bytes",
- "encoding_rs",
- "futures-core",
- "futures-util",
- "h2",
- "http",
- "http-body",
- "http-body-util",
- "hyper",
- "hyper-rustls",
- "hyper-util",
- "ipnet",
- "js-sys",
- "log",
- "mime",
- "once_cell",
- "percent-encoding",
- "pin-project-lite",
- "quinn",
- "rustls",
- "rustls-native-certs",
- "rustls-pemfile",
- "rustls-pki-types",
- "serde",
- "serde_json",
- "serde_urlencoded",
- "sync_wrapper",
- "system-configuration",
- "tokio",
- "tokio-rustls",
- "tokio-socks",
- "tokio-util",
- "tower-service",
- "url",
- "wasm-bindgen",
- "wasm-bindgen-futures",
- "wasm-streams",
- "web-sys",
- "windows-registry 0.2.0",
-]
-
[[package]]
name = "reqwest"
version = "0.12.15"
@@ -4957,10 +4904,58 @@ dependencies = [
"windows-registry 0.4.0",
]
+[[package]]
+name = "reqwest"
+version = "0.12.15"
+source = "git+https://github.com/zed-industries/reqwest.git?rev=951c770a32f1998d6e999cef3e59e0013e6c4415#951c770a32f1998d6e999cef3e59e0013e6c4415"
+dependencies = [
+ "base64",
+ "bytes",
+ "encoding_rs",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http",
+ "http-body",
+ "http-body-util",
+ "hyper",
+ "hyper-rustls",
+ "hyper-util",
+ "ipnet",
+ "js-sys",
+ "log",
+ "mime",
+ "once_cell",
+ "percent-encoding",
+ "pin-project-lite",
+ "quinn",
+ "rustls",
+ "rustls-native-certs",
+ "rustls-pemfile",
+ "rustls-pki-types",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "sync_wrapper",
+ "system-configuration",
+ "tokio",
+ "tokio-rustls",
+ "tokio-socks",
+ "tokio-util",
+ "tower",
+ "tower-service",
+ "url",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "wasm-streams",
+ "web-sys",
+ "windows-registry 0.4.0",
+]
+
[[package]]
name = "reqwest_client"
version = "0.1.0"
-source = "git+https://github.com/zed-industries/zed#f060918b578bb3b565adb9daf3a387d40496ca92"
+source = "git+https://github.com/zed-industries/zed#1a4d7249f6cf59dc37f64c8f745f0dee47a4e9ce"
dependencies = [
"anyhow",
"bytes",
@@ -4969,7 +4964,7 @@ dependencies = [
"http_client_tls",
"log",
"regex",
- "reqwest 0.12.8",
+ "reqwest 0.12.15 (git+https://github.com/zed-industries/reqwest.git?rev=951c770a32f1998d6e999cef3e59e0013e6c4415)",
"serde",
"smol",
"tokio",
@@ -5430,7 +5425,7 @@ checksum = "0f7d95a54511e0c7be3f51e8867aa8cf35148d7b9445d44de2f943e2b206e749"
[[package]]
name = "semantic_version"
version = "0.1.0"
-source = "git+https://github.com/zed-industries/zed#f060918b578bb3b565adb9daf3a387d40496ca92"
+source = "git+https://github.com/zed-industries/zed#1a4d7249f6cf59dc37f64c8f745f0dee47a4e9ce"
dependencies = [
"anyhow",
"serde",
@@ -5753,7 +5748,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "sum_tree"
version = "0.1.0"
-source = "git+https://github.com/zed-industries/zed#f060918b578bb3b565adb9daf3a387d40496ca92"
+source = "git+https://github.com/zed-industries/zed#1a4d7249f6cf59dc37f64c8f745f0dee47a4e9ce"
dependencies = [
"arrayvec",
"log",
@@ -6266,9 +6261,9 @@ dependencies = [
[[package]]
name = "toml"
-version = "0.8.21"
+version = "0.8.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "900f6c86a685850b1bc9f6223b20125115ee3f31e01207d81655bbcc0aea9231"
+checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae"
dependencies = [
"serde",
"serde_spanned",
@@ -6287,9 +6282,9 @@ dependencies = [
[[package]]
name = "toml_edit"
-version = "0.22.25"
+version = "0.22.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "10558ed0bd2a1562e630926a2d1f0b98c827da99fabd3fe20920a59642504485"
+checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e"
dependencies = [
"indexmap",
"serde",
@@ -6301,9 +6296,9 @@ dependencies = [
[[package]]
name = "toml_write"
-version = "0.1.0"
+version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "28391a4201ba7eb1984cfeb6862c0b3ea2cfe23332298967c749dddc0d6cd976"
+checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076"
[[package]]
name = "tower"
@@ -6663,7 +6658,7 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "util"
version = "0.1.0"
-source = "git+https://github.com/zed-industries/zed#f060918b578bb3b565adb9daf3a387d40496ca92"
+source = "git+https://github.com/zed-industries/zed#1a4d7249f6cf59dc37f64c8f745f0dee47a4e9ce"
dependencies = [
"anyhow",
"async-fs",
@@ -6921,9 +6916,9 @@ dependencies = [
[[package]]
name = "wayland-backend"
-version = "0.3.8"
+version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7208998eaa3870dad37ec8836979581506e0c5c64c20c9e79e9d2a10d6f47bf"
+checksum = "fe770181423e5fc79d3e2a7f4410b7799d5aab1de4372853de3c6aa13ca24121"
dependencies = [
"cc",
"downcast-rs",
@@ -6935,9 +6930,9 @@ dependencies = [
[[package]]
name = "wayland-client"
-version = "0.31.8"
+version = "0.31.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c2120de3d33638aaef5b9f4472bff75f07c56379cf76ea320bd3a3d65ecaf73f"
+checksum = "978fa7c67b0847dbd6a9f350ca2569174974cd4082737054dbb7fbb79d7d9a61"
dependencies = [
"bitflags 2.9.0",
"rustix 0.38.44",
@@ -6947,9 +6942,9 @@ dependencies = [
[[package]]
name = "wayland-cursor"
-version = "0.31.8"
+version = "0.31.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a93029cbb6650748881a00e4922b076092a6a08c11e7fbdb923f064b23968c5d"
+checksum = "a65317158dec28d00416cb16705934070aef4f8393353d41126c54264ae0f182"
dependencies = [
"rustix 0.38.44",
"wayland-client",
@@ -7244,17 +7239,6 @@ dependencies = [
"windows-link",
]
-[[package]]
-name = "windows-registry"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0"
-dependencies = [
- "windows-result 0.2.0",
- "windows-strings 0.1.0",
- "windows-targets 0.52.6",
-]
-
[[package]]
name = "windows-registry"
version = "0.4.0"
@@ -7286,15 +7270,6 @@ dependencies = [
"windows-targets 0.52.6",
]
-[[package]]
-name = "windows-result"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e"
-dependencies = [
- "windows-targets 0.52.6",
-]
-
[[package]]
name = "windows-result"
version = "0.3.2"
@@ -7304,16 +7279,6 @@ dependencies = [
"windows-link",
]
-[[package]]
-name = "windows-strings"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10"
-dependencies = [
- "windows-result 0.2.0",
- "windows-targets 0.52.6",
-]
-
[[package]]
name = "windows-strings"
version = "0.3.1"
diff --git a/assets/icons/filter-fill.svg b/assets/icons/filter-fill.svg
new file mode 100644
index 0000000..97b94eb
--- /dev/null
+++ b/assets/icons/filter-fill.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/icons/filter.svg b/assets/icons/filter.svg
new file mode 100644
index 0000000..2b587d5
--- /dev/null
+++ b/assets/icons/filter.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/icons/toggle-fill.svg b/assets/icons/toggle-fill.svg
new file mode 100644
index 0000000..8b1e834
--- /dev/null
+++ b/assets/icons/toggle-fill.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/icons/toggle.svg b/assets/icons/toggle.svg
new file mode 100644
index 0000000..e4bd9f9
--- /dev/null
+++ b/assets/icons/toggle.svg
@@ -0,0 +1,3 @@
+
diff --git a/crates/coop/src/views/sidebar/folder.rs b/crates/coop/src/views/sidebar/folder.rs
index e862c88..2906451 100644
--- a/crates/coop/src/views/sidebar/folder.rs
+++ b/crates/coop/src/views/sidebar/folder.rs
@@ -7,6 +7,7 @@ use gpui::{
};
use ui::{
theme::{scale::ColorScaleStep, ActiveTheme},
+ tooltip::Tooltip,
Collapsible, Icon, IconName, Sizable, StyledExt,
};
@@ -16,6 +17,7 @@ type Handler = Rc;
pub struct Parent {
base: Div,
icon: Option,
+ tooltip: Option,
label: SharedString,
items: Vec,
collapsed: bool,
@@ -28,6 +30,7 @@ impl Parent {
base: div().flex().flex_col().gap_2(),
label: label.into(),
icon: None,
+ tooltip: None,
items: Vec::new(),
collapsed: false,
handler: Rc::new(|_, _, _| {}),
@@ -39,6 +42,11 @@ impl Parent {
self
}
+ pub fn tooltip(mut self, tooltip: impl Into) -> Self {
+ self.tooltip = Some(tooltip.into());
+ self
+ }
+
pub fn collapsed(mut self, collapsed: bool) -> Self {
self.collapsed = collapsed;
self
@@ -105,6 +113,11 @@ impl RenderOnce for Parent {
.when_some(self.icon, |this, icon| this.child(icon.small()))
.child(self.label.clone()),
)
+ .when_some(self.tooltip.clone(), |this, tooltip| {
+ this.tooltip(move |window, cx| {
+ Tooltip::new(tooltip.clone(), window, cx).into()
+ })
+ })
.hover(|this| this.bg(cx.theme().base.step(cx, ColorScaleStep::THREE)))
.on_click(move |ev, window, cx| handler(ev, window, cx)),
)
@@ -118,6 +131,7 @@ impl RenderOnce for Parent {
pub struct Folder {
base: Div,
icon: Option,
+ tooltip: Option,
label: SharedString,
items: Vec,
collapsed: bool,
@@ -130,6 +144,7 @@ impl Folder {
base: div().flex().flex_col().gap_2(),
label: label.into(),
icon: None,
+ tooltip: None,
items: Vec::new(),
collapsed: false,
handler: Rc::new(|_, _, _| {}),
@@ -141,6 +156,11 @@ impl Folder {
self
}
+ pub fn tooltip(mut self, tooltip: impl Into) -> Self {
+ self.tooltip = Some(tooltip.into());
+ self
+ }
+
pub fn collapsed(mut self, collapsed: bool) -> Self {
self.collapsed = collapsed;
self
@@ -201,6 +221,11 @@ impl RenderOnce for Folder {
.when_some(self.icon, |this, icon| this.child(icon.small()))
.child(self.label.clone()),
)
+ .when_some(self.tooltip.clone(), |this, tooltip| {
+ this.tooltip(move |window, cx| {
+ Tooltip::new(tooltip.clone(), window, cx).into()
+ })
+ })
.hover(|this| this.bg(cx.theme().base.step(cx, ColorScaleStep::THREE)))
.on_click(move |ev, window, cx| handler(ev, window, cx)),
)
diff --git a/crates/coop/src/views/sidebar/mod.rs b/crates/coop/src/views/sidebar/mod.rs
index 86e8ffd..9e44347 100644
--- a/crates/coop/src/views/sidebar/mod.rs
+++ b/crates/coop/src/views/sidebar/mod.rs
@@ -1,3 +1,5 @@
+use std::{cmp::Reverse, collections::HashSet};
+
use account::Account;
use button::SidebarButton;
use chats::{
@@ -10,10 +12,11 @@ use global::get_client;
use gpui::{
actions, div, img, prelude::FluentBuilder, AnyElement, App, AppContext, Context, Entity,
EventEmitter, FocusHandle, Focusable, InteractiveElement, IntoElement, ParentElement, Render,
- SharedString, Styled, Task, Window,
+ ScrollHandle, SharedString, StatefulInteractiveElement, Styled, Task, Window,
};
+use itertools::Itertools;
use ui::{
- button::{Button, ButtonVariants},
+ button::{Button, ButtonCustomVariant, ButtonVariants},
dock_area::{
dock::DockPlacement,
panel::{Panel, PanelEvent},
@@ -36,13 +39,25 @@ pub fn init(window: &mut Window, cx: &mut App) -> Entity {
Sidebar::new(window, cx)
}
+#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+pub enum Item {
+ Ongoing,
+ Incoming,
+}
+
+#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+pub enum SubItem {
+ Trusted,
+ Unknown,
+}
+
pub struct Sidebar {
name: SharedString,
+ split_into_folders: bool,
+ active_items: HashSet- ,
+ active_subitems: HashSet,
focus_handle: FocusHandle,
- ongoing: bool,
- incoming: bool,
- trusted: bool,
- unknown: bool,
+ scroll_handle: ScrollHandle,
}
impl Sidebar {
@@ -52,34 +67,41 @@ impl Sidebar {
fn view(_window: &mut Window, cx: &mut Context) -> Self {
let focus_handle = cx.focus_handle();
+ let scroll_handle = ScrollHandle::default();
+
+ let mut active_items = HashSet::with_capacity(2);
+ active_items.insert(Item::Ongoing);
+
+ let mut active_subitems = HashSet::with_capacity(2);
+ active_subitems.insert(SubItem::Trusted);
+ active_subitems.insert(SubItem::Unknown);
Self {
name: "Chat Sidebar".into(),
- ongoing: false,
- incoming: false,
- trusted: true,
- unknown: true,
+ split_into_folders: false,
+ active_items,
+ active_subitems,
focus_handle,
+ scroll_handle,
}
}
- fn ongoing(&mut self, cx: &mut Context) {
- self.ongoing = !self.ongoing;
+ fn toggle_item(&mut self, item: Item, cx: &mut Context) {
+ if !self.active_items.remove(&item) {
+ self.active_items.insert(item);
+ }
cx.notify();
}
- fn incoming(&mut self, cx: &mut Context) {
- self.incoming = !self.incoming;
+ fn toggle_subitem(&mut self, subitem: SubItem, cx: &mut Context) {
+ if !self.active_subitems.remove(&subitem) {
+ self.active_subitems.insert(subitem);
+ }
cx.notify();
}
- fn trusted(&mut self, cx: &mut Context) {
- self.trusted = !self.trusted;
- cx.notify();
- }
-
- fn unknown(&mut self, cx: &mut Context) {
- self.unknown = !self.unknown;
+ fn split_into_folders(&mut self, cx: &mut Context) {
+ self.split_into_folders = !self.split_into_folders;
cx.notify();
}
@@ -176,20 +198,18 @@ impl Focusable for Sidebar {
}
impl Render for Sidebar {
- fn render(&mut self, _window: &mut Window, cx: &mut Context) -> impl IntoElement {
+ fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl IntoElement {
let account = Account::global(cx).read(cx).profile.as_ref();
let registry = ChatRegistry::global(cx).read(cx);
let rooms = registry.rooms(cx);
let loading = registry.loading();
- let ongoing = rooms.get(&RoomKind::Ongoing);
- let trusted = rooms.get(&RoomKind::Trusted);
- let unknown = rooms.get(&RoomKind::Unknown);
-
div()
- .scrollable(cx.entity_id(), ScrollbarAxis::Vertical)
+ .id("sidebar")
+ .track_scroll(&self.scroll_handle)
.on_action(cx.listener(Self::on_logout))
+ .overflow_y_scroll()
.size_full()
.flex()
.flex_col()
@@ -279,23 +299,65 @@ impl Render for Sidebar {
.gap_2()
.child(
div()
- .px_2()
+ .pl_2()
+ .pr_1()
+ .flex()
+ .justify_between()
+ .items_center()
.text_xs()
.font_semibold()
.text_color(cx.theme().base.step(cx, ColorScaleStep::NINE))
- .child("Messages"),
+ .child("Messages")
+ .child(
+ Button::new("menu")
+ .tooltip("Toggle chat folders")
+ .map(|this| {
+ if self.split_into_folders {
+ this.icon(IconName::ToggleFill)
+ } else {
+ this.icon(IconName::Toggle)
+ }
+ })
+ .small()
+ .custom(
+ ButtonCustomVariant::new(window, cx)
+ .foreground(
+ cx.theme().base.step(cx, ColorScaleStep::NINE),
+ )
+ .color(cx.theme().transparent)
+ .hover(cx.theme().transparent)
+ .active(cx.theme().transparent)
+ .border(cx.theme().transparent),
+ )
+ .on_click(cx.listener(move |this, _, _, cx| {
+ this.split_into_folders(cx);
+ })),
+ ),
)
.map(|this| {
if loading {
this.children(self.render_skeleton(6))
+ } else if !self.split_into_folders {
+ let rooms: Vec<_> = rooms
+ .values()
+ .flat_map(|v| v.iter().cloned())
+ .sorted_by_key(|e| Reverse(e.read(cx).created_at))
+ .collect();
+
+ this.children(Self::render_items(&rooms, cx))
} else {
+ let ongoing = rooms.get(&RoomKind::Ongoing);
+ let trusted = rooms.get(&RoomKind::Trusted);
+ let unknown = rooms.get(&RoomKind::Unknown);
+
this.when_some(ongoing, |this, rooms| {
this.child(
Folder::new("Ongoing")
.icon(IconName::Folder)
- .collapsed(self.ongoing)
+ .tooltip("All ongoing conversations")
+ .collapsed(!self.active_items.contains(&Item::Ongoing))
.on_click(cx.listener(move |this, _, _, cx| {
- this.ongoing(cx);
+ this.toggle_item(Item::Ongoing, cx);
}))
.children(Self::render_items(rooms, cx)),
)
@@ -303,17 +365,23 @@ impl Render for Sidebar {
.child(
Parent::new("Incoming")
.icon(IconName::Folder)
- .collapsed(self.incoming)
+ .tooltip("Incoming messages")
+ .collapsed(!self.active_items.contains(&Item::Incoming))
.on_click(cx.listener(move |this, _, _, cx| {
- this.incoming(cx);
+ this.toggle_item(Item::Incoming, cx);
}))
.when_some(trusted, |this, rooms| {
this.child(
Folder::new("Trusted")
.icon(IconName::Folder)
- .collapsed(self.trusted)
+ .tooltip("Incoming messages from trusted contacts")
+ .collapsed(
+ !self
+ .active_subitems
+ .contains(&SubItem::Trusted),
+ )
.on_click(cx.listener(move |this, _, _, cx| {
- this.trusted(cx);
+ this.toggle_subitem(SubItem::Trusted, cx);
}))
.children(Self::render_items(rooms, cx)),
)
@@ -322,9 +390,14 @@ impl Render for Sidebar {
this.child(
Folder::new("Unknown")
.icon(IconName::Folder)
- .collapsed(self.unknown)
+ .tooltip("Incoming messages from unknowns")
+ .collapsed(
+ !self
+ .active_subitems
+ .contains(&SubItem::Unknown),
+ )
.on_click(cx.listener(move |this, _, _, cx| {
- this.unknown(cx);
+ this.toggle_subitem(SubItem::Unknown, cx);
}))
.children(Self::render_items(rooms, cx)),
)
diff --git a/crates/ui/src/icon.rs b/crates/ui/src/icon.rs
index 3f631be..fd18ae7 100644
--- a/crates/ui/src/icon.rs
+++ b/crates/ui/src/icon.rs
@@ -36,6 +36,8 @@ pub enum IconName {
EmojiFill,
Folder,
FolderFill,
+ Filter,
+ FilterFill,
Inbox,
Info,
Loader,
@@ -61,6 +63,8 @@ pub enum IconName {
SortAscending,
SortDescending,
Sun,
+ Toggle,
+ ToggleFill,
ThumbsDown,
ThumbsUp,
TriangleAlert,
@@ -101,6 +105,8 @@ impl IconName {
Self::EyeOff => "icons/eye-off.svg",
Self::Folder => "icons/folder.svg",
Self::FolderFill => "icons/folder-fill.svg",
+ Self::Filter => "icons/filter.svg",
+ Self::FilterFill => "icons/filter-fill.svg",
Self::Inbox => "icons/inbox.svg",
Self::Info => "icons/info.svg",
Self::Loader => "icons/loader.svg",
@@ -126,6 +132,8 @@ impl IconName {
Self::SortAscending => "icons/sort-ascending.svg",
Self::SortDescending => "icons/sort-descending.svg",
Self::Sun => "icons/sun.svg",
+ Self::Toggle => "icons/toggle.svg",
+ Self::ToggleFill => "icons/toggle-fill.svg",
Self::ThumbsDown => "icons/thumbs-down.svg",
Self::ThumbsUp => "icons/thumbs-up.svg",
Self::TriangleAlert => "icons/triangle-alert.svg",
diff --git a/crates/ui/src/styled.rs b/crates/ui/src/styled.rs
index a97e8de..2e40986 100644
--- a/crates/ui/src/styled.rs
+++ b/crates/ui/src/styled.rs
@@ -64,7 +64,7 @@ pub trait StyledExt: Styled + Sized {
/// Set as Popover style
fn popover_style(self, cx: &mut App) -> Self {
- self.bg(cx.theme().base.step(cx, ColorScaleStep::TWO))
+ self.bg(cx.theme().background)
.border_1()
.border_color(cx.theme().base.step(cx, ColorScaleStep::SIX))
.shadow_lg()