Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added icons/dash.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,9 @@ impl AppState {

impl App for AppState {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
// Apply Dash theme on first update
crate::ui::theme::apply_theme(ctx);

if let Ok(event) = self.current_app_context().rx_zmq_status.try_recv() {
if let Ok(mut status) = self.current_app_context().zmq_connection_status.lock() {
*status = event;
Expand Down
22 changes: 14 additions & 8 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ pub struct Config {
pub testnet_config: Option<NetworkConfig>,
pub devnet_config: Option<NetworkConfig>,
pub local_config: Option<NetworkConfig>,
/// Global developer mode setting
pub developer_mode: Option<bool>,
}

#[derive(Debug, thiserror::Error)]
Expand Down Expand Up @@ -44,8 +46,6 @@ pub struct NetworkConfig {
pub wallet_private_key: Option<String>,
/// Should this network be visible in the UI
pub show_in_ui: bool,
/// Developer mode
pub developer_mode: Option<bool>,
}

impl Config {
Expand Down Expand Up @@ -121,12 +121,6 @@ impl Config {
writeln!(env_file, "{}show_in_ui={}", prefix, config.show_in_ui)
.map_err(|e| ConfigError::LoadError(e.to_string()))?;

// Developer mode
if let Some(developer_mode) = config.developer_mode {
writeln!(env_file, "{}developer_mode={}", prefix, developer_mode)
.map_err(|e| ConfigError::LoadError(e.to_string()))?;
}

// Add a blank line after each config block
writeln!(env_file).map_err(|e| ConfigError::LoadError(e.to_string()))?;

Expand Down Expand Up @@ -155,6 +149,12 @@ impl Config {
write_network_config("LOCAL_", local_config)?;
}

// Save global developer mode
if let Some(developer_mode) = self.developer_mode {
writeln!(env_file, "DEVELOPER_MODE={}", developer_mode)
.map_err(|e| ConfigError::LoadError(e.to_string()))?;
}

tracing::info!("Successfully saved configuration to {:?}", env_file_path);
Ok(())
}
Expand Down Expand Up @@ -241,11 +241,17 @@ impl Config {
);
}

// Load global developer mode
let developer_mode = std::env::var("DEVELOPER_MODE")
.ok()
.and_then(|s| s.parse::<bool>().ok());

Ok(Config {
mainnet_config,
testnet_config,
devnet_config,
local_config,
developer_mode,
})
}

Expand Down
6 changes: 2 additions & 4 deletions src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ impl AppContext {

let app_context = AppContext {
network,
developer_mode: AtomicBool::new(network_config.developer_mode.unwrap_or(false)),
developer_mode: AtomicBool::new(config.developer_mode.unwrap_or(false)),
devnet_name: None,
db,
sdk: sdk.into(),
Expand Down Expand Up @@ -192,9 +192,7 @@ impl AppContext {
cfg_lock.clone()
};

// Update the developer_mode from the config
self.developer_mode
.store(cfg.developer_mode.unwrap_or(false), Ordering::Relaxed);
// Note: developer_mode is now global and managed separately

// 2. Rebuild the RPC client with the new password
let addr = format!("http://{}:{}", cfg.core_host, cfg.core_rpc_port);
Expand Down
3 changes: 2 additions & 1 deletion src/database/identities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ impl Database {
/// Retrieves all local user identities along with their associated wallet IDs.
///
/// Caller should insert wallet references into associated_wallets before using the identities.
#[allow(clippy::let_and_return)]
pub fn get_local_user_identities(
&self,
app_context: &AppContext,
Expand All @@ -372,7 +373,7 @@ impl Database {
let mut stmt = conn.prepare(
"SELECT data,wallet FROM identity WHERE is_local = 1 AND network = ? AND identity_type = 'User' AND data IS NOT NULL",
)?;
let identities = stmt
let identities: Result<Vec<(QualifiedIdentity, WalletSeedHash)>, rusqlite::Error> = stmt
.query_map(params![network], |row| {
let data: Vec<u8> = row.get(0)?;
let wallet_id: WalletSeedHash = row.get(1)?;
Expand Down
1 change: 1 addition & 0 deletions src/model/qualified_identity/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ impl QualifiedIdentity {
keys
}

#[allow(dead_code)]
pub fn available_authentication_keys_with_critical_or_high_security_level(
&self,
) -> Vec<&QualifiedIdentityPublicKey> {
Expand Down
410 changes: 237 additions & 173 deletions src/ui/components/contract_chooser_panel.rs

Large diffs are not rendered by default.

123 changes: 78 additions & 45 deletions src/ui/components/dpns_subscreen_chooser_panel.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use crate::context::AppContext;
use crate::ui::dpns::dpns_contested_names_screen::DPNSSubscreen;
use crate::ui::theme::{DashColors, Shadow, Shape, Spacing, Typography};
use crate::ui::RootScreenType;
use crate::{app::AppAction, ui};
use egui::{Color32, Context, Frame, Margin, RichText, SidePanel};
use egui::{Context, Frame, Margin, RichText, SidePanel};

pub fn add_dpns_subscreen_chooser_panel(ctx: &Context, app_context: &AppContext) -> AppAction {
let mut action = AppAction::None;
Expand All @@ -26,59 +27,91 @@ pub fn add_dpns_subscreen_chooser_panel(ctx: &Context, app_context: &AppContext)
};

SidePanel::left("dpns_subscreen_chooser_panel")
.default_width(250.0)
.default_width(270.0) // Increased to account for margins
.frame(
Frame::new()
.fill(ctx.style().visuals.panel_fill)
.inner_margin(Margin::same(10)),
.fill(DashColors::BACKGROUND) // Light background instead of transparent
.inner_margin(Margin::symmetric(10, 10)), // Add margins for island effect
)
.show(ctx, |ui| {
// Display subscreen names
ui.vertical(|ui| {
ui.label("DPNS Subscreens");
ui.add_space(10.0);
// Fill the entire available height
let available_height = ui.available_height();

for subscreen in subscreens {
let is_active = active_screen == subscreen;
let (button_color, text_color) = if is_active {
(Color32::from_rgb(0, 128, 255), Color32::WHITE)
} else {
(Color32::GRAY, Color32::WHITE)
};
let button = egui::Button::new(
RichText::new(subscreen.display_name()).color(text_color),
)
.fill(button_color);
// Show the subscreen name as a clickable option
if ui.add(button).clicked() {
// Handle navigation based on which subscreen is selected
match subscreen {
DPNSSubscreen::Active => {
action = AppAction::SetMainScreen(
RootScreenType::RootScreenDPNSActiveContests,
)
}
DPNSSubscreen::Past => {
action = AppAction::SetMainScreen(
RootScreenType::RootScreenDPNSPastContests,
)
}
DPNSSubscreen::Owned => {
action = AppAction::SetMainScreen(
RootScreenType::RootScreenDPNSOwnedNames,
// Create an island panel with rounded edges that fills the height
Frame::new()
.fill(DashColors::SURFACE)
.stroke(egui::Stroke::new(1.0, DashColors::BORDER_LIGHT))
.inner_margin(Margin::same(Spacing::MD_I8))
.corner_radius(egui::CornerRadius::same(Shape::RADIUS_LG))
.shadow(Shadow::elevated())
.show(ui, |ui| {
// Account for both outer margin (10px * 2) and inner margin
ui.set_min_height(available_height - 2.0 - (Spacing::MD_I8 as f32 * 2.0));
// Display subscreen names
ui.vertical(|ui| {
ui.label(
RichText::new("DPNS Subscreens")
.font(Typography::heading_small())
.color(DashColors::TEXT_PRIMARY),
);
ui.add_space(Spacing::MD);

for subscreen in subscreens {
let is_active = active_screen == subscreen;

let button = if is_active {
egui::Button::new(
RichText::new(subscreen.display_name())
.color(DashColors::WHITE)
.size(Typography::SCALE_SM),
)
}
DPNSSubscreen::ScheduledVotes => {
action = AppAction::SetMainScreen(
RootScreenType::RootScreenDPNSScheduledVotes,
.fill(DashColors::DASH_BLUE)
.stroke(egui::Stroke::NONE)
.corner_radius(egui::CornerRadius::same(Shape::RADIUS_MD))
.min_size(egui::Vec2::new(150.0, 28.0))
} else {
egui::Button::new(
RichText::new(subscreen.display_name())
.color(DashColors::TEXT_PRIMARY)
.size(Typography::SCALE_SM),
)
.fill(DashColors::WHITE)
.stroke(egui::Stroke::new(1.0, DashColors::BORDER))
.corner_radius(egui::CornerRadius::same(Shape::RADIUS_MD))
.min_size(egui::Vec2::new(150.0, 28.0))
};

// Show the subscreen name as a clickable option
if ui.add(button).clicked() {
// Handle navigation based on which subscreen is selected
match subscreen {
DPNSSubscreen::Active => {
action = AppAction::SetMainScreen(
RootScreenType::RootScreenDPNSActiveContests,
)
}
DPNSSubscreen::Past => {
action = AppAction::SetMainScreen(
RootScreenType::RootScreenDPNSPastContests,
)
}
DPNSSubscreen::Owned => {
action = AppAction::SetMainScreen(
RootScreenType::RootScreenDPNSOwnedNames,
)
}
DPNSSubscreen::ScheduledVotes => {
action = AppAction::SetMainScreen(
RootScreenType::RootScreenDPNSScheduledVotes,
)
}
}
}
}
}

ui.add_space(5.0);
}
});
ui.add_space(Spacing::SM);
}
});
}); // Close the island frame
});

action
Expand Down
25 changes: 14 additions & 11 deletions src/ui/components/entropy_grid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,29 @@ impl U256EntropyGrid {
// Add padding around the grid
ui.add_space(10.0); // Top padding

// Calculate button size based on available width and enforce max height of 120px.
let available_width = ui.available_width() - 20.0; // Account for 10px left and right buffers
let max_height = 120;
// Calculate button size - make it fixed size for consistency
let max_grid_width = 400.0; // Maximum width for the entropy grid
let available_width = ui.available_width().min(max_grid_width) - 20.0; // Account for padding
let columns = 32usize; // Reduced from 64 for better usability
let rows = 8usize; // Increased from 4 to maintain 256 bits
let max_height = 160; // Adjusted for 8 rows
let button_size = Vec2::new(
available_width / 64.0, // Divide the width into 64 columns.
(max_height / 4).min(available_width as i32 / 64) as f32, // Ensure height stays within limit.
available_width / columns as f32, // Divide the width into columns
(max_height / rows as i32).min(available_width as i32 / columns as i32) as f32, // Ensure height stays within limit
);

// Create a grid with 4 rows and 64 columns (256 bits total).
// Create a grid with 8 rows and 32 columns (256 bits total).
ui.horizontal(|ui| {
ui.add_space(10.0); // Left padding

Grid::new("entropy_grid")
.num_columns(64) // 64 columns, each representing a bit.
.num_columns(columns) // columns, each representing a bit.
.spacing(Vec2::new(0.0, 0.0)) // No spacing for compact layout.
.min_col_width(0.0) // Allow columns to shrink without restriction.
.show(ui, |ui| {
for row in 0..4 {
for col in 0..64 {
let bit_position = (row * 64 + col) as u8;
for row in 0..rows {
for col in 0..columns {
let bit_position = (row * columns + col) as u8;
let byte_index = (bit_position / 8) as usize;
let bit_in_byte = (bit_position % 8) as usize;

Expand All @@ -70,7 +73,7 @@ impl U256EntropyGrid {
self.toggle_bit(byte_index, bit_in_byte); // Toggle the bit.
}
}
ui.end_row(); // Move to the next row after 64 bits.
ui.end_row(); // Move to the next row after columns bits.
}
});

Expand Down
Loading