use iced::Task;
use crate::message::{Message, RepoPayload};
use crate::state::GitKraft;
use super::commands;
pub fn update(state: &mut GitKraft, message: Message) -> Task<Message> {
match message {
Message::OpenRepo => {
let tab = state.active_tab_mut();
tab.is_loading = true;
tab.status_message = Some("Opening folder picker…".into());
commands::pick_folder_open()
}
Message::InitRepo => {
let tab = state.active_tab_mut();
tab.is_loading = true;
tab.status_message = Some("Opening folder picker for init…".into());
commands::pick_folder_init()
}
Message::RepoSelected(maybe_path) => {
if let Some(path) = maybe_path {
let tab = state.active_tab_mut();
tab.status_message = Some(format!("Opening {}…", path.display()));
commands::load_repo(path)
} else {
let tab = state.active_tab_mut();
tab.is_loading = false;
tab.status_message = None;
Task::none()
}
}
Message::RepoInitSelected(maybe_path) => {
if let Some(path) = maybe_path {
let tab = state.active_tab_mut();
tab.status_message = Some(format!("Initializing {}…", path.display()));
commands::init_repo(path)
} else {
let tab = state.active_tab_mut();
tab.is_loading = false;
tab.status_message = None;
Task::none()
}
}
Message::RepoOpened(result) => handle_repo_loaded(state, result),
Message::RefreshRepo => with_repo!(state, loading, "Refreshing…".into(), |path| {
commands::refresh_repo(path)
}),
Message::RepoRefreshed(result) => handle_repo_loaded(state, result),
Message::OpenRecentRepo(path) => {
let tab = state.active_tab_mut();
tab.is_loading = true;
tab.status_message = Some(format!("Opening {}…", path.display()));
commands::load_repo(path)
}
Message::CloseRepo => {
state.tabs[state.active_tab] = crate::state::RepoTab::new_empty();
state.dragging = None;
state.dragging_h = None;
state.drag_initialized = false;
state.drag_initialized_h = false;
let open_tabs = state.open_tab_paths();
let active = state.active_tab;
Task::batch([
commands::load_recent_repos_async(),
commands::save_session_async(open_tabs, active),
])
}
Message::RepoRestoredAt(tab_index, result) => {
handle_repo_loaded_at(state, tab_index, result)
}
Message::RepoRecorded(result) => {
if let Ok(recent) = result {
state.recent_repos = recent;
}
Task::none()
}
Message::SettingsLoaded(result) => {
if let Ok(recent) = result {
state.recent_repos = recent;
}
Task::none()
}
Message::MoreCommitsLoaded(result) => handle_more_commits_loaded(state, result),
Message::GitOperationResult(result) => handle_repo_loaded(state, result),
_ => Task::none(),
}
}
fn handle_repo_loaded(state: &mut GitKraft, result: Result<RepoPayload, String>) -> Task<Message> {
state.active_tab_mut().is_loading = false;
match result {
Ok(payload) => {
let path = payload
.info
.workdir
.clone()
.unwrap_or_else(|| payload.info.path.clone());
let tab = state.active_tab_mut();
tab.apply_payload(payload, path.clone());
tab.commit_display = compute_commit_display(&tab.commits);
let open_tabs = state.open_tab_paths();
let active = state.active_tab;
Task::batch([
commands::record_repo_and_save_session_async(path, open_tabs, active),
iced::widget::scrollable::scroll_to(
crate::features::commits::view::commit_log_scroll_id(active),
iced::widget::scrollable::AbsoluteOffset { x: 0.0, y: 0.0 },
),
])
}
Err(e) => {
let tab = state.active_tab_mut();
tab.error_message = Some(e);
tab.status_message = None;
Task::none()
}
}
}
fn handle_repo_loaded_at(
state: &mut GitKraft,
tab_index: usize,
result: Result<RepoPayload, String>,
) -> Task<Message> {
if tab_index >= state.tabs.len() {
return Task::none(); }
state.tabs[tab_index].is_loading = false;
match result {
Ok(payload) => {
let path = payload
.info
.workdir
.clone()
.unwrap_or_else(|| payload.info.path.clone());
let tab = &mut state.tabs[tab_index];
tab.apply_payload(payload, path);
tab.commit_display = compute_commit_display(&tab.commits);
Task::none()
}
Err(e) => {
let tab = &mut state.tabs[tab_index];
tab.error_message = Some(e);
tab.status_message = None;
Task::none()
}
}
}
fn handle_more_commits_loaded(
state: &mut GitKraft,
result: Result<crate::message::CommitPage, String>,
) -> Task<Message> {
let tab = state.active_tab_mut();
tab.is_loading_more_commits = false;
match result {
Ok(page) => {
let prev_count = tab.commits.len();
let new_total = page.commits.len();
tab.has_more_commits = new_total > prev_count;
if new_total > prev_count {
let new_display = compute_commit_display(&page.commits[prev_count..]);
tab.commit_display.extend(new_display);
}
tab.commits = page.commits;
tab.graph_rows = page.graph_rows;
}
Err(e) => {
tab.status_message = Some(format!("Failed to load more commits: {e}"));
}
}
Task::none()
}
fn compute_commit_display(commits: &[gitkraft_core::CommitInfo]) -> Vec<(String, String, String)> {
commits
.iter()
.map(|c| {
let summary = c.summary.clone();
let time = gitkraft_core::utils::relative_time(c.time);
let author = gitkraft_core::truncate_str(&c.author_name, 14);
(summary, time, author)
})
.collect()
}