chore: update the unlock dialog
This commit is contained in:
@@ -30,6 +30,7 @@ pub enum IconName {
|
|||||||
Search,
|
Search,
|
||||||
Settings,
|
Settings,
|
||||||
Settings2,
|
Settings2,
|
||||||
|
Unlock,
|
||||||
Upload,
|
Upload,
|
||||||
Warning,
|
Warning,
|
||||||
}
|
}
|
||||||
@@ -63,6 +64,7 @@ impl IconNamed for IconName {
|
|||||||
Self::Search => "icons/search.svg",
|
Self::Search => "icons/search.svg",
|
||||||
Self::Settings => "icons/settings.svg",
|
Self::Settings => "icons/settings.svg",
|
||||||
Self::Settings2 => "icons/settings2.svg",
|
Self::Settings2 => "icons/settings2.svg",
|
||||||
|
Self::Unlock => "icons/unlock.svg",
|
||||||
Self::Upload => "icons/upload.svg",
|
Self::Upload => "icons/upload.svg",
|
||||||
Self::Warning => "icons/warning.svg",
|
Self::Warning => "icons/warning.svg",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use gpui::prelude::FluentBuilder;
|
use gpui::prelude::FluentBuilder;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
App, AppContext, Context, Entity, IntoElement, ParentElement, Render, SharedString, Styled,
|
App, AppContext, Context, Div, Entity, IntoElement, ParentElement, Render, SharedString,
|
||||||
Subscription, Task, Window, div, px, relative,
|
Styled, Subscription, Task, Window, div, px, relative,
|
||||||
};
|
};
|
||||||
use gpui_kit::component::button::{Button, ButtonVariants};
|
use gpui_kit::component::button::{Button, ButtonVariants};
|
||||||
|
use gpui_kit::component::dialog::{DialogDescription, DialogFooter, DialogHeader, DialogTitle};
|
||||||
|
use gpui_kit::component::form::{field, v_form};
|
||||||
use gpui_kit::component::input::{Input, InputEvent, InputState};
|
use gpui_kit::component::input::{Input, InputEvent, InputState};
|
||||||
use gpui_kit::component::{ActiveTheme, Disableable, WindowExt, v_flex};
|
use gpui_kit::component::{ActiveTheme, Disableable, WindowExt, v_flex};
|
||||||
use instant::Duration;
|
use instant::Duration;
|
||||||
use nostr_connect::prelude::*;
|
use nostr_connect::prelude::*;
|
||||||
use state::{NostrRegistry, StateEvent};
|
use state::{NostrRegistry, StateEvent};
|
||||||
|
use ui::IconName;
|
||||||
|
|
||||||
pub fn open(window: &mut Window, cx: &mut App) {
|
pub fn open(window: &mut Window, cx: &mut App) {
|
||||||
let import = cx.new(|cx| ImportIdentity::new(window, cx));
|
let import = cx.new(|cx| ImportIdentity::new(window, cx));
|
||||||
@@ -32,7 +35,6 @@ pub fn open_unlock(window: &mut Window, cx: &mut App) {
|
|||||||
this.close_button(false)
|
this.close_button(false)
|
||||||
.overlay_closable(false)
|
.overlay_closable(false)
|
||||||
.keyboard(false)
|
.keyboard(false)
|
||||||
.title("Unlock your identity")
|
|
||||||
.child(import.clone())
|
.child(import.clone())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -74,7 +76,15 @@ impl ImportIdentity {
|
|||||||
fn build(mode: Mode, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
fn build(mode: Mode, window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||||
let nostr = NostrRegistry::global(cx);
|
let nostr = NostrRegistry::global(cx);
|
||||||
let key_input = cx.new(|cx| InputState::new(window, cx).placeholder("secret or bunker://"));
|
let key_input = cx.new(|cx| InputState::new(window, cx).placeholder("secret or bunker://"));
|
||||||
let pass_input = cx.new(|cx| InputState::new(window, cx).masked(true));
|
let pass_input = cx.new(|cx| {
|
||||||
|
let input = InputState::new(window, cx).masked(true);
|
||||||
|
|
||||||
|
if mode == Mode::Unlock {
|
||||||
|
input.placeholder("Passphrase to unlock your identity")
|
||||||
|
} else {
|
||||||
|
input
|
||||||
|
}
|
||||||
|
});
|
||||||
let repass_input = cx.new(|cx| InputState::new(window, cx).masked(true));
|
let repass_input = cx.new(|cx| InputState::new(window, cx).masked(true));
|
||||||
let error = cx.new(|_| None);
|
let error = cx.new(|_| None);
|
||||||
|
|
||||||
@@ -235,15 +245,59 @@ impl ImportIdentity {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render_unlock(&self, cx: &mut Context<Self>) -> Div {
|
||||||
|
v_flex()
|
||||||
|
.gap_4()
|
||||||
|
.child(
|
||||||
|
DialogHeader::new()
|
||||||
|
.child(DialogTitle::new().child("Unlock your identity"))
|
||||||
|
.child(
|
||||||
|
DialogDescription::new()
|
||||||
|
.child("Enter the passphrase used to encrypt this identity."),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
v_form().child(
|
||||||
|
field()
|
||||||
|
.label("Passphrase")
|
||||||
|
.required(true)
|
||||||
|
.child(Input::new(&self.pass_input)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.when_some(self.error.read(cx).as_ref(), |this, error| {
|
||||||
|
this.child(
|
||||||
|
div()
|
||||||
|
.text_sm()
|
||||||
|
.text_color(cx.theme().danger)
|
||||||
|
.child(error.clone()),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.child(
|
||||||
|
DialogFooter::new().child(
|
||||||
|
Button::new("unlock")
|
||||||
|
.primary()
|
||||||
|
.icon(IconName::Unlock)
|
||||||
|
.label("Unlock")
|
||||||
|
.loading(self.loading)
|
||||||
|
.disabled(self.loading)
|
||||||
|
.on_click(cx.listener(move |this, _ev, _window, cx| {
|
||||||
|
this.login(cx);
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for ImportIdentity {
|
impl Render for ImportIdentity {
|
||||||
fn render(&mut self, _window: &mut gpui::Window, cx: &mut Context<Self>) -> impl IntoElement {
|
fn render(&mut self, _window: &mut gpui::Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
|
if self.mode == Mode::Unlock {
|
||||||
|
return self.render_unlock(cx);
|
||||||
|
}
|
||||||
|
|
||||||
const BUNKER_WARN: &str = "Nostr Connect will usually take more time to get all your messages. Please keep your session open until you see all your messages.";
|
const BUNKER_WARN: &str = "Nostr Connect will usually take more time to get all your messages. Please keep your session open until you see all your messages.";
|
||||||
const KEY_WARN: &str = "Coop encrypts your key with your passphrase and stores it on this device. You only need the passphrase to sign in next time.";
|
const KEY_WARN: &str = "Coop encrypts your key with your passphrase and stores it on this device. You only need the passphrase to sign in next time.";
|
||||||
|
|
||||||
let is_unlock = self.mode == Mode::Unlock;
|
|
||||||
|
|
||||||
let value = self.key_input.read(cx).value().trim().to_string();
|
let value = self.key_input.read(cx).value().trim().to_string();
|
||||||
let require_password = value.starts_with("ncryptsec1");
|
let require_password = value.starts_with("ncryptsec1");
|
||||||
let require_encrypt = value.starts_with("nsec1");
|
let require_encrypt = value.starts_with("nsec1");
|
||||||
@@ -257,25 +311,19 @@ impl Render for ImportIdentity {
|
|||||||
.child(
|
.child(
|
||||||
v_flex()
|
v_flex()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
.when(!is_unlock, |this| {
|
.child(
|
||||||
|
v_flex()
|
||||||
|
.gap_1()
|
||||||
|
.text_color(cx.theme().muted_foreground)
|
||||||
|
.child("Use secret key or bunker connection")
|
||||||
|
.child(Input::new(&self.key_input)),
|
||||||
|
)
|
||||||
|
.when(require_password, |this| {
|
||||||
this.child(
|
this.child(
|
||||||
v_flex()
|
v_flex()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.text_color(cx.theme().muted_foreground)
|
.text_color(cx.theme().muted_foreground)
|
||||||
.child("Use secret key or bunker connection")
|
.child("Decrypt Password:")
|
||||||
.child(Input::new(&self.key_input)),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.when(is_unlock || require_password, |this| {
|
|
||||||
this.child(
|
|
||||||
v_flex()
|
|
||||||
.gap_1()
|
|
||||||
.text_color(cx.theme().muted_foreground)
|
|
||||||
.child(if is_unlock {
|
|
||||||
"Passphrase to unlock your identity:"
|
|
||||||
} else {
|
|
||||||
"Decrypt Password:"
|
|
||||||
})
|
|
||||||
.child(Input::new(&self.pass_input)),
|
.child(Input::new(&self.pass_input)),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@@ -323,7 +371,7 @@ impl Render for ImportIdentity {
|
|||||||
.child({
|
.child({
|
||||||
let content = v_flex().gap_1().child(
|
let content = v_flex().gap_1().child(
|
||||||
Button::new("login")
|
Button::new("login")
|
||||||
.label(if is_unlock { "Unlock" } else { "Continue" })
|
.label("Continue")
|
||||||
.primary()
|
.primary()
|
||||||
.loading(self.loading)
|
.loading(self.loading)
|
||||||
.disabled(self.loading)
|
.disabled(self.loading)
|
||||||
@@ -333,30 +381,26 @@ impl Render for ImportIdentity {
|
|||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
let content = content.when(!is_unlock, |this| {
|
let content = content.child(
|
||||||
this.child(
|
Button::new("proxy")
|
||||||
Button::new("proxy")
|
.label("Connect via Web Extension")
|
||||||
.label("Connect via Web Extension")
|
.ghost()
|
||||||
.ghost()
|
.disabled(self.loading)
|
||||||
.disabled(self.loading)
|
.on_click(cx.listener(move |this, _ev, _window, cx| {
|
||||||
.on_click(cx.listener(move |this, _ev, _window, cx| {
|
this.proxy(cx);
|
||||||
this.proxy(cx);
|
})),
|
||||||
})),
|
);
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
let content = content.when(!is_unlock, |this| {
|
let content = content.child(
|
||||||
this.child(
|
Button::new("extension")
|
||||||
Button::new("extension")
|
.label("Continue with Browser Extension")
|
||||||
.label("Continue with Browser Extension")
|
.ghost()
|
||||||
.ghost()
|
.disabled(self.loading)
|
||||||
.disabled(self.loading)
|
.on_click(cx.listener(move |this, _ev, _window, cx| {
|
||||||
.on_click(cx.listener(move |this, _ev, _window, cx| {
|
this.extension(cx);
|
||||||
this.extension(cx);
|
})),
|
||||||
})),
|
);
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
content
|
content
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user