use super::theme;
use super::theme::ThemeName;
use crate::app::App;
use ratatui::prelude::*;
use ratatui::widgets::{Block, Borders, Clear, Paragraph};
pub fn render(frame: &mut Frame, area: Rect, app: &App) {
let popup_area = super::centered_rect(54, 64, area);
frame.render_widget(Clear, popup_area);
let block = Block::default()
.title(Span::styled(" ✦ DriftFM Config Console ✦ ", theme::title()))
.borders(Borders::ALL)
.border_style(
Style::default()
.fg(theme::highlight())
.add_modifier(Modifier::BOLD),
)
.border_type(ratatui::widgets::BorderType::Rounded)
.style(Style::default().bg(theme::bg()));
let inner_area = block.inner(popup_area);
frame.render_widget(block, popup_area);
let chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([
Constraint::Length(1), Constraint::Length(2), Constraint::Length(2), Constraint::Length(2), Constraint::Length(2), Constraint::Length(2), Constraint::Length(2), Constraint::Min(0), ])
.split(inner_area);
let notify_enabled = app.library.settings.notifications_enabled;
let autoplay_enabled = app.library.settings.autoplay_last;
let rec_dir = &app.library.settings.recording_dir;
let keep_snippets = app.library.settings.keep_snippets;
let min_duration = app.library.settings.min_song_duration_secs;
let current_theme = ThemeName::from_key(&app.library.settings.theme);
let active_style = Style::default()
.fg(theme::accent_secondary())
.add_modifier(Modifier::BOLD);
let normal_style = Style::default().fg(theme::text().fg.unwrap());
let active_bg = Style::default().bg(theme::surface_color());
let notify_spans = vec![
Span::styled(
if app.selected_setting_idx == 0 {
" ▸ "
} else {
" "
},
active_style,
),
Span::styled(
if notify_enabled {
"[ ▣ ] "
} else {
"[ ▢ ] "
},
Style::default()
.fg(if notify_enabled {
theme::accent_secondary()
} else {
theme::dim().fg.unwrap()
})
.add_modifier(Modifier::BOLD),
),
Span::styled(
"Desktop Song Notifications",
if app.selected_setting_idx == 0 {
active_style
} else {
normal_style
},
),
];
let mut notify_para = Paragraph::new(Line::from(notify_spans));
if app.selected_setting_idx == 0 {
notify_para = notify_para.style(active_bg);
}
frame.render_widget(notify_para, chunks[1]);
let autoplay_spans = vec![
Span::styled(
if app.selected_setting_idx == 1 {
" ▸ "
} else {
" "
},
active_style,
),
Span::styled(
if autoplay_enabled {
"[ ▣ ] "
} else {
"[ ▢ ] "
},
Style::default()
.fg(if autoplay_enabled {
theme::accent_secondary()
} else {
theme::dim().fg.unwrap()
})
.add_modifier(Modifier::BOLD),
),
Span::styled(
"Autoplay Last Played Station on Boot",
if app.selected_setting_idx == 1 {
active_style
} else {
normal_style
},
),
];
let mut autoplay_para = Paragraph::new(Line::from(autoplay_spans));
if app.selected_setting_idx == 1 {
autoplay_para = autoplay_para.style(active_bg);
}
frame.render_widget(autoplay_para, chunks[2]);
let rec_spans = vec![
Span::styled(
if app.selected_setting_idx == 2 {
" ▸ "
} else {
" "
},
active_style,
),
Span::styled(
"[ 🗁 ] ",
Style::default()
.fg(theme::highlight())
.add_modifier(Modifier::BOLD),
),
Span::styled(
"Tape Capture Folder: ",
if app.selected_setting_idx == 2 {
active_style
} else {
normal_style
},
),
Span::styled(
format!("{} ", rec_dir),
Style::default()
.fg(theme::highlight())
.add_modifier(Modifier::UNDERLINED)
.add_modifier(Modifier::BOLD),
),
Span::styled("(Press Space to cycle)", theme::dim()),
];
let mut rec_para = Paragraph::new(Line::from(rec_spans));
if app.selected_setting_idx == 2 {
rec_para = rec_para.style(active_bg);
}
frame.render_widget(rec_para, chunks[3]);
let snippets_spans = vec![
Span::styled(
if app.selected_setting_idx == 3 {
" ▸ "
} else {
" "
},
active_style,
),
Span::styled(
if keep_snippets {
"[ ▣ ] "
} else {
"[ ▢ ] "
},
Style::default()
.fg(if keep_snippets {
theme::accent_secondary()
} else {
theme::dim().fg.unwrap()
})
.add_modifier(Modifier::BOLD),
),
Span::styled(
"Keep Partial Snippets & Commercial Ads",
if app.selected_setting_idx == 3 {
active_style
} else {
normal_style
},
),
];
let mut snippets_para = Paragraph::new(Line::from(snippets_spans));
if app.selected_setting_idx == 3 {
snippets_para = snippets_para.style(active_bg);
}
frame.render_widget(snippets_para, chunks[4]);
let duration_dimmed = keep_snippets;
let duration_fg = if duration_dimmed {
theme::dim().fg.unwrap()
} else {
theme::highlight()
};
let duration_spans = vec![
Span::styled(
if app.selected_setting_idx == 4 {
" ▸ "
} else {
" "
},
if duration_dimmed {
theme::dim()
} else {
active_style
},
),
Span::styled(
"[ ⏱ ] ",
Style::default()
.fg(duration_fg)
.add_modifier(Modifier::BOLD),
),
Span::styled(
"Min Song Duration: ",
if app.selected_setting_idx == 4 && !duration_dimmed {
active_style
} else if duration_dimmed {
theme::dim()
} else {
normal_style
},
),
Span::styled(
format!("{}s ", min_duration),
Style::default()
.fg(duration_fg)
.add_modifier(Modifier::BOLD),
),
Span::styled(
if duration_dimmed {
"(disabled — keeping all)"
} else {
"(Press Space to cycle)"
},
theme::dim(),
),
];
let mut duration_para = Paragraph::new(Line::from(duration_spans));
if app.selected_setting_idx == 4 {
duration_para = duration_para.style(active_bg);
}
frame.render_widget(duration_para, chunks[5]);
let theme_spans = vec![
Span::styled(
if app.selected_setting_idx == 5 {
" ▸ "
} else {
" "
},
active_style,
),
Span::styled(
"[ 🎨 ] ",
Style::default()
.fg(theme::highlight())
.add_modifier(Modifier::BOLD),
),
Span::styled(
"Theme: ",
if app.selected_setting_idx == 5 {
active_style
} else {
normal_style
},
),
Span::styled(
format!("{} ", current_theme.label()),
Style::default()
.fg(theme::highlight())
.add_modifier(Modifier::BOLD),
),
Span::styled("(Press Space to cycle)", theme::dim()),
];
let mut theme_para = Paragraph::new(Line::from(theme_spans));
if app.selected_setting_idx == 5 {
theme_para = theme_para.style(active_bg);
}
frame.render_widget(theme_para, chunks[6]);
let footer_line = Line::from(vec![
Span::styled(
" j/k",
Style::default()
.fg(theme::highlight())
.add_modifier(Modifier::BOLD),
),
Span::styled(" Navigate • ", theme::dim()),
Span::styled(
"Space",
Style::default()
.fg(theme::highlight())
.add_modifier(Modifier::BOLD),
),
Span::styled(" Toggle / Cycle • ", theme::dim()),
Span::styled(
"Esc/,",
Style::default()
.fg(theme::highlight())
.add_modifier(Modifier::BOLD),
),
Span::styled(" Exit Config", theme::dim()),
]);
let footer = Paragraph::new(vec![Line::from(""), footer_line]).alignment(Alignment::Center);
frame.render_widget(footer, chunks[7]);
}