Add nerd font icons and UI polish
All checks were successful
Build and Release / build-and-release (push) Successful in 1m18s

- Add nerd font file type icons:
  - Folder icons: closed/open folders with visual state
  - Music files: icon in green (mp3, flac, wav, ogg, etc.)
  - Video files: icon in yellow (mp4, mkv, avi, mov, etc.)
- Add spacing after icons for better readability

- Add "Refresh" option to title bar right-click menu
- Make all context menus more compact (13 chars wide)

- Change panel titles to lowercase:
  - "Media Files" → "files"
  - "Playlist" → "playlist"
- Remove bold styling from focused panel titles

- All icons show as bold black on selection bar
- Folders show in blue, music in green, video in yellow
This commit is contained in:
Christoffer Martinsson 2025-12-08 23:07:28 +01:00
parent f60ff02b2a
commit ed6765039c
2 changed files with 34 additions and 24 deletions

View File

@ -1,6 +1,6 @@
[package]
name = "cm-player"
version = "0.1.13"
version = "0.1.14"
edition = "2021"
[dependencies]

View File

@ -147,16 +147,40 @@ fn render_file_panel(frame: &mut Frame, state: &mut AppState, area: Rect) {
// Only show selection bar when file panel has focus
let is_selected = !state.focus_playlist && idx == state.selected_index;
// Add folder icon for directories
// Add icon for directories and files
let icon = if item.node.is_dir {
let is_expanded = state.expanded_dirs.contains(&item.node.path);
// Nerd font folder icons: \u{eaf7} = open, \u{ea83} = closed
let icon_char = if is_expanded { "\u{eaf7} " } else { "\u{ea83} " };
// Bold black icon on selection bar, blue otherwise
if is_selected {
Span::styled("", Style::default().fg(Theme::background()).add_modifier(Modifier::BOLD))
Span::styled(icon_char, Style::default().fg(Theme::background()).add_modifier(Modifier::BOLD))
} else {
Span::styled("", Style::default().fg(Theme::highlight()))
Span::styled(icon_char, Style::default().fg(Theme::highlight()))
}
} else {
Span::raw(" ")
// File icons based on extension
let extension = item.node.path.extension()
.and_then(|e| e.to_str())
.unwrap_or("")
.to_lowercase();
let (icon_char, color) = match extension.as_str() {
// Audio files - music note icon
"mp3" | "flac" | "wav" | "ogg" | "m4a" | "aac" | "wma" | "opus" =>
("\u{f0e2a} ", Theme::success()), //
// Video files - film icon
"mp4" | "mkv" | "avi" | "mov" | "webm" | "flv" | "wmv" | "m4v" =>
("\u{f1c8} ", Theme::warning()), //
_ => (" ", Theme::foreground()),
};
if is_selected {
Span::styled(icon_char, Style::default().fg(Theme::background()).add_modifier(Modifier::BOLD))
} else {
Span::styled(icon_char, Style::default().fg(color))
}
};
let name_spans = if in_search && !search_query.is_empty() {
highlight_search_matches(&item.node.name, &search_query, is_selected)
@ -201,20 +225,13 @@ fn render_file_panel(frame: &mut Frame, state: &mut AppState, area: Rect) {
items.push(more_item);
}
let title_style = if !state.focus_playlist {
// File panel has focus - bold title
Theme::title_style().add_modifier(Modifier::BOLD)
} else {
Theme::title_style()
};
let list = List::new(items)
.block(
Block::default()
.borders(Borders::ALL)
.title("Media Files")
.title("files")
.style(Theme::widget_border_style())
.title_style(title_style),
.title_style(Theme::title_style()),
);
let mut list_state = ListState::default();
@ -311,16 +328,9 @@ fn render_right_panel(frame: &mut Frame, state: &mut AppState, area: Rect) {
}
let playlist_title = if !state.playlist.is_empty() {
format!("Playlist [{}/{}]", state.playlist_index + 1, state.playlist.len())
format!("playlist [{}/{}]", state.playlist_index + 1, state.playlist.len())
} else {
"Playlist (empty)".to_string()
};
let playlist_title_style = if state.focus_playlist {
// Playlist has focus - bold title
Theme::title_style().add_modifier(Modifier::BOLD)
} else {
Theme::title_style()
"playlist (empty)".to_string()
};
let playlist_widget = List::new(playlist_items)
@ -329,7 +339,7 @@ fn render_right_panel(frame: &mut Frame, state: &mut AppState, area: Rect) {
.borders(Borders::ALL)
.title(playlist_title)
.style(Theme::widget_border_style())
.title_style(playlist_title_style),
.title_style(Theme::title_style()),
);
let mut playlist_state = ListState::default();