gitkraft_gui/features/diff/
update.rs1use iced::Task;
4
5use crate::message::Message;
6use crate::state::GitKraft;
7
8pub(crate) fn update(state: &mut GitKraft, message: Message) -> Task<Message> {
11 match message {
12 Message::SelectDiffByIndex(index) => {
13 let shift_held = state.keyboard_modifiers.shift();
14 let tab = state.active_tab();
15 let repo_path = tab.repo_path.clone();
16 let oid = tab.selected_commit_oid.clone();
17
18 if shift_held {
19 let anchor = state
21 .active_tab()
22 .anchor_file_index
23 .or(state.active_tab().selected_file_index);
24
25 let range = crate::view_utils::shift_click_range(anchor, index);
26 let count = range.len();
27
28 let tab = state.active_tab_mut();
29 tab.selected_commit_file_indices = range;
30 tab.selected_file_index = Some(index);
31
32 if count == 1 {
33 tab.multi_file_diffs.clear();
36 let file_entry = tab.commit_files.get(index).cloned();
37 if let (Some(entry), Some(path), Some(oid)) = (file_entry, repo_path, oid) {
38 let file_path = entry.display_path().to_string();
39 let tab = state.active_tab_mut();
40 tab.is_loading_file_diff = true;
41 tab.diff_scroll_offset = 0.0;
42 return crate::features::commits::commands::load_single_file_diff(
43 path, oid, file_path,
44 );
45 }
46 } else {
47 tab.selected_diff = None;
49 tab.is_loading_file_diff = true;
50 tab.diff_scroll_offset = 0.0;
51 let file_paths: Vec<String> = tab
52 .selected_commit_file_indices
53 .iter()
54 .filter_map(|&i| {
55 tab.commit_files
56 .get(i)
57 .map(|f| f.display_path().to_string())
58 })
59 .collect();
60 if let (Some(path), Some(oid)) = (repo_path, oid) {
61 return crate::features::commits::commands::load_commit_multi_diffs(
62 path, oid, file_paths,
63 );
64 }
65 }
66 Task::none()
67 } else {
68 let tab = state.active_tab_mut();
70 tab.anchor_file_index = Some(index); tab.selected_commit_file_indices.clear();
72 let file_entry = tab.commit_files.get(index).cloned();
81 if let (Some(entry), Some(path), Some(oid)) = (file_entry, repo_path, oid) {
82 let file_path = entry.display_path().to_string();
83 let tab = state.active_tab_mut();
84 tab.selected_file_index = Some(index);
85 tab.is_loading_file_diff = true;
86 crate::features::commits::commands::load_single_file_diff(path, oid, file_path)
87 } else {
88 Task::none()
89 }
90 }
91 }
92
93 Message::LoadStagingFileDiff(path, staged) => {
94 state.active_tab_mut().context_menu = None;
95 if let Some(repo_path) = state.active_tab().repo_path.clone() {
96 crate::features::staging::commands::load_staging_file_diff(repo_path, path, staged)
97 } else {
98 Task::none()
99 }
100 }
101
102 Message::StagingFileDiffLoaded(result) => {
103 let tab = state.active_tab_mut();
104 match result {
105 Ok(diff) => {
106 tab.selected_diff = Some(diff);
107 tab.diff_scroll_offset = 0.0;
108 }
109 Err(e) => {
110 tab.error_message = Some(format!("Failed to load staging diff: {e}"));
111 }
112 }
113 clear_preview!(state);
115 Task::none()
116 }
117
118 Message::CommitMultiDiffLoaded(result) => {
119 let tab = state.active_tab_mut();
120 tab.is_loading_file_diff = false;
121 match result {
122 Ok(diffs) => {
123 tab.multi_file_diffs = diffs;
124 tab.selected_diff = None;
125 tab.diff_scroll_offset = 0.0;
126 }
127 Err(e) => {
128 tab.multi_file_diffs.clear();
129 tab.error_message = Some(format!("Failed to load multi-file diff: {e}"));
130 }
131 }
132 Task::none()
133 }
134
135 _ => Task::none(),
136 }
137}