use std::borrow::Cow;
use rust_i18n::t;
use crate::config::Language;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SettingRow {
Theme,
Language,
WidgetAccount,
WidgetEvents,
HideEmptySections,
Profile
}
pub const SETTING_ROWS: [SettingRow; 6] = [
SettingRow::Theme,
SettingRow::Language,
SettingRow::WidgetAccount,
SettingRow::WidgetEvents,
SettingRow::HideEmptySections,
SettingRow::Profile
];
#[derive(Debug, Clone)]
pub struct SettingsPicker {
pub row: SettingRow,
pub title: String,
pub options: Vec<String>,
pub selected: usize
}
impl SettingRow {
#[must_use]
pub fn label(self) -> Cow<'static, str> {
match self {
Self::Theme => t!("settings.theme"),
Self::Language => t!("settings.language"),
Self::WidgetAccount => t!("settings.widget_account"),
Self::WidgetEvents => t!("settings.widget_events"),
Self::HideEmptySections => t!("settings.hide_empty"),
Self::Profile => t!("settings.profile")
}
}
#[must_use]
pub const fn icon(self) -> &'static str {
match self {
Self::Theme => "\u{f1fc}",
Self::Language => "\u{f0ac}",
Self::WidgetAccount => "\u{f2bb}",
Self::WidgetEvents => "\u{f03a}",
Self::HideEmptySections => "\u{f070}",
Self::Profile => "\u{f2c0}"
}
}
}
impl super::App {
#[must_use]
pub fn setting_value(&self, row: SettingRow) -> String {
match row {
SettingRow::Theme => theme_name(self.theme).to_string(),
SettingRow::Language => language_name(self.language).to_string(),
SettingRow::WidgetAccount
| SettingRow::WidgetEvents
| SettingRow::HideEmptySections => {
if self.setting_enabled(row).unwrap_or(false) {
t!("settings.on").into_owned()
} else {
t!("settings.off").into_owned()
}
}
SettingRow::Profile => self.active_profile.clone()
}
}
#[must_use]
pub fn setting_enabled(&self, row: SettingRow) -> Option<bool> {
match row {
SettingRow::WidgetAccount => Some(self.is_widget_enabled("account")),
SettingRow::WidgetEvents => Some(self.is_widget_enabled("events")),
SettingRow::HideEmptySections => Some(self.hide_empty_tabs),
SettingRow::Theme | SettingRow::Language | SettingRow::Profile => None
}
}
pub fn settings_move(&mut self, dir: super::FocusDir) {
self.settings_selected = super::grid_step(
self.settings_selected,
SETTING_ROWS.len(),
self.resource_cols,
dir
);
}
pub fn settings_activate(&mut self) {
let row = SETTING_ROWS[self.settings_selected.min(SETTING_ROWS.len() - 1)];
match row {
SettingRow::WidgetAccount => {
self.widgets.toggle("account");
self.prefs_dirty = true;
}
SettingRow::WidgetEvents => {
self.widgets.toggle("events");
self.prefs_dirty = true;
}
SettingRow::HideEmptySections => {
self.toggle_hide_empty_tabs();
if let Some(index) = self
.nav_items()
.iter()
.position(|i| matches!(i.kind, super::NavKind::Settings))
{
self.nav_selected = index;
}
}
SettingRow::Theme => {
let options: Vec<String> = crate::tui::themes::Theme::ALL
.iter()
.map(|t| theme_name(*t).to_string())
.collect();
let selected = crate::tui::themes::Theme::ALL
.iter()
.position(|t| *t == self.theme)
.unwrap_or(0);
self.picker = Some(SettingsPicker {
row,
title: row.label().into_owned(),
options,
selected
});
}
SettingRow::Language => {
let selected = usize::from(self.language == Language::Ru);
self.picker = Some(SettingsPicker {
row,
title: row.label().into_owned(),
options: vec!["English".to_string(), "Русский".to_string()],
selected
});
}
SettingRow::Profile => {
if self.profiles.len() < 2 {
self.status_message = Some(t!("app.no_other_profiles").to_string());
return;
}
let selected = self
.profiles
.iter()
.position(|p| *p == self.active_profile)
.unwrap_or(0);
self.picker = Some(SettingsPicker {
row,
title: row.label().into_owned(),
options: self.profiles.clone(),
selected
});
}
}
}
#[must_use]
pub const fn picker_open(&self) -> bool {
self.picker.is_some()
}
pub fn picker_next(&mut self) {
if let Some(p) = self.picker.as_mut()
&& p.selected + 1 < p.options.len()
{
p.selected += 1;
}
}
pub fn picker_previous(&mut self) {
if let Some(p) = self.picker.as_mut() {
p.selected = p.selected.saturating_sub(1);
}
}
pub fn picker_close(&mut self) {
self.picker = None;
}
pub fn picker_apply(&mut self) {
let Some(picker) = self.picker.take() else {
return;
};
match picker.row {
SettingRow::Theme => {
if let Some(theme) = crate::tui::themes::Theme::ALL.get(picker.selected) {
self.theme = *theme;
self.prefs_dirty = true;
}
}
SettingRow::Language => {
let next = if picker.selected == 1 {
Language::Ru
} else {
Language::En
};
self.set_language(next);
}
SettingRow::Profile => {
if let Some(profile) = picker.options.get(picker.selected)
&& *profile != self.active_profile
{
self.switch_profile = Some(profile.clone());
}
}
SettingRow::WidgetAccount
| SettingRow::WidgetEvents
| SettingRow::HideEmptySections => {}
}
}
}
#[must_use]
pub const fn theme_name(theme: crate::tui::themes::Theme) -> &'static str {
match theme {
crate::tui::themes::Theme::GruvboxDark => "Gruvbox Dark",
crate::tui::themes::Theme::GruvboxLight => "Gruvbox Light",
crate::tui::themes::Theme::CatppuccinMocha => "Catppuccin Mocha",
crate::tui::themes::Theme::CatppuccinLatte => "Catppuccin Latte"
}
}
#[must_use]
pub const fn language_name(language: Language) -> &'static str {
match language {
Language::En => "English",
Language::Ru => "Русский"
}
}