chore: change code formatting, use space for tabs and indents instead of tabs

This commit is contained in:
Suyog Tandel
2026-01-28 17:29:07 +05:30
parent 38d05db1c5
commit 0d837a19b4
23 changed files with 2248 additions and 2284 deletions
Generated
-31
View File
@@ -1469,15 +1469,6 @@ dependencies = [
"dirs-sys 0.4.1",
]
[[package]]
name = "dirs"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
dependencies = [
"dirs-sys 0.5.0",
]
[[package]]
name = "dirs-sys"
version = "0.3.7"
@@ -2416,17 +2407,6 @@ dependencies = [
"zed-sum-tree",
]
[[package]]
name = "gpui-component-assets"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5842ea3f1e596fbc611894dcc0266df7125bc226f603ca313f5460b700503564"
dependencies = [
"anyhow",
"gpui",
"rust-embed",
]
[[package]]
name = "gpui-component-macros"
version = "0.5.0"
@@ -4304,7 +4284,6 @@ dependencies = [
"directories",
"gpui",
"gpui-component",
"gpui-component-assets",
"hex",
"hidapi",
"log",
@@ -4986,7 +4965,6 @@ dependencies = [
"proc-macro2",
"quote",
"rust-embed-utils",
"shellexpand",
"syn 2.0.114",
"walkdir",
]
@@ -5503,15 +5481,6 @@ dependencies = [
"digest",
]
[[package]]
name = "shellexpand"
version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b1fdf65dd6331831494dd616b30351c38e96e45921a27745cf98490458b90bb"
dependencies = [
"dirs 6.0.0",
]
[[package]]
name = "shlex"
version = "1.3.0"
+1 -3
View File
@@ -7,7 +7,7 @@ license = "AGPL-3.0"
edition = "2024"
[dependencies]
tokio = { version = "1.0", features = ["full"] }
tokio = { version = "1.49", features = ["full"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
log = "0.4" # Logging facade
@@ -30,8 +30,6 @@ ring = "0.17" # For signing fido2 messages with pin token
# For Application UI:
gpui = "0.2.2"
gpui-component = "0.5.0"
# Optional, for default bundled assets
gpui-component-assets = "0.5.0"
rust-embed = "8.11.0"
[profile.dev]
+1 -1
View File
@@ -1,4 +1,4 @@
edition = "2024"
hard_tabs = true
hard_tabs = false
tab_spaces = 4
max_width = 100
+34 -34
View File
@@ -1,44 +1,44 @@
/// Custom error types for Pico Forge application.
#[derive(Debug, thiserror::Error)]
pub enum PFError {
#[error("No device found")]
NoDevice,
#[error("PCSC Error: {0}")]
Pcsc(#[from] pcsc::Error),
#[error("IO/Hex Error: {0}")]
Io(String),
#[error("Device Error: {0}")]
Device(String),
#[error("No device found")]
NoDevice,
#[error("PCSC Error: {0}")]
Pcsc(#[from] pcsc::Error),
#[error("IO/Hex Error: {0}")]
Io(String),
#[error("Device Error: {0}")]
Device(String),
}
// Allow error to be serialized to string for Tauri
impl serde::Serialize for PFError {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeStruct;
let mut state = serializer.serialize_struct("PFError", 2)?;
match self {
PFError::NoDevice => {
state.serialize_field("type", "NoDevice")?;
state.serialize_field("message", "No device found")?;
}
PFError::Pcsc(err) => {
state.serialize_field("type", "Pcsc")?;
state.serialize_field("message", &err.to_string())?;
}
PFError::Io(msg) => {
state.serialize_field("type", "Io")?;
state.serialize_field("message", msg)?;
}
PFError::Device(msg) => {
state.serialize_field("type", "Device")?;
state.serialize_field("message", msg)?;
}
}
state.end()
}
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeStruct;
let mut state = serializer.serialize_struct("PFError", 2)?;
match self {
PFError::NoDevice => {
state.serialize_field("type", "NoDevice")?;
state.serialize_field("message", "No device found")?;
}
PFError::Pcsc(err) => {
state.serialize_field("type", "Pcsc")?;
state.serialize_field("message", &err.to_string())?;
}
PFError::Io(msg) => {
state.serialize_field("type", "Io")?;
state.serialize_field("message", msg)?;
}
PFError::Device(msg) => {
state.serialize_field("type", "Device")?;
state.serialize_field("message", msg)?;
}
}
state.end()
}
}
// pub type Result<T> = std::result::Result<T, PFError>;
File diff suppressed because it is too large Load Diff
+434 -434
View File
File diff suppressed because it is too large Load Diff
+396 -396
View File
File diff suppressed because it is too large Load Diff
+26 -26
View File
@@ -2,57 +2,57 @@
use crate::{device::error::PFError, device::fido, device::rescue, device::types::*};
pub fn read_device_details() -> Result<FullDeviceStatus, PFError> {
match rescue::read_device_details() {
Ok(status) => Ok(status),
Err(e) => {
log::warn!("Rescue method failed: {}. Falling back to FIDO...", e);
fido::read_device_details()
}
}
match rescue::read_device_details() {
Ok(status) => Ok(status),
Err(e) => {
log::warn!("Rescue method failed: {}. Falling back to FIDO...", e);
fido::read_device_details()
}
}
}
pub fn write_config(
config: AppConfigInput,
method: DeviceMethod,
pin: Option<String>,
config: AppConfigInput,
method: DeviceMethod,
pin: Option<String>,
) -> Result<String, PFError> {
if method == DeviceMethod::Fido {
fido::write_config(config, pin)
} else {
rescue::write_config(config)
}
if method == DeviceMethod::Fido {
fido::write_config(config, pin)
} else {
rescue::write_config(config)
}
}
pub fn enable_secure_boot(lock: bool) -> Result<String, PFError> {
rescue::enable_secure_boot(lock)
rescue::enable_secure_boot(lock)
}
pub(crate) fn get_fido_info() -> Result<FidoDeviceInfo, String> {
fido::get_fido_info()
fido::get_fido_info()
}
pub(crate) fn change_fido_pin(
current_pin: Option<String>,
new_pin: String,
current_pin: Option<String>,
new_pin: String,
) -> Result<String, String> {
fido::change_fido_pin(current_pin, new_pin)
fido::change_fido_pin(current_pin, new_pin)
}
pub(crate) fn set_min_pin_length(
current_pin: String,
min_pin_length: u8,
current_pin: String,
min_pin_length: u8,
) -> Result<String, String> {
fido::set_min_pin_length(current_pin, min_pin_length)
fido::set_min_pin_length(current_pin, min_pin_length)
}
pub fn reboot(to_bootsel: bool) -> Result<String, PFError> {
rescue::reboot_device(to_bootsel)
rescue::reboot_device(to_bootsel)
}
pub fn get_credentials(pin: String) -> Result<Vec<StoredCredential>, String> {
fido::get_credentials(pin)
fido::get_credentials(pin)
}
pub fn delete_credential(pin: String, credential_id: String) -> Result<String, String> {
fido::delete_credential(pin, credential_id)
fido::delete_credential(pin, credential_id)
}
+4 -4
View File
@@ -1,19 +1,19 @@
use directories::ProjectDirs;
use log::LevelFilter;
use log4rs::{
append::{
console::{ConsoleAppender, Target},
rolling_file::{
policy::compound::{
roll::delete::DeleteRoller, trigger::size::SizeTrigger, CompoundPolicy,
},
RollingFileAppender,
policy::compound::{
CompoundPolicy, roll::delete::DeleteRoller, trigger::size::SizeTrigger,
},
},
},
config::{Appender, Logger, Root},
encode::pattern::PatternEncoder,
};
use std::fs;
use directories::ProjectDirs;
/// Initializes log4rs with custom configuration for stdout and file logging.
pub fn logger_init() {
+49 -49
View File
@@ -29,53 +29,53 @@ pub const RESCUE_AID: &[u8] = &[0xA0, 0x58, 0x3F, 0xC1, 0x9B, 0x7E, 0x4F, 0x21];
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RescueInstruction {
KeyDevSign = 0x10,
Write = 0x1C,
Secure = 0x1D,
Read = 0x1E,
Reboot = 0x1F,
KeyDevSign = 0x10,
Write = 0x1C,
Secure = 0x1D,
Read = 0x1E,
Reboot = 0x1F,
}
/// P1 Parameters for RescueInstruction::Read (0x1E)
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ReadParam {
PhyConfig = 0x01,
FlashInfo = 0x02,
SecureBootStatus = 0x03,
PhyConfig = 0x01,
FlashInfo = 0x02,
SecureBootStatus = 0x03,
}
/// P1 Parameters for WRITE (0x1C)
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WriteParam {
PhyConfig = 0x01,
PhyConfig = 0x01,
}
/// P1 Parameters for RescueInstruction::KeyDevSign (0x10)
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SignParam {
SignData = 0x01,
GetPublicKey = 0x02,
UploadCert = 0x03,
SignData = 0x01,
GetPublicKey = 0x02,
UploadCert = 0x03,
}
/// P1 Parameters for RescueInstruction::Reboot (0x1F)
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RebootParam {
Normal = 0x00,
Bootsel = 0x01,
Normal = 0x00,
Bootsel = 0x01,
}
/// P2 Parameters for SECURE (0x1D)
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum SecureLockParam {
#[default]
Unlock = 0x00,
Lock = 0x01,
#[default]
Unlock = 0x00,
Lock = 0x01,
}
/// Default P2 value when not used
@@ -87,45 +87,45 @@ pub const P2_UNUSED: u8 = 0x00;
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PhyTag {
VidPid = 0x00,
LedGpio = 0x04,
LedBrightness = 0x05,
Opts = 0x06,
PresenceTimeout = 0x08, // Previously TAG_UP_BTN
UsbProduct = 0x09,
Curves = 0x0A,
LedDriver = 0x0C,
VidPid = 0x00,
LedGpio = 0x04,
LedBrightness = 0x05,
Opts = 0x06,
PresenceTimeout = 0x08, // Previously TAG_UP_BTN
UsbProduct = 0x09,
Curves = 0x0A,
LedDriver = 0x0C,
}
impl PhyTag {
/// Helper to convert raw u8 from device back to Enum
pub fn from_u8(val: u8) -> Option<Self> {
match val {
0x00 => Some(Self::VidPid),
0x04 => Some(Self::LedGpio),
0x05 => Some(Self::LedBrightness),
0x06 => Some(Self::Opts),
0x08 => Some(Self::PresenceTimeout),
0x09 => Some(Self::UsbProduct),
0x0A => Some(Self::Curves),
0x0C => Some(Self::LedDriver),
_ => None,
}
}
/// Helper to convert raw u8 from device back to Enum
pub fn from_u8(val: u8) -> Option<Self> {
match val {
0x00 => Some(Self::VidPid),
0x04 => Some(Self::LedGpio),
0x05 => Some(Self::LedBrightness),
0x06 => Some(Self::Opts),
0x08 => Some(Self::PresenceTimeout),
0x09 => Some(Self::UsbProduct),
0x0A => Some(Self::Curves),
0x0C => Some(Self::LedDriver),
_ => None,
}
}
}
bitflags::bitflags! {
/// Configuration options for TAG_OPTS (Tag 0x06)
pub struct RescueOptions: u16 {
const LED_DIMMABLE = 0x02;
const DISABLE_POWER_RESET = 0x04;
const LED_STEADY = 0x08;
}
/// Configuration options for TAG_OPTS (Tag 0x06)
pub struct RescueOptions: u16 {
const LED_DIMMABLE = 0x02;
const DISABLE_POWER_RESET = 0x04;
const LED_STEADY = 0x08;
}
}
bitflags::bitflags! {
/// Enabled curves for TAG_CURVES (Tag 0x0A)
pub struct RescueCurves: u32 {
const SECP256K1 = 0x08;
}
/// Enabled curves for TAG_CURVES (Tag 0x0A)
pub struct RescueCurves: u32 {
const SECP256K1 = 0x08;
}
}
+342 -342
View File
File diff suppressed because it is too large Load Diff
+51 -51
View File
@@ -3,66 +3,66 @@
use serde::{Deserialize, Serialize};
struct PForgeState {
device_info: DeviceInfo,
device_info: DeviceInfo,
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DeviceInfo {
pub serial: String,
pub flash_used: u32,
pub flash_total: u32,
pub firmware_version: String,
pub serial: String,
pub flash_used: u32,
pub flash_total: u32,
pub firmware_version: String,
}
#[derive(Serialize, Deserialize, Debug, Default)]
#[serde(rename_all = "camelCase")]
pub struct AppConfig {
pub vid: String,
pub pid: String,
pub product_name: String,
pub led_gpio: u8,
pub led_brightness: u8,
pub touch_timeout: u8,
#[serde(skip_serializing_if = "Option::is_none")]
pub led_driver: Option<u8>,
pub led_dimmable: bool,
pub power_cycle_on_reset: bool,
pub led_steady: bool,
pub enable_secp256k1: bool,
pub vid: String,
pub pid: String,
pub product_name: String,
pub led_gpio: u8,
pub led_brightness: u8,
pub touch_timeout: u8,
#[serde(skip_serializing_if = "Option::is_none")]
pub led_driver: Option<u8>,
pub led_dimmable: bool,
pub power_cycle_on_reset: bool,
pub led_steady: bool,
pub enable_secp256k1: bool,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "camelCase")]
pub struct AppConfigInput {
pub vid: Option<String>,
pub pid: Option<String>,
pub product_name: Option<String>,
pub led_gpio: Option<u8>,
pub led_brightness: Option<u8>,
pub touch_timeout: Option<u8>,
pub led_driver: Option<u8>,
pub led_dimmable: Option<bool>,
pub power_cycle_on_reset: Option<bool>,
pub led_steady: Option<bool>,
pub enable_secp256k1: Option<bool>,
pub vid: Option<String>,
pub pid: Option<String>,
pub product_name: Option<String>,
pub led_gpio: Option<u8>,
pub led_brightness: Option<u8>,
pub touch_timeout: Option<u8>,
pub led_driver: Option<u8>,
pub led_dimmable: Option<bool>,
pub power_cycle_on_reset: Option<bool>,
pub led_steady: Option<bool>,
pub enable_secp256k1: Option<bool>,
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct FullDeviceStatus {
pub info: DeviceInfo,
pub config: AppConfig,
pub secure_boot: bool,
pub secure_lock: bool,
pub method: DeviceMethod,
pub info: DeviceInfo,
pub config: AppConfig,
pub secure_boot: bool,
pub secure_lock: bool,
pub method: DeviceMethod,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub enum DeviceMethod {
#[serde(rename = "FIDO")]
Fido,
Rescue,
#[serde(rename = "FIDO")]
Fido,
Rescue,
}
// Fido stuff:
@@ -70,24 +70,24 @@ pub enum DeviceMethod {
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct FidoDeviceInfo {
pub versions: Vec<String>,
pub extensions: Vec<String>,
pub aaguid: String,
pub options: std::collections::HashMap<String, bool>,
pub max_msg_size: i32,
pub pin_protocols: Vec<u32>,
// pub remaining_disc_creds: u32,
pub min_pin_length: u32,
pub firmware_version: String,
pub versions: Vec<String>,
pub extensions: Vec<String>,
pub aaguid: String,
pub options: std::collections::HashMap<String, bool>,
pub max_msg_size: i32,
pub pin_protocols: Vec<u32>,
// pub remaining_disc_creds: u32,
pub min_pin_length: u32,
pub firmware_version: String,
}
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct StoredCredential {
pub rp_id: String,
pub rp_name: String,
pub user_name: String,
pub user_display_name: String,
pub user_id: String,
pub credential_id: String,
pub rp_id: String,
pub rp_name: String,
pub user_name: String,
pub user_display_name: String,
pub user_id: String,
pub credential_id: String,
}
+44 -47
View File
@@ -2,69 +2,66 @@ use gpui::*;
use gpui_component::Root;
use gpui_component::{Theme, ThemeMode};
use ui::rootview::ApplicationRoot;
// use crate::ui::assets::Assets;
mod device;
mod ui;
fn main() {
// TODO: Configure and add custom assets.
// let app = Application::new().with_assets(gpui_component_assets::Assets);
let app = Application::new().with_assets(ui::assets::Assets);
let app = Application::new().with_assets(ui::assets::Assets);
app.run(move |cx| {
gpui_component::init(cx);
Theme::change(ThemeMode::Dark, None, cx);
// Theme::change(ThemeMode::Dark, Some(ui::theme::dark_theme()), cx);
app.run(move |cx| {
gpui_component::init(cx);
Theme::change(ThemeMode::Dark, None, cx);
// Theme::change(ThemeMode::Dark, Some(ui::theme::dark_theme()), cx);
cx.activate(true);
cx.activate(true);
let mut window_size = size(px(1280.0), px(720.0));
let mut window_size = size(px(1280.0), px(720.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.
if let Some(display) = cx.primary_display() {
let display_size = display.bounds().size;
// 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.
if let Some(display) = cx.primary_display() {
let display_size = display.bounds().size;
window_size.width = window_size.width.min(display_size.width * 0.85);
window_size.height = window_size.height.min(display_size.height * 0.85);
}
window_size.width = window_size.width.min(display_size.width * 0.85);
window_size.height = window_size.height.min(display_size.height * 0.85);
}
let window_bounds = Bounds::centered(None, window_size, cx);
let window_bounds = Bounds::centered(None, window_size, cx);
cx.spawn(async move |cx| {
let window_options = WindowOptions {
app_id: Some("in.suyogtandel.picoforge".into()),
cx.spawn(async move |cx| {
let window_options = WindowOptions {
app_id: Some("in.suyogtandel.picoforge".into()),
window_bounds: Some(WindowBounds::Windowed(window_bounds)),
window_bounds: Some(WindowBounds::Windowed(window_bounds)),
titlebar: Some(TitlebarOptions {
title: Some("PicoForge".into()),
appears_transparent: true,
// TODO: This option needs to be tested and adjusted on macos
traffic_light_position: Some(gpui::point(px(12.0), px(12.0))),
}),
titlebar: Some(TitlebarOptions {
title: Some("PicoForge".into()),
appears_transparent: true,
// TODO: This option needs to be tested and adjusted on macos
traffic_light_position: Some(gpui::point(px(12.0), px(12.0))),
}),
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
window_background: gpui::WindowBackgroundAppearance::Transparent,
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
window_decorations: Some(gpui::WindowDecorations::Client),
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
window_background: gpui::WindowBackgroundAppearance::Transparent,
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
window_decorations: Some(gpui::WindowDecorations::Client),
window_min_size: Some(gpui::Size {
width: px(650.),
height: px(300.),
}),
kind: WindowKind::Normal,
..Default::default()
};
window_min_size: Some(gpui::Size {
width: px(650.),
height: px(300.),
}),
kind: WindowKind::Normal,
..Default::default()
};
cx.open_window(window_options, |window, cx| {
let view = cx.new(|_| ApplicationRoot::new());
cx.new(|cx| Root::new(view, window, cx))
})?;
cx.open_window(window_options, |window, cx| {
let view = cx.new(|_| ApplicationRoot::new());
cx.new(|cx| Root::new(view, window, cx))
})?;
Ok::<_, anyhow::Error>(())
})
.detach();
});
Ok::<_, anyhow::Error>(())
})
.detach();
});
}
+13 -13
View File
@@ -11,19 +11,19 @@ use std::borrow::Cow;
pub struct Assets;
impl AssetSource for Assets {
fn load(&self, path: &str) -> Result<Option<Cow<'static, [u8]>>> {
if path.is_empty() {
return Ok(None);
}
fn load(&self, path: &str) -> Result<Option<Cow<'static, [u8]>>> {
if path.is_empty() {
return Ok(None);
}
Self::get(path)
.map(|f| Some(f.data))
.ok_or_else(|| anyhow!("could not find asset at path \"{path}\""))
}
Self::get(path)
.map(|f| Some(f.data))
.ok_or_else(|| anyhow!("could not find asset at path \"{path}\""))
}
fn list(&self, path: &str) -> Result<Vec<SharedString>> {
Ok(Self::iter()
.filter_map(|p| p.starts_with(path).then(|| p.into()))
.collect())
}
fn list(&self, path: &str) -> Result<Vec<SharedString>> {
Ok(Self::iter()
.filter_map(|p| p.starts_with(path).then(|| p.into()))
.collect())
}
}
+1 -1
View File
@@ -11,4 +11,4 @@ pub mod zinc {
pub const ZINC800: u32 = 0x27272a;
pub const ZINC900: u32 = 0x18181b;
pub const ZINC950: u32 = 0x09090b;
}
}
+2 -2
View File
@@ -1,4 +1,4 @@
pub mod views;
pub mod assets;
pub mod rootview;
pub mod colors;
pub mod rootview;
pub mod views;
+122 -122
View File
@@ -1,141 +1,141 @@
use crate::ui::colors;
use crate::ui::views::{
about::AboutView, config::ConfigView, home::HomeView, logs::LogsView, passkeys::PasskeysView,
security::SecurityView,
about::AboutView, config::ConfigView, home::HomeView, logs::LogsView, passkeys::PasskeysView,
security::SecurityView,
};
use gpui::*;
use gpui_component::button::{Button, ButtonVariants};
use gpui_component::scroll::ScrollableElement;
use gpui_component::{ActiveTheme, Icon, IconName, TitleBar, h_flex, v_flex};
use gpui_component::{ActiveTheme, Icon, IconName, StyledExt, TitleBar, h_flex, v_flex};
use gpui_component::{Side, sidebar::*};
#[derive(Clone, Copy, PartialEq)]
enum ActiveView {
Home,
Passkeys,
Configuration,
Security,
Logs,
About,
Home,
Passkeys,
Configuration,
Security,
Logs,
About,
}
pub struct ApplicationRoot {
active_view: ActiveView,
collapsed: bool,
active_view: ActiveView,
collapsed: bool,
}
impl ApplicationRoot {
pub fn new() -> Self {
Self {
active_view: ActiveView::Home,
collapsed: false,
}
}
pub fn new() -> Self {
Self {
active_view: ActiveView::Home,
collapsed: false,
}
}
}
impl Render for ApplicationRoot {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
h_flex()
.size_full()
.child(
Sidebar::new(Side::Left)
.collapsed(self.collapsed)
.collapsible(true)
.h_full()
.bg(rgb(0x18181b))
// .header(SidebarHeader::new().child("PicoForge"))
.child(
SidebarGroup::new("Menu").child(
SidebarMenu::new()
.child(
SidebarMenuItem::new("Home")
.icon(Icon::default().path("icons/house.svg"))
.active(self.active_view == ActiveView::Home)
.on_click(cx.listener(|this, _, _, _| {
this.active_view = ActiveView::Home;
})),
)
.child(
SidebarMenuItem::new("Passkeys")
.icon(Icon::default().path("icons/key-round.svg"))
.active(self.active_view == ActiveView::Passkeys)
.on_click(cx.listener(|this, _, _, _| {
this.active_view = ActiveView::Passkeys;
})),
)
.child(
SidebarMenuItem::new("Configuration")
.icon(Icon::default().path("icons/settings.svg"))
.active(self.active_view == ActiveView::Configuration)
.on_click(cx.listener(|this, _, _, _| {
this.active_view = ActiveView::Configuration;
})),
)
// TODO: Replace these icons with correct ones from lucide
.child(
SidebarMenuItem::new("Security")
.icon(Icon::default().path("icons/shield-check.svg"))
.active(self.active_view == ActiveView::Security)
.on_click(cx.listener(|this, _, _, _| {
this.active_view = ActiveView::Security;
})),
)
.child(
SidebarMenuItem::new("Logs")
.icon(Icon::default().path("icons/scroll-text.svg"))
.active(self.active_view == ActiveView::Logs)
.on_click(cx.listener(|this, _, _, _| {
this.active_view = ActiveView::Logs;
})),
)
.child(
SidebarMenuItem::new("About")
.icon(Icon::default().path("icons/shield-check.svg"))
.active(self.active_view == ActiveView::About)
.on_click(cx.listener(|this, _, _, _| {
this.active_view = ActiveView::About;
})),
),
),
), // .footer(SidebarFooter::new().child("Device Status")),
)
.child(
v_flex()
.size_full()
.child(
TitleBar::new().child(
h_flex()
.w_full()
.justify_between()
// .px_4()
.items_center()
.cursor(gpui::CursorStyle::OpenHand)
.child(
Button::new("sidebar_toggle")
.ghost()
.icon(IconName::PanelLeft)
.on_click(cx.listener(|this, _, _, _| {
this.collapsed = !this.collapsed;
}))
.tooltip("Toggle Sidebar"),
),
),
)
.child(
v_flex()
.min_h(px(0.))
.min_w(px(0.))
.overflow_y_scrollbar()
.flex_grow()
.bg(cx.theme().background)
.child(match self.active_view {
ActiveView::Home => HomeView::build(cx.theme()).into_any_element(),
ActiveView::Passkeys => PasskeysView::build().into_any_element(),
ActiveView::Configuration => ConfigView::build().into_any_element(),
ActiveView::Security => SecurityView::build().into_any_element(),
ActiveView::Logs => LogsView::build().into_any_element(),
ActiveView::About => AboutView::build().into_any_element(),
}),
),
)
}
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
h_flex()
.size_full()
.child(
Sidebar::new(Side::Left)
.collapsed(self.collapsed)
.collapsible(true)
.h_full()
.bg(rgb(0x18181b))
.child(
SidebarGroup::new("Menu").child(
SidebarMenu::new()
.child(
SidebarMenuItem::new("Home")
.icon(Icon::default().path("icons/house.svg"))
.active(self.active_view == ActiveView::Home)
.on_click(cx.listener(|this, _, _, _| {
this.active_view = ActiveView::Home;
})),
)
.child(
SidebarMenuItem::new("Passkeys")
.icon(Icon::default().path("icons/key-round.svg"))
.active(self.active_view == ActiveView::Passkeys)
.on_click(cx.listener(|this, _, _, _| {
this.active_view = ActiveView::Passkeys;
})),
)
.child(
SidebarMenuItem::new("Configuration")
.icon(Icon::default().path("icons/settings.svg"))
.active(self.active_view == ActiveView::Configuration)
.on_click(cx.listener(|this, _, _, _| {
this.active_view = ActiveView::Configuration;
})),
)
// TODO: Replace these icons with correct ones from lucide
.child(
SidebarMenuItem::new("Security")
.icon(Icon::default().path("icons/shield-check.svg"))
.active(self.active_view == ActiveView::Security)
.on_click(cx.listener(|this, _, _, _| {
this.active_view = ActiveView::Security;
})),
)
.child(
SidebarMenuItem::new("Logs")
.icon(Icon::default().path("icons/scroll-text.svg"))
.active(self.active_view == ActiveView::Logs)
.on_click(cx.listener(|this, _, _, _| {
this.active_view = ActiveView::Logs;
})),
)
.child(
SidebarMenuItem::new("About")
.icon(IconName::Info)
.active(self.active_view == ActiveView::About)
.on_click(cx.listener(|this, _, _, _| {
this.active_view = ActiveView::About;
})),
),
),
),
)
.child(
v_flex()
.size_full()
.child(
TitleBar::new().bg(rgba(colors::zinc::ZINC900)).child(
h_flex()
.w_full()
.justify_between()
.bg(rgba(colors::zinc::ZINC900))
.items_center()
.cursor(gpui::CursorStyle::OpenHand)
.child(
Button::new("sidebar_toggle")
.ghost()
.icon(IconName::PanelLeft)
.on_click(cx.listener(|this, _, _, _| {
this.collapsed = !this.collapsed;
}))
.tooltip("Toggle Sidebar"),
),
),
)
.child(
v_flex()
.min_h(px(0.))
.min_w(px(0.))
.overflow_y_scrollbar()
.flex_grow()
.bg(cx.theme().background)
.child(match self.active_view {
ActiveView::Home => HomeView::build(cx.theme()).into_any_element(),
ActiveView::Passkeys => PasskeysView::build().into_any_element(),
ActiveView::Configuration => ConfigView::build().into_any_element(),
ActiveView::Security => SecurityView::build().into_any_element(),
ActiveView::Logs => LogsView::build().into_any_element(),
ActiveView::About => AboutView::build().into_any_element(),
}),
),
)
}
}
+3 -3
View File
@@ -4,7 +4,7 @@ use gpui::*;
pub struct AboutView;
impl AboutView {
pub fn build() -> impl IntoElement {
div().size_full().p_8().child("About goes here...")
}
pub fn build() -> impl IntoElement {
div().size_full().p_8().child("About goes here...")
}
}
+6 -6
View File
@@ -4,10 +4,10 @@ use gpui::*;
pub struct ConfigView;
impl ConfigView {
pub fn build() -> impl IntoElement {
div()
.size_full()
.p_8()
.child("Passkey Management List goes here...")
}
pub fn build() -> impl IntoElement {
div()
.size_full()
.p_8()
.child("Passkey Management List goes here...")
}
}
+481 -481
View File
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More