eazygit 0.5.1

A fast TUI for Git with staging, conflicts, rebase, and palette-first UX
Documentation
use crate::app::{actions::Action, state::AppState};

pub fn handle(state: &mut AppState, action: &Action) -> bool {
    match action {
        Action::FilterConflictsOnly => {
            state.conflicts_only = true;
        }
        Action::ClearConflictFilter => {
            state.conflicts_only = false;
        }
        Action::StartFilter => {
            state.filter_mode = true;
            state.status_filter.clear();
        }
        Action::CancelFilter => {
            state.filter_mode = false;
            state.status_filter.clear();
        }
        Action::SetStatusFilter(s) => {
            state.status_filter = s.clone();
        }
        Action::SetFilterMode(on) => {
            state.filter_mode = *on;
        }
        Action::FilterInputChar(c) => {
            state.status_filter.push(*c);
        }
        Action::FilterInputBackspace => {
            state.status_filter.pop();
        }
        Action::ShowConflictsPopup => {
            state.conflicts_popup = true;
            state.conflicts_popup_selected = 0;
            state.conflicts_only = true;
            state.command_palette = false;
        }
        Action::HideConflictsPopup => {
            state.conflicts_popup = false;
        }
        Action::ConflictsPopupUp => {
            if state.conflicts_popup_selected > 0 {
                state.conflicts_popup_selected -= 1;
            }
        }
        Action::ConflictsPopupDown => {
            let total_conflicts = state
                .status_entries
                .iter()
                .filter(|e| e.conflict)
                .count()
                .saturating_sub(1);
            if state.conflicts_popup_selected < total_conflicts {
                state.conflicts_popup_selected += 1;
            }
        }
        Action::SelectConflict(path) => {
            if let Some((idx, _)) = state
                .status_entries
                .iter()
                .enumerate()
                .find(|(_, e)| &e.path == path)
            {
                state.status_selected = idx;
                state.status_selected_path = path.clone();
            }
            state.conflicts_only = true;
            state.conflicts_popup = false;
        }
        Action::OpenConflictInEditor(path) => {
            if let Some((idx, _)) = state
                .status_entries
                .iter()
                .enumerate()
                .find(|(_, e)| &e.path == path)
            {
                state.status_selected = idx;
                state.status_selected_path = path.clone();
            }
            state.conflicts_only = true;
            state.conflicts_popup = false;
        }
        Action::ShowConflictsGuided => {
            state.conflicts_guided = true;
            state.conflicts_guided_selected = 0;
            state.conflicts_only = true;
            state.command_palette = false;
        }
        Action::HideConflictsGuided => {
            state.conflicts_guided = false;
        }
        Action::ConflictsGuidedUp => {
            if state.conflicts_guided_selected > 0 {
                state.conflicts_guided_selected -= 1;
            }
        }
        Action::ConflictsGuidedDown => {
            let total_conflicts = state
                .status_entries
                .iter()
                .filter(|e| e.conflict)
                .count()
                .saturating_sub(1);
            if state.conflicts_guided_selected < total_conflicts {
                state.conflicts_guided_selected += 1;
            }
        }
        Action::OpenGuidedConflictInEditor => {
            let conflicts: Vec<&crate::git::parsers::status::StatusEntry> = state
                .status_entries
                .iter()
                .filter(|e| e.conflict)
                .collect();
            let idx = state.conflicts_guided_selected.min(conflicts.len().saturating_sub(1));
            if let Some(entry) = conflicts.get(idx) {
                if let Some((sel_idx, _)) = state
                    .status_entries
                    .iter()
                    .enumerate()
                    .find(|(_, e)| e.path == entry.path)
                {
                    state.status_selected = sel_idx;
                    state.status_selected_path = entry.path.clone();
                }
            }
            state.conflicts_guided = false;
        }
        _ => return false,
    }
    true
}