mirror of
https://github.com/librekeys/picoforge.git
synced 2026-07-28 08:01:19 -07:00
chore: change code formatting, use space for tabs and indents instead of tabs
This commit is contained in:
Generated
-31
@@ -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
@@ -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
@@ -1,4 +1,4 @@
|
||||
edition = "2024"
|
||||
hard_tabs = true
|
||||
hard_tabs = false
|
||||
tab_spaces = 4
|
||||
max_width = 100
|
||||
|
||||
+34
-34
@@ -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>;
|
||||
|
||||
+223
-223
File diff suppressed because it is too large
Load Diff
+434
-434
File diff suppressed because it is too large
Load Diff
+396
-396
File diff suppressed because it is too large
Load Diff
+26
-26
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
+51
-51
@@ -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
@@ -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
@@ -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
@@ -11,4 +11,4 @@ pub mod zinc {
|
||||
pub const ZINC800: u32 = 0x27272a;
|
||||
pub const ZINC900: u32 = 0x18181b;
|
||||
pub const ZINC950: u32 = 0x09090b;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
pub mod views;
|
||||
pub mod assets;
|
||||
pub mod rootview;
|
||||
pub mod colors;
|
||||
pub mod rootview;
|
||||
pub mod views;
|
||||
|
||||
+122
-122
@@ -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(),
|
||||
}),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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...")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
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
Reference in New Issue
Block a user