Skip to content

Commit b3aa569

Browse files
authored
Merge pull request #7 from mazdak/codex/add-color-to-profiles-for-distinction
Add profile color support
2 parents 04aa93c + 9ee616b commit b3aa569

File tree

2 files changed

+74
-9
lines changed

2 files changed

+74
-9
lines changed

src/config.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,58 @@
11
use serde::{Deserialize, Serialize};
22
use std::{fs, path::{Path, PathBuf}};
3+
use ratatui::style::Color;
34

45
#[derive(Deserialize, Serialize, Debug, Clone, PartialEq)]
56
pub struct ConnectionProfile {
67
pub name: String,
78
pub url: String,
89
pub db: Option<u8>,
910
pub dev: Option<bool>,
11+
pub color: Option<String>,
12+
}
13+
14+
impl ConnectionProfile {
15+
pub fn resolved_color(&self) -> Color {
16+
self.color
17+
.as_deref()
18+
.map(parse_color)
19+
.unwrap_or(Color::White)
20+
}
21+
}
22+
23+
fn parse_color(spec: &str) -> Color {
24+
match spec.trim().to_lowercase().as_str() {
25+
"black" => Color::Black,
26+
"red" => Color::Red,
27+
"green" => Color::Green,
28+
"yellow" => Color::Yellow,
29+
"blue" => Color::Blue,
30+
"magenta" => Color::Magenta,
31+
"cyan" => Color::Cyan,
32+
"gray" | "grey" => Color::Gray,
33+
"darkgray" | "darkgrey" => Color::DarkGray,
34+
"lightred" => Color::LightRed,
35+
"lightgreen" => Color::LightGreen,
36+
"lightyellow" => Color::LightYellow,
37+
"lightblue" => Color::LightBlue,
38+
"lightmagenta" => Color::LightMagenta,
39+
"lightcyan" => Color::LightCyan,
40+
"white" => Color::White,
41+
other => {
42+
if let Some(hex) = other.strip_prefix('#') {
43+
if hex.len() == 6 {
44+
if let (Ok(r), Ok(g), Ok(b)) = (
45+
u8::from_str_radix(&hex[0..2], 16),
46+
u8::from_str_radix(&hex[2..4], 16),
47+
u8::from_str_radix(&hex[4..6], 16),
48+
) {
49+
return Color::Rgb(r, g, b);
50+
}
51+
}
52+
}
53+
Color::White
54+
}
55+
}
1056
}
1157

1258
#[derive(Deserialize, Serialize, Debug, Default, PartialEq)]
@@ -24,6 +70,7 @@ impl Config {
2470
url: "redis://127.0.0.1:6379".to_string(),
2571
db: Some(0),
2672
dev: Some(true),
73+
color: Some("green".to_string()),
2774
}
2875
]
2976
}
@@ -112,6 +159,7 @@ mod tests {
112159
assert_eq!(cfg, loaded);
113160
assert_eq!(cfg.profiles.len(), 1);
114161
assert_eq!(cfg.profiles[0].name, "Default");
162+
assert_eq!(cfg.profiles[0].color.as_deref(), Some("green"));
115163
}
116164

117165
#[test]
@@ -128,6 +176,7 @@ mod tests {
128176
url: "redis://localhost:6379".to_string(),
129177
db: Some(1),
130178
dev: Some(false),
179+
color: Some("red".to_string()),
131180
}],
132181
};
133182
fs::write(&cfg_file, toml::to_string(&custom_cfg).unwrap()).unwrap();

src/ui.rs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,14 @@ fn draw_profiles_or_db_list(f: &mut Frame, app: &App, area: Rect) {
118118
f.render_stateful_widget(db_list_widget, db_list_area, &mut db_list_state);
119119

120120
// Render Status
121+
let profile_color = app
122+
.profiles
123+
.get(app.current_profile_index)
124+
.map(|p| p.resolved_color())
125+
.unwrap_or(Color::White);
126+
121127
let connection_status_paragraph = Paragraph::new(app.connection_status.as_str())
128+
.style(Style::default().fg(profile_color))
122129
.wrap(Wrap { trim: true })
123130
.alignment(Alignment::Center); // Center status text
124131
f.render_widget(connection_status_paragraph, status_area);
@@ -326,18 +333,27 @@ fn draw_profile_selector_modal(f: &mut Frame, app: &App) {
326333
let area = centered_rect(60, 50, f.area());
327334
f.render_widget(Clear, area); // Clear the background
328335

329-
let profiles: Vec<ListItem> = app.profiles.iter().enumerate().map(|(idx, profile)| {
330-
let style = if idx == app.selected_profile_list_index {
331-
Style::default().fg(Color::Black).bg(Color::White) // Highlight selected
332-
} else {
333-
Style::default()
334-
};
335-
ListItem::new(format!("{} ({})", profile.name, profile.url)).style(style)
336-
}).collect();
336+
let profiles: Vec<ListItem> = app
337+
.profiles
338+
.iter()
339+
.enumerate()
340+
.map(|(idx, profile)| {
341+
let item_color = profile.resolved_color();
342+
let style = if idx == app.selected_profile_list_index {
343+
Style::default()
344+
.fg(Color::Black)
345+
.bg(item_color)
346+
.add_modifier(Modifier::BOLD)
347+
} else {
348+
Style::default().fg(item_color)
349+
};
350+
ListItem::new(format!("{} ({})", profile.name, profile.url)).style(style)
351+
})
352+
.collect();
337353

338354
let list_widget = List::new(profiles)
339355
.block(Block::default().borders(Borders::ALL).title("Select Connection Profile (p/Esc to close)"))
340-
.highlight_style(Style::default().add_modifier(Modifier::BOLD).fg(Color::Black).bg(Color::White)) // Ensure highlight is visible
356+
.highlight_style(Style::default().add_modifier(Modifier::BOLD))
341357
.highlight_symbol(">> ");
342358

343359
let mut list_state = ListState::default();

0 commit comments

Comments
 (0)