gitkraft_gui/features/commits/
update.rs1use iced::Task;
4
5use crate::message::Message;
6use crate::state::GitKraft;
7
8use super::commands;
9
10pub fn update(state: &mut GitKraft, message: Message) -> Task<Message> {
13 match message {
14 Message::SelectCommit(index) => {
15 let repo_path = state.active_tab().repo_path.clone();
17 let commit_info = state
18 .active_tab()
19 .commits
20 .get(index)
21 .map(|c| (c.oid.clone(), c.short_oid.clone()));
22
23 let tab = state.active_tab_mut();
24 tab.selected_commit = Some(index);
25 tab.show_commit_detail = true;
26 tab.commit_files.clear();
28 tab.selected_diff = None;
29 tab.selected_file_index = None;
30 tab.diff_scroll_offset = 0.0;
31
32 if let (Some(path), Some((oid, short_oid))) = (repo_path, commit_info) {
34 let tab = state.active_tab_mut();
35 tab.status_message = Some(format!("Loading files for {short_oid}…"));
36 tab.selected_commit_oid = Some(oid.clone());
37 commands::load_commit_file_list(path, oid)
38 } else {
39 Task::none()
40 }
41 }
42
43 Message::CommitFileListLoaded(result) => {
44 match result {
45 Ok(files) => {
46 let file_count = files.len();
47 let tab = state.active_tab_mut();
48 tab.commit_files = files;
49 tab.status_message = Some(format!("{file_count} file(s) changed."));
50
51 if file_count > 0 {
53 let first_file = &tab.commit_files[0];
54 let file_path = first_file.display_path().to_string();
55 tab.selected_file_index = Some(0);
56 tab.is_loading_file_diff = true;
57
58 if let (Some(repo_path), Some(oid)) =
59 (tab.repo_path.clone(), tab.selected_commit_oid.clone())
60 {
61 return commands::load_single_file_diff(repo_path, oid, file_path);
62 }
63 }
64 }
65 Err(e) => {
66 let tab = state.active_tab_mut();
67 tab.commit_files.clear();
68 tab.error_message = Some(format!("Failed to load commit files: {e}"));
69 tab.status_message = None;
70 }
71 }
72 Task::none()
73 }
74
75 Message::SingleFileDiffLoaded(result) => {
76 let tab = state.active_tab_mut();
77 tab.is_loading_file_diff = false;
78 match result {
79 Ok(diff) => {
80 tab.selected_diff = Some(diff);
81 tab.diff_scroll_offset = 0.0;
82 }
83 Err(e) => {
84 tab.selected_diff = None;
85 tab.error_message = Some(format!("Failed to load file diff: {e}"));
86 }
87 }
88 Task::none()
89 }
90
91 Message::CommitMessageChanged(msg) => {
92 state.active_tab_mut().commit_message = msg;
93 Task::none()
94 }
95
96 Message::CreateCommit => {
97 let msg;
98 let staged_empty;
99 {
100 let tab = state.active_tab();
101 msg = tab.commit_message.trim().to_string();
102 staged_empty = tab.staged_changes.is_empty();
103 }
104 if msg.is_empty() || staged_empty {
105 return Task::none();
106 }
107 with_repo!(state, loading, "Creating commit…".into(), |repo_path| {
108 commands::create_commit(repo_path, msg)
109 })
110 }
111
112 Message::CommitCreated(result) => {
113 state.active_tab_mut().is_loading = false;
114 match result {
115 Ok(()) => {
116 {
117 let tab = state.active_tab_mut();
118 tab.commit_message.clear();
119 tab.status_message = Some("Commit created.".into());
120 }
121 state.refresh_active_tab()
122 }
123 Err(e) => {
124 let tab = state.active_tab_mut();
125 tab.error_message = Some(format!("Commit failed: {e}"));
126 tab.status_message = None;
127 Task::none()
128 }
129 }
130 }
131
132 _ => Task::none(),
133 }
134}