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
37 changes: 37 additions & 0 deletions src/cortex-tui/src/app/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,43 @@ impl AppState {
}
}

// ============================================================================
// APPSTATE METHODS - Theme Preview
// ============================================================================

impl AppState {
/// Start previewing a theme.
///
/// This updates the cached theme colors to show the preview theme,
/// without changing the active theme.
pub fn start_theme_preview(&mut self, theme_name: &str) {
self.set_preview_theme(Some(theme_name.to_string()));
}

/// Cancel theme preview and revert to the original (active) theme.
///
/// Restores the cached colors to the active theme.
pub fn cancel_theme_preview(&mut self) {
self.set_preview_theme(None);
}

/// Confirm the previewed theme as the active theme.
///
/// Makes the preview theme the new active theme and clears the preview state.
pub fn confirm_theme_preview(&mut self) {
if let Some(preview) = self.preview_theme.take() {
self.active_theme = preview.clone();
// Colors are already set to the preview theme, just need to clear preview state
self.preview_theme = None;
}
}

/// Check if a theme preview is active.
pub fn has_theme_preview(&self) -> bool {
self.preview_theme.is_some()
}
}

// ============================================================================
// APPSTATE METHODS - Operation Mode
// ============================================================================
Expand Down
25 changes: 25 additions & 0 deletions src/cortex-tui/src/app/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ pub struct AppState {
pub input_mode: crate::interactive::InputMode,
/// Active theme name
pub active_theme: String,
/// Preview theme name (for live theme preview in selector)
pub preview_theme: Option<String>,
/// Cached theme colors for quick access
pub theme_colors: ThemeColors,
/// Cached markdown theme for quick access
Expand Down Expand Up @@ -238,6 +240,7 @@ impl AppState {
diff_scroll: 0,
input_mode: crate::interactive::InputMode::Normal,
active_theme: "dark".to_string(),
preview_theme: None,
theme_colors: ThemeColors::dark(),
markdown_theme: MarkdownTheme::default(),
compact_mode: false,
Expand Down Expand Up @@ -372,10 +375,32 @@ impl AppState {
/// Change the active theme
pub fn set_theme(&mut self, name: &str) {
self.active_theme = name.to_string();
self.preview_theme = None; // Clear any preview when setting the theme
self.theme_colors = ThemeColors::from_name(name);
self.markdown_theme = MarkdownTheme::from_name(name);
}

/// Set a preview theme for live preview functionality
///
/// Updates the cached theme_colors to the preview theme colors.
pub fn set_preview_theme(&mut self, theme: Option<String>) {
self.preview_theme = theme.clone();
// Update cached colors based on preview or active theme
let effective_theme = theme.as_deref().unwrap_or(&self.active_theme);
self.theme_colors = ThemeColors::from_name(effective_theme);
self.markdown_theme = MarkdownTheme::from_name(effective_theme);
}

/// Get the effective theme colors (preview if set, otherwise active)
pub fn get_effective_theme_colors(&self) -> &ThemeColors {
&self.theme_colors
}

/// Get the name of the effective theme (preview if set, otherwise active)
pub fn get_effective_theme_name(&self) -> &str {
self.preview_theme.as_deref().unwrap_or(&self.active_theme)
}

/// Get AdaptiveColors from the current theme
pub fn adaptive_colors(&self) -> crate::ui::AdaptiveColors {
crate::ui::AdaptiveColors::from_theme_colors(&self.theme_colors)
Expand Down
14 changes: 14 additions & 0 deletions src/cortex-tui/src/modal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ pub enum ModalResult {
Close,
/// Perform an action and close
Action(ModalAction),
/// Perform an action but keep the modal open (for live preview)
ActionContinue(ModalAction),
/// Push a new modal on top of this one
Push(Box<dyn Modal>),
/// Replace this modal with another
Expand Down Expand Up @@ -172,6 +174,14 @@ pub enum ModalAction {
api_key: String,
},

// Theme Preview Actions
/// Preview a theme without applying it permanently
PreviewTheme(String),
/// Revert to the original theme (cancel preview)
RevertTheme,
/// Confirm and apply the previewed theme
ConfirmTheme(String),

// Generic/Custom
Custom(String),
}
Expand Down Expand Up @@ -253,6 +263,10 @@ impl ModalStack {
self.pop();
ModalResult::Action(action)
}
ModalResult::ActionContinue(action) => {
// Return the action but keep the modal open (for live preview)
ModalResult::ActionContinue(action)
}
other => other,
}
} else {
Expand Down
Loading