Adjust login form x2
This commit is contained in:
@@ -59,6 +59,31 @@ fn handle_form_key(form: &mut LoginForm, runtime: &mut Runtime, key: KeyEvent) {
|
||||
}
|
||||
|
||||
fn handle_sso_key(form: &mut LoginForm, runtime: &mut Runtime, key: KeyEvent) {
|
||||
// Ctrl-shortcuts first: plain letters belong to the paste field.
|
||||
if key.modifiers.contains(KeyModifiers::CONTROL) {
|
||||
match key.code {
|
||||
// Copy the full SSO URL — terminals can't copy a wrapped link
|
||||
// in one piece, the clipboard can.
|
||||
KeyCode::Char('l') => {
|
||||
form.error = None;
|
||||
match copy_to_clipboard(&form.sso_url) {
|
||||
Ok(()) => form.error = Some("link copied to clipboard".to_string()),
|
||||
Err(err) => {
|
||||
tracing::warn!(%err, "clipboard copy failed");
|
||||
form.error = Some(format!("copy failed: {err}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
KeyCode::Char('o') => {
|
||||
if let Err(err) = open::that_detached(&form.sso_url) {
|
||||
tracing::warn!(%err, "failed to reopen browser");
|
||||
form.error = Some("couldn't open a browser".to_string());
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
return;
|
||||
}
|
||||
match key.code {
|
||||
KeyCode::Esc => {
|
||||
if let Some(listener) = runtime.sso.take() {
|
||||
@@ -77,6 +102,10 @@ fn handle_sso_key(form: &mut LoginForm, runtime: &mut Runtime, key: KeyEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
fn copy_to_clipboard(text: &str) -> Result<(), arboard::Error> {
|
||||
arboard::Clipboard::new()?.set_text(text.to_string())
|
||||
}
|
||||
|
||||
fn is_typing(key: KeyEvent) -> bool {
|
||||
key.modifiers
|
||||
.difference(KeyModifiers::SHIFT)
|
||||
|
||||
+15
-16
@@ -66,13 +66,11 @@ fn draw_form(frame: &mut Frame, form: &LoginForm) {
|
||||
}
|
||||
|
||||
fn draw_sso_pending(frame: &mut Frame, form: &LoginForm) {
|
||||
// The dialog grows with the URL so it is always shown in full and can
|
||||
// be copied/typed manually.
|
||||
let width = 78.min(frame.area().width.saturating_sub(2)).max(40);
|
||||
let inner_width = usize::from(width - 2);
|
||||
let url_lines = (form.sso_url.len().div_ceil(inner_width.max(1)) as u16).clamp(1, 6);
|
||||
let height = (13 + url_lines).min(frame.area().height);
|
||||
let area = centered(frame.area(), width, height);
|
||||
// The URL stays on ONE line (wrapping breaks copy-paste); the dialog is
|
||||
// as wide as the terminal allows and ctrl-l copies the full link.
|
||||
let width = (form.sso_url.len() as u16 + 4)
|
||||
.clamp(48, frame.area().width.saturating_sub(2).max(40));
|
||||
let area = centered(frame.area(), width, 14.min(frame.area().height));
|
||||
|
||||
let block = Block::bordered()
|
||||
.title(" Continue with SSO ")
|
||||
@@ -84,7 +82,7 @@ fn draw_sso_pending(frame: &mut Frame, form: &LoginForm) {
|
||||
let [steps, url_label, url, paste, message, hint] = Layout::vertical([
|
||||
Constraint::Length(3),
|
||||
Constraint::Length(1),
|
||||
Constraint::Length(url_lines),
|
||||
Constraint::Length(1),
|
||||
Constraint::Length(3),
|
||||
Constraint::Length(2),
|
||||
Constraint::Length(1),
|
||||
@@ -111,25 +109,26 @@ fn draw_sso_pending(frame: &mut Frame, form: &LoginForm) {
|
||||
|
||||
frame.render_widget(
|
||||
Paragraph::new(Line::styled(
|
||||
"If the browser didn't open, visit:",
|
||||
"If the browser didn't open — ctrl-l copies this link, ctrl-o retries:",
|
||||
theme::dim(),
|
||||
)),
|
||||
url_label,
|
||||
);
|
||||
// Unbordered and character-wrapped: the URL is fully visible and can be
|
||||
// selected in the terminal without picking up border glyphs.
|
||||
// One line, never wrapped: a wrapped URL copies with a line break and
|
||||
// stops working. If it doesn't fit, ctrl-l still copies it whole.
|
||||
frame.render_widget(
|
||||
Paragraph::new(form.sso_url.clone())
|
||||
.style(theme::accent())
|
||||
.wrap(Wrap { trim: false }),
|
||||
Paragraph::new(Line::styled(form.sso_url.clone(), theme::accent())),
|
||||
url,
|
||||
);
|
||||
|
||||
draw_field(frame, paste, "Link or code", &form.sso_paste, false, true);
|
||||
draw_message(frame, message, form);
|
||||
frame.render_widget(
|
||||
Paragraph::new(Line::styled("enter submit · esc back · ctrl-c quit", theme::dim()))
|
||||
.alignment(Alignment::Center),
|
||||
Paragraph::new(Line::styled(
|
||||
"enter submit · ctrl-l copy link · esc back · ctrl-c quit",
|
||||
theme::dim(),
|
||||
))
|
||||
.alignment(Alignment::Center),
|
||||
hint,
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user