fix(ui): fido mode config write raised in issue #62

This commit is contained in:
Suyog Tandel
2026-02-18 16:40:51 +05:30
parent a804d59dcd
commit 7201f18fe7
3 changed files with 139 additions and 57 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ fn main() {
cx.activate(true);
let mut window_size = size(px(1280.0), px(720.0));
let mut window_size = size(px(1344.0), px(756.0));
// Basically, make sure that the window is max to max 85 percent size of the actual
// monitor/display, so the window does not get too big on small monitors.
+10 -2
View File
@@ -99,7 +99,15 @@ impl ApplicationRoot {
impl Render for ApplicationRoot {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let target_width = if self.collapsed { px(48.) } else { px(255.) };
let window_width = window.bounds().size.width;
let is_window_wide = window_width > px(800.0);
let is_sidebar_collapsed = self.collapsed || !is_window_wide;
let target_width = if is_sidebar_collapsed {
px(48.)
} else {
px(255.)
};
if (self.sidebar_width - target_width).abs() > px(0.1) {
self.sidebar_width = self.sidebar_width + (target_width - self.sidebar_width) * 0.2;
@@ -117,7 +125,7 @@ impl Render for ApplicationRoot {
AppSidebar::new(
self.active_view,
self.sidebar_width,
self.collapsed,
is_sidebar_collapsed,
self.state.clone(),
)
.on_select(|this: &mut Self, view, _, _| {
+128 -54
View File
@@ -5,7 +5,7 @@ use crate::ui::ui_types::{LedDriverType, UsbIdentityPreset};
use gpui::*;
use gpui_component::button::{ButtonCustomVariant, ButtonVariants};
use gpui_component::{
ActiveTheme, Disableable, Icon, Theme,
ActiveTheme, Disableable, Icon, Theme, WindowExt,
button::Button,
input::{Input, InputState},
select::{Select, SelectItem, SelectState},
@@ -206,7 +206,128 @@ impl ConfigView {
}
}
fn apply_changes(&mut self, _window: &mut Window, cx: &mut Context<Self>) {
fn write_config_to_device(
&mut self,
changes: AppConfigInput,
method: crate::device::types::DeviceMethod,
pin: Option<String>,
cx: &mut Context<Self>,
) {
self.loading = true;
cx.notify();
let entity = cx.entity().downgrade();
self._task = Some(cx.spawn(async move |_, cx| {
let result = cx
.background_executor()
.spawn(async move { io::write_config(changes, method, pin) })
.await;
let new_status_result = if result.is_ok() {
Some(
cx.background_executor()
.spawn(async move { io::read_device_details() })
.await,
)
} else {
None
};
let _ = entity.update(cx, |this, cx| {
this.loading = false;
match result {
Ok(msg) => {
log::info!("Success: {}", msg);
if let Some(Ok(new_status)) = new_status_result {
log::info!(
"Refreshed device status. LED Steady: {}",
new_status.config.led_steady
);
let config = &new_status.config;
this.led_dimmable = config.led_dimmable;
this.led_steady = config.led_steady;
this.power_cycle = config.power_cycle_on_reset;
this.enable_secp256k1 = config.enable_secp256k1;
this.device_status = Some(new_status);
cx.notify();
}
}
Err(e) => {
log::error!("Error saving config: {}", e);
}
}
cx.notify();
});
}));
}
fn open_pin_dialog(
&mut self,
changes: AppConfigInput,
window: &mut Window,
cx: &mut Context<Self>,
) {
let pin_input = cx.new(|cx| {
InputState::new(window, cx)
.placeholder("Enter FIDO PIN")
.masked(true)
});
let view_handle = cx.entity().downgrade();
window.open_dialog(cx, move |dialog, _, _| {
let view_handle_for_footer = view_handle.clone();
let pin_input_for_footer = pin_input.clone();
let changes = changes.clone();
dialog
.title("Authentication Required")
.child(
v_flex()
.gap_4()
.pb_4()
.child("Enter your device PIN to apply changes.")
.child(Input::new(&pin_input)),
)
.footer(move |_, _, _, _| {
let view = view_handle_for_footer.clone();
let input = pin_input_for_footer.clone();
let changes = changes.clone();
vec![
Button::new("cancel")
.label("Cancel")
.on_click(|_, window, cx| {
window.close_dialog(cx);
}),
Button::new("confirm").primary().label("Confirm").on_click(
move |_, window, cx| {
let pin = input.read(cx).text().to_string();
if !pin.is_empty() {
window.close_dialog(cx);
let _ = view.update(cx, |this, cx| {
this.write_config_to_device(
changes.clone(),
crate::device::types::DeviceMethod::Fido,
Some(pin),
cx,
);
});
}
},
),
]
})
});
}
fn apply_changes(&mut self, window: &mut Window, cx: &mut Context<Self>) {
let status = if let Some(s) = &self.device_status {
s
} else {
@@ -302,60 +423,13 @@ impl ConfigView {
return;
}
self.loading = true;
cx.notify();
let entity = cx.entity().downgrade();
let method = status.method.clone();
self._task = Some(cx.spawn(async move |_, cx| {
let result = cx
.background_executor()
.spawn(async move { io::write_config(changes, method, None) })
.await;
let new_status_result = if result.is_ok() {
Some(
cx.background_executor()
.spawn(async move { io::read_device_details() })
.await,
)
} else {
None
};
let _ = entity.update(cx, |this, cx| {
this.loading = false;
match result {
Ok(msg) => {
log::info!("Success: {}", msg);
if let Some(Ok(new_status)) = new_status_result {
log::info!(
"Refreshed device status. LED Steady: {}",
new_status.config.led_steady
);
let config = &new_status.config;
this.led_dimmable = config.led_dimmable;
this.led_steady = config.led_steady;
this.power_cycle = config.power_cycle_on_reset;
this.enable_secp256k1 = config.enable_secp256k1;
this.device_status = Some(new_status);
cx.notify();
}
}
Err(e) => {
log::error!("Error saving config: {}", e);
}
}
cx.notify();
});
}));
if method == crate::device::types::DeviceMethod::Fido {
self.open_pin_dialog(changes, window, cx);
} else {
self.write_config_to_device(changes, method, None, cx);
}
}
pub(crate) fn update_device_status(