feat: refactor encryption panel #13

Merged
reya merged 2 commits from improve-enc-panel into master 2026-02-28 11:25:03 +00:00
6 changed files with 207 additions and 75 deletions
Showing only changes of commit 635c500233 - Show all commits

101
Cargo.lock generated
View File

@@ -772,6 +772,15 @@ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "block2"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5"
dependencies = [
"objc2",
]
[[package]] [[package]]
name = "blocking" name = "blocking"
version = "1.6.2" version = "1.6.2"
@@ -1189,7 +1198,7 @@ dependencies = [
[[package]] [[package]]
name = "collections" name = "collections"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"rustc-hash 2.1.1", "rustc-hash 2.1.1",
@@ -1318,6 +1327,7 @@ dependencies = [
"chat", "chat",
"chat_ui", "chat_ui",
"common", "common",
"core-text",
"device", "device",
"futures", "futures",
"gpui", "gpui",
@@ -1400,19 +1410,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "core-graphics"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "064badf302c3194842cf2c5d61f56cc88e54a759313879cdf03abdd27d0c3b97"
dependencies = [
"bitflags 2.11.0",
"core-foundation 0.10.0",
"core-graphics-types 0.2.0",
"foreign-types",
"libc",
]
[[package]] [[package]]
name = "core-graphics-helmer-fork" name = "core-graphics-helmer-fork"
version = "0.24.0" version = "0.24.0"
@@ -1463,13 +1460,14 @@ dependencies = [
[[package]] [[package]]
name = "core-text" name = "core-text"
version = "21.1.0" version = "21.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fce32d657e17d6e4a8e70fe2ae6875218015f320620a78e5949d228bc76622bd" checksum = "a593227b66cbd4007b2a050dfdd9e1d1318311409c8d600dc82ba1b15ca9c130"
dependencies = [ dependencies = [
"core-foundation 0.10.0", "core-foundation 0.10.0",
"core-graphics 0.25.0", "core-graphics 0.24.0",
"foreign-types", "foreign-types",
"libc",
] ]
[[package]] [[package]]
@@ -1646,7 +1644,7 @@ dependencies = [
[[package]] [[package]]
name = "derive_refineable" name = "derive_refineable"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -1730,6 +1728,18 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
[[package]]
name = "dispatch2"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38"
dependencies = [
"bitflags 2.11.0",
"block2",
"libc",
"objc2",
]
[[package]] [[package]]
name = "displaydoc" name = "displaydoc"
version = "0.2.5" version = "0.2.5"
@@ -2587,7 +2597,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui" name = "gpui"
version = "0.2.2" version = "0.2.2"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-channel 2.5.0", "async-channel 2.5.0",
@@ -2666,7 +2676,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui_linux" name = "gpui_linux"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"as-raw-xcb-connection", "as-raw-xcb-connection",
@@ -2714,11 +2724,10 @@ dependencies = [
[[package]] [[package]]
name = "gpui_macos" name = "gpui_macos"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-task", "async-task",
"bindgen",
"block", "block",
"cbindgen", "cbindgen",
"cocoa 0.26.0", "cocoa 0.26.0",
@@ -2730,6 +2739,7 @@ dependencies = [
"core-video", "core-video",
"ctor", "ctor",
"derive_more", "derive_more",
"dispatch2",
"etagere", "etagere",
"foreign-types", "foreign-types",
"futures", "futures",
@@ -2750,12 +2760,13 @@ dependencies = [
"strum", "strum",
"util", "util",
"uuid", "uuid",
"zed-font-kit",
] ]
[[package]] [[package]]
name = "gpui_macros" name = "gpui_macros"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"heck 0.5.0", "heck 0.5.0",
"proc-macro2", "proc-macro2",
@@ -2766,7 +2777,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui_platform" name = "gpui_platform"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"console_error_panic_hook", "console_error_panic_hook",
"gpui", "gpui",
@@ -2779,7 +2790,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui_tokio" name = "gpui_tokio"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"gpui", "gpui",
@@ -2790,7 +2801,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui_util" name = "gpui_util"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"log", "log",
@@ -2799,7 +2810,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui_web" name = "gpui_web"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"console_error_panic_hook", "console_error_panic_hook",
@@ -2822,7 +2833,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui_wgpu" name = "gpui_wgpu"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytemuck", "bytemuck",
@@ -2850,7 +2861,7 @@ dependencies = [
[[package]] [[package]]
name = "gpui_windows" name = "gpui_windows"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"collections", "collections",
@@ -3094,7 +3105,7 @@ dependencies = [
[[package]] [[package]]
name = "http_client" name = "http_client"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-compression", "async-compression",
@@ -3119,7 +3130,7 @@ dependencies = [
[[package]] [[package]]
name = "http_client_tls" name = "http_client_tls"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"rustls", "rustls",
"rustls-platform-verifier", "rustls-platform-verifier",
@@ -3880,7 +3891,7 @@ dependencies = [
[[package]] [[package]]
name = "media" name = "media"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bindgen", "bindgen",
@@ -4624,7 +4635,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220"
[[package]] [[package]]
name = "perf" name = "perf"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"collections", "collections",
"serde", "serde",
@@ -4742,9 +4753,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]] [[package]]
name = "piper" name = "piper"
version = "0.2.4" version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" checksum = "c835479a4443ded371d6c535cbfd8d31ad92c5d23ae9770a61bc155e4992a3c1"
dependencies = [ dependencies = [
"atomic-waker", "atomic-waker",
"fastrand 2.3.0", "fastrand 2.3.0",
@@ -5305,7 +5316,7 @@ dependencies = [
[[package]] [[package]]
name = "refineable" name = "refineable"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"derive_refineable", "derive_refineable",
] ]
@@ -5404,7 +5415,7 @@ dependencies = [
[[package]] [[package]]
name = "reqwest_client" name = "reqwest_client"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"bytes", "bytes",
@@ -5459,7 +5470,7 @@ dependencies = [
[[package]] [[package]]
name = "rope" name = "rope"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"arrayvec", "arrayvec",
"log", "log",
@@ -5721,7 +5732,7 @@ dependencies = [
[[package]] [[package]]
name = "scheduler" name = "scheduler"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"async-task", "async-task",
"backtrace", "backtrace",
@@ -6315,7 +6326,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]] [[package]]
name = "sum_tree" name = "sum_tree"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"arrayvec", "arrayvec",
"log", "log",
@@ -7258,7 +7269,7 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]] [[package]]
name = "util" name = "util"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-fs", "async-fs",
@@ -7297,7 +7308,7 @@ dependencies = [
[[package]] [[package]]
name = "util_macros" name = "util_macros"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"perf", "perf",
"quote", "quote",
@@ -9100,7 +9111,7 @@ dependencies = [
[[package]] [[package]]
name = "zlog" name = "zlog"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",
@@ -9117,7 +9128,7 @@ checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
[[package]] [[package]]
name = "ztracing" name = "ztracing"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
dependencies = [ dependencies = [
"tracing", "tracing",
"tracing-subscriber", "tracing-subscriber",
@@ -9128,7 +9139,7 @@ dependencies = [
[[package]] [[package]]
name = "ztracing_macro" name = "ztracing_macro"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/zed-industries/zed#1123140e40f47ad7b12815c16de0d49e42e36617" source = "git+https://github.com/zed-industries/zed#b06522e978b5ed24bcc2cf07a6de794179d69176"
[[package]] [[package]]
name = "zune-core" name = "zune-core"

View File

@@ -9,17 +9,14 @@ edition = "2021"
publish = false publish = false
[workspace.dependencies] [workspace.dependencies]
# GPUI # GPUI
gpui = { git = "https://github.com/zed-industries/zed" } gpui = { git = "https://github.com/zed-industries/zed" }
gpui_platform = { git = "https://github.com/zed-industries/zed", features = ["screen-capture", "x11", "wayland", "runtime_shaders"] } gpui_platform = { git = "https://github.com/zed-industries/zed", features = ["font-kit", "screen-capture", "x11", "wayland", "runtime_shaders"] }
gpui_linux = { git = "https://github.com/zed-industries/zed" } gpui_linux = { git = "https://github.com/zed-industries/zed" }
gpui_windows = { git = "https://github.com/zed-industries/zed" } gpui_windows = { git = "https://github.com/zed-industries/zed" }
gpui_macos = { git = "https://github.com/zed-industries/zed" } gpui_macos = { git = "https://github.com/zed-industries/zed" }
gpui_tokio = { git = "https://github.com/zed-industries/zed" } gpui_tokio = { git = "https://github.com/zed-industries/zed" }
reqwest_client = { git = "https://github.com/zed-industries/zed" } reqwest_client = { git = "https://github.com/zed-industries/zed" }
# TODO: remove after fixed, issue: https://github.com/zed-industries/zed/issues/47168
core-text = "=21.0.0"
# Nostr # Nostr
nostr-lmdb = { git = "https://github.com/rust-nostr/nostr" } nostr-lmdb = { git = "https://github.com/rust-nostr/nostr" }

View File

@@ -65,3 +65,7 @@ webbrowser.workspace = true
indexset = "0.12.3" indexset = "0.12.3"
tracing-subscriber = { version = "0.3.18", features = ["fmt"] } tracing-subscriber = { version = "0.3.18", features = ["fmt"] }
[target.'cfg(target_os = "macos")'.dependencies]
# Temporary workaround https://github.com/zed-industries/zed/issues/47168
core-text = "=21.0.0"

View File

@@ -2,6 +2,7 @@ use std::sync::Arc;
use ::settings::AppSettings; use ::settings::AppSettings;
use chat::{ChatEvent, ChatRegistry, InboxState}; use chat::{ChatEvent, ChatRegistry, InboxState};
use device::DeviceRegistry;
use gpui::prelude::FluentBuilder; use gpui::prelude::FluentBuilder;
use gpui::{ use gpui::{
div, px, Action, App, AppContext, Axis, Context, Entity, InteractiveElement, IntoElement, div, px, Action, App, AppContext, Axis, Context, Entity, InteractiveElement, IntoElement,
@@ -19,6 +20,7 @@ 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::menu::{DropdownMenu, PopupMenuItem}; use ui::menu::{DropdownMenu, PopupMenuItem};
use ui::notification::Notification;
use ui::{h_flex, v_flex, IconName, Root, Sizable, WindowExtension}; use ui::{h_flex, v_flex, IconName, Root, Sizable, WindowExtension};
use crate::dialogs::settings; use crate::dialogs::settings;
@@ -27,6 +29,13 @@ use crate::panels::{
}; };
use crate::sidebar; use crate::sidebar;
const ENC_MSG: &str =
"Encryption Key is a special key that used to encrypt and decrypt your messages. \
Your identity is completely decoupled from all encryption processes to protect your privacy.";
const ENC_WARN: &str = "By resetting your encryption key, you will lose access to \
all your encrypted messages before. This action cannot be undone.";
pub fn init(window: &mut Window, cx: &mut App) -> Entity<Workspace> { pub fn init(window: &mut Window, cx: &mut App) -> Entity<Workspace> {
cx.new(|cx| Workspace::new(window, cx)) cx.new(|cx| Workspace::new(window, cx))
} }
@@ -36,8 +45,10 @@ pub fn init(window: &mut Window, cx: &mut App) -> Entity<Workspace> {
enum Command { enum Command {
ToggleTheme, ToggleTheme,
RefreshEncryption,
RefreshRelayList, RefreshRelayList,
RefreshMessagingRelays, RefreshMessagingRelays,
ResetEncryption,
ShowRelayList, ShowRelayList,
ShowMessaging, ShowMessaging,
@@ -273,12 +284,21 @@ impl Workspace {
); );
}); });
} }
Command::RefreshEncryption => {
let device = DeviceRegistry::global(cx);
device.update(cx, |this, cx| {
this.get_announcement(cx);
});
}
Command::RefreshRelayList => { Command::RefreshRelayList => {
let nostr = NostrRegistry::global(cx); let nostr = NostrRegistry::global(cx);
nostr.update(cx, |this, cx| { nostr.update(cx, |this, cx| {
this.ensure_relay_list(cx); this.ensure_relay_list(cx);
}); });
} }
Command::ResetEncryption => {
self.confirm_reset_encryption(window, cx);
}
Command::RefreshMessagingRelays => { Command::RefreshMessagingRelays => {
let chat = ChatRegistry::global(cx); let chat = ChatRegistry::global(cx);
chat.update(cx, |this, cx| { chat.update(cx, |this, cx| {
@@ -291,6 +311,54 @@ impl Workspace {
} }
} }
fn confirm_reset_encryption(&mut self, window: &mut Window, cx: &mut Context<Self>) {
window.open_modal(cx, |this, _window, cx| {
this.confirm()
.show_close(true)
.title("Reset Encryption Keys")
.child(
v_flex()
.gap_1()
.text_sm()
.child(SharedString::from(ENC_MSG))
.child(
div()
.italic()
.text_color(cx.theme().warning_active)
.child(SharedString::from(ENC_WARN)),
),
)
.on_ok(move |_ev, window, cx| {
let device = DeviceRegistry::global(cx);
let task = device.read(cx).create_encryption(cx);
window
.spawn(cx, async move |cx| {
let result = task.await;
cx.update(|window, cx| match result {
Ok(keys) => {
device.update(cx, |this, cx| {
this.set_signer(keys, cx);
this.listen_request(cx);
});
window.close_modal(cx);
}
Err(e) => {
window
.push_notification(Notification::error(e.to_string()), cx);
}
})
.ok();
})
.detach();
// false to keep modal open
false
})
});
}
fn theme_selector(&mut self, window: &mut Window, cx: &mut Context<Self>) { fn theme_selector(&mut self, window: &mut Window, cx: &mut Context<Self>) {
window.open_modal(cx, move |this, _window, cx| { window.open_modal(cx, move |this, _window, cx| {
let registry = ThemeRegistry::global(cx); let registry = ThemeRegistry::global(cx);
@@ -471,8 +539,44 @@ impl Workspace {
.tooltip("Decoupled encryption key") .tooltip("Decoupled encryption key")
.small() .small()
.ghost() .ghost()
.on_click(|_ev, window, cx| { .dropdown_menu(move |this, _window, cx| {
window.dispatch_action(Box::new(Command::ShowEncryption), cx); let device = DeviceRegistry::global(cx);
let state = device.read(cx).state();
this.min_w(px(260.))
.item(
PopupMenuItem::element(move |_window, _cx| {
h_flex()
.px_1()
.w_full()
.gap_2()
.text_sm()
.child(
div()
.size_1p5()
.rounded_full()
.when(state.set(), |this| this.bg(gpui::green()))
.when(state.requesting(), |this| {
this.bg(gpui::yellow())
}),
)
.child(SharedString::from(state.to_string()))
})
.on_click(|_ev, window, cx| {
window.dispatch_action(Box::new(Command::ShowEncryption), cx);
}),
)
.separator()
.menu_with_icon(
"Reload",
IconName::Refresh,
Box::new(Command::RefreshEncryption),
)
.menu_with_icon(
"Reset",
IconName::Warning,
Box::new(Command::ResetEncryption),
)
}), }),
) )
.child( .child(

View File

@@ -151,7 +151,7 @@ impl DeviceRegistry {
} }
/// Set the decoupled encryption key for the current user /// Set the decoupled encryption key for the current user
fn set_signer<S>(&mut self, new: S, cx: &mut Context<Self>) pub fn set_signer<S>(&mut self, new: S, cx: &mut Context<Self>)
where where
S: NostrSigner + 'static, S: NostrSigner + 'static,
{ {
@@ -242,7 +242,7 @@ impl DeviceRegistry {
} }
/// Get device announcement for current user /// Get device announcement for current user
fn get_announcement(&mut self, cx: &mut Context<Self>) { pub fn get_announcement(&mut self, cx: &mut Context<Self>) {
let nostr = NostrRegistry::global(cx); let nostr = NostrRegistry::global(cx);
let client = nostr.read(cx).client(); let client = nostr.read(cx).client();
@@ -307,8 +307,8 @@ impl DeviceRegistry {
})); }));
} }
/// Create a new device signer and announce it /// Create new encryption keys
fn announce(&mut self, cx: &mut Context<Self>) { pub fn create_encryption(&self, cx: &App) -> Task<Result<Keys, Error>> {
let nostr = NostrRegistry::global(cx); let nostr = NostrRegistry::global(cx);
let client = nostr.read(cx).client(); let client = nostr.read(cx).client();
@@ -323,7 +323,7 @@ impl DeviceRegistry {
let secret = keys.secret_key().to_secret_hex(); let secret = keys.secret_key().to_secret_hex();
let n = keys.public_key(); let n = keys.public_key();
let task: Task<Result<(), Error>> = cx.background_spawn(async move { cx.background_spawn(async move {
let urls = write_relays.await; let urls = write_relays.await;
// Construct an announcement event // Construct an announcement event
@@ -340,23 +340,29 @@ impl DeviceRegistry {
// Save device keys to the database // Save device keys to the database
set_keys(&client, &secret).await?; set_keys(&client, &secret).await?;
Ok(()) Ok(keys)
}); })
}
/// Create a new device signer and announce it
fn announce(&mut self, cx: &mut Context<Self>) {
let task = self.create_encryption(cx);
self.tasks.push(cx.spawn(async move |this, cx| { self.tasks.push(cx.spawn(async move |this, cx| {
if task.await.is_ok() { let keys = task.await?;
this.update(cx, |this, cx| {
this.set_signer(keys, cx); // Update signer
this.listen_request(cx); this.update(cx, |this, cx| {
})?; this.set_signer(keys, cx);
} this.listen_request(cx);
})?;
Ok(()) Ok(())
})); }));
} }
/// Initialize device signer (decoupled encryption key) for the current user /// Initialize device signer (decoupled encryption key) for the current user
fn new_signer(&mut self, event: &Event, cx: &mut Context<Self>) { pub fn new_signer(&mut self, event: &Event, cx: &mut Context<Self>) {
let nostr = NostrRegistry::global(cx); let nostr = NostrRegistry::global(cx);
let client = nostr.read(cx).client(); let client = nostr.read(cx).client();
@@ -375,31 +381,29 @@ impl DeviceRegistry {
} }
}); });
cx.spawn(async move |this, cx| { self.tasks.push(cx.spawn(async move |this, cx| {
match task.await { match task.await {
Ok(keys) => { Ok(keys) => {
this.update(cx, |this, cx| { this.update(cx, |this, cx| {
this.set_signer(keys, cx); this.set_signer(keys, cx);
this.listen_request(cx); this.listen_request(cx);
}) })?;
.ok();
} }
Err(e) => { Err(e) => {
log::warn!("Failed to initialize device signer: {e}");
this.update(cx, |this, cx| { this.update(cx, |this, cx| {
this.request(cx); this.request(cx);
this.listen_approval(cx); this.listen_approval(cx);
}) })?;
.ok();
log::warn!("Failed to initialize device signer: {e}");
} }
}; };
})
.detach(); Ok(())
}));
} }
/// Listen for device key requests on user's write relays /// Listen for device key requests on user's write relays
fn listen_request(&mut self, cx: &mut Context<Self>) { pub fn listen_request(&mut self, cx: &mut Context<Self>) {
let nostr = NostrRegistry::global(cx); let nostr = NostrRegistry::global(cx);
let client = nostr.read(cx).client(); let client = nostr.read(cx).client();

View File

@@ -1,3 +1,5 @@
use std::fmt::Display;
use gpui::SharedString; use gpui::SharedString;
use nostr_sdk::prelude::*; use nostr_sdk::prelude::*;
@@ -9,6 +11,16 @@ pub enum DeviceState {
Set, Set,
} }
impl Display for DeviceState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
DeviceState::Idle => write!(f, "Idle"),
DeviceState::Requesting => write!(f, "Wait for approval"),
DeviceState::Set => write!(f, "Encryption Key is ready"),
}
}
}
impl DeviceState { impl DeviceState {
pub fn idle(&self) -> bool { pub fn idle(&self) -> bool {
matches!(self, DeviceState::Idle) matches!(self, DeviceState::Idle)